From 07a375e2d626428f5a1b9f02907120a4b3b3a08a Mon Sep 17 00:00:00 2001 From: raysan5 Date: Tue, 26 Jul 2016 13:02:25 +0200 Subject: Corrected issue with HIghDPI display on OSX Well, not tested yet but it should work... --- src/core.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/core.c') diff --git a/src/core.c b/src/core.c index a3253d79..022fbfe9 100644 --- a/src/core.c +++ b/src/core.c @@ -1614,7 +1614,14 @@ static void InitGraphicsDevice(int width, int height) TraceLog(INFO, "Trying to enable VSYNC"); } - //glfwGetFramebufferSize(window, &renderWidth, &renderHeight); // Get framebuffer size of current window +#ifdef __APPLE__ + // Get framebuffer size of current window + // NOTE: Required to handle HighDPI display correctly + // TODO: Probably should be added for other systems too or managed + // internally by GLFW3 callback: glfwSetFramebufferSizeCallback() + glfwGetFramebufferSize(window, &renderWidth, &renderHeight); +#endif + #endif // defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) #if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) @@ -1765,6 +1772,7 @@ static void InitGraphicsDevice(int width, int height) #endif // defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) // Initialize OpenGL context (states and resources) + // NOTE: screenWidth and screenHeight not used, just stored as globals rlglInit(screenWidth, screenHeight); // Initialize screen viewport (area of the screen that you will actually draw to) -- cgit v1.2.3 From a422e394925e68ab687ef70527c3e207234d8bd7 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Tue, 26 Jul 2016 16:55:46 +0200 Subject: Corrected issue on OSX with High DPI display Many thanks to Marcelo Paez (paezao) --- README.md | 1 + src/core.c | 21 +++++++++++---------- 2 files changed, 12 insertions(+), 10 deletions(-) (limited to 'src/core.c') diff --git a/README.md b/README.md index 71052a0f..64cfcc53 100644 --- a/README.md +++ b/README.md @@ -249,6 +249,7 @@ contributing (in some way or another) to make raylib project better. Huge thanks - [Chris Hemingway](https://github.com/cHemingway) for improving raylib on OSX build system. - [Emanuele Petriglia](https://github.com/LelixSuper) for working on multiple GNU/Linux improvements and developing [TicTacToe](https://github.com/LelixSuper/TicTacToe) raylib game. - [Joshua Reisenauer](https://github.com/kd7tck) for adding audio modules support (XM, MOD) and reviewing audio system. + - Marcelo Paez (paezao) for his help on OSX to solve High DPI display issue. Thanks Marcelo! [raysan5]: mailto:raysan5@gmail.com "Ramon Santamaria - Ray San" diff --git a/src/core.c b/src/core.c index 022fbfe9..0008ef2f 100644 --- a/src/core.c +++ b/src/core.c @@ -1612,16 +1612,7 @@ static void InitGraphicsDevice(int width, int height) { glfwSwapInterval(1); TraceLog(INFO, "Trying to enable VSYNC"); - } - -#ifdef __APPLE__ - // Get framebuffer size of current window - // NOTE: Required to handle HighDPI display correctly - // TODO: Probably should be added for other systems too or managed - // internally by GLFW3 callback: glfwSetFramebufferSizeCallback() - glfwGetFramebufferSize(window, &renderWidth, &renderHeight); -#endif - + } #endif // defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) #if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) @@ -1775,9 +1766,19 @@ static void InitGraphicsDevice(int width, int height) // NOTE: screenWidth and screenHeight not used, just stored as globals rlglInit(screenWidth, screenHeight); +#ifdef __APPLE__ + // Get framebuffer size of current window + // NOTE: Required to handle HighDPI display correctly on OSX because framebuffer + // is automatically reasized to adapt to new DPI. + // When OS does that, it can be detected using GLFW3 callback: glfwSetFramebufferSizeCallback() + int fbWidth, fbHeight; + glfwGetFramebufferSize(window, &fbWidth, &fbHeight); + rlViewport(renderOffsetX/2, renderOffsetY/2, fbWidth - renderOffsetX, fbHeight - renderOffsetY); +#else // Initialize screen viewport (area of the screen that you will actually draw to) // NOTE: Viewport must be recalculated if screen is resized rlViewport(renderOffsetX/2, renderOffsetY/2, renderWidth - renderOffsetX, renderHeight - renderOffsetY); +#endif // Initialize internal projection and modelview matrices // NOTE: Default to orthographic projection mode with top-left corner at (0,0) -- cgit v1.2.3 From d5f5f0a9302435945b730e5ec001bda39741f3c7 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sat, 6 Aug 2016 11:33:05 +0200 Subject: Updated raylib version to 1.6 --- src/core.c | 4 ++-- src/raylib.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/core.c') diff --git a/src/core.c b/src/core.c index 0008ef2f..47463a23 100644 --- a/src/core.c +++ b/src/core.c @@ -293,7 +293,7 @@ static void *GamepadThread(void *arg); // Mouse reading thread // Initialize Window and Graphics Context (OpenGL) void InitWindow(int width, int height, const char *title) { - TraceLog(INFO, "Initializing raylib (v1.5.0)"); + TraceLog(INFO, "Initializing raylib (v1.6.0)"); // Store window title (could be useful...) windowTitle = title; @@ -347,7 +347,7 @@ void InitWindow(int width, int height, const char *title) // Android activity initialization void InitWindow(int width, int height, struct android_app *state) { - TraceLog(INFO, "Initializing raylib (v1.5.0)"); + TraceLog(INFO, "Initializing raylib (v1.6.0)"); app_dummy(); diff --git a/src/raylib.h b/src/raylib.h index d9a12cec..104d5677 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1,6 +1,6 @@ /********************************************************************************************** * -* raylib 1.5.0 (www.raylib.com) +* raylib 1.6.0 (www.raylib.com) * * A simple and easy-to-use library to learn videogames programming * -- cgit v1.2.3 From 3b80e2c1e03e0f87d50ca8876b50a11c7df1f56f Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sat, 6 Aug 2016 16:32:46 +0200 Subject: Redesigned gestures module to header-only --- src/Makefile | 6 +- src/core.c | 16 +- src/gestures.c | 423 -------------------------------------------------- src/gestures.h | 480 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- src/raylib.h | 17 +- src/rlua.h | 10 +- 6 files changed, 458 insertions(+), 494 deletions(-) delete mode 100644 src/gestures.c (limited to 'src/core.c') diff --git a/src/Makefile b/src/Makefile index 1360a920..e82c2861 100644 --- a/src/Makefile +++ b/src/Makefile @@ -168,7 +168,7 @@ endif # compile all modules with their prerequisites # compile core module -core.o : core.c raylib.h rlgl.h utils.h raymath.h +core.o : core.c raylib.h rlgl.h utils.h raymath.h gestures.h $(CC) -c $< $(CFLAGS) $(INCLUDES) -D$(PLATFORM) # compile rlgl module @@ -207,10 +207,6 @@ utils.o : utils.c utils.h camera.o : camera.c raylib.h $(CC) -c $< $(CFLAGS) $(INCLUDES) -#compile gestures module -gestures.o : gestures.c raylib.h - $(CC) -c $< $(CFLAGS) $(INCLUDES) - # It installs generated and needed files to compile projects using raylib. # The installation works manually. # TODO: add other platforms. diff --git a/src/core.c b/src/core.c index 47463a23..4cb34b0a 100644 --- a/src/core.c +++ b/src/core.c @@ -39,13 +39,15 @@ #include "raylib.h" // raylib main header #include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2 -#include "utils.h" // TraceLog() function - // NOTE: Includes Android fopen map, InitAssetManager() - +#include "utils.h" // Includes Android fopen map, InitAssetManager(), TraceLog() + #define RAYMATH_IMPLEMENTATION // Use raymath as a header-only library (includes implementation) #define RAYMATH_EXTERN_INLINE // Compile raymath functions as static inline (remember, it's a compiler hint) #include "raymath.h" // Required for Vector3 and Matrix functions +#define GESTURES_IMPLEMENTATION +#include "gestures.h" // Gestures detection functionality + #include // Standard input / output lib #include // Declares malloc() and free() for memory management, rand(), atexit() #include // Required for typedef unsigned long long int uint64_t, used by hi-res timer @@ -234,6 +236,9 @@ static bool showLogo = false; // Track if showing logo at init is extern void LoadDefaultFont(void); // [Module: text] Loads default font on InitWindow() extern void UnloadDefaultFont(void); // [Module: text] Unloads default font from GPU memory +extern void ProcessGestureEvent(GestureEvent event); // [Module: gestures] Process gesture event and translate it into gestures +extern void UpdateGestures(void); // [Module: gestures] Update gestures detected (called in PollInputEvents()) + //---------------------------------------------------------------------------------- // Module specific Functions Declaration //---------------------------------------------------------------------------------- @@ -2052,10 +2057,7 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i // NOTE: Before closing window, while loop must be left! } #if defined(PLATFORM_DESKTOP) - else if (key == GLFW_KEY_F12 && action == GLFW_PRESS) - { - TakeScreenshot(); - } + else if (key == GLFW_KEY_F12 && action == GLFW_PRESS) TakeScreenshot(); #endif else { diff --git a/src/gestures.c b/src/gestures.c deleted file mode 100644 index 57b96bd2..00000000 --- a/src/gestures.c +++ /dev/null @@ -1,423 +0,0 @@ -/********************************************************************************************** -* -* raylib Gestures System - Gestures Processing based on input gesture events (touch/mouse) -* -* Initial design by Marc Palau -* Redesigned by Albert Martos and Ian Eito -* Reviewed by 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 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: Vector2, Gestures -#endif - -#include // Required for: atan2(), sqrt() -#include // Required for: uint64_t - -#if defined(_WIN32) - // Functions required to query time on Windows - int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount); - int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency); -#elif defined(__linux) - #include // Required for: timespec - #include // Required for: clock_gettime() -#endif - -//---------------------------------------------------------------------------------- -// Defines and Macros -//---------------------------------------------------------------------------------- -#define FORCE_TO_SWIPE 0.0005f // Measured in normalized screen units/time -#define MINIMUM_DRAG 0.015f // Measured in normalized screen units (0.0f to 1.0f) -#define MINIMUM_PINCH 0.005f // Measured in normalized screen units (0.0f to 1.0f) -#define TAP_TIMEOUT 300 // Time in milliseconds -#define PINCH_TIMEOUT 300 // Time in milliseconds -#define DOUBLETAP_RANGE 0.03f // Measured in normalized screen units (0.0f to 1.0f) - -//---------------------------------------------------------------------------------- -// Types and Structures Definition -//---------------------------------------------------------------------------------- -// ... - -//---------------------------------------------------------------------------------- -// Global Variables Definition -//---------------------------------------------------------------------------------- - -// Touch gesture variables -static Vector2 touchDownPosition = { 0.0f, 0.0f }; -static Vector2 touchDownPosition2 = { 0.0f, 0.0f }; -static Vector2 touchDownDragPosition = { 0.0f, 0.0f }; -static Vector2 touchUpPosition = { 0.0f, 0.0f }; -static Vector2 moveDownPosition = { 0.0f, 0.0f }; -static Vector2 moveDownPosition2 = { 0.0f, 0.0f }; -static int numTap = 0; - -static int pointCount = 0; -static int firstTouchId = -1; - -static double eventTime = 0.0; -static double swipeTime = 0.0; - -// Hold gesture variables -static int numHold = 0; -static float timeHold = 0.0f; - -// Drag gesture variables -static Vector2 dragVector = { 0.0f , 0.0f }; // DRAG vector (between initial and current position) -static float dragAngle = 0.0f; // DRAG angle (relative to x-axis) -static float dragDistance = 0.0f; // DRAG distance (from initial touch point to final) (normalized [0..1]) -static float dragIntensity = 0.0f; // DRAG intensity, how far why did the DRAG (pixels per frame) -static bool startMoving = false; // SWIPE used to define when start measuring swipeTime - -// Pinch gesture variables -static Vector2 pinchVector = { 0.0f , 0.0f }; // PINCH vector (between first and second touch points) -static float pinchAngle = 0.0f; // PINCH angle (relative to x-axis) -static float pinchDistance = 0.0f; // PINCH displacement distance (normalized [0..1]) - -// Detected gestures -static int previousGesture = GESTURE_NONE; -static int currentGesture = GESTURE_NONE; - -// Enabled gestures flags, all gestures enabled by default -static unsigned int enabledGestures = 0b0000001111111111; - -//---------------------------------------------------------------------------------- -// Module specific Functions Declaration -//---------------------------------------------------------------------------------- -static float Vector2Angle(Vector2 initialPosition, Vector2 finalPosition); -static float Vector2Distance(Vector2 v1, Vector2 v2); -static double GetCurrentTime(void); - -//---------------------------------------------------------------------------------- -// Module Functions Definition -//---------------------------------------------------------------------------------- - -// Enable only desired getures to be detected -void SetGesturesEnabled(unsigned int gestureFlags) -{ - enabledGestures = gestureFlags; -} - -// Check if a gesture have been detected -bool IsGestureDetected(int gesture) -{ - if ((enabledGestures & currentGesture) == gesture) return true; - else return false; -} - -// Process gesture event and translate it into gestures -void ProcessGestureEvent(GestureEvent event) -{ - // Reset required variables - previousGesture = currentGesture; - - pointCount = event.pointCount; // Required on UpdateGestures() - - if (pointCount < 2) - { - if (event.touchAction == TOUCH_DOWN) - { - numTap++; // Tap counter - - // Detect GESTURE_DOUBLE_TAP - if ((currentGesture == GESTURE_NONE) && (numTap >= 2) && ((GetCurrentTime() - eventTime) < TAP_TIMEOUT) && (Vector2Distance(touchDownPosition, event.position[0]) < DOUBLETAP_RANGE)) - { - currentGesture = GESTURE_DOUBLETAP; - numTap = 0; - } - else // Detect GESTURE_TAP - { - numTap = 1; - currentGesture = GESTURE_TAP; - } - - touchDownPosition = event.position[0]; - touchDownDragPosition = event.position[0]; - - touchUpPosition = touchDownPosition; - eventTime = GetCurrentTime(); - - firstTouchId = event.pointerId[0]; - - dragVector = (Vector2){ 0.0f, 0.0f }; - } - else if (event.touchAction == TOUCH_UP) - { - if (currentGesture == GESTURE_DRAG) touchUpPosition = event.position[0]; - - // NOTE: dragIntensity dependend on the resolution of the screen - dragDistance = Vector2Distance(touchDownPosition, touchUpPosition); - dragIntensity = dragDistance/(float)((GetCurrentTime() - swipeTime)); - - startMoving = false; - - // Detect GESTURE_SWIPE - if ((dragIntensity > FORCE_TO_SWIPE) && firstTouchId == event.pointerId[0]) - { - // NOTE: Angle should be inverted in Y - dragAngle = 360.0f - Vector2Angle(touchDownPosition, touchUpPosition); - - if ((dragAngle < 30) || (dragAngle > 330)) currentGesture = GESTURE_SWIPE_RIGHT; // Right - else if ((dragAngle > 30) && (dragAngle < 120)) currentGesture = GESTURE_SWIPE_UP; // Up - else if ((dragAngle > 120) && (dragAngle < 210)) currentGesture = GESTURE_SWIPE_LEFT; // Left - else if ((dragAngle > 210) && (dragAngle < 300)) currentGesture = GESTURE_SWIPE_DOWN; // Down - else currentGesture = GESTURE_NONE; - } - else - { - dragDistance = 0.0f; - dragIntensity = 0.0f; - dragAngle = 0.0f; - - currentGesture = GESTURE_NONE; - } - - touchDownDragPosition = (Vector2){ 0.0f, 0.0f }; - pointCount = 0; - } - else if (event.touchAction == TOUCH_MOVE) - { - if (currentGesture == GESTURE_DRAG) eventTime = GetCurrentTime(); - - if (!startMoving) - { - swipeTime = GetCurrentTime(); - startMoving = true; - } - - moveDownPosition = event.position[0]; - - if (currentGesture == GESTURE_HOLD) - { - if (numHold == 1) touchDownPosition = event.position[0]; - - numHold = 2; - - // Detect GESTURE_DRAG - if (Vector2Distance(touchDownPosition, moveDownPosition) >= MINIMUM_DRAG) - { - eventTime = GetCurrentTime(); - currentGesture = GESTURE_DRAG; - } - } - - dragVector.x = moveDownPosition.x - touchDownDragPosition.x; - dragVector.y = moveDownPosition.y - touchDownDragPosition.y; - } - } - else // Two touch points - { - if (event.touchAction == TOUCH_DOWN) - { - touchDownPosition = event.position[0]; - touchDownPosition2 = event.position[1]; - - //pinchDistance = Vector2Distance(touchDownPosition, touchDownPosition2); - - pinchVector.x = touchDownPosition2.x - touchDownPosition.x; - pinchVector.y = touchDownPosition2.y - touchDownPosition.y; - - currentGesture = GESTURE_HOLD; - timeHold = GetCurrentTime(); - } - else if (event.touchAction == TOUCH_MOVE) - { - pinchDistance = Vector2Distance(moveDownPosition, moveDownPosition2); - - touchDownPosition = moveDownPosition; - touchDownPosition2 = moveDownPosition2; - - moveDownPosition = event.position[0]; - moveDownPosition2 = event.position[1]; - - pinchVector.x = moveDownPosition2.x - moveDownPosition.x; - pinchVector.y = moveDownPosition2.y - moveDownPosition.y; - - if ((Vector2Distance(touchDownPosition, moveDownPosition) >= MINIMUM_PINCH) || (Vector2Distance(touchDownPosition2, moveDownPosition2) >= MINIMUM_PINCH)) - { - if ((Vector2Distance(moveDownPosition, moveDownPosition2) - pinchDistance) < 0) currentGesture = GESTURE_PINCH_IN; - else currentGesture = GESTURE_PINCH_OUT; - } - else - { - currentGesture = GESTURE_HOLD; - timeHold = GetCurrentTime(); - } - - // NOTE: Angle should be inverted in Y - pinchAngle = 360.0f - Vector2Angle(moveDownPosition, moveDownPosition2); - } - else if (event.touchAction == TOUCH_UP) - { - pinchDistance = 0.0f; - pinchAngle = 0.0f; - pinchVector = (Vector2){ 0.0f, 0.0f }; - pointCount = 0; - - currentGesture = GESTURE_NONE; - } - } -} - -// Update gestures detected (must be called every frame) -void UpdateGestures(void) -{ - // NOTE: Gestures are processed through system callbacks on touch events - - // Detect GESTURE_HOLD - if (((currentGesture == GESTURE_TAP) || (currentGesture == GESTURE_DOUBLETAP)) && (pointCount < 2)) - { - currentGesture = GESTURE_HOLD; - timeHold = GetCurrentTime(); - } - - if (((GetCurrentTime() - eventTime) > TAP_TIMEOUT) && (currentGesture == GESTURE_DRAG) && (pointCount < 2)) - { - currentGesture = GESTURE_HOLD; - timeHold = GetCurrentTime(); - numHold = 1; - } - - // Detect GESTURE_NONE - if ((currentGesture == GESTURE_SWIPE_RIGHT) || (currentGesture == GESTURE_SWIPE_UP) || (currentGesture == GESTURE_SWIPE_LEFT) || (currentGesture == GESTURE_SWIPE_DOWN)) - { - currentGesture = GESTURE_NONE; - } -} - -// Get number of touch points -int GetTouchPointsCount(void) -{ - // NOTE: point count is calculated when ProcessGestureEvent(GestureEvent event) is called - - return pointCount; -} - -// Get latest detected gesture -int GetGestureDetected(void) -{ - // Get current gesture only if enabled - return (enabledGestures & currentGesture); -} - -// Hold time measured in ms -float GetGestureHoldDuration(void) -{ - // NOTE: time is calculated on current gesture HOLD - - float time = 0.0f; - - if (currentGesture == GESTURE_HOLD) time = (float)GetCurrentTime() - timeHold; - - return time; -} - -// Get drag vector (between initial touch point to current) -Vector2 GetGestureDragVector(void) -{ - // NOTE: drag vector is calculated on one touch points TOUCH_MOVE - - return dragVector; -} - -// Get drag angle -// NOTE: Angle in degrees, horizontal-right is 0, counterclock-wise -float GetGestureDragAngle(void) -{ - // NOTE: drag angle is calculated on one touch points TOUCH_UP - - return dragAngle; -} - -// Get distance between two pinch points -Vector2 GetGesturePinchVector(void) -{ - // NOTE: The position values used for pinchDistance are not modified like the position values of [core.c]-->GetTouchPosition(int index) - // NOTE: pinch distance is calculated on two touch points TOUCH_MOVE - - return pinchVector; -} - -// Get angle beween two pinch points -// NOTE: Angle in degrees, horizontal-right is 0, counterclock-wise -float GetGesturePinchAngle(void) -{ - // NOTE: pinch angle is calculated on two touch points TOUCH_MOVE - - return pinchAngle; -} - -//---------------------------------------------------------------------------------- -// Module specific Functions Definition -//---------------------------------------------------------------------------------- - -// Returns angle from two-points vector with X-axis -static float Vector2Angle(Vector2 initialPosition, Vector2 finalPosition) -{ - float angle; - - angle = atan2(finalPosition.y - initialPosition.y, finalPosition.x - initialPosition.x); - angle *= RAD2DEG; - - if (angle < 0) angle += 360.0f; - - return angle; -} - -// Calculate distance between two Vector2 -static float Vector2Distance(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; -} - -// Time measure returned are milliseconds -static double GetCurrentTime(void) -{ - double time = 0; - -#if defined(_WIN32) - unsigned long long int clockFrequency, currentTime; - - QueryPerformanceFrequency(&clockFrequency); - QueryPerformanceCounter(¤tTime); - - time = (double)currentTime/clockFrequency*1000.0f; // Time in miliseconds -#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 in nanoseconds - - time = ((double)nowTime/1000000.0); // Time in miliseconds -#endif - - return time; -} diff --git a/src/gestures.h b/src/gestures.h index 912d0b92..4c59ee39 100644 --- a/src/gestures.h +++ b/src/gestures.h @@ -1,8 +1,21 @@ /********************************************************************************************** * -* raylib Gestures System - Gestures Detection and Usage Functions (Android and HTML5) +* raylib Gestures System - Gestures Processing based on input gesture events (touch/mouse) * -* Copyright (c) 2015 Marc Palau and Ramon Santamaria +* #define GESTURES_IMPLEMENTATION +* Generates the implementation of the library into the included file. +* If not defined, the library is in header only mode and can be included in other headers +* or source files without problems. But only ONE file should hold the implementation. +* +* #define GESTURES_STANDALONE +* If defined, the library can be used as standalone to process gesture events with +* no external dependencies. +* +* NOTE: Memory footprint of this library is aproximately 128 bytes +* +* Initial design by Marc Palau +* Redesigned by Albert Martos and Ian Eito +* Reviewed by 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. @@ -28,9 +41,6 @@ #define PI 3.14159265358979323846 #endif -#define DEG2RAD (PI / 180.0f) -#define RAD2DEG (180.0f / PI) - //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- @@ -40,32 +50,34 @@ // Types and Structures Definition // NOTE: Below types are required for GESTURES_STANDALONE usage //---------------------------------------------------------------------------------- -#ifndef __cplusplus - // Boolean type - typedef enum { false, true } bool; -#endif +#if defined(GESTURES_STANDALONE) + #ifndef __cplusplus + // Boolean type + typedef enum { false, true } bool; + #endif + + // Vector2 type + typedef struct Vector2 { + float x; + float y; + } Vector2; -// Vector2 type -typedef struct Vector2 { - float x; - float y; -} Vector2; - -// Gestures type -// NOTE: It could be used as flags to enable only some gestures -typedef enum { - GESTURE_NONE = 1, - GESTURE_TAP = 2, - GESTURE_DOUBLETAP = 4, - GESTURE_HOLD = 8, - GESTURE_DRAG = 16, - GESTURE_SWIPE_RIGHT = 32, - GESTURE_SWIPE_LEFT = 64, - GESTURE_SWIPE_UP = 128, - GESTURE_SWIPE_DOWN = 256, - GESTURE_PINCH_IN = 512, - GESTURE_PINCH_OUT = 1024 -} Gestures; + // Gestures type + // NOTE: It could be used as flags to enable only some gestures + typedef enum { + GESTURE_NONE = 1, + GESTURE_TAP = 2, + GESTURE_DOUBLETAP = 4, + GESTURE_HOLD = 8, + GESTURE_DRAG = 16, + GESTURE_SWIPE_RIGHT = 32, + GESTURE_SWIPE_LEFT = 64, + GESTURE_SWIPE_UP = 128, + GESTURE_SWIPE_DOWN = 256, + GESTURE_PINCH_IN = 512, + GESTURE_PINCH_OUT = 1024 + } Gestures; +#endif typedef enum { TOUCH_UP, TOUCH_DOWN, TOUCH_MOVE } TouchAction; @@ -90,22 +102,422 @@ extern "C" { // Prevents name mangling of functions //---------------------------------------------------------------------------------- // Module Functions Declaration //---------------------------------------------------------------------------------- -void SetGesturesEnabled(unsigned int gestureFlags); // Enable a set of gestures using flags -bool IsGestureDetected(int gesture); // Check if a gesture have been detected void ProcessGestureEvent(GestureEvent event); // Process gesture event and translate it into gestures void UpdateGestures(void); // Update gestures detected (must be called every frame) -int GetTouchPointsCount(void); // Get touch points count +#if defined(GESTURES_STANDALONE) +void SetGesturesEnabled(unsigned int gestureFlags); // Enable a set of gestures using flags +bool IsGestureDetected(int gesture); // Check if a gesture have been detected int GetGestureDetected(void); // Get latest detected gesture +int GetTouchPointsCount(void); // Get touch points count float GetGestureHoldDuration(void); // Get gesture hold time in milliseconds Vector2 GetGestureDragVector(void); // Get gesture drag vector float GetGestureDragAngle(void); // Get gesture drag angle Vector2 GetGesturePinchVector(void); // Get gesture pinch delta float GetGesturePinchAngle(void); // Get gesture pinch angle - +#endif #ifdef __cplusplus } #endif #endif // GESTURES_H + +/*********************************************************************************** +* +* GESTURES IMPLEMENTATION +* +************************************************************************************/ + +#if defined(GESTURES_IMPLEMENTATION) + +#include // Required for: atan2(), sqrt() +#include // Required for: uint64_t + +#if defined(_WIN32) + // Functions required to query time on Windows + int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount); + int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency); +#elif defined(__linux) + #include // Required for: timespec + #include // Required for: clock_gettime() +#endif + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- +#define FORCE_TO_SWIPE 0.0005f // Measured in normalized screen units/time +#define MINIMUM_DRAG 0.015f // Measured in normalized screen units (0.0f to 1.0f) +#define MINIMUM_PINCH 0.005f // Measured in normalized screen units (0.0f to 1.0f) +#define TAP_TIMEOUT 300 // Time in milliseconds +#define PINCH_TIMEOUT 300 // Time in milliseconds +#define DOUBLETAP_RANGE 0.03f // Measured in normalized screen units (0.0f to 1.0f) + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +// ... + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- + +// Touch gesture variables +static Vector2 touchDownPosition = { 0.0f, 0.0f }; +static Vector2 touchDownPosition2 = { 0.0f, 0.0f }; +static Vector2 touchDownDragPosition = { 0.0f, 0.0f }; +static Vector2 touchUpPosition = { 0.0f, 0.0f }; +static Vector2 moveDownPosition = { 0.0f, 0.0f }; +static Vector2 moveDownPosition2 = { 0.0f, 0.0f }; + +static int pointCount = 0; // Touch points counter +static int firstTouchId = -1; // Touch id for first touch point +static double eventTime = 0.0; // Time stamp when an event happened + +// Tap gesture variables +static int tapCounter = 0; // TAP counter (one tap implies TOUCH_DOWN and TOUCH_UP actions) + +// Hold gesture variables +static bool resetHold = false; // HOLD reset to get first touch point again +static float timeHold = 0.0f; // HOLD duration in milliseconds + +// Drag gesture variables +static Vector2 dragVector = { 0.0f , 0.0f }; // DRAG vector (between initial and current position) +static float dragAngle = 0.0f; // DRAG angle (relative to x-axis) +static float dragDistance = 0.0f; // DRAG distance (from initial touch point to final) (normalized [0..1]) +static float dragIntensity = 0.0f; // DRAG intensity, how far why did the DRAG (pixels per frame) + +// Swipe gestures variables +static bool startMoving = false; // SWIPE used to define when start measuring swipeTime +static double swipeTime = 0.0; // SWIPE time to calculate drag intensity + +// Pinch gesture variables +static Vector2 pinchVector = { 0.0f , 0.0f }; // PINCH vector (between first and second touch points) +static float pinchAngle = 0.0f; // PINCH angle (relative to x-axis) +static float pinchDistance = 0.0f; // PINCH displacement distance (normalized [0..1]) + +static int currentGesture = GESTURE_NONE; // Current detected gesture + +// Enabled gestures flags, all gestures enabled by default +static unsigned int enabledGestures = 0b0000001111111111; + +//---------------------------------------------------------------------------------- +// Module specific Functions Declaration +//---------------------------------------------------------------------------------- +static float Vector2Angle(Vector2 initialPosition, Vector2 finalPosition); +static float Vector2Distance(Vector2 v1, Vector2 v2); +static double GetCurrentTime(void); + +//---------------------------------------------------------------------------------- +// Module Functions Definition +//---------------------------------------------------------------------------------- + +// Enable only desired getures to be detected +void SetGesturesEnabled(unsigned int gestureFlags) +{ + enabledGestures = gestureFlags; +} + +// Check if a gesture have been detected +bool IsGestureDetected(int gesture) +{ + if ((enabledGestures & currentGesture) == gesture) return true; + else return false; +} + +// Process gesture event and translate it into gestures +void ProcessGestureEvent(GestureEvent event) +{ + // Reset required variables + pointCount = event.pointCount; // Required on UpdateGestures() + + if (pointCount < 2) + { + if (event.touchAction == TOUCH_DOWN) + { + tapCounter++; // Tap counter + + // Detect GESTURE_DOUBLE_TAP + if ((currentGesture == GESTURE_NONE) && (tapCounter >= 2) && ((GetCurrentTime() - eventTime) < TAP_TIMEOUT) && (Vector2Distance(touchDownPosition, event.position[0]) < DOUBLETAP_RANGE)) + { + currentGesture = GESTURE_DOUBLETAP; + tapCounter = 0; + } + else // Detect GESTURE_TAP + { + tapCounter = 1; + currentGesture = GESTURE_TAP; + } + + touchDownPosition = event.position[0]; + touchDownDragPosition = event.position[0]; + + touchUpPosition = touchDownPosition; + eventTime = GetCurrentTime(); + + firstTouchId = event.pointerId[0]; + + dragVector = (Vector2){ 0.0f, 0.0f }; + } + else if (event.touchAction == TOUCH_UP) + { + if (currentGesture == GESTURE_DRAG) touchUpPosition = event.position[0]; + + // NOTE: dragIntensity dependend on the resolution of the screen + dragDistance = Vector2Distance(touchDownPosition, touchUpPosition); + dragIntensity = dragDistance/(float)((GetCurrentTime() - swipeTime)); + + startMoving = false; + + // Detect GESTURE_SWIPE + if ((dragIntensity > FORCE_TO_SWIPE) && (firstTouchId == event.pointerId[0])) + { + // NOTE: Angle should be inverted in Y + dragAngle = 360.0f - Vector2Angle(touchDownPosition, touchUpPosition); + + if ((dragAngle < 30) || (dragAngle > 330)) currentGesture = GESTURE_SWIPE_RIGHT; // Right + else if ((dragAngle > 30) && (dragAngle < 120)) currentGesture = GESTURE_SWIPE_UP; // Up + else if ((dragAngle > 120) && (dragAngle < 210)) currentGesture = GESTURE_SWIPE_LEFT; // Left + else if ((dragAngle > 210) && (dragAngle < 300)) currentGesture = GESTURE_SWIPE_DOWN; // Down + else currentGesture = GESTURE_NONE; + } + else + { + dragDistance = 0.0f; + dragIntensity = 0.0f; + dragAngle = 0.0f; + + currentGesture = GESTURE_NONE; + } + + touchDownDragPosition = (Vector2){ 0.0f, 0.0f }; + pointCount = 0; + } + else if (event.touchAction == TOUCH_MOVE) + { + if (currentGesture == GESTURE_DRAG) eventTime = GetCurrentTime(); + + if (!startMoving) + { + swipeTime = GetCurrentTime(); + startMoving = true; + } + + moveDownPosition = event.position[0]; + + if (currentGesture == GESTURE_HOLD) + { + if (resetHold) touchDownPosition = event.position[0]; + + resetHold = false; + + // Detect GESTURE_DRAG + if (Vector2Distance(touchDownPosition, moveDownPosition) >= MINIMUM_DRAG) + { + eventTime = GetCurrentTime(); + currentGesture = GESTURE_DRAG; + } + } + + dragVector.x = moveDownPosition.x - touchDownDragPosition.x; + dragVector.y = moveDownPosition.y - touchDownDragPosition.y; + } + } + else // Two touch points + { + if (event.touchAction == TOUCH_DOWN) + { + touchDownPosition = event.position[0]; + touchDownPosition2 = event.position[1]; + + //pinchDistance = Vector2Distance(touchDownPosition, touchDownPosition2); + + pinchVector.x = touchDownPosition2.x - touchDownPosition.x; + pinchVector.y = touchDownPosition2.y - touchDownPosition.y; + + currentGesture = GESTURE_HOLD; + timeHold = GetCurrentTime(); + } + else if (event.touchAction == TOUCH_MOVE) + { + pinchDistance = Vector2Distance(moveDownPosition, moveDownPosition2); + + touchDownPosition = moveDownPosition; + touchDownPosition2 = moveDownPosition2; + + moveDownPosition = event.position[0]; + moveDownPosition2 = event.position[1]; + + pinchVector.x = moveDownPosition2.x - moveDownPosition.x; + pinchVector.y = moveDownPosition2.y - moveDownPosition.y; + + if ((Vector2Distance(touchDownPosition, moveDownPosition) >= MINIMUM_PINCH) || (Vector2Distance(touchDownPosition2, moveDownPosition2) >= MINIMUM_PINCH)) + { + if ((Vector2Distance(moveDownPosition, moveDownPosition2) - pinchDistance) < 0) currentGesture = GESTURE_PINCH_IN; + else currentGesture = GESTURE_PINCH_OUT; + } + else + { + currentGesture = GESTURE_HOLD; + timeHold = GetCurrentTime(); + } + + // NOTE: Angle should be inverted in Y + pinchAngle = 360.0f - Vector2Angle(moveDownPosition, moveDownPosition2); + } + else if (event.touchAction == TOUCH_UP) + { + pinchDistance = 0.0f; + pinchAngle = 0.0f; + pinchVector = (Vector2){ 0.0f, 0.0f }; + pointCount = 0; + + currentGesture = GESTURE_NONE; + } + } +} + +// Update gestures detected (must be called every frame) +void UpdateGestures(void) +{ + // NOTE: Gestures are processed through system callbacks on touch events + + // Detect GESTURE_HOLD + if (((currentGesture == GESTURE_TAP) || (currentGesture == GESTURE_DOUBLETAP)) && (pointCount < 2)) + { + currentGesture = GESTURE_HOLD; + timeHold = GetCurrentTime(); + } + + if (((GetCurrentTime() - eventTime) > TAP_TIMEOUT) && (currentGesture == GESTURE_DRAG) && (pointCount < 2)) + { + currentGesture = GESTURE_HOLD; + timeHold = GetCurrentTime(); + resetHold = true; + } + + // Detect GESTURE_NONE + if ((currentGesture == GESTURE_SWIPE_RIGHT) || (currentGesture == GESTURE_SWIPE_UP) || (currentGesture == GESTURE_SWIPE_LEFT) || (currentGesture == GESTURE_SWIPE_DOWN)) + { + currentGesture = GESTURE_NONE; + } +} + +// Get number of touch points +int GetTouchPointsCount(void) +{ + // NOTE: point count is calculated when ProcessGestureEvent(GestureEvent event) is called + + return pointCount; +} + +// Get latest detected gesture +int GetGestureDetected(void) +{ + // Get current gesture only if enabled + return (enabledGestures & currentGesture); +} + +// Hold time measured in ms +float GetGestureHoldDuration(void) +{ + // NOTE: time is calculated on current gesture HOLD + + float time = 0.0f; + + if (currentGesture == GESTURE_HOLD) time = (float)GetCurrentTime() - timeHold; + + return time; +} + +// Get drag vector (between initial touch point to current) +Vector2 GetGestureDragVector(void) +{ + // NOTE: drag vector is calculated on one touch points TOUCH_MOVE + + return dragVector; +} + +// Get drag angle +// NOTE: Angle in degrees, horizontal-right is 0, counterclock-wise +float GetGestureDragAngle(void) +{ + // NOTE: drag angle is calculated on one touch points TOUCH_UP + + return dragAngle; +} + +// Get distance between two pinch points +Vector2 GetGesturePinchVector(void) +{ + // NOTE: The position values used for pinchDistance are not modified like the position values of [core.c]-->GetTouchPosition(int index) + // NOTE: pinch distance is calculated on two touch points TOUCH_MOVE + + return pinchVector; +} + +// Get angle beween two pinch points +// NOTE: Angle in degrees, horizontal-right is 0, counterclock-wise +float GetGesturePinchAngle(void) +{ + // NOTE: pinch angle is calculated on two touch points TOUCH_MOVE + + return pinchAngle; +} + +//---------------------------------------------------------------------------------- +// Module specific Functions Definition +//---------------------------------------------------------------------------------- + +// Returns angle from two-points vector with X-axis +static float Vector2Angle(Vector2 initialPosition, Vector2 finalPosition) +{ + float angle; + + angle = atan2(finalPosition.y - initialPosition.y, finalPosition.x - initialPosition.x)*(180.0f/PI); + + if (angle < 0) angle += 360.0f; + + return angle; +} + +// Calculate distance between two Vector2 +static float Vector2Distance(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; +} + +// Time measure returned are milliseconds +static double GetCurrentTime(void) +{ + double time = 0; + +#if defined(_WIN32) + unsigned long long int clockFrequency, currentTime; + + QueryPerformanceFrequency(&clockFrequency); + QueryPerformanceCounter(¤tTime); + + time = (double)currentTime/clockFrequency*1000.0f; // Time in miliseconds +#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 in nanoseconds + + time = ((double)nowTime/1000000.0); // Time in miliseconds +#endif + + return time; +} + +#endif // GESTURES_IMPLEMENTATION diff --git a/src/raylib.h b/src/raylib.h index 104d5677..1489546a 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -570,18 +570,6 @@ typedef enum { GESTURE_PINCH_OUT = 512 } Gestures; -// Touch action (fingers or mouse) -typedef enum { TOUCH_UP, TOUCH_DOWN, TOUCH_MOVE } TouchAction; - -// Gesture events -// NOTE: MAX_TOUCH_POINTS fixed to 2 -typedef struct GestureEvent { - int touchAction; - int pointCount; - int pointerId[MAX_TOUCH_POINTS]; - Vector2 position[MAX_TOUCH_POINTS]; -} GestureEvent; - // Camera system modes typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON } CameraMode; @@ -711,11 +699,8 @@ bool IsButtonReleased(int button); // Detect if an android //------------------------------------------------------------------------------------ void SetGesturesEnabled(unsigned int gestureFlags); // Enable a set of gestures using flags bool IsGestureDetected(int gesture); // Check if a gesture have been detected -void ProcessGestureEvent(GestureEvent event); // Process gesture event and translate it into gestures -void UpdateGestures(void); // Update gestures detected (called automatically in PollInputEvents()) - -int GetTouchPointsCount(void); // Get touch points count int GetGestureDetected(void); // Get latest detected gesture +int GetTouchPointsCount(void); // Get touch points count float GetGestureHoldDuration(void); // Get gesture hold time in milliseconds Vector2 GetGestureDragVector(void); // Get gesture drag vector float GetGestureDragAngle(void); // Get gesture drag angle diff --git a/src/rlua.h b/src/rlua.h index 675edbfc..acd0d037 100644 --- a/src/rlua.h +++ b/src/rlua.h @@ -1313,12 +1313,6 @@ int lua_IsGestureDetected(lua_State* L) return 1; } -int lua_UpdateGestures(lua_State* L) -{ - UpdateGestures(); - return 0; -} - int lua_GetTouchPointsCount(lua_State* L) { int result = GetTouchPointsCount(); @@ -3576,10 +3570,8 @@ static luaL_Reg raylib_functions[] = { REG(SetGesturesEnabled) REG(IsGestureDetected) - //REG(ProcessGestureEvent) - REG(UpdateGestures) - REG(GetTouchPointsCount) REG(GetGestureDetected) + REG(GetTouchPointsCount) REG(GetGestureHoldDuration) REG(GetGestureDragVector) REG(GetGestureDragAngle) -- cgit v1.2.3 From 289e04a62a64a6e82aa5da3397baaa7f48cc45ed Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 10 Aug 2016 12:55:54 +0200 Subject: Ported camera module to header-only --- src/Makefile | 4 - src/camera.c | 523 ---------------------------------------------------- src/camera.h | 586 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- src/core.c | 3 + 4 files changed, 559 insertions(+), 557 deletions(-) delete mode 100644 src/camera.c (limited to 'src/core.c') diff --git a/src/Makefile b/src/Makefile index e82c2861..b4eccdb2 100644 --- a/src/Makefile +++ b/src/Makefile @@ -203,10 +203,6 @@ external/stb_vorbis.o: external/stb_vorbis.c external/stb_vorbis.h utils.o : utils.c utils.h $(CC) -c $< $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -# compile camera module -camera.o : camera.c raylib.h - $(CC) -c $< $(CFLAGS) $(INCLUDES) - # It installs generated and needed files to compile projects using raylib. # The installation works manually. # TODO: add other platforms. diff --git a/src/camera.c b/src/camera.c deleted file mode 100644 index 11571cca..00000000 --- a/src/camera.c +++ /dev/null @@ -1,523 +0,0 @@ -/********************************************************************************************** -* -* raylib Camera System - Camera Modes Setup and Control Functions -* -* Copyright (c) 2015 Marc Palau and 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 CAMERA_STANDALONE // NOTE: To use the camera module as standalone lib, just uncomment this line - // NOTE: ProcessCamera() should be reviewed to adapt inputs to other systems - -#if defined(CAMERA_STANDALONE) - #include "camera.h" -#else - #include "raylib.h" -#endif - -#include // Required for: sqrt(), sin(), cos() - -//---------------------------------------------------------------------------------- -// Defines and Macros -//---------------------------------------------------------------------------------- -// CAMERA_GENERIC -#define CAMERA_SCROLL_SENSITIVITY 1.5f - -// FREE_CAMERA -#define FREE_CAMERA_MOUSE_SENSITIVITY 0.01f -#define FREE_CAMERA_DISTANCE_MIN_CLAMP 0.3f -#define FREE_CAMERA_DISTANCE_MAX_CLAMP 120.0f -#define FREE_CAMERA_MIN_CLAMP 85.0f -#define FREE_CAMERA_MAX_CLAMP -85.0f -#define FREE_CAMERA_SMOOTH_ZOOM_SENSITIVITY 0.05f -#define FREE_CAMERA_PANNING_DIVIDER 5.1f - -// ORBITAL_CAMERA -#define ORBITAL_CAMERA_SPEED 0.01f - -// FIRST_PERSON -//#define FIRST_PERSON_MOUSE_SENSITIVITY 0.003f -#define FIRST_PERSON_FOCUS_DISTANCE 25.0f -#define FIRST_PERSON_MIN_CLAMP 85.0f -#define FIRST_PERSON_MAX_CLAMP -85.0f - -#define FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER 5.0f -#define FIRST_PERSON_STEP_DIVIDER 30.0f -#define FIRST_PERSON_WAVING_DIVIDER 200.0f - -#define FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION 0.85f - -// THIRD_PERSON -//#define THIRD_PERSON_MOUSE_SENSITIVITY 0.003f -#define THIRD_PERSON_DISTANCE_CLAMP 1.2f -#define THIRD_PERSON_MIN_CLAMP 5.0f -#define THIRD_PERSON_MAX_CLAMP -85.0f -#define THIRD_PERSON_OFFSET (Vector3){ 0.4f, 0.0f, 0.0f } - -// PLAYER (used by camera) -#define PLAYER_WIDTH 0.4f -#define PLAYER_HEIGHT 0.9f -#define PLAYER_DEPTH 0.4f -#define PLAYER_MOVEMENT_DIVIDER 20.0f - -//---------------------------------------------------------------------------------- -// Types and Structures Definition -//---------------------------------------------------------------------------------- -// Camera move modes (first person and third person cameras) -typedef enum { MOVE_FRONT = 0, MOVE_LEFT, MOVE_BACK, MOVE_RIGHT, MOVE_UP, MOVE_DOWN } CameraMove; - -//---------------------------------------------------------------------------------- -// Global Variables Definition -//---------------------------------------------------------------------------------- -static Camera internalCamera = {{ 2.0f, 0.0f, 2.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f }; -static Vector2 cameraAngle = { 0.0f, 0.0f }; -static float cameraTargetDistance = 5.0f; -static Vector2 cameraMousePosition = { 0.0f, 0.0f }; -static Vector2 cameraMouseVariation = { 0.0f, 0.0f }; -static float mouseSensitivity = 0.003f; -static int cameraMoveControl[6] = { 'W', 'A', 'S', 'D', 'E', 'Q' }; -static int cameraMoveCounter = 0; -static int cameraUseGravity = 1; -static int panControlKey = 2; // raylib: MOUSE_MIDDLE_BUTTON -static int altControlKey = 342; // raylib: KEY_LEFT_ALT -static int smoothZoomControlKey = 341; // raylib: KEY_LEFT_CONTROL - -static int cameraMode = CAMERA_CUSTOM; - -//---------------------------------------------------------------------------------- -// Module specific Functions Declaration -//---------------------------------------------------------------------------------- -static void ProcessCamera(Camera *camera, Vector3 *playerPosition); - -#if defined(CAMERA_STANDALONE) -// NOTE: Camera controls depend on some raylib input functions -// TODO: Set your own input functions (used in ProcessCamera()) -static Vector2 GetMousePosition() { return (Vector2){ 0.0f, 0.0f }; } -static void SetMousePosition(Vector2 pos) {} -static int IsMouseButtonDown(int button) { return 0;} -static int GetMouseWheelMove() { return 0; } -static int GetScreenWidth() { return 1280; } -static int GetScreenHeight() { return 720; } -static void ShowCursor() {} -static void HideCursor() {} -static int IsKeyDown(int key) { return 0; } -#endif - -//---------------------------------------------------------------------------------- -// Module Functions Definition -//---------------------------------------------------------------------------------- - -// Select camera mode (multiple camera modes available) -// TODO: Review hardcoded values when changing modes... -void SetCameraMode(int mode) -{ - if ((cameraMode == CAMERA_FIRST_PERSON) && (mode == CAMERA_FREE)) - { - cameraMode = CAMERA_THIRD_PERSON; - cameraTargetDistance = 5.0f; - cameraAngle.y = -40*DEG2RAD; - ProcessCamera(&internalCamera, &internalCamera.position); - } - else if ((cameraMode == CAMERA_FIRST_PERSON) && (mode == CAMERA_ORBITAL)) - { - cameraMode = CAMERA_THIRD_PERSON; - cameraTargetDistance = 5.0f; - cameraAngle.y = -40*DEG2RAD; - ProcessCamera(&internalCamera, &internalCamera.position); - } - else if ((cameraMode == CAMERA_CUSTOM) && (mode == CAMERA_FREE)) - { - cameraTargetDistance = 10.0f; - cameraAngle.x = 45*DEG2RAD; - cameraAngle.y = -40*DEG2RAD; - internalCamera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; - ProcessCamera(&internalCamera, &internalCamera.position); - - ShowCursor(); - } - else if ((cameraMode == CAMERA_CUSTOM) && (mode == CAMERA_ORBITAL)) - { - cameraTargetDistance = 10.0f; - cameraAngle.x = 225*DEG2RAD; - cameraAngle.y = -40*DEG2RAD; - internalCamera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; - ProcessCamera(&internalCamera, &internalCamera.position); - } - - cameraMode = mode; -} - -// Update camera (player position is ignored) -void UpdateCamera(Camera *camera) -{ - Vector3 position = { 0.0f, 0.0f, 0.0f }; - - // Process internal camera and player position (if required) - if (cameraMode != CAMERA_CUSTOM) ProcessCamera(&internalCamera, &position); - - *camera = internalCamera; -} - -// Update camera and player position (1st person and 3rd person cameras) -void UpdateCameraPlayer(Camera *camera, Vector3 *position) -{ - // Process internal camera and player position (if required) - if (cameraMode != CAMERA_CUSTOM) ProcessCamera(&internalCamera, position); - - *camera = internalCamera; -} - -// Set internal camera position -void SetCameraPosition(Vector3 position) -{ - internalCamera.position = position; - - Vector3 v1 = internalCamera.position; - Vector3 v2 = internalCamera.target; - - float dx = v2.x - v1.x; - float dy = v2.y - v1.y; - float dz = v2.z - v1.z; - - cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz); -} - -// Set internal camera target -void SetCameraTarget(Vector3 target) -{ - internalCamera.target = target; - - Vector3 v1 = internalCamera.position; - Vector3 v2 = internalCamera.target; - - float dx = v2.x - v1.x; - float dy = v2.y - v1.y; - float dz = v2.z - v1.z; - - cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz); -} - -// Set internal camera fovy -void SetCameraFovy(float fovy) -{ - internalCamera.fovy = fovy; -} - -// Set camera pan key to combine with mouse movement (free camera) -void SetCameraPanControl(int panKey) -{ - panControlKey = panKey; -} - -// Set camera alt key to combine with mouse movement (free camera) -void SetCameraAltControl(int altKey) -{ - altControlKey = altKey; -} - -// Set camera smooth zoom key to combine with mouse (free camera) -void SetCameraSmoothZoomControl(int szKey) -{ - smoothZoomControlKey = szKey; -} - -// Set camera move controls (1st person and 3rd person cameras) -void SetCameraMoveControls(int frontKey, int backKey, int leftKey, int rightKey, int upKey, int downKey) -{ - cameraMoveControl[MOVE_FRONT] = frontKey; - cameraMoveControl[MOVE_LEFT] = leftKey; - cameraMoveControl[MOVE_BACK] = backKey; - cameraMoveControl[MOVE_RIGHT] = rightKey; - cameraMoveControl[MOVE_UP] = upKey; - cameraMoveControl[MOVE_DOWN] = downKey; -} - -// Set camera mouse sensitivity (1st person and 3rd person cameras) -void SetCameraMouseSensitivity(float sensitivity) -{ - mouseSensitivity = (sensitivity/10000.0f); -} - -//---------------------------------------------------------------------------------- -// Module specific Functions Definition -//---------------------------------------------------------------------------------- - -// Process desired camera mode and controls -// NOTE: Camera controls depend on some raylib functions: -// Mouse: GetMousePosition(), SetMousePosition(), IsMouseButtonDown(), GetMouseWheelMove() -// System: GetScreenWidth(), GetScreenHeight(), ShowCursor(), HideCursor() -// Keys: IsKeyDown() -static void ProcessCamera(Camera *camera, Vector3 *playerPosition) -{ - // Mouse movement detection - Vector2 mousePosition = GetMousePosition(); - int mouseWheelMove = GetMouseWheelMove(); - int panKey = IsMouseButtonDown(panControlKey); // bool value - - int screenWidth = GetScreenWidth(); - int screenHeight = GetScreenHeight(); - - if ((cameraMode != CAMERA_FREE) && (cameraMode != CAMERA_ORBITAL)) - { - HideCursor(); - - if (mousePosition.x < screenHeight/3) SetMousePosition((Vector2){ screenWidth - screenHeight/3, mousePosition.y}); - else if (mousePosition.y < screenHeight/3) SetMousePosition((Vector2){ mousePosition.x, screenHeight - screenHeight/3}); - else if (mousePosition.x > screenWidth - screenHeight/3) SetMousePosition((Vector2) { screenHeight/3, mousePosition.y}); - else if (mousePosition.y > screenHeight - screenHeight/3) SetMousePosition((Vector2){ mousePosition.x, screenHeight/3}); - else - { - cameraMouseVariation.x = mousePosition.x - cameraMousePosition.x; - cameraMouseVariation.y = mousePosition.y - cameraMousePosition.y; - } - } - else - { - ShowCursor(); - - cameraMouseVariation.x = mousePosition.x - cameraMousePosition.x; - cameraMouseVariation.y = mousePosition.y - cameraMousePosition.y; - } - - // NOTE: We GetMousePosition() again because it can be modified by a previous SetMousePosition() call - // If using directly mousePosition variable we have problems on CAMERA_FIRST_PERSON and CAMERA_THIRD_PERSON - cameraMousePosition = GetMousePosition(); - - // Support for multiple automatic camera modes - switch (cameraMode) - { - case CAMERA_FREE: - { - // Camera zoom - if ((cameraTargetDistance < FREE_CAMERA_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0)) - { - cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY); - - if (cameraTargetDistance > FREE_CAMERA_DISTANCE_MAX_CLAMP) cameraTargetDistance = FREE_CAMERA_DISTANCE_MAX_CLAMP; - } - // Camera looking down - else if ((camera->position.y > camera->target.y) && (cameraTargetDistance == FREE_CAMERA_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0)) - { - camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; - camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; - camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; - } - else if ((camera->position.y > camera->target.y) && (camera->target.y >= 0)) - { - camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; - camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; - camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; - - // if (camera->target.y < 0) camera->target.y = -0.001; - } - else if ((camera->position.y > camera->target.y) && (camera->target.y < 0) && (mouseWheelMove > 0)) - { - cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY); - if (cameraTargetDistance < FREE_CAMERA_DISTANCE_MIN_CLAMP) cameraTargetDistance = FREE_CAMERA_DISTANCE_MIN_CLAMP; - } - // Camera looking up - else if ((camera->position.y < camera->target.y) && (cameraTargetDistance == FREE_CAMERA_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0)) - { - camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; - camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; - camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; - } - else if ((camera->position.y < camera->target.y) && (camera->target.y <= 0)) - { - camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; - camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; - camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; - - // if (camera->target.y > 0) camera->target.y = 0.001; - } - else if ((camera->position.y < camera->target.y) && (camera->target.y > 0) && (mouseWheelMove > 0)) - { - cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY); - if (cameraTargetDistance < FREE_CAMERA_DISTANCE_MIN_CLAMP) cameraTargetDistance = FREE_CAMERA_DISTANCE_MIN_CLAMP; - } - - // Inputs - if (IsKeyDown(altControlKey)) - { - if (IsKeyDown(smoothZoomControlKey)) - { - // Camera smooth zoom - if (panKey) cameraTargetDistance += (cameraMouseVariation.y*FREE_CAMERA_SMOOTH_ZOOM_SENSITIVITY); - } - // Camera orientation calculation - else if (panKey) - { - // Camera orientation calculation - // Get the mouse sensitivity - cameraAngle.x += cameraMouseVariation.x*-FREE_CAMERA_MOUSE_SENSITIVITY; - cameraAngle.y += cameraMouseVariation.y*-FREE_CAMERA_MOUSE_SENSITIVITY; - - // Angle clamp - if (cameraAngle.y > FREE_CAMERA_MIN_CLAMP*DEG2RAD) cameraAngle.y = FREE_CAMERA_MIN_CLAMP*DEG2RAD; - else if (cameraAngle.y < FREE_CAMERA_MAX_CLAMP*DEG2RAD) cameraAngle.y = FREE_CAMERA_MAX_CLAMP*DEG2RAD; - } - } - // Paning - else if (panKey) - { - camera->target.x += ((cameraMouseVariation.x*-FREE_CAMERA_MOUSE_SENSITIVITY)*cos(cameraAngle.x) + (cameraMouseVariation.y*FREE_CAMERA_MOUSE_SENSITIVITY)*sin(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/FREE_CAMERA_PANNING_DIVIDER); - camera->target.y += ((cameraMouseVariation.y*FREE_CAMERA_MOUSE_SENSITIVITY)*cos(cameraAngle.y))*(cameraTargetDistance/FREE_CAMERA_PANNING_DIVIDER); - camera->target.z += ((cameraMouseVariation.x*FREE_CAMERA_MOUSE_SENSITIVITY)*sin(cameraAngle.x) + (cameraMouseVariation.y*FREE_CAMERA_MOUSE_SENSITIVITY)*cos(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/FREE_CAMERA_PANNING_DIVIDER); - } - - // Focus to center - // TODO: Move this function out of this module? - if (IsKeyDown('Z')) camera->target = (Vector3){ 0.0f, 0.0f, 0.0f }; - - // Camera position update - camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x; - - if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; - else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; - - camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z; - - } break; - case CAMERA_ORBITAL: - { - cameraAngle.x += ORBITAL_CAMERA_SPEED; - - // Camera zoom - cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY); - - // Camera distance clamp - if (cameraTargetDistance < THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = THIRD_PERSON_DISTANCE_CLAMP; - - // Focus to center - if (IsKeyDown('Z')) camera->target = (Vector3){ 0.0f, 0.0f, 0.0f }; - - // Camera position update - camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x; - - if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; - else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; - - camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z; - - } break; - case CAMERA_FIRST_PERSON: - case CAMERA_THIRD_PERSON: - { - bool isMoving = false; - - // Keyboard inputs - if (IsKeyDown(cameraMoveControl[MOVE_FRONT])) - { - playerPosition->x -= sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; - playerPosition->z -= cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; - - if (!cameraUseGravity) camera->position.y += sin(cameraAngle.y)/PLAYER_MOVEMENT_DIVIDER; - - isMoving = true; - } - else if (IsKeyDown(cameraMoveControl[MOVE_BACK])) - { - playerPosition->x += sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; - playerPosition->z += cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; - - if (!cameraUseGravity) camera->position.y -= sin(cameraAngle.y)/PLAYER_MOVEMENT_DIVIDER; - - isMoving = true; - } - - if (IsKeyDown(cameraMoveControl[MOVE_LEFT])) - { - playerPosition->x -= cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; - playerPosition->z += sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; - - isMoving = true; - } - else if (IsKeyDown(cameraMoveControl[MOVE_RIGHT])) - { - playerPosition->x += cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; - playerPosition->z -= sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; - - isMoving = true; - } - - if (IsKeyDown(cameraMoveControl[MOVE_UP])) - { - if (!cameraUseGravity) playerPosition->y += 1.0f/PLAYER_MOVEMENT_DIVIDER; - } - else if (IsKeyDown(cameraMoveControl[MOVE_DOWN])) - { - if (!cameraUseGravity) playerPosition->y -= 1.0f/PLAYER_MOVEMENT_DIVIDER; - } - - if (cameraMode == CAMERA_THIRD_PERSON) - { - // Camera orientation calculation - cameraAngle.x += cameraMouseVariation.x*-mouseSensitivity; - cameraAngle.y += cameraMouseVariation.y*-mouseSensitivity; - - // Angle clamp - if (cameraAngle.y > THIRD_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = THIRD_PERSON_MIN_CLAMP*DEG2RAD; - else if (cameraAngle.y < THIRD_PERSON_MAX_CLAMP*DEG2RAD) cameraAngle.y = THIRD_PERSON_MAX_CLAMP*DEG2RAD; - - // Camera zoom - cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY); - - // Camera distance clamp - if (cameraTargetDistance < THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = THIRD_PERSON_DISTANCE_CLAMP; - - // Camera is always looking at player - camera->target.x = playerPosition->x + THIRD_PERSON_OFFSET.x*cos(cameraAngle.x) + THIRD_PERSON_OFFSET.z*sin(cameraAngle.x); - camera->target.y = playerPosition->y + PLAYER_HEIGHT*FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION + THIRD_PERSON_OFFSET.y; - camera->target.z = playerPosition->z + THIRD_PERSON_OFFSET.z*sin(cameraAngle.x) - THIRD_PERSON_OFFSET.x*sin(cameraAngle.x); - - // Camera position update - camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x; - - if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; - else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; - - camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z; - } - else // CAMERA_FIRST_PERSON - { - if (isMoving) cameraMoveCounter++; - - // Camera orientation calculation - cameraAngle.x += (cameraMouseVariation.x * -mouseSensitivity); - cameraAngle.y += (cameraMouseVariation.y * -mouseSensitivity); - - // Angle clamp - if (cameraAngle.y > FIRST_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = FIRST_PERSON_MIN_CLAMP*DEG2RAD; - else if (cameraAngle.y < FIRST_PERSON_MAX_CLAMP*DEG2RAD) cameraAngle.y = FIRST_PERSON_MAX_CLAMP*DEG2RAD; - - // Camera is always looking at player - camera->target.x = camera->position.x - sin(cameraAngle.x)*FIRST_PERSON_FOCUS_DISTANCE; - camera->target.y = camera->position.y + sin(cameraAngle.y)*FIRST_PERSON_FOCUS_DISTANCE; - camera->target.z = camera->position.z - cos(cameraAngle.x)*FIRST_PERSON_FOCUS_DISTANCE; - - camera->position.x = playerPosition->x; - camera->position.y = (playerPosition->y + PLAYER_HEIGHT*FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION) - sin(cameraMoveCounter/FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/FIRST_PERSON_STEP_DIVIDER; - camera->position.z = playerPosition->z; - - camera->up.x = sin(cameraMoveCounter/(FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/FIRST_PERSON_WAVING_DIVIDER; - camera->up.z = -sin(cameraMoveCounter/(FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/FIRST_PERSON_WAVING_DIVIDER; - } - } break; - default: break; - } -} diff --git a/src/camera.h b/src/camera.h index 8d8029af..f5bb867d 100644 --- a/src/camera.h +++ b/src/camera.h @@ -2,7 +2,19 @@ * * raylib Camera System - Camera Modes Setup and Control Functions * -* Copyright (c) 2015 Marc Palau and Ramon Santamaria +* #define CAMERA_IMPLEMENTATION +* Generates the implementation of the library into the included file. +* If not defined, the library is in header only mode and can be included in other headers +* or source files without problems. But only ONE file should hold the implementation. +* +* #define CAMERA_STANDALONE +* If defined, the library can be used as standalone as a camera system but some +* functions must be redefined to manage inputs accordingly. +* +* NOTE: Memory footprint of this library is aproximately 112 bytes +* +* Initial design by Marc Palau (2014) +* Reviewed by Ramon Santamaria (2015-2016) * * 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. @@ -24,13 +36,6 @@ #ifndef CAMERA_H #define CAMERA_H -#ifndef PI - #define PI 3.14159265358979323846 -#endif - -#define DEG2RAD (PI/180.0f) -#define RAD2DEG (180.0f/PI) - //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- @@ -40,28 +45,30 @@ // Types and Structures Definition // NOTE: Below types are required for CAMERA_STANDALONE usage //---------------------------------------------------------------------------------- -// Camera modes -typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON } CameraMode; - -// Vector2 type -typedef struct Vector2 { - float x; - float y; -} Vector2; - -// Vector3 type -typedef struct Vector3 { - float x; - float y; - float z; -} Vector3; - -// Camera type, defines a camera position/orientation in 3d space -typedef struct Camera { - Vector3 position; - Vector3 target; - Vector3 up; -} Camera; +#if defined(CAMERA_STANDALONE) + // Camera modes + typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON } CameraMode; + + // Vector2 type + typedef struct Vector2 { + float x; + float y; + } Vector2; + + // Vector3 type + typedef struct Vector3 { + float x; + float y; + float z; + } Vector3; + + // Camera type, defines a camera position/orientation in 3d space + typedef struct Camera { + Vector3 position; + Vector3 target; + Vector3 up; + } Camera; +#endif #ifdef __cplusplus extern "C" { // Prevents name mangling of functions @@ -75,6 +82,7 @@ extern "C" { // Prevents name mangling of functions //---------------------------------------------------------------------------------- // Module Functions Declaration //---------------------------------------------------------------------------------- +#if defined(CAMERA_STANDALONE) void SetCameraMode(int mode); // Set camera mode (multiple camera modes available) void UpdateCamera(Camera *camera); // Update camera (player position is ignored) void UpdateCameraPlayer(Camera *camera, Vector3 *position); // Update camera and player position (1st person and 3rd person cameras) @@ -91,9 +99,527 @@ void SetCameraMoveControls(int frontKey, int backKey, int leftKey, int rightKey, int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras) void SetCameraMouseSensitivity(float sensitivity); // Set camera mouse sensitivity (1st person and 3rd person cameras) +#endif #ifdef __cplusplus } #endif #endif // CAMERA_H + + +/*********************************************************************************** +* +* CAMERA IMPLEMENTATION +* +************************************************************************************/ + +#if defined(CAMERA_IMPLEMENTATION) + +#include // Required for: sqrt(), sin(), cos() + +#ifndef PI + #define PI 3.14159265358979323846 +#endif + +#ifndef DEG2RAD + #define DEG2RAD (PI/180.0f) +#endif + +#ifndef RAD2DEG + #define RAD2DEG (180.0f/PI) +#endif + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- +// CAMERA_GENERIC +#define CAMERA_SCROLL_SENSITIVITY 1.5f + +// FREE_CAMERA +#define CAMERA_FREE_MOUSE_SENSITIVITY 0.01f +#define CAMERA_FREE_DISTANCE_MIN_CLAMP 0.3f +#define CAMERA_FREE_DISTANCE_MAX_CLAMP 120.0f +#define CAMERA_FREE_MIN_CLAMP 85.0f +#define CAMERA_FREE_MAX_CLAMP -85.0f +#define CAMERA_FREE_SMOOTH_ZOOM_SENSITIVITY 0.05f +#define CAMERA_FREE_PANNING_DIVIDER 5.1f + +// ORBITAL_CAMERA +#define CAMERA_ORBITAL_SPEED 0.01f + +// FIRST_PERSON +//#define CAMERA_FIRST_PERSON_MOUSE_SENSITIVITY 0.003f +#define CAMERA_FIRST_PERSON_FOCUS_DISTANCE 25.0f +#define CAMERA_FIRST_PERSON_MIN_CLAMP 85.0f +#define CAMERA_FIRST_PERSON_MAX_CLAMP -85.0f + +#define CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER 5.0f +#define CAMERA_FIRST_PERSON_STEP_DIVIDER 30.0f +#define CAMERA_FIRST_PERSON_WAVING_DIVIDER 200.0f + +#define CAMERA_FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION 0.85f + +// THIRD_PERSON +//#define CAMERA_THIRD_PERSON_MOUSE_SENSITIVITY 0.003f +#define CAMERA_THIRD_PERSON_DISTANCE_CLAMP 1.2f +#define CAMERA_THIRD_PERSON_MIN_CLAMP 5.0f +#define CAMERA_THIRD_PERSON_MAX_CLAMP -85.0f +#define CAMERA_THIRD_PERSON_OFFSET (Vector3){ 0.4f, 0.0f, 0.0f } + +// PLAYER (used by camera) +#define PLAYER_WIDTH 0.4f +#define PLAYER_HEIGHT 0.9f +#define PLAYER_DEPTH 0.4f +#define PLAYER_MOVEMENT_DIVIDER 20.0f + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +// Camera move modes (first person and third person cameras) +typedef enum { MOVE_FRONT = 0, MOVE_LEFT, MOVE_BACK, MOVE_RIGHT, MOVE_UP, MOVE_DOWN } CameraMove; + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +static Camera internalCamera = {{ 2.0f, 0.0f, 2.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f }; + +static Vector2 cameraAngle = { 0.0f, 0.0f }; +static float cameraTargetDistance = 5.0f; +static Vector2 cameraMousePosition = { 0.0f, 0.0f }; +static Vector2 cameraMouseVariation = { 0.0f, 0.0f }; + +static int cameraMoveControl[6] = { 'W', 'A', 'S', 'D', 'E', 'Q' }; +static int cameraPanControlKey = 2; // raylib: MOUSE_MIDDLE_BUTTON +static int cameraAltControlKey = 342; // raylib: KEY_LEFT_ALT +static int cameraSmoothZoomControlKey = 341; // raylib: KEY_LEFT_CONTROL + +static int cameraMoveCounter = 0; // Used for 1st person swinging movement +static float cameraMouseSensitivity = 0.003f; // How sensible is camera movement to mouse movement + +static int cameraMode = CAMERA_CUSTOM; // Current internal camera mode + +//---------------------------------------------------------------------------------- +// Module specific Functions Declaration +//---------------------------------------------------------------------------------- +static void ProcessCamera(Camera *camera, Vector3 *playerPosition); + +#if defined(CAMERA_STANDALONE) +// NOTE: Camera controls depend on some raylib input functions +// TODO: Set your own input functions (used in ProcessCamera()) +static Vector2 GetMousePosition() { return (Vector2){ 0.0f, 0.0f }; } +static void SetMousePosition(Vector2 pos) {} +static int IsMouseButtonDown(int button) { return 0;} +static int GetMouseWheelMove() { return 0; } +static int GetScreenWidth() { return 1280; } +static int GetScreenHeight() { return 720; } +static void ShowCursor() {} +static void HideCursor() {} +static int IsKeyDown(int key) { return 0; } +#endif + +//---------------------------------------------------------------------------------- +// Module Functions Definition +//---------------------------------------------------------------------------------- + +// Select camera mode (multiple camera modes available) +// TODO: Review hardcoded values when changing modes... +void SetCameraMode(int mode) +{ + if ((cameraMode == CAMERA_FIRST_PERSON) && (mode == CAMERA_FREE)) + { + cameraMode = CAMERA_THIRD_PERSON; + cameraTargetDistance = 5.0f; + cameraAngle.y = -40*DEG2RAD; + ProcessCamera(&internalCamera, &internalCamera.position); + } + else if ((cameraMode == CAMERA_FIRST_PERSON) && (mode == CAMERA_ORBITAL)) + { + cameraMode = CAMERA_THIRD_PERSON; + cameraTargetDistance = 5.0f; + cameraAngle.y = -40*DEG2RAD; + ProcessCamera(&internalCamera, &internalCamera.position); + } + else if ((cameraMode == CAMERA_CUSTOM) && (mode == CAMERA_FREE)) + { + cameraTargetDistance = 10.0f; + cameraAngle.x = 45*DEG2RAD; + cameraAngle.y = -40*DEG2RAD; + internalCamera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; + ProcessCamera(&internalCamera, &internalCamera.position); + + ShowCursor(); + } + else if ((cameraMode == CAMERA_CUSTOM) && (mode == CAMERA_ORBITAL)) + { + cameraTargetDistance = 10.0f; + cameraAngle.x = 225*DEG2RAD; + cameraAngle.y = -40*DEG2RAD; + internalCamera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; + ProcessCamera(&internalCamera, &internalCamera.position); + } + + cameraMode = mode; +} + +// Update camera (player position is ignored) +void UpdateCamera(Camera *camera) +{ + Vector3 position = { 0.0f, 0.0f, 0.0f }; + + // Process internal camera and player position (if required) + if (cameraMode != CAMERA_CUSTOM) ProcessCamera(&internalCamera, &position); + + *camera = internalCamera; +} + +// Update camera and player position (1st person and 3rd person cameras) +void UpdateCameraPlayer(Camera *camera, Vector3 *position) +{ + // Process internal camera and player position (if required) + if (cameraMode != CAMERA_CUSTOM) ProcessCamera(&internalCamera, position); + + *camera = internalCamera; +} + +// Set internal camera position +void SetCameraPosition(Vector3 position) +{ + internalCamera.position = position; + + Vector3 v1 = internalCamera.position; + Vector3 v2 = internalCamera.target; + + float dx = v2.x - v1.x; + float dy = v2.y - v1.y; + float dz = v2.z - v1.z; + + cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz); +} + +// Set internal camera target +void SetCameraTarget(Vector3 target) +{ + internalCamera.target = target; + + Vector3 v1 = internalCamera.position; + Vector3 v2 = internalCamera.target; + + float dx = v2.x - v1.x; + float dy = v2.y - v1.y; + float dz = v2.z - v1.z; + + cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz); +} + +// Set internal camera fovy +void SetCameraFovy(float fovy) +{ + internalCamera.fovy = fovy; +} + +// Set camera pan key to combine with mouse movement (free camera) +void SetCameraPanControl(int panKey) +{ + cameraPanControlKey = panKey; +} + +// Set camera alt key to combine with mouse movement (free camera) +void SetCameraAltControl(int altKey) +{ + cameraAltControlKey = altKey; +} + +// Set camera smooth zoom key to combine with mouse (free camera) +void SetCameraSmoothZoomControl(int szKey) +{ + cameraSmoothZoomControlKey = szKey; +} + +// Set camera move controls (1st person and 3rd person cameras) +void SetCameraMoveControls(int frontKey, int backKey, int leftKey, int rightKey, int upKey, int downKey) +{ + cameraMoveControl[MOVE_FRONT] = frontKey; + cameraMoveControl[MOVE_LEFT] = leftKey; + cameraMoveControl[MOVE_BACK] = backKey; + cameraMoveControl[MOVE_RIGHT] = rightKey; + cameraMoveControl[MOVE_UP] = upKey; + cameraMoveControl[MOVE_DOWN] = downKey; +} + +// Set camera mouse sensitivity (1st person and 3rd person cameras) +void SetCameracameraMouseSensitivity(float sensitivity) +{ + cameraMouseSensitivity = (sensitivity/10000.0f); +} + +//---------------------------------------------------------------------------------- +// Module specific Functions Definition +//---------------------------------------------------------------------------------- + +// Process desired camera mode and controls +// NOTE: Camera controls depend on some raylib functions: +// Mouse: GetMousePosition(), SetMousePosition(), IsMouseButtonDown(), GetMouseWheelMove() +// System: GetScreenWidth(), GetScreenHeight(), ShowCursor(), HideCursor() +// Keys: IsKeyDown() +static void ProcessCamera(Camera *camera, Vector3 *playerPosition) +{ + // Mouse movement detection + Vector2 mousePosition = GetMousePosition(); + int mouseWheelMove = GetMouseWheelMove(); + int panKey = IsMouseButtonDown(cameraPanControlKey); // bool value + + int screenWidth = GetScreenWidth(); + int screenHeight = GetScreenHeight(); + + if ((cameraMode != CAMERA_FREE) && (cameraMode != CAMERA_ORBITAL)) + { + HideCursor(); + + if (mousePosition.x < screenHeight/3) SetMousePosition((Vector2){ screenWidth - screenHeight/3, mousePosition.y}); + else if (mousePosition.y < screenHeight/3) SetMousePosition((Vector2){ mousePosition.x, screenHeight - screenHeight/3}); + else if (mousePosition.x > screenWidth - screenHeight/3) SetMousePosition((Vector2) { screenHeight/3, mousePosition.y}); + else if (mousePosition.y > screenHeight - screenHeight/3) SetMousePosition((Vector2){ mousePosition.x, screenHeight/3}); + else + { + cameraMouseVariation.x = mousePosition.x - cameraMousePosition.x; + cameraMouseVariation.y = mousePosition.y - cameraMousePosition.y; + } + } + else + { + ShowCursor(); + + cameraMouseVariation.x = mousePosition.x - cameraMousePosition.x; + cameraMouseVariation.y = mousePosition.y - cameraMousePosition.y; + } + + // NOTE: We GetMousePosition() again because it can be modified by a previous SetMousePosition() call + // If using directly mousePosition variable we have problems on CAMERA_FIRST_PERSON and CAMERA_THIRD_PERSON + cameraMousePosition = GetMousePosition(); + + // Support for multiple automatic camera modes + switch (cameraMode) + { + case CAMERA_FREE: + { + // Camera zoom + if ((cameraTargetDistance < CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0)) + { + cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY); + + if (cameraTargetDistance > CAMERA_FREE_DISTANCE_MAX_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MAX_CLAMP; + } + // Camera looking down + else if ((camera->position.y > camera->target.y) && (cameraTargetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0)) + { + camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; + camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; + camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; + } + else if ((camera->position.y > camera->target.y) && (camera->target.y >= 0)) + { + camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; + camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; + camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; + + // if (camera->target.y < 0) camera->target.y = -0.001; + } + else if ((camera->position.y > camera->target.y) && (camera->target.y < 0) && (mouseWheelMove > 0)) + { + cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY); + if (cameraTargetDistance < CAMERA_FREE_DISTANCE_MIN_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MIN_CLAMP; + } + // Camera looking up + else if ((camera->position.y < camera->target.y) && (cameraTargetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0)) + { + camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; + camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; + camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; + } + else if ((camera->position.y < camera->target.y) && (camera->target.y <= 0)) + { + camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; + camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; + camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; + + // if (camera->target.y > 0) camera->target.y = 0.001; + } + else if ((camera->position.y < camera->target.y) && (camera->target.y > 0) && (mouseWheelMove > 0)) + { + cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY); + if (cameraTargetDistance < CAMERA_FREE_DISTANCE_MIN_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MIN_CLAMP; + } + + // Inputs + if (IsKeyDown(cameraAltControlKey)) + { + if (IsKeyDown(cameraSmoothZoomControlKey)) + { + // Camera smooth zoom + if (panKey) cameraTargetDistance += (cameraMouseVariation.y*CAMERA_FREE_SMOOTH_ZOOM_SENSITIVITY); + } + // Camera orientation calculation + else if (panKey) + { + // Camera orientation calculation + // Get the mouse sensitivity + cameraAngle.x += cameraMouseVariation.x*-CAMERA_FREE_MOUSE_SENSITIVITY; + cameraAngle.y += cameraMouseVariation.y*-CAMERA_FREE_MOUSE_SENSITIVITY; + + // Angle clamp + if (cameraAngle.y > CAMERA_FREE_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FREE_MIN_CLAMP*DEG2RAD; + else if (cameraAngle.y < CAMERA_FREE_MAX_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FREE_MAX_CLAMP*DEG2RAD; + } + } + // Paning + else if (panKey) + { + camera->target.x += ((cameraMouseVariation.x*-CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.x) + (cameraMouseVariation.y*CAMERA_FREE_MOUSE_SENSITIVITY)*sin(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); + camera->target.y += ((cameraMouseVariation.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); + camera->target.z += ((cameraMouseVariation.x*CAMERA_FREE_MOUSE_SENSITIVITY)*sin(cameraAngle.x) + (cameraMouseVariation.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); + } + + // Focus to center + // TODO: Move this function out of this module? + if (IsKeyDown('Z')) camera->target = (Vector3){ 0.0f, 0.0f, 0.0f }; + + // Camera position update + camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x; + + if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; + else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; + + camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z; + + } break; + case CAMERA_ORBITAL: + { + cameraAngle.x += CAMERA_ORBITAL_SPEED; + + // Camera zoom + cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY); + + // Camera distance clamp + if (cameraTargetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP; + + // Focus to center + if (IsKeyDown('Z')) camera->target = (Vector3){ 0.0f, 0.0f, 0.0f }; + + // Camera position update + camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x; + + if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; + else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; + + camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z; + + } break; + case CAMERA_FIRST_PERSON: + case CAMERA_THIRD_PERSON: + { + bool isMoving = false; + + // Keyboard inputs + if (IsKeyDown(cameraMoveControl[MOVE_FRONT])) + { + playerPosition->x -= sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; + playerPosition->z -= cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; + + camera->position.y += sin(cameraAngle.y)/PLAYER_MOVEMENT_DIVIDER; + + isMoving = true; + } + else if (IsKeyDown(cameraMoveControl[MOVE_BACK])) + { + playerPosition->x += sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; + playerPosition->z += cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; + + camera->position.y -= sin(cameraAngle.y)/PLAYER_MOVEMENT_DIVIDER; + + isMoving = true; + } + + if (IsKeyDown(cameraMoveControl[MOVE_LEFT])) + { + playerPosition->x -= cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; + playerPosition->z += sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; + + isMoving = true; + } + else if (IsKeyDown(cameraMoveControl[MOVE_RIGHT])) + { + playerPosition->x += cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; + playerPosition->z -= sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; + + isMoving = true; + } + + if (IsKeyDown(cameraMoveControl[MOVE_UP])) + { + playerPosition->y += 1.0f/PLAYER_MOVEMENT_DIVIDER; + } + else if (IsKeyDown(cameraMoveControl[MOVE_DOWN])) + { + playerPosition->y -= 1.0f/PLAYER_MOVEMENT_DIVIDER; + } + + if (cameraMode == CAMERA_THIRD_PERSON) + { + // Camera orientation calculation + cameraAngle.x += cameraMouseVariation.x*-cameraMouseSensitivity; + cameraAngle.y += cameraMouseVariation.y*-cameraMouseSensitivity; + + // Angle clamp + if (cameraAngle.y > CAMERA_THIRD_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_THIRD_PERSON_MIN_CLAMP*DEG2RAD; + else if (cameraAngle.y < CAMERA_THIRD_PERSON_MAX_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_THIRD_PERSON_MAX_CLAMP*DEG2RAD; + + // Camera zoom + cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY); + + // Camera distance clamp + if (cameraTargetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP; + + // Camera is always looking at player + camera->target.x = playerPosition->x + CAMERA_THIRD_PERSON_OFFSET.x*cos(cameraAngle.x) + CAMERA_THIRD_PERSON_OFFSET.z*sin(cameraAngle.x); + camera->target.y = playerPosition->y + PLAYER_HEIGHT*CAMERA_FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION + CAMERA_THIRD_PERSON_OFFSET.y; + camera->target.z = playerPosition->z + CAMERA_THIRD_PERSON_OFFSET.z*sin(cameraAngle.x) - CAMERA_THIRD_PERSON_OFFSET.x*sin(cameraAngle.x); + + // Camera position update + camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x; + + if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; + else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; + + camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z; + } + else // CAMERA_FIRST_PERSON + { + if (isMoving) cameraMoveCounter++; + + // Camera orientation calculation + cameraAngle.x += (cameraMouseVariation.x*-cameraMouseSensitivity); + cameraAngle.y += (cameraMouseVariation.y*-cameraMouseSensitivity); + + // Angle clamp + if (cameraAngle.y > CAMERA_FIRST_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FIRST_PERSON_MIN_CLAMP*DEG2RAD; + else if (cameraAngle.y < CAMERA_FIRST_PERSON_MAX_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FIRST_PERSON_MAX_CLAMP*DEG2RAD; + + // Camera is always looking at player + camera->target.x = camera->position.x - sin(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE; + camera->target.y = camera->position.y + sin(cameraAngle.y)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE; + camera->target.z = camera->position.z - cos(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE; + + camera->position.x = playerPosition->x; + camera->position.y = (playerPosition->y + PLAYER_HEIGHT*CAMERA_FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION) - sin(cameraMoveCounter/CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/CAMERA_FIRST_PERSON_STEP_DIVIDER; + camera->position.z = playerPosition->z; + + camera->up.x = sin(cameraMoveCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER; + camera->up.z = -sin(cameraMoveCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER; + } + } break; + default: break; + } +} + +#endif // CAMERA_IMPLEMENTATION diff --git a/src/core.c b/src/core.c index 4cb34b0a..2b5329e3 100644 --- a/src/core.c +++ b/src/core.c @@ -48,6 +48,9 @@ #define GESTURES_IMPLEMENTATION #include "gestures.h" // Gestures detection functionality +#define CAMERA_IMPLEMENTATION +#include "camera.h" // Camera system functionality + #include // Standard input / output lib #include // Declares malloc() and free() for memory management, rand(), atexit() #include // Required for typedef unsigned long long int uint64_t, used by hi-res timer -- cgit v1.2.3 From 959a228815edcecdde692fcd47a7b540844c5712 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Tue, 16 Aug 2016 11:09:55 +0200 Subject: Removed useless spacing --- src/audio.c | 74 +++++------ src/core.c | 342 ++++++++++++++++++++++++------------------------- src/models.c | 134 +++++++++---------- src/raylib.h | 4 +- src/rlgl.h | 26 ++-- src/rlua.h | 72 +++++------ src/text.c | 146 ++++++++++----------- src/textures.c | 398 ++++++++++++++++++++++++++++----------------------------- 8 files changed, 598 insertions(+), 598 deletions(-) (limited to 'src/core.c') diff --git a/src/audio.c b/src/audio.c index 683ee66b..1772196f 100644 --- a/src/audio.c +++ b/src/audio.c @@ -183,7 +183,7 @@ void CloseAudioDevice(void) alcMakeContextCurrent(NULL); alcDestroyContext(context); alcCloseDevice(device); - + TraceLog(INFO, "Audio device closed successfully"); } @@ -217,7 +217,7 @@ Sound LoadSound(char *fileName) else TraceLog(WARNING, "[%s] Sound extension not recognized, it can't be loaded", fileName); Sound sound = LoadSoundFromWave(wave); - + // Sound is loaded, we can unload wave UnloadWave(wave); @@ -233,7 +233,7 @@ Sound LoadSoundFromWave(Wave wave) if (wave.data != NULL) { ALenum format = 0; - + // The OpenAL format is worked out by looking at the number of channels and the sample size (bits per sample) if (wave.channels == 1) { @@ -256,7 +256,7 @@ Sound LoadSoundFromWave(Wave wave) } } else TraceLog(WARNING, "Wave number of channels not supported: %i", wave.channels); - + // Create an audio source ALuint source; alGenSources(1, &source); // Generate pointer to audio source @@ -271,7 +271,7 @@ Sound LoadSoundFromWave(Wave wave) //---------------------------------------- ALuint buffer; alGenBuffers(1, &buffer); // Generate pointer to buffer - + unsigned int dataSize = wave.sampleCount*wave.sampleSize/8; // Size in bytes // Upload sound data to buffer @@ -367,7 +367,7 @@ Sound LoadSoundFromRES(const char *rresName, int resId) free(data); sound = LoadSoundFromWave(wave); - + // Sound is loaded, we can unload wave data UnloadWave(wave); } @@ -506,13 +506,13 @@ Music LoadMusicStream(char *fileName) TraceLog(DEBUG, "[%s] OGG sample rate: %i", fileName, info.sample_rate); TraceLog(DEBUG, "[%s] OGG channels: %i", fileName, info.channels); TraceLog(DEBUG, "[%s] OGG memory required: %i", fileName, info.temp_memory_required); - + } } else if (strcmp(GetExtension(fileName), "xm") == 0) { int result = jar_xm_create_context_from_file(&music->ctxXm, 48000, fileName); - + if (!result) // XM context created successfully { jar_xm_set_max_loop_count(music->ctxXm, 0); // Set infinite number of loops @@ -523,7 +523,7 @@ Music LoadMusicStream(char *fileName) music->samplesLeft = music->totalSamples; music->ctxType = MUSIC_MODULE_XM; music->loop = true; - + TraceLog(DEBUG, "[%s] XM number of samples: %i", fileName, music->totalSamples); TraceLog(DEBUG, "[%s] XM track length: %11.6f sec", fileName, (float)music->totalSamples/48000.0f); } @@ -555,11 +555,11 @@ Music LoadMusicStream(char *fileName) void UnloadMusicStream(Music music) { CloseAudioStream(music->stream); - + if (music->ctxType == MUSIC_AUDIO_OGG) stb_vorbis_close(music->ctxOgg); else if (music->ctxType == MUSIC_MODULE_XM) jar_xm_free_context(music->ctxXm); else if (music->ctxType == MUSIC_MODULE_MOD) jar_mod_unload(&music->ctxMod); - + free(music); } @@ -597,58 +597,58 @@ void UpdateMusicStream(Music music) // Determine if music stream is ready to be written alGetSourcei(music->stream.source, AL_BUFFERS_PROCESSED, &processed); - + int numBuffersToProcess = processed; - + if (processed > 0) { bool active = true; short pcm[AUDIO_BUFFER_SIZE]; float pcmf[AUDIO_BUFFER_SIZE]; - - int numSamples = 0; // Total size of data steamed in L+R samples for xm floats, + + int numSamples = 0; // Total size of data steamed in L+R samples for xm floats, // individual L or R for ogg shorts for (int i = 0; i < numBuffersToProcess; i++) { switch (music->ctxType) { - case MUSIC_AUDIO_OGG: + case MUSIC_AUDIO_OGG: { if (music->samplesLeft >= AUDIO_BUFFER_SIZE) numSamples = AUDIO_BUFFER_SIZE; else numSamples = music->samplesLeft; - + // NOTE: Returns the number of samples to process (should be the same as numSamples -> it is) int numSamplesOgg = stb_vorbis_get_samples_short_interleaved(music->ctxOgg, music->stream.channels, pcm, numSamples); // TODO: Review stereo channels Ogg, not enough samples served! UpdateAudioStream(music->stream, pcm, numSamplesOgg*music->stream.channels); music->samplesLeft -= (numSamplesOgg*music->stream.channels); - + } break; - case MUSIC_MODULE_XM: + case MUSIC_MODULE_XM: { if (music->samplesLeft >= AUDIO_BUFFER_SIZE/2) numSamples = AUDIO_BUFFER_SIZE/2; else numSamples = music->samplesLeft; - + // NOTE: Output buffer is 2*numsamples elements (left and right value for each sample) jar_xm_generate_samples(music->ctxXm, pcmf, numSamples); UpdateAudioStream(music->stream, pcmf, numSamples*2); // Using 32bit PCM data music->samplesLeft -= numSamples; - + //TraceLog(INFO, "Samples left: %i", music->samplesLeft); - + } break; - case MUSIC_MODULE_MOD: + case MUSIC_MODULE_MOD: { if (music->samplesLeft >= AUDIO_BUFFER_SIZE/2) numSamples = AUDIO_BUFFER_SIZE/2; else numSamples = music->samplesLeft; - + // NOTE: Output buffer size is nbsample*channels (default: 48000Hz, 16bit, Stereo) - jar_mod_fillbuffer(&music->ctxMod, pcm, numSamples, 0); + jar_mod_fillbuffer(&music->ctxMod, pcm, numSamples, 0); UpdateAudioStream(music->stream, pcm, numSamples*2); music->samplesLeft -= numSamples; - + } break; default: break; } @@ -659,15 +659,15 @@ void UpdateMusicStream(Music music) break; } } - + // Reset audio stream for looping if (!active && music->loop) { // Restart music context (if required) - //if (music->ctxType == MUSIC_MODULE_XM) + //if (music->ctxType == MUSIC_MODULE_XM) if (music->ctxType == MUSIC_MODULE_MOD) jar_mod_seek_start(&music->ctxMod); else if (music->ctxType == MUSIC_AUDIO_OGG) stb_vorbis_seek_start(music->ctxOgg); - + // Reset samples left to total samples music->samplesLeft = music->totalSamples; } @@ -713,7 +713,7 @@ void SetMusicPitch(Music music, float pitch) float GetMusicTimeLength(Music music) { float totalSeconds = (float)music->totalSamples/music->stream.sampleRate; - + return totalSeconds; } @@ -732,7 +732,7 @@ float GetMusicTimePlayed(Music music) AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels) { AudioStream stream = { 0 }; - + stream.sampleRate = sampleRate; stream.sampleSize = sampleSize; stream.channels = channels; @@ -791,7 +791,7 @@ AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, un } alSourceQueueBuffers(stream.source, MAX_STREAM_BUFFERS, stream.buffers); - + TraceLog(INFO, "[AUD ID %i] Audio stream loaded successfully", stream.source); return stream; @@ -806,9 +806,9 @@ void CloseAudioStream(AudioStream stream) // Flush out all queued buffers int queued = 0; alGetSourcei(stream.source, AL_BUFFERS_QUEUED, &queued); - + ALuint buffer = 0; - + while (queued > 0) { alSourceUnqueueBuffers(stream.source, 1, &buffer); @@ -818,7 +818,7 @@ void CloseAudioStream(AudioStream stream) // Delete source and buffers alDeleteSources(1, &stream.source); alDeleteBuffers(MAX_STREAM_BUFFERS, stream.buffers); - + TraceLog(INFO, "[AUD ID %i] Unloaded audio stream data", stream.source); } @@ -828,14 +828,14 @@ void UpdateAudioStream(AudioStream stream, void *data, int numSamples) { ALuint buffer = 0; alSourceUnqueueBuffers(stream.source, 1, &buffer); - + // Check if any buffer was available for unqueue if (alGetError() != AL_INVALID_VALUE) { if (stream.sampleSize == 8) alBufferData(buffer, stream.format, (unsigned char *)data, numSamples*sizeof(unsigned char), stream.sampleRate); else if (stream.sampleSize == 16) alBufferData(buffer, stream.format, (short *)data, numSamples*sizeof(short), stream.sampleRate); else if (stream.sampleSize == 32) alBufferData(buffer, stream.format, (float *)data, numSamples*sizeof(float), stream.sampleRate); - + alSourceQueueBuffers(stream.source, 1, &buffer); } } diff --git a/src/core.c b/src/core.c index 2b5329e3..a76fe0be 100644 --- a/src/core.c +++ b/src/core.c @@ -120,9 +120,9 @@ //#define DEFAULT_KEYBOARD_DEV "/dev/input/eventN" //#define DEFAULT_MOUSE_DEV "/dev/input/eventN" //#define DEFAULT_GAMEPAD_DEV "/dev/input/eventN" - + #define MOUSE_SENSITIVITY 0.8f - + #define MAX_GAMEPADS 2 // Max number of gamepads supported #define MAX_GAMEPAD_BUTTONS 11 // Max bumber of buttons supported (per gamepad) #define MAX_GAMEPAD_AXIS 8 // Max number of axis supported (per gamepad) @@ -333,7 +333,7 @@ void InitWindow(int width, int height, const char *title) emscripten_set_touchend_callback("#canvas", NULL, 1, EmscriptenInputCallback); emscripten_set_touchmove_callback("#canvas", NULL, 1, EmscriptenInputCallback); emscripten_set_touchcancel_callback("#canvas", NULL, 1, EmscriptenInputCallback); - + // TODO: Add gamepad support (not provided by GLFW3 on emscripten) //emscripten_set_gamepadconnected_callback(NULL, 1, EmscriptenInputCallback); //emscripten_set_gamepaddisconnected_callback(NULL, 1, EmscriptenInputCallback); @@ -394,7 +394,7 @@ void InitWindow(int width, int height, struct android_app *state) //state->userData = &engine; app->onAppCmd = AndroidCommandCallback; app->onInputEvent = AndroidInputCallback; - + InitAssetManager(app->activity->assetManager); TraceLog(INFO, "Android app initialized successfully"); @@ -447,7 +447,7 @@ void CloseWindow(void) eglTerminate(display); display = EGL_NO_DISPLAY; - } + } #endif #if defined(PLATFORM_RPI) @@ -527,7 +527,7 @@ void BeginDrawing(void) currentTime = GetTime(); // Number of elapsed seconds since InitTimer() was called updateTime = currentTime - previousTime; previousTime = currentTime; - + rlClearScreenBuffers(); // Clear current framebuffers rlLoadIdentity(); // Reset current matrix (MODELVIEW) rlMultMatrixf(MatrixToFloat(downscaleView)); // If downscale required, apply it here @@ -543,7 +543,7 @@ void EndDrawing(void) SwapBuffers(); // Copy back buffer to front buffer PollInputEvents(); // Poll user events - + // Frame time control system currentTime = GetTime(); drawTime = currentTime - previousTime; @@ -575,9 +575,9 @@ void Begin2dMode(Camera2D camera) Matrix matRotation = MatrixRotate((Vector3){ 0.0f, 0.0f, 1.0f }, camera.rotation*DEG2RAD); Matrix matScale = MatrixScale(camera.zoom, camera.zoom, 1.0f); Matrix matTranslation = MatrixTranslate(camera.offset.x + camera.target.x, camera.offset.y + camera.target.y, 0.0f); - + Matrix matTransform = MatrixMultiply(MatrixMultiply(matOrigin, MatrixMultiply(matScale, matRotation)), matTranslation); - + rlMultMatrixf(MatrixToFloat(matTransform)); } @@ -593,14 +593,14 @@ void End2dMode(void) void Begin3dMode(Camera camera) { rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) - + if (IsVrDeviceReady()) BeginVrDrawing(); rlMatrixMode(RL_PROJECTION); // Switch to projection matrix rlPushMatrix(); // Save previous matrix, which contains the settings for the 2d ortho projection rlLoadIdentity(); // Reset current matrix (PROJECTION) - + // Setup perspective projection float aspect = (float)screenWidth/(float)screenHeight; double top = 0.01*tan(camera.fovy*PI/360.0); @@ -615,15 +615,15 @@ void Begin3dMode(Camera camera) // Setup Camera view Matrix cameraView = MatrixLookAt(camera.position, camera.target, camera.up); rlMultMatrixf(MatrixToFloat(cameraView)); // Multiply MODELVIEW matrix by view matrix (camera) - + rlEnableDepthTest(); // Enable DEPTH_TEST for 3D } // Ends 3D mode and returns to default 2D orthographic mode void End3dMode(void) -{ +{ rlglDraw(); // Process internal buffers (update + draw) - + if (IsVrDeviceReady()) EndVrDrawing(); rlMatrixMode(RL_PROJECTION); // Switch to projection matrix @@ -633,7 +633,7 @@ void End3dMode(void) rlLoadIdentity(); // Reset current matrix (MODELVIEW) //rlTranslatef(0.375, 0.375, 0); // HACK to ensure pixel-perfect drawing on OpenGL (after exiting 3D mode) - + rlDisableDepthTest(); // Disable DEPTH_TEST for 2D } @@ -645,16 +645,16 @@ void BeginTextureMode(RenderTexture2D target) rlEnableRenderTexture(target.id); // Enable render target rlClearScreenBuffers(); // Clear render texture buffers - + // Set viewport to framebuffer size - rlViewport(0, 0, target.texture.width, target.texture.height); - + rlViewport(0, 0, target.texture.width, target.texture.height); + rlMatrixMode(RL_PROJECTION); // Switch to PROJECTION matrix rlLoadIdentity(); // Reset current matrix (PROJECTION) // Set orthographic projection to current framebuffer size // NOTE: Configured top-left corner as (0, 0) - rlOrtho(0, target.texture.width, target.texture.height, 0, 0.0f, 1.0f); + rlOrtho(0, target.texture.width, target.texture.height, 0, 0.0f, 1.0f); rlMatrixMode(RL_MODELVIEW); // Switch back to MODELVIEW matrix rlLoadIdentity(); // Reset current matrix (MODELVIEW) @@ -672,10 +672,10 @@ void EndTextureMode(void) // Set viewport to default framebuffer size (screen size) // TODO: consider possible viewport offsets rlViewport(0, 0, GetScreenWidth(), GetScreenHeight()); - + rlMatrixMode(RL_PROJECTION); // Switch to PROJECTION matrix rlLoadIdentity(); // Reset current matrix (PROJECTION) - + // Set orthographic projection to current framebuffer size // NOTE: Configured top-left corner as (0, 0) rlOrtho(0, GetScreenWidth(), GetScreenHeight(), 0, 0.0f, 1.0f); @@ -701,7 +701,7 @@ float GetFPS(void) // Returns time in seconds for one frame float GetFrameTime(void) { - // As we are operate quite a lot with frameTime, + // As we are operate quite a lot with frameTime, // it could be no stable, so we round it before passing it around // NOTE: There are still problems with high framerates (>500fps) double roundedFrameTime = round(frameTime*10000)/10000.0; @@ -735,7 +735,7 @@ float *VectorToFloat(Vector3 vec) } // Converts Matrix to float array -// NOTE: Returned vector is a transposed version of the Matrix struct, +// NOTE: Returned vector is a transposed version of the Matrix struct, // it should be this way because, despite raymath use OpenGL column-major convention, // Matrix struct memory alignment and variables naming are not coherent float *MatrixToFloat(Matrix mat) @@ -799,7 +799,7 @@ Color Fade(Color color, float alpha) { if (alpha < 0.0f) alpha = 0.0f; else if (alpha > 1.0f) alpha = 1.0f; - + float colorAlpha = (float)color.a*alpha; return (Color){color.r, color.g, color.b, (unsigned char)colorAlpha}; @@ -841,9 +841,9 @@ void ClearDroppedFiles(void) if (dropFilesCount > 0) { for (int i = 0; i < dropFilesCount; i++) free(dropFilesPath[i]); - + free(dropFilesPath); - + dropFilesCount = 0; } } @@ -854,7 +854,7 @@ void ClearDroppedFiles(void) void StorageSaveValue(int position, int value) { FILE *storageFile = NULL; - + char path[128]; #if defined(PLATFORM_ANDROID) strcpy(path, internalDataPath); @@ -865,7 +865,7 @@ void StorageSaveValue(int position, int value) #endif // Try open existing file to append data - storageFile = fopen(path, "rb+"); + storageFile = fopen(path, "rb+"); // If file doesn't exist, create a new storage data file if (!storageFile) storageFile = fopen(path, "wb"); @@ -877,14 +877,14 @@ void StorageSaveValue(int position, int value) fseek(storageFile, 0, SEEK_END); int fileSize = ftell(storageFile); // Size in bytes fseek(storageFile, 0, SEEK_SET); - + if (fileSize < (position*4)) TraceLog(WARNING, "Storage position could not be found"); else { fseek(storageFile, (position*4), SEEK_SET); fwrite(&value, 1, 4, storageFile); } - + fclose(storageFile); } } @@ -894,7 +894,7 @@ void StorageSaveValue(int position, int value) int StorageLoadValue(int position) { int value = 0; - + char path[128]; #if defined(PLATFORM_ANDROID) strcpy(path, internalDataPath); @@ -903,9 +903,9 @@ int StorageLoadValue(int position) #else strcpy(path, STORAGE_FILENAME); #endif - + // Try open existing file to append data - FILE *storageFile = fopen(path, "rb"); + FILE *storageFile = fopen(path, "rb"); if (!storageFile) TraceLog(WARNING, "Storage data file could not be found"); else @@ -914,42 +914,42 @@ int StorageLoadValue(int position) fseek(storageFile, 0, SEEK_END); int fileSize = ftell(storageFile); // Size in bytes rewind(storageFile); - + if (fileSize < (position*4)) TraceLog(WARNING, "Storage position could not be found"); else { fseek(storageFile, (position*4), SEEK_SET); fread(&value, 1, 4, storageFile); } - + fclose(storageFile); } - + return value; } // Returns a ray trace from mouse position Ray GetMouseRay(Vector2 mousePosition, Camera camera) -{ +{ Ray ray; - + // Calculate normalized device coordinates // NOTE: y value is negative float x = (2.0f*mousePosition.x)/(float)GetScreenWidth() - 1.0f; float y = 1.0f - (2.0f*mousePosition.y)/(float)GetScreenHeight(); float z = 1.0f; - + // Store values in a vector Vector3 deviceCoords = { x, y, z }; - + TraceLog(DEBUG, "Device coordinates: (%f, %f, %f)", deviceCoords.x, deviceCoords.y, deviceCoords.z); - + // Calculate projection matrix (from perspective instead of frustum) Matrix matProj = MatrixPerspective(camera.fovy, ((double)GetScreenWidth()/(double)GetScreenHeight()), 0.01, 1000.0); - + // Calculate view matrix from camera look at Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up); - + // Do I need to transpose it? It seems that yes... // NOTE: matrix order may be incorrect... In OpenGL to get world position from // camera view it just needs to get inverted, but here we need to transpose it too. @@ -957,10 +957,10 @@ Ray GetMouseRay(Vector2 mousePosition, Camera camera) // to a vector, you will get its 3d world position coordinates (camera.position). // If you don't transpose, final position will be wrong. MatrixTranspose(&matView); - + //#define USE_RLGL_UNPROJECT #if defined(USE_RLGL_UNPROJECT) // OPTION 1: Use rlglUnproject() - + Vector3 nearPoint = rlglUnproject((Vector3){ deviceCoords.x, deviceCoords.y, 0.0f }, matProj, matView); Vector3 farPoint = rlglUnproject((Vector3){ deviceCoords.x, deviceCoords.y, 1.0f }, matProj, matView); @@ -969,56 +969,56 @@ Ray GetMouseRay(Vector2 mousePosition, Camera camera) // Calculate unproject matrix (multiply projection matrix and view matrix) and invert it Matrix matProjView = MatrixMultiply(matProj, matView); MatrixInvert(&matProjView); - + // Calculate far and near points Quaternion near = { deviceCoords.x, deviceCoords.y, 0.0f, 1.0f }; Quaternion far = { deviceCoords.x, deviceCoords.y, 1.0f, 1.0f }; - + // Multiply points by unproject matrix QuaternionTransform(&near, matProjView); QuaternionTransform(&far, matProjView); - + // Calculate normalized world points in vectors Vector3 nearPoint = { near.x/near.w, near.y/near.w, near.z/near.w}; Vector3 farPoint = { far.x/far.w, far.y/far.w, far.z/far.w}; #endif - + // Calculate normalized direction vector Vector3 direction = VectorSubtract(farPoint, nearPoint); VectorNormalize(&direction); - + // Apply calculated vectors to ray ray.position = camera.position; ray.direction = direction; - + return ray; } // Returns the screen space position from a 3d world space position Vector2 GetWorldToScreen(Vector3 position, Camera camera) -{ +{ // Calculate projection matrix (from perspective instead of frustum Matrix matProj = MatrixPerspective(camera.fovy, (double)GetScreenWidth()/(double)GetScreenHeight(), 0.01, 1000.0); - + // Calculate view matrix from camera look at (and transpose it) Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up); MatrixTranspose(&matView); - + // Convert world position vector to quaternion Quaternion worldPos = { position.x, position.y, position.z, 1.0f }; - + // Transform world position to view QuaternionTransform(&worldPos, matView); - + // Transform result to projection (clip space position) QuaternionTransform(&worldPos, matProj); - + // Calculate normalized device coordinates (inverted y) Vector3 ndcPos = { worldPos.x / worldPos.w, -worldPos.y / worldPos.w, worldPos.z / worldPos.z }; - + // Calculate 2d screen position vector Vector2 screenPosition = { (ndcPos.x + 1.0f)/2.0f*(float)GetScreenWidth(), (ndcPos.y + 1.0f)/2.0f*(float)GetScreenHeight() }; - + return screenPosition; } @@ -1144,7 +1144,7 @@ bool IsCursorHidden() bool IsGamepadAvailable(int gamepad) { bool result = false; - + #if defined(PLATFORM_RPI) if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad]) result = true; #else @@ -1158,7 +1158,7 @@ bool IsGamepadAvailable(int gamepad) float GetGamepadAxisMovement(int gamepad, int axis) { float value = 0; - + #if defined(PLATFORM_RPI) if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad]) { @@ -1167,9 +1167,9 @@ float GetGamepadAxisMovement(int gamepad, int axis) #else const float *axes; int axisCount = 0; - + axes = glfwGetJoystickAxes(gamepad, &axisCount); - + if (axis < axisCount) value = axes[axis]; #endif @@ -1197,7 +1197,7 @@ bool IsGamepadButtonPressed(int gamepad, int button) bool IsGamepadButtonDown(int gamepad, int button) { bool result = false; - + #if defined(PLATFORM_RPI) // Get gamepad buttons information if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (gamepadButtons[gamepad][button] == 1)) result = true; @@ -1205,13 +1205,13 @@ bool IsGamepadButtonDown(int gamepad, int button) #else const unsigned char *buttons; int buttonsCount; - + buttons = glfwGetJoystickButtons(gamepad, &buttonsCount); if ((buttons != NULL) && (buttons[button] == GLFW_PRESS)) result = true; else result = false; #endif - + return result; } @@ -1260,7 +1260,7 @@ bool IsGamepadButtonUp(int gamepad, int button) bool IsMouseButtonPressed(int button) { bool pressed = false; - + #if defined(PLATFORM_ANDROID) if (IsGestureDetected(GESTURE_TAP)) pressed = true; #else @@ -1274,13 +1274,13 @@ bool IsMouseButtonPressed(int button) bool IsMouseButtonDown(int button) { bool down = false; - + #if defined(PLATFORM_ANDROID) if (IsGestureDetected(GESTURE_HOLD)) down = true; #else if (GetMouseButtonStatus(button) == 1) down = true; #endif - + return down; } @@ -1288,7 +1288,7 @@ bool IsMouseButtonDown(int button) bool IsMouseButtonReleased(int button) { bool released = false; - + #if !defined(PLATFORM_ANDROID) if ((currentMouseState[button] != previousMouseState[button]) && (currentMouseState[button] == 0)) released = true; #endif @@ -1300,7 +1300,7 @@ bool IsMouseButtonReleased(int button) bool IsMouseButtonUp(int button) { bool up = false; - + #if !defined(PLATFORM_ANDROID) if (GetMouseButtonStatus(button) == 0) up = true; #endif @@ -1385,7 +1385,7 @@ int GetTouchY(void) Vector2 GetTouchPosition(int index) { Vector2 position = { -1.0f, -1.0f }; - + #if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB) if (index < MAX_TOUCH_POINTS) position = touchPosition[index]; else TraceLog(WARNING, "Required touch point out of range (Max touch points: %i)", MAX_TOUCH_POINTS); @@ -1493,7 +1493,7 @@ static void InitGraphicsDevice(int width, int height) // NOTE: When asking for an OpenGL context version, most drivers provide highest supported version // with forward compatibility to older OpenGL versions. // For example, if using OpenGL 1.1, driver can provide a 3.3 context fordward compatible. - + if (configFlags & FLAG_MSAA_4X_HINT) { glfwWindowHint(GLFW_SAMPLES, 4); // Enables multisampling x4 (MSAA), default is 0 @@ -1513,7 +1513,7 @@ static void InitGraphicsDevice(int width, int height) glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // Profiles Hint: Only 3.3 and above! // Other values: GLFW_OPENGL_ANY_PROFILE, GLFW_OPENGL_COMPAT_PROFILE #ifdef __APPLE__ - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // OSX Requires + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // OSX Requires #else glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_FALSE); // Fordward Compatibility Hint: Only 3.3 and above! #endif @@ -1523,9 +1523,9 @@ static void InitGraphicsDevice(int width, int height) if (fullscreen) { // Obtain recommended displayWidth/displayHeight from a valid videomode for the monitor - int count; + int count; const GLFWvidmode *modes = glfwGetVideoModes(glfwGetPrimaryMonitor(), &count); - + // Get closest videomode to desired screenWidth/screenHeight for (int i = 0; i < count; i++) { @@ -1539,7 +1539,7 @@ static void InitGraphicsDevice(int width, int height) } } } - + TraceLog(WARNING, "Closest fullscreen videomode: %i x %i", displayWidth, displayHeight); // NOTE: ISSUE: Closest videomode could not match monitor aspect-ratio, for example, @@ -1548,12 +1548,12 @@ static void InitGraphicsDevice(int width, int height) // by the sides to fit all monitor space... // At this point we need to manage render size vs screen size - // NOTE: This function uses and modifies global module variables: + // NOTE: This function uses and modifies global module variables: // screenWidth/screenHeight - renderWidth/renderHeight - downscaleView SetupFramebufferSize(displayWidth, displayHeight); window = glfwCreateWindow(displayWidth, displayHeight, windowTitle, glfwGetPrimaryMonitor(), NULL); - + // NOTE: Full-screen change, not working properly... //glfwSetWindowMonitor(window, glfwGetPrimaryMonitor(), 0, 0, screenWidth, screenHeight, GLFW_DONT_CARE); } @@ -1561,15 +1561,15 @@ static void InitGraphicsDevice(int width, int height) { // No-fullscreen window creation window = glfwCreateWindow(screenWidth, screenHeight, windowTitle, NULL, NULL); - + #if defined(PLATFORM_DESKTOP) // Center window on screen int windowPosX = displayWidth/2 - screenWidth/2; int windowPosY = displayHeight/2 - screenHeight/2; - + if (windowPosX < 0) windowPosX = 0; if (windowPosY < 0) windowPosY = 0; - + glfwSetWindowPos(window, windowPosX, windowPosY); #endif renderWidth = screenWidth; @@ -1612,7 +1612,7 @@ static void InitGraphicsDevice(int width, int height) // NOTE: GLFW loader function is passed as parameter rlglLoadExtensions(glfwGetProcAddress); #endif - + // Enables GPU v-sync, so frames are not limited to screen refresh rate (60Hz -> 60 FPS) // If not set, swap interval uses GPU v-sync configuration // Framerate can be setup using SetTargetFPS() @@ -1620,7 +1620,7 @@ static void InitGraphicsDevice(int width, int height) { glfwSwapInterval(1); TraceLog(INFO, "Trying to enable VSYNC"); - } + } #endif // defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) #if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) @@ -1643,13 +1643,13 @@ static void InitGraphicsDevice(int width, int height) EGLint samples = 0; EGLint sampleBuffer = 0; - if (configFlags & FLAG_MSAA_4X_HINT) + if (configFlags & FLAG_MSAA_4X_HINT) { samples = 4; sampleBuffer = 1; TraceLog(INFO, "Trying to enable MSAA x4"); } - + const EGLint framebufferAttribs[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, // Type of context support -> Required on RPI? @@ -1773,10 +1773,10 @@ static void InitGraphicsDevice(int width, int height) // Initialize OpenGL context (states and resources) // NOTE: screenWidth and screenHeight not used, just stored as globals rlglInit(screenWidth, screenHeight); - + #ifdef __APPLE__ // Get framebuffer size of current window - // NOTE: Required to handle HighDPI display correctly on OSX because framebuffer + // NOTE: Required to handle HighDPI display correctly on OSX because framebuffer // is automatically reasized to adapt to new DPI. // When OS does that, it can be detected using GLFW3 callback: glfwSetFramebufferSizeCallback() int fbWidth, fbHeight; @@ -1792,7 +1792,7 @@ static void InitGraphicsDevice(int width, int height) // NOTE: Default to orthographic projection mode with top-left corner at (0,0) rlMatrixMode(RL_PROJECTION); // Switch to PROJECTION matrix rlLoadIdentity(); // Reset current matrix (PROJECTION) - rlOrtho(0, renderWidth - renderOffsetX, renderHeight - renderOffsetY, 0, 0.0f, 1.0f); + rlOrtho(0, renderWidth - renderOffsetX, renderHeight - renderOffsetY, 0, 0.0f, 1.0f); rlMatrixMode(RL_MODELVIEW); // Switch back to MODELVIEW matrix rlLoadIdentity(); // Reset current matrix (MODELVIEW) @@ -1806,7 +1806,7 @@ static void InitGraphicsDevice(int width, int height) // Compute framebuffer size relative to screen size and display size // NOTE: Global variables renderWidth/renderHeight and renderOffsetX/renderOffsetY can be modified static void SetupFramebufferSize(int displayWidth, int displayHeight) -{ +{ // Calculate renderWidth and renderHeight, we have the display size (input params) and the desired screen size (global var) if ((screenWidth > displayWidth) || (screenHeight > displayHeight)) { @@ -1945,7 +1945,7 @@ static void PollInputEvents(void) // NOTE: Gestures update must be called every frame to reset gestures correctly // because ProcessGestureEvent() is just called on an event, not every frame UpdateGestures(); - + #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) // Mouse input polling double mouseX; @@ -2025,7 +2025,7 @@ static void TakeScreenshot(void) unsigned char *imgData = rlglReadScreenPixels(renderWidth, renderHeight); sprintf(buffer, "screenshot%03i.png", shotNum); - + // Save image as PNG WritePNG(buffer, imgData, renderWidth, renderHeight, 4); @@ -2062,7 +2062,7 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i #if defined(PLATFORM_DESKTOP) else if (key == GLFW_KEY_F12 && action == GLFW_PRESS) TakeScreenshot(); #endif - else + else { currentKeyState[key] = action; if (action == GLFW_PRESS) lastKeyPressed = key; @@ -2073,27 +2073,27 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i static void MouseButtonCallback(GLFWwindow *window, int button, int action, int mods) { currentMouseState[button] = action; - + #define ENABLE_MOUSE_GESTURES #if defined(ENABLE_MOUSE_GESTURES) // Process mouse events as touches to be able to use mouse-gestures GestureEvent gestureEvent; - + // Register touch actions if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) gestureEvent.touchAction = TOUCH_DOWN; else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) gestureEvent.touchAction = TOUCH_UP; - + // NOTE: TOUCH_MOVE event is registered in MouseCursorPosCallback() - + // Assign a pointer ID gestureEvent.pointerId[0] = 0; - + // Register touch points count gestureEvent.pointCount = 1; - + // Register touch points position, only one point registered gestureEvent.position[0] = GetMousePosition(); - + // Normalize gestureEvent.position[0] for screenWidth and screenHeight gestureEvent.position[0].x /= (float)GetScreenWidth(); gestureEvent.position[0].y /= (float)GetScreenHeight(); @@ -2112,20 +2112,20 @@ static void MouseCursorPosCallback(GLFWwindow *window, double x, double y) GestureEvent gestureEvent; gestureEvent.touchAction = TOUCH_MOVE; - + // Assign a pointer ID gestureEvent.pointerId[0] = 0; // Register touch points count gestureEvent.pointCount = 1; - + // Register touch points position, only one point registered gestureEvent.position[0] = (Vector2){ (float)x, (float)y }; - + touchPosition[0] = gestureEvent.position[0]; - + // Normalize gestureEvent.position[0] for screenWidth and screenHeight - gestureEvent.position[0].x /= (float)GetScreenWidth(); + gestureEvent.position[0].x /= (float)GetScreenWidth(); gestureEvent.position[0].y /= (float)GetScreenHeight(); // Gesture data is sent to gestures system for processing @@ -2166,7 +2166,7 @@ static void WindowSizeCallback(GLFWwindow *window, int width, int height) screenHeight = height; renderWidth = width; renderHeight = height; - + // NOTE: Postprocessing texture is not scaled to new size } @@ -2185,9 +2185,9 @@ static void WindowIconifyCallback(GLFWwindow* window, int iconified) static void WindowDropCallback(GLFWwindow *window, int count, const char **paths) { ClearDroppedFiles(); - + dropFilesPath = (char **)malloc(sizeof(char *)*count); - + for (int i = 0; i < count; i++) { dropFilesPath[i] = (char *)malloc(sizeof(char)*256); // Max path length set to 256 char @@ -2249,7 +2249,7 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd) for (int i = 0; i < assetsCount; i++) { // TODO: Unload old asset if required - + // Load texture again to pointed texture (*textureAsset + i) = LoadTexture(assetPath[i]); } @@ -2292,7 +2292,7 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd) // 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"); @@ -2329,7 +2329,7 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd) 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) @@ -2337,7 +2337,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) // Get first touch position touchPosition[0].x = AMotionEvent_getX(event, 0); touchPosition[0].y = AMotionEvent_getY(event, 0); - + // Get second touch position touchPosition[1].x = AMotionEvent_getX(event, 1); touchPosition[1].y = AMotionEvent_getY(event, 1); @@ -2346,7 +2346,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) { int32_t keycode = AKeyEvent_getKeyCode(event); //int32_t AKeyEvent_getMetaState(event); - + // Save current button and its state currentButtonState[keycode] = AKeyEvent_getAction(event); // Down = 0, Up = 1 @@ -2358,7 +2358,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) // NOTE: AndroidManifest.xml must have // Before that change, activity was calling CMD_TERM_WINDOW and CMD_DESTROY when locking mobile, so that was not a normal behaviour return 0; - } + } else if ((keycode == AKEYCODE_BACK) || (keycode == AKEYCODE_MENU)) { // Eat BACK_BUTTON and AKEYCODE_MENU, just do nothing... and don't let to be handled by OS! @@ -2370,36 +2370,36 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) 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 id gestureEvent.pointerId[0] = AMotionEvent_getPointerId(event, 0); gestureEvent.pointerId[1] = AMotionEvent_getPointerId(event, 1); - + // 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) }; - + // Normalize gestureEvent.position[x] for screenWidth and screenHeight - gestureEvent.position[0].x /= (float)GetScreenWidth(); + gestureEvent.position[0].x /= (float)GetScreenWidth(); gestureEvent.position[0].y /= (float)GetScreenHeight(); - - gestureEvent.position[1].x /= (float)GetScreenWidth(); + + gestureEvent.position[1].x /= (float)GetScreenWidth(); gestureEvent.position[1].y /= (float)GetScreenHeight(); - + // Gesture data is sent to gestures system for processing ProcessGestureEvent(gestureEvent); @@ -2410,13 +2410,13 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) #if defined(PLATFORM_WEB) static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const EmscriptenFullscreenChangeEvent *e, void *userData) { - //isFullscreen: int e->isFullscreen - //fullscreenEnabled: int e->fullscreenEnabled + //isFullscreen: int e->isFullscreen + //fullscreenEnabled: int e->fullscreenEnabled //fs element nodeName: (char *) e->nodeName //fs element id: (char *) e->id //Current element size: (int) e->elementWidth, (int) e->elementHeight //Screen size:(int) e->screenWidth, (int) e->screenHeight - + if (e->isFullscreen) { TraceLog(INFO, "Canvas scaled to fullscreen. ElementSize: (%ix%i), ScreenSize(%ix%i)", e->elementWidth, e->elementHeight, e->screenWidth, e->screenHeight); @@ -2425,7 +2425,7 @@ static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const Emscripte { TraceLog(INFO, "Canvas scaled to windowed. ElementSize: (%ix%i), ScreenSize(%ix%i)", e->elementWidth, e->elementHeight, e->screenWidth, e->screenHeight); } - + // TODO: Depending on scaling factor (screen vs element), calculate factor to scale mouse/touch input return 0; @@ -2445,33 +2445,33 @@ static EM_BOOL EmscriptenInputCallback(int eventType, const EmscriptenTouchEvent 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 id gestureEvent.pointerId[0] = touchEvent->touches[0].identifier; gestureEvent.pointerId[1] = touchEvent->touches[1].identifier; - + // Register touch points position // NOTE: Only two points registered // TODO: Touch data should be scaled accordingly! @@ -2482,12 +2482,12 @@ static EM_BOOL EmscriptenInputCallback(int eventType, const EmscriptenTouchEvent touchPosition[0] = gestureEvent.position[0]; touchPosition[1] = gestureEvent.position[1]; - + // Normalize gestureEvent.position[x] for screenWidth and screenHeight - gestureEvent.position[0].x /= (float)GetScreenWidth(); + gestureEvent.position[0].x /= (float)GetScreenWidth(); gestureEvent.position[0].y /= (float)GetScreenHeight(); - - gestureEvent.position[1].x /= (float)GetScreenWidth(); + + gestureEvent.position[1].x /= (float)GetScreenWidth(); gestureEvent.position[1].y /= (float)GetScreenHeight(); // Gesture data is sent to gestures system for processing @@ -2533,7 +2533,7 @@ static void InitKeyboard(void) else { // We reconfigure keyboard mode to get: - // - scancodes (K_RAW) + // - scancodes (K_RAW) // - keycodes (K_MEDIUMRAW) // - ASCII chars (K_XLATE) // - UNICODE chars (K_UNICODE) @@ -2549,7 +2549,7 @@ static void InitKeyboard(void) static void ProcessKeyboard(void) { #define MAX_KEYBUFFER_SIZE 32 // Max size in bytes to read - + // Keyboard input polling (fill keys[256] array with status) int bufferByteCount = 0; // Bytes available on the buffer char keysBuffer[MAX_KEYBUFFER_SIZE]; // Max keys to be read at a time @@ -2564,7 +2564,7 @@ static void ProcessKeyboard(void) for (int i = 0; i < bufferByteCount; i++) { TraceLog(DEBUG, "Bytes on keysBuffer: %i", bufferByteCount); - + //printf("Key(s) bytes: "); //for (int i = 0; i < bufferByteCount; i++) printf("0x%02x ", keysBuffer[i]); //printf("\n"); @@ -2598,7 +2598,7 @@ static void ProcessKeyboard(void) case 0x34: currentKeyState[301] = 1; break; // raylib KEY_F12 default: break; } - + if (keysBuffer[i + 2] == 0x5b) i += 4; else if ((keysBuffer[i + 2] == 0x31) || (keysBuffer[i + 2] == 0x32)) i += 5; } @@ -2615,7 +2615,7 @@ static void ProcessKeyboard(void) i += 3; // Jump to next key } - + // NOTE: Some keys are not directly keymapped (CTRL, ALT, SHIFT) } } @@ -2625,7 +2625,7 @@ static void ProcessKeyboard(void) else { TraceLog(DEBUG, "Pressed key (ASCII): 0x%02x", keysBuffer[i]); - + // Translate lowercase a-z letters to A-Z if ((keysBuffer[i] >= 97) && (keysBuffer[i] <= 122)) { @@ -2634,10 +2634,10 @@ static void ProcessKeyboard(void) else currentKeyState[(int)keysBuffer[i]] = 1; } } - + // Check exit key (same functionality as GLFW3 KeyCallback()) if (currentKeyState[exitKey] == 1) windowShouldClose = true; - + // Check screen capture key if (currentKeyState[301] == 1) TakeScreenshot(); // raylib key: KEY_F12 (GLFW_KEY_F12) } @@ -2647,7 +2647,7 @@ static void RestoreKeyboard(void) { // Reset to default keyboard settings tcsetattr(STDIN_FILENO, TCSANOW, &defaultKeyboardSettings); - + // Reconfigure keyboard to default mode ioctl(STDIN_FILENO, KDSKBMODE, defaultKeyboardMode); } @@ -2677,14 +2677,14 @@ static void InitMouse(void) static void *MouseThread(void *arg) { const unsigned char XSIGN = 1<<4, YSIGN = 1<<5; - - typedef struct { + + typedef struct { char buttons; - char dx, dy; + char dx, dy; } MouseEvent; - + MouseEvent mouse; - + int mouseRelX = 0; int mouseRelY = 0; @@ -2693,7 +2693,7 @@ static void *MouseThread(void *arg) if (read(mouseStream, &mouse, sizeof(MouseEvent)) == (int)sizeof(MouseEvent)) { if ((mouse.buttons & 0x08) == 0) break; // This bit should always be set - + // Check Left button pressed if ((mouse.buttons & 0x01) > 0) currentMouseState[0] = 1; else currentMouseState[0] = 0; @@ -2701,27 +2701,27 @@ static void *MouseThread(void *arg) // Check Right button pressed if ((mouse.buttons & 0x02) > 0) currentMouseState[1] = 1; else currentMouseState[1] = 0; - + // Check Middle button pressed if ((mouse.buttons & 0x04) > 0) currentMouseState[2] = 1; else currentMouseState[2] = 0; - + mouseRelX = (int)mouse.dx; mouseRelY = (int)mouse.dy; - + if ((mouse.buttons & XSIGN) > 0) mouseRelX = -1*(255 - mouseRelX); if ((mouse.buttons & YSIGN) > 0) mouseRelY = -1*(255 - mouseRelY); - + // NOTE: Mouse movement is normalized to not be screen resolution dependant // We suppose 2*255 (max relative movement) is equivalent to screenWidth (max pixels width) // Result after normalization is multiplied by MOUSE_SENSITIVITY factor mousePosition.x += (float)mouseRelX*((float)screenWidth/(2*255))*MOUSE_SENSITIVITY; mousePosition.y -= (float)mouseRelY*((float)screenHeight/(2*255))*MOUSE_SENSITIVITY; - + if (mousePosition.x < 0) mousePosition.x = 0; if (mousePosition.y < 0) mousePosition.y = 0; - + if (mousePosition.x > screenWidth) mousePosition.x = screenWidth; if (mousePosition.y > screenHeight) mousePosition.y = screenHeight; } @@ -2735,12 +2735,12 @@ static void *MouseThread(void *arg) static void InitGamepad(void) { char gamepadDev[128] = ""; - + for (int i = 0; i < MAX_GAMEPADS; i++) { sprintf(gamepadDev, "%s%i", DEFAULT_GAMEPAD_DEV, i); - - if ((gamepadStream[i] = open(gamepadDev, O_RDONLY|O_NONBLOCK)) < 0) + + if ((gamepadStream[i] = open(gamepadDev, O_RDONLY|O_NONBLOCK)) < 0) { // NOTE: Only show message for first gamepad if (i == 0) TraceLog(WARNING, "Gamepad device could not be opened, no gamepad available"); @@ -2758,7 +2758,7 @@ static void InitGamepad(void) else TraceLog(INFO, "Gamepad device initialized successfully"); } } - } + } } // Process Gamepad (/dev/input/js0) @@ -2777,7 +2777,7 @@ static void *GamepadThread(void *arg) // Read gamepad event struct js_event gamepadEvent; - + while (!windowShouldClose) { for (int i = 0; i < MAX_GAMEPADS; i++) @@ -2785,22 +2785,22 @@ static void *GamepadThread(void *arg) if (read(gamepadStream[i], &gamepadEvent, sizeof(struct js_event)) == (int)sizeof(struct js_event)) { gamepadEvent.type &= ~JS_EVENT_INIT; // Ignore synthetic events - + // Process gamepad events by type - if (gamepadEvent.type == JS_EVENT_BUTTON) + if (gamepadEvent.type == JS_EVENT_BUTTON) { TraceLog(DEBUG, "Gamepad button: %i, value: %i", gamepadEvent.number, gamepadEvent.value); - - if (gamepadEvent.number < MAX_GAMEPAD_BUTTONS) + + if (gamepadEvent.number < MAX_GAMEPAD_BUTTONS) { // 1 - button pressed, 0 - button released gamepadButtons[i][gamepadEvent.number] = (int)gamepadEvent.value; } } - else if (gamepadEvent.type == JS_EVENT_AXIS) + else if (gamepadEvent.type == JS_EVENT_AXIS) { TraceLog(DEBUG, "Gamepad axis: %i, value: %i", gamepadEvent.number, gamepadEvent.value); - + if (gamepadEvent.number < MAX_GAMEPAD_AXIS) { // NOTE: Scaling of gamepadEvent.value to get values between -1..1 diff --git a/src/models.c b/src/models.c index 24238ed2..e9044e96 100644 --- a/src/models.c +++ b/src/models.c @@ -81,12 +81,12 @@ void DrawCircle3D(Vector3 center, float radius, float rotationAngle, Vector3 rot rlPushMatrix(); rlTranslatef(center.x, center.y, center.z); rlRotatef(rotationAngle, rotation.x, rotation.y, rotation.z); - + rlBegin(RL_LINES); for (int i = 0; i < 360; i += 10) { rlColor4ub(color.r, color.g, color.b, color.a); - + rlVertex3f(sin(DEG2RAD*i)*radius, cos(DEG2RAD*i)*radius, 0.0f); rlVertex3f(sin(DEG2RAD*(i + 10)) * radius, cos(DEG2RAD*(i + 10)) * radius, 0.0f); } @@ -583,13 +583,13 @@ void DrawLight(Light light) DrawCircle3D(light->position, light->radius, 90.0f, (Vector3){ 0, 1, 0 }, (light->enabled ? light->diffuse : BLACK)); } break; case LIGHT_DIRECTIONAL: - { + { DrawLine3D(light->position, light->target, (light->enabled ? light->diffuse : BLACK)); DrawSphereWires(light->position, 0.3f*light->intensity, 4, 8, (light->enabled ? light->diffuse : BLACK)); DrawCubeWires(light->target, 0.3f, 0.3f, 0.3f, (light->enabled ? light->diffuse : BLACK)); } break; case LIGHT_SPOT: - { + { DrawLine3D(light->position, light->target, (light->enabled ? light->diffuse : BLACK)); DrawCylinderWires(light->position, 0.0f, 0.3f*light->coneAngle/50, 0.6f, 5, (light->enabled ? light->diffuse : BLACK)); DrawCubeWires(light->target, 0.3f, 0.3f, 0.3f, (light->enabled ? light->diffuse : BLACK)); @@ -602,7 +602,7 @@ void DrawLight(Light light) Model LoadModel(const char *fileName) { Model model = { 0 }; - + // TODO: Initialize default data for model in case loading fails, maybe a cube? if (strcmp(GetExtension(fileName), "obj") == 0) model.mesh = LoadOBJ(fileName); @@ -612,7 +612,7 @@ Model LoadModel(const char *fileName) else { rlglLoadMesh(&model.mesh, false); // Upload vertex data to GPU (static model) - + model.transform = MatrixIdentity(); model.material = LoadDefaultMaterial(); } @@ -626,12 +626,12 @@ Model LoadModelEx(Mesh data, bool dynamic) Model model = { 0 }; model.mesh = data; - + rlglLoadMesh(&model.mesh, dynamic); // Upload vertex data to GPU - + model.transform = MatrixIdentity(); model.material = LoadDefaultMaterial(); - + return model; } @@ -723,11 +723,11 @@ Model LoadModelFromRES(const char *rresName, int resId) Model LoadHeightmap(Image heightmap, Vector3 size) { Model model = { 0 }; - + model.mesh = GenMeshHeightmap(heightmap, size); - + rlglLoadMesh(&model.mesh, false); // Upload vertex data to GPU (static model) - + model.transform = MatrixIdentity(); model.material = LoadDefaultMaterial(); @@ -738,11 +738,11 @@ Model LoadHeightmap(Image heightmap, Vector3 size) Model LoadCubicmap(Image cubicmap) { Model model = { 0 }; - + model.mesh = GenMeshCubicmap(cubicmap, (Vector3){ 1.0f, 1.5f, 1.0f }); - + rlglLoadMesh(&model.mesh, false); // Upload vertex data to GPU (static model) - + model.transform = MatrixIdentity(); model.material = LoadDefaultMaterial(); @@ -755,7 +755,7 @@ void UnloadModel(Model model) rlglUnloadMesh(&model.mesh); UnloadMaterial(model.material); - + TraceLog(INFO, "Unloaded model data from RAM and VRAM"); } @@ -763,10 +763,10 @@ void UnloadModel(Model model) Material LoadMaterial(const char *fileName) { Material material = { 0 }; - + if (strcmp(GetExtension(fileName), "mtl") == 0) material = LoadMTL(fileName); else TraceLog(WARNING, "[%s] Material extension not recognized, it can't be loaded", fileName); - + return material; } @@ -774,7 +774,7 @@ Material LoadMaterial(const char *fileName) Material LoadDefaultMaterial(void) { Material material = { 0 }; - + material.shader = GetDefaultShader(); material.texDiffuse = GetDefaultTexture(); // White texture (1x1 pixel) //material.texNormal; // NOTE: By default, not set @@ -783,9 +783,9 @@ Material LoadDefaultMaterial(void) material.colDiffuse = WHITE; // Diffuse color material.colAmbient = WHITE; // Ambient color material.colSpecular = WHITE; // Specular color - + material.glossiness = 100.0f; // Glossiness level - + return material; } @@ -794,7 +794,7 @@ Material LoadDefaultMaterial(void) Material LoadStandardMaterial(void) { Material material = LoadDefaultMaterial(); - + material.shader = GetStandardShader(); return material; @@ -812,12 +812,12 @@ void UnloadMaterial(Material material) static Mesh GenMeshHeightmap(Image heightmap, Vector3 size) { #define GRAY_VALUE(c) ((c.r+c.g+c.b)/3) - + Mesh mesh = { 0 }; int mapX = heightmap.width; int mapZ = heightmap.height; - + Color *pixels = GetImageData(heightmap); // NOTE: One vertex per pixel @@ -908,7 +908,7 @@ static Mesh GenMeshHeightmap(Image heightmap, Vector3 size) trisCounter += 2; } } - + free(pixels); return mesh; @@ -919,7 +919,7 @@ static Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize) Mesh mesh = { 0 }; Color *cubicmapPixels = GetImageData(cubicmap); - + int mapWidth = cubicmap.width; int mapHeight = cubicmap.height; @@ -1262,9 +1262,9 @@ static Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize) free(mapVertices); free(mapNormals); free(mapTexcoords); - + free(cubicmapPixels); // Free image pixel data - + return mesh; } @@ -1273,7 +1273,7 @@ void DrawModel(Model model, Vector3 position, float scale, Color tint) { Vector3 vScale = { scale, scale, scale }; Vector3 rotationAxis = { 0.0f, 0.0f, 0.0f }; - + DrawModelEx(model, position, rotationAxis, 0.0f, vScale, tint); } @@ -1285,13 +1285,13 @@ void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rota Matrix matRotation = MatrixRotate(rotationAxis, rotationAngle*DEG2RAD); Matrix matScale = MatrixScale(scale.x, scale.y, scale.z); Matrix matTranslation = MatrixTranslate(position.x, position.y, position.z); - + // Combine model transformation matrix (model.transform) with matrix generated by function parameters (matTransform) //Matrix matModel = MatrixMultiply(model.transform, matTransform); // Transform to world-space coordinates - + model.transform = MatrixMultiply(MatrixMultiply(matScale, matRotation), matTranslation); model.material.colDiffuse = tint; // TODO: Multiply tint color by diffuse color? - + rlglDrawMesh(model.mesh, model.material, model.transform); } @@ -1299,9 +1299,9 @@ void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rota void DrawModelWires(Model model, Vector3 position, float scale, Color tint) { rlEnableWireMode(); - + DrawModel(model, position, scale, tint); - + rlDisableWireMode(); } @@ -1309,9 +1309,9 @@ void DrawModelWires(Model model, Vector3 position, float scale, Color tint) void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint) { rlEnableWireMode(); - + DrawModelEx(model, position, rotationAxis, rotationAngle, scale, tint); - + rlDisableWireMode(); } @@ -1319,7 +1319,7 @@ void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint) { Rectangle sourceRec = { 0, 0, texture.width, texture.height }; - + DrawBillboardRec(camera, texture, sourceRec, center, size, tint); } @@ -1334,7 +1334,7 @@ void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vec Vector3 right = { viewMatrix.m0, viewMatrix.m4, viewMatrix.m8 }; //Vector3 up = { viewMatrix.m1, viewMatrix.m5, viewMatrix.m9 }; - + // NOTE: Billboard locked on axis-Y Vector3 up = { 0.0f, 1.0f, 0.0f }; /* @@ -1384,13 +1384,13 @@ void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vec void DrawBoundingBox(BoundingBox box, Color color) { Vector3 size; - + size.x = fabsf(box.max.x - box.min.x); size.y = fabsf(box.max.y - box.min.y); size.z = fabsf(box.max.z - box.min.z); - + Vector3 center = { box.min.x + size.x/2.0f, box.min.y + size.y/2.0f, box.min.z + size.z/2.0f }; - + DrawCubeWires(center, size.x, size.y, size.z, color); } @@ -1451,14 +1451,14 @@ bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radius bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius) { bool collision = false; - + Vector3 raySpherePos = VectorSubtract(spherePosition, ray.position); float distance = VectorLength(raySpherePos); float vector = VectorDotProduct(raySpherePos, ray.direction); float d = sphereRadius*sphereRadius - (distance*distance - vector*vector); - + if (d >= 0.0f) collision = true; - + return collision; } @@ -1466,29 +1466,29 @@ bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, Vector3 *collisionPoint) { bool collision = false; - + Vector3 raySpherePos = VectorSubtract(spherePosition, ray.position); float distance = VectorLength(raySpherePos); float vector = VectorDotProduct(raySpherePos, ray.direction); float d = sphereRadius*sphereRadius - (distance*distance - vector*vector); - + if (d >= 0.0f) collision = true; - + // Calculate collision point Vector3 offset = ray.direction; float collisionDistance = 0; - + // Check if ray origin is inside the sphere to calculate the correct collision point if (distance < sphereRadius) collisionDistance = vector + sqrt(d); else collisionDistance = vector - sqrt(d); - + VectorScale(&offset, collisionDistance); Vector3 cPoint = VectorAdd(ray.position, offset); - + collisionPoint->x = cPoint.x; collisionPoint->y = cPoint.y; collisionPoint->z = cPoint.z; - + return collision; } @@ -1496,7 +1496,7 @@ bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadi bool CheckCollisionRayBox(Ray ray, BoundingBox box) { bool collision = false; - + float t[8]; t[0] = (box.min.x - ray.position.x)/ray.direction.x; t[1] = (box.max.x - ray.position.x)/ray.direction.x; @@ -1506,9 +1506,9 @@ bool CheckCollisionRayBox(Ray ray, BoundingBox box) t[5] = (box.max.z - ray.position.z)/ray.direction.z; t[6] = fmax(fmax(fmin(t[0], t[1]), fmin(t[2], t[3])), fmin(t[4], t[5])); t[7] = fmin(fmin(fmax(t[0], t[1]), fmax(t[2], t[3])), fmax(t[4], t[5])); - + collision = !(t[7] < 0 || t[6] > t[7]); - + return collision; } @@ -1524,19 +1524,19 @@ BoundingBox CalculateBoundingBox(Mesh mesh) { minVertex = (Vector3){ mesh.vertices[0], mesh.vertices[1], mesh.vertices[2] }; maxVertex = (Vector3){ mesh.vertices[0], mesh.vertices[1], mesh.vertices[2] }; - + for (int i = 1; i < mesh.vertexCount; i++) { minVertex = VectorMin(minVertex, (Vector3){ mesh.vertices[i*3], mesh.vertices[i*3 + 1], mesh.vertices[i*3 + 2] }); maxVertex = VectorMax(maxVertex, (Vector3){ mesh.vertices[i*3], mesh.vertices[i*3 + 1], mesh.vertices[i*3 + 2] }); } } - + // Create the bounding box BoundingBox box; box.min = minVertex; box.max = maxVertex; - + return box; } @@ -1546,9 +1546,9 @@ BoundingBox CalculateBoundingBox(Mesh mesh) Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *playerPosition, float radius) { #define CUBIC_MAP_HALF_BLOCK_SIZE 0.5 - + Color *cubicmapPixels = GetImageData(cubicmap); - + // Detect the cell where the player is located Vector3 impactDirection = { 0.0f, 0.0f, 0.0f }; @@ -1784,7 +1784,7 @@ Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *p playerPosition->y = (1.5f - radius) - 0.01f; impactDirection = (Vector3) { impactDirection.x, 1, impactDirection.z}; } - + free(cubicmapPixels); return impactDirection; @@ -2049,9 +2049,9 @@ static Mesh LoadOBJ(const char *fileName) static Material LoadMTL(const char *fileName) { #define MAX_BUFFER_SIZE 128 - + Material material = { 0 }; // LoadDefaultMaterial(); - + char buffer[MAX_BUFFER_SIZE]; Vector3 color = { 1.0f, 1.0f, 1.0f }; char *mapFileName = NULL; @@ -2069,14 +2069,14 @@ static Material LoadMTL(const char *fileName) while (!feof(mtlFile)) { fgets(buffer, MAX_BUFFER_SIZE, mtlFile); - + switch (buffer[0]) { case 'n': // newmtl string Material name. Begins a new material description. { // TODO: Support multiple materials in a single .mtl sscanf(buffer, "newmtl %s", mapFileName); - + TraceLog(INFO, "[%s] Loading material...", mapFileName); } case 'i': // illum int Illumination model @@ -2123,7 +2123,7 @@ static Material LoadMTL(const char *fileName) { int shininess = 0; sscanf(buffer, "Ns %i", &shininess); - + material.glossiness = (float)shininess; } else if (buffer[1] == 'i') // Ni int Refraction index. @@ -2192,7 +2192,7 @@ static Material LoadMTL(const char *fileName) float ialpha = 0.0f; sscanf(buffer, "Tr %f", &ialpha); material.colDiffuse.a = (unsigned char)((1.0f - ialpha)*255); - + } break; case 'r': // refl string Reflection texture map default: break; @@ -2203,6 +2203,6 @@ static Material LoadMTL(const char *fileName) // NOTE: At this point we have all material data TraceLog(INFO, "[%s] Material loaded successfully", fileName); - + return material; } diff --git a/src/raylib.h b/src/raylib.h index 22494aec..7b7348c8 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -930,8 +930,8 @@ RLAPI void SetMusicPitch(Music music, float pitch); // Set pit RLAPI float GetMusicTimeLength(Music music); // Get music time length (in seconds) RLAPI float GetMusicTimePlayed(Music music); // Get current music time played (in seconds) -RLAPI AudioStream InitAudioStream(unsigned int sampleRate, - unsigned int sampleSize, +RLAPI AudioStream InitAudioStream(unsigned int sampleRate, + unsigned int sampleSize, unsigned int channels); // Init audio stream (to stream audio pcm data) RLAPI void UpdateAudioStream(AudioStream stream, void *data, int numSamples); // Update audio stream buffers with data RLAPI void CloseAudioStream(AudioStream stream); // Close audio stream and free memory diff --git a/src/rlgl.h b/src/rlgl.h index bcb7c24f..3fc54219 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -107,7 +107,7 @@ typedef enum { OPENGL_11 = 1, OPENGL_21, OPENGL_33, OPENGL_ES_20 } GlVersion; // byte type typedef unsigned char byte; - + // Color type, RGBA (32bit) typedef struct Color { unsigned char r; @@ -117,7 +117,7 @@ typedef enum { OPENGL_11 = 1, OPENGL_21, OPENGL_33, OPENGL_ES_20 } GlVersion; } Color; // Texture formats (support depends on OpenGL version) - typedef enum { + typedef enum { UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha) UNCOMPRESSED_GRAY_ALPHA, UNCOMPRESSED_R5G6B5, // 16 bpp @@ -157,7 +157,7 @@ typedef enum { OPENGL_11 = 1, OPENGL_21, OPENGL_33, OPENGL_ES_20 } GlVersion; // Shader type (generic shader) typedef struct Shader { unsigned int id; // Shader program id - + // Vertex attributes locations (default locations) int vertexLoc; // Vertex attribute location point (default-location = 0) int texcoordLoc; // Texcoord attribute location point (default-location = 1) @@ -169,7 +169,7 @@ typedef enum { OPENGL_11 = 1, OPENGL_21, OPENGL_33, OPENGL_ES_20 } GlVersion; // Uniform locations int mvpLoc; // ModelView-Projection matrix uniform location point (vertex shader) int tintColorLoc; // Color uniform location point (fragment shader) - + // Texture map locations (generic for any kind of map) int mapTexture0Loc; // Map texture uniform location point (default-texture-unit = 0) int mapTexture1Loc; // Map texture uniform location point (default-texture-unit = 1) @@ -185,14 +185,14 @@ typedef enum { OPENGL_11 = 1, OPENGL_21, OPENGL_33, OPENGL_ES_20 } GlVersion; int mipmaps; // Mipmap levels, 1 by default int format; // Data format (TextureFormat) } Texture2D; - + // RenderTexture2D type, for texture rendering typedef struct RenderTexture2D { unsigned int id; // Render texture (fbo) id Texture2D texture; // Color buffer attachment texture Texture2D depth; // Depth buffer attachment texture } RenderTexture2D; - + // Material type typedef struct Material { Shader shader; // Standard shader (supports 3 map types: diffuse, normal, specular) @@ -204,10 +204,10 @@ typedef enum { OPENGL_11 = 1, OPENGL_21, OPENGL_33, OPENGL_ES_20 } GlVersion; Color colDiffuse; // Diffuse color Color colAmbient; // Ambient color Color colSpecular; // Specular color - + float glossiness; // Glossiness level (Ranges from 0 to 1000) } Material; - + // Camera type, defines a camera position/orientation in 3d space typedef struct Camera { Vector3 position; // Camera position @@ -225,22 +225,22 @@ typedef enum { OPENGL_11 = 1, OPENGL_21, OPENGL_33, OPENGL_ES_20 } GlVersion; Vector3 position; // Light position Vector3 target; // Light target: LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction target) float radius; // Light attenuation radius light intensity reduced with distance (world distance) - + Color diffuse; // Light diffuse color float intensity; // Light intensity level - + float coneAngle; // Light cone max angle: LIGHT_SPOT } LightData, *Light; - + // Light types typedef enum { LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT } LightType; // Color blending modes (pre-defined) typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode; - + // TraceLog message types typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType; - + // VR Head Mounted Display devices typedef enum { HMD_DEFAULT_DEVICE = 0, diff --git a/src/rlua.h b/src/rlua.h index b100b06d..1c8c7b38 100644 --- a/src/rlua.h +++ b/src/rlua.h @@ -6,7 +6,7 @@ * The following types: * Color, Vector2, Vector3, Rectangle, Ray, Camera, Camera2D * are treated as objects with named fields, same as in C. -* +* * Lua defines utility functions for creating those objects. * Usage: * local cl = Color(255,255,255,255) @@ -27,7 +27,7 @@ * NOTE 02: * Some raylib functions take a pointer to an array, and the size of that array. * The equivalent Lua functions take only an array table of the specified type UNLESS -* it's a pointer to a large char array (e.g. for images), then it takes (and potentially returns) +* it's a pointer to a large char array (e.g. for images), then it takes (and potentially returns) * a Lua string (without the size argument, as Lua strings are sized by default). * * NOTE 03: @@ -362,7 +362,7 @@ static void LuaBuildOpaqueMetatables(void) lua_pushcfunction(L, &LuaIndexTexture2D); lua_setfield(L, -2, "__index"); lua_pop(L, 1); - + luaL_newmetatable(L, "RenderTexture2D"); lua_pushcfunction(L, &LuaIndexRenderTexture2D); lua_setfield(L, -2, "__index"); @@ -3112,7 +3112,7 @@ int lua_TraceLog(lua_State* L) lua_getfield(L, 1, "format"); /// fmt, args..., [string], format() lua_rotate(L, 1, 2); /// [string], format(), fmt, args... lua_call(L, num_args, 1); /// [string], formatted_string - + TraceLog(arg1, "%s", luaL_checkstring(L,-1)); return 0; } @@ -3525,7 +3525,7 @@ int lua_QuaternionTransform(lua_State* L) // raylib Functions (and data types) list static luaL_Reg raylib_functions[] = { - + // Register non-opaque data types REG(Color) REG(Vector2) @@ -3547,7 +3547,7 @@ static luaL_Reg raylib_functions[] = { REG(ToggleFullscreen) REG(GetScreenWidth) REG(GetScreenHeight) - + REG(ShowCursor) REG(HideCursor) REG(IsCursorHidden) @@ -3563,11 +3563,11 @@ static luaL_Reg raylib_functions[] = { REG(End3dMode) REG(BeginTextureMode) REG(EndTextureMode) - + REG(GetMouseRay) REG(GetWorldToScreen) REG(GetCameraMatrix) - + #if defined(PLATFORM_WEB) REG(SetDrawingLoop) #else @@ -3575,7 +3575,7 @@ static luaL_Reg raylib_functions[] = { #endif REG(GetFPS) REG(GetFrameTime) - + REG(GetColor) REG(GetHexValue) REG(ColorToFloat) @@ -3585,13 +3585,13 @@ static luaL_Reg raylib_functions[] = { REG(Fade) REG(SetConfigFlags) REG(ShowLogo) - + REG(IsFileDropped) REG(GetDroppedFiles) REG(ClearDroppedFiles) REG(StorageSaveValue) REG(StorageLoadValue) - + #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB) REG(IsKeyPressed) REG(IsKeyDown) @@ -3599,7 +3599,7 @@ static luaL_Reg raylib_functions[] = { REG(IsKeyUp) REG(GetKeyPressed) REG(SetExitKey) - + REG(IsGamepadAvailable) REG(GetGamepadAxisMovement) REG(IsGamepadButtonPressed) @@ -3643,13 +3643,13 @@ static luaL_Reg raylib_functions[] = { REG(SetCameraPosition) REG(SetCameraTarget) REG(SetCameraFovy) - + REG(SetCameraPanControl) REG(SetCameraAltControl) REG(SetCameraSmoothZoomControl) REG(SetCameraMoveControls) REG(SetCameraMouseSensitivity) - + REG(DrawPixel) REG(DrawPixelV) REG(DrawLine) @@ -3668,7 +3668,7 @@ static luaL_Reg raylib_functions[] = { REG(DrawPoly) REG(DrawPolyEx) REG(DrawPolyExLines) - + REG(CheckCollisionRecs) REG(CheckCollisionCircles) REG(CheckCollisionCircleRec) @@ -3676,7 +3676,7 @@ static luaL_Reg raylib_functions[] = { REG(CheckCollisionPointRec) REG(CheckCollisionPointCircle) REG(CheckCollisionPointTriangle) - + REG(LoadImage) REG(LoadImageEx) REG(LoadImageRaw) @@ -3712,13 +3712,13 @@ static luaL_Reg raylib_functions[] = { REG(ImageColorBrightness) REG(GenTextureMipmaps) REG(UpdateTexture) - + REG(DrawTexture) REG(DrawTextureV) REG(DrawTextureEx) REG(DrawTextureRec) REG(DrawTexturePro) - + REG(GetDefaultFont) REG(LoadSpriteFont) REG(UnloadSpriteFont) @@ -3727,7 +3727,7 @@ static luaL_Reg raylib_functions[] = { REG(MeasureText) REG(MeasureTextEx) REG(DrawFPS) - + REG(DrawLine3D) REG(DrawCircle3D) REG(DrawCube) @@ -3744,7 +3744,7 @@ static luaL_Reg raylib_functions[] = { REG(DrawGrid) REG(DrawGizmo) REG(DrawLight) - + REG(LoadModel) REG(LoadModelEx) REG(LoadModelFromRES) @@ -3756,7 +3756,7 @@ static luaL_Reg raylib_functions[] = { REG(LoadStandardMaterial) REG(UnloadMaterial) //REG(GenMesh*) // Not ready yet... - + REG(DrawModel) REG(DrawModelEx) REG(DrawModelWires) @@ -3771,7 +3771,7 @@ static luaL_Reg raylib_functions[] = { REG(CheckCollisionRaySphereEx) REG(CheckCollisionRayBox) REG(ResolveCollisionCubicmap) - + REG(LoadShader) REG(UnloadShader) REG(GetDefaultShader) @@ -3789,13 +3789,13 @@ static luaL_Reg raylib_functions[] = { REG(EndBlendMode) REG(CreateLight) REG(DestroyLight) - + REG(InitVrDevice) REG(CloseVrDevice) REG(IsVrDeviceReady) REG(UpdateVrTracking) REG(ToggleVrMode) - + REG(InitAudioDevice) REG(CloseAudioDevice) REG(IsAudioDeviceReady) @@ -3810,7 +3810,7 @@ static luaL_Reg raylib_functions[] = { REG(IsSoundPlaying) REG(SetSoundVolume) REG(SetSoundPitch) - + REG(LoadMusicStream) REG(UnloadMusicStream) REG(UpdateMusicStream) @@ -3823,7 +3823,7 @@ static luaL_Reg raylib_functions[] = { REG(SetMusicPitch) REG(GetMusicTimeLength) REG(GetMusicTimePlayed) - + REG(InitAudioStream) REG(UpdateAudioStream) REG(CloseAudioStream) @@ -3906,7 +3906,7 @@ RLUADEF void InitLuaDevice(void) { mainLuaState = luaL_newstate(); L = mainLuaState; - + LuaStartEnum(); LuaSetEnum("FULLSCREEN_MODE", 1); LuaSetEnum("SHOW_LOGO", 2); @@ -4001,7 +4001,7 @@ RLUADEF void InitLuaDevice(void) LuaSetEnum("PS3_BUTTON_L2", 8); LuaSetEnum("PS3_BUTTON_SELECT", 9); LuaSetEnum("PS3_BUTTON_START", 10); - + LuaSetEnum("XBOX_BUTTON_A", 0); LuaSetEnum("XBOX_BUTTON_B", 1); LuaSetEnum("XBOX_BUTTON_X", 2); @@ -4086,9 +4086,9 @@ RLUADEF void InitLuaDevice(void) LuaSetEnum("ADDITIVE", BLEND_ADDITIVE); LuaSetEnum("MULTIPLIED", BLEND_MULTIPLIED); LuaEndEnum("BlendMode"); - + LuaStartEnum(); - LuaSetEnum("POINT", LIGHT_POINT); + LuaSetEnum("POINT", LIGHT_POINT); LuaSetEnum("DIRECTIONAL", LIGHT_DIRECTIONAL); LuaSetEnum("SPOT", LIGHT_SPOT); LuaEndEnum("LightType"); @@ -4114,7 +4114,7 @@ RLUADEF void InitLuaDevice(void) LuaSetEnum("FIRST_PERSON", CAMERA_FIRST_PERSON); LuaSetEnum("THIRD_PERSON", CAMERA_THIRD_PERSON); LuaEndEnum("CameraMode"); - + LuaStartEnum(); LuaSetEnum("DEFAULT_DEVICE", HMD_DEFAULT_DEVICE); LuaSetEnum("OCULUS_RIFT_DK2", HMD_OCULUS_RIFT_DK2); @@ -4138,9 +4138,9 @@ RLUADEF void InitLuaDevice(void) lua_pushboolean(L, true); #if defined(PLATFORM_DESKTOP) lua_setglobal(L, "PLATFORM_DESKTOP"); -#elif defined(PLATFORM_ANDROID) +#elif defined(PLATFORM_ANDROID) lua_setglobal(L, "PLATFORM_ANDROID"); -#elif defined(PLATFORM_RPI) +#elif defined(PLATFORM_RPI) lua_setglobal(L, "PLATFORM_RPI"); #elif defined(PLATFORM_WEB) lua_setglobal(L, "PLATFORM_WEB"); @@ -4148,7 +4148,7 @@ RLUADEF void InitLuaDevice(void) luaL_openlibs(L); LuaBuildOpaqueMetatables(); - + LuaRegisterRayLib(0); } @@ -4173,7 +4173,7 @@ RLUADEF void ExecuteLuaCode(const char *code) } int result = luaL_dostring(L, code); - + switch (result) { case LUA_OK: break; @@ -4193,7 +4193,7 @@ RLUADEF void ExecuteLuaFile(const char *filename) } int result = luaL_dofile(L, filename); - + switch (result) { case LUA_OK: break; diff --git a/src/text.c b/src/text.c index 2f347b5d..8dc55455 100644 --- a/src/text.c +++ b/src/text.c @@ -151,7 +151,7 @@ extern void LoadDefaultFont(void) //---------------------------------------------------------------------- int imWidth = 128; int imHeight = 128; - + Color *imagePixels = (Color *)malloc(imWidth*imHeight*sizeof(Color)); for (int i = 0; i < imWidth*imHeight; i++) imagePixels[i] = BLANK; // Initialize array @@ -174,7 +174,7 @@ extern void LoadDefaultFont(void) //FILE *myimage = fopen("default_font.raw", "wb"); //fwrite(image.pixels, 1, 128*128*4, myimage); //fclose(myimage); - + Image image = LoadImageEx(imagePixels, imWidth, imHeight); ImageFormat(&image, UNCOMPRESSED_GRAY_ALPHA); @@ -185,13 +185,13 @@ extern void LoadDefaultFont(void) // Reconstruct charSet using charsWidth[], charsHeight, charsDivisor, numChars //------------------------------------------------------------------------------ - defaultFont.charValues = (int *)malloc(defaultFont.numChars*sizeof(int)); + defaultFont.charValues = (int *)malloc(defaultFont.numChars*sizeof(int)); defaultFont.charRecs = (Rectangle *)malloc(defaultFont.numChars*sizeof(Rectangle)); // Allocate space for our character rectangle data // This memory should be freed at end! --> Done on CloseWindow() - + defaultFont.charOffsets = (Vector2 *)malloc(defaultFont.numChars*sizeof(Vector2)); defaultFont.charAdvanceX = (int *)malloc(defaultFont.numChars*sizeof(int)); - + int currentLine = 0; int currentPosX = charsDivisor; int testPosX = charsDivisor; @@ -199,7 +199,7 @@ extern void LoadDefaultFont(void) for (int i = 0; i < defaultFont.numChars; i++) { defaultFont.charValues[i] = FONT_FIRST_CHAR + i; // First char is 32 - + defaultFont.charRecs[i].x = currentPosX; defaultFont.charRecs[i].y = charsDivisor + currentLine * (charsHeight + charsDivisor); defaultFont.charRecs[i].width = charsWidth[i]; @@ -217,12 +217,12 @@ extern void LoadDefaultFont(void) defaultFont.charRecs[i].y = charsDivisor + currentLine*(charsHeight + charsDivisor); } else currentPosX = testPosX; - + // NOTE: On default font character offsets and xAdvance are not required defaultFont.charOffsets[i] = (Vector2){ 0.0f, 0.0f }; defaultFont.charAdvanceX[i] = 0; } - + defaultFont.size = defaultFont.charRecs[0].height; TraceLog(INFO, "[TEX ID %i] Default font loaded successfully", defaultFont.texture.id); @@ -262,7 +262,7 @@ SpriteFont LoadSpriteFont(const char *fileName) if (image.data != NULL) spriteFont = LoadImageFont(image, MAGENTA, FONT_FIRST_CHAR); UnloadImage(image); } - + if (spriteFont.texture.id == 0) { TraceLog(WARNING, "[%s] SpriteFont could not be loaded, using default font", fileName); @@ -316,15 +316,15 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float scaleFactor = fontSize/spriteFont.size; - // NOTE: Some ugly hacks are made to support Latin-1 Extended characters directly + // NOTE: Some ugly hacks are made to support Latin-1 Extended characters directly // written in C code files (codified by default as UTF-8) - + for(int i = 0; i < length; i++) { // TODO: Right now we are supposing characters that follow a continous order and start at FONT_FIRST_CHAR, // this sytem can be improved to support any characters order and init value... // An intermediate table could be created to link char values with predefined char position index in chars rectangle array - + if ((unsigned char)text[i] == 0xc2) // UTF-8 encoding identification HACK! { // Support UTF-8 encoded values from [0xc2 0x80] -> [0xc2 0xbf](¿) @@ -353,8 +353,8 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float if (rec.x > 0) { - DrawTexturePro(spriteFont.texture, rec, (Rectangle){ position.x + textOffsetX + spriteFont.charOffsets[(int)text[i] - FONT_FIRST_CHAR].x*scaleFactor, - position.y + textOffsetY + spriteFont.charOffsets[(int)text[i] - FONT_FIRST_CHAR].y*scaleFactor, + DrawTexturePro(spriteFont.texture, rec, (Rectangle){ position.x + textOffsetX + spriteFont.charOffsets[(int)text[i] - FONT_FIRST_CHAR].x*scaleFactor, + position.y + textOffsetY + spriteFont.charOffsets[(int)text[i] - FONT_FIRST_CHAR].y*scaleFactor, rec.width*scaleFactor, rec.height*scaleFactor} , (Vector2){ 0, 0 }, 0.0f, tint); if (spriteFont.charAdvanceX[(int)text[i] - FONT_FIRST_CHAR] == 0) textOffsetX += (rec.width*scaleFactor + spacing); @@ -381,15 +381,15 @@ const char *SubText(const char *text, int position, int length) { static char buffer[MAX_SUBTEXT_LENGTH]; int textLength = strlen(text); - + if (position >= textLength) { position = textLength - 1; length = 0; } - + if (length >= textLength) length = textLength; - + for (int c = 0 ; c < length ; c++) { *(buffer+c) = *(text+position); @@ -421,17 +421,17 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int int len = strlen(text); int tempLen = 0; // Used to count longer text line num chars int lenCounter = 0; - + int textWidth = 0; int tempTextWidth = 0; // Used to count longer text line width - + int textHeight = spriteFont.size; float scaleFactor; for (int i = 0; i < len; i++) { lenCounter++; - + if (text[i] != '\n') { if (spriteFont.charAdvanceX[(int)text[i] - FONT_FIRST_CHAR] != 0) textWidth += spriteFont.charAdvanceX[(int)text[i] - FONT_FIRST_CHAR]; @@ -444,10 +444,10 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int textWidth = 0; textHeight += (spriteFont.size + spriteFont.size/2); // NOTE: Fixed line spacing of 1.5 lines } - + if (tempLen < lenCounter) tempLen = lenCounter; } - + if (tempTextWidth < textWidth) tempTextWidth = textWidth; if (fontSize <= spriteFont.size) scaleFactor = 1.0f; @@ -496,21 +496,21 @@ void DrawFPS(int posX, int posY) static SpriteFont LoadImageFont(Image image, Color key, int firstChar) { #define COLOR_EQUAL(col1, col2) ((col1.r == col2.r)&&(col1.g == col2.g)&&(col1.b == col2.b)&&(col1.a == col2.a)) - + int charSpacing = 0; int lineSpacing = 0; int x = 0; int y = 0; - + // Default number of characters expected supported #define MAX_FONTCHARS 128 - // We allocate a temporal arrays for chars data measures, + // We allocate a temporal arrays for chars data measures, // once we get the actual number of chars, we copy data to a sized arrays int tempCharValues[MAX_FONTCHARS]; Rectangle tempCharRecs[MAX_FONTCHARS]; - + Color *pixels = GetImageData(image); // Parse image data to get charSpacing and lineSpacing @@ -545,7 +545,7 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar) !COLOR_EQUAL((pixels[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*image.width + xPosToRead]), key)) { tempCharValues[index] = firstChar + index; - + tempCharRecs[index].x = xPosToRead; tempCharRecs[index].y = lineSpacing + lineToRead * (charHeight + lineSpacing); tempCharRecs[index].height = charHeight; @@ -564,14 +564,14 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar) lineToRead++; xPosToRead = charSpacing; } - + free(pixels); - + TraceLog(DEBUG, "SpriteFont data parsed correctly from image"); - + // Create spritefont with all data parsed from image SpriteFont spriteFont = { 0 }; - + spriteFont.texture = LoadTextureFromImage(image); // Convert loaded image to OpenGL texture spriteFont.numChars = index; @@ -586,12 +586,12 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar) { spriteFont.charValues[i] = tempCharValues[i]; spriteFont.charRecs[i] = tempCharRecs[i]; - + // NOTE: On image based fonts (XNA style), character offsets and xAdvance are not required (set to 0) spriteFont.charOffsets[i] = (Vector2){ 0.0f, 0.0f }; spriteFont.charAdvanceX[i] = 0; } - + spriteFont.size = spriteFont.charRecs[0].height; return spriteFont; @@ -631,7 +631,7 @@ static SpriteFont LoadRBMF(const char *fileName) if (rbmfFile == NULL) { TraceLog(WARNING, "[%s] rBMF font file could not be opened, using default font", fileName); - + spriteFont = GetDefaultFont(); } else @@ -670,10 +670,10 @@ static SpriteFont LoadRBMF(const char *fileName) counter++; } - + Image image = LoadImageEx(imagePixels, rbmfHeader.imgWidth, rbmfHeader.imgHeight); ImageFormat(&image, UNCOMPRESSED_GRAY_ALPHA); - + free(imagePixels); TraceLog(DEBUG, "[%s] Image reconstructed correctly, now converting it to texture", fileName); @@ -685,7 +685,7 @@ static SpriteFont LoadRBMF(const char *fileName) //TraceLog(INFO, "[%s] Starting chars set reconstruction", fileName); // Get characters data using rbmfCharWidthData, rbmfHeader.charHeight, charsDivisor, rbmfHeader.numChars - spriteFont.charValues = (int *)malloc(spriteFont.numChars*sizeof(int)); + spriteFont.charValues = (int *)malloc(spriteFont.numChars*sizeof(int)); spriteFont.charRecs = (Rectangle *)malloc(spriteFont.numChars*sizeof(Rectangle)); spriteFont.charOffsets = (Vector2 *)malloc(spriteFont.numChars*sizeof(Vector2)); spriteFont.charAdvanceX = (int *)malloc(spriteFont.numChars*sizeof(int)); @@ -697,12 +697,12 @@ static SpriteFont LoadRBMF(const char *fileName) for (int i = 0; i < spriteFont.numChars; i++) { spriteFont.charValues[i] = (int)rbmfHeader.firstChar + i; - + spriteFont.charRecs[i].x = currentPosX; spriteFont.charRecs[i].y = charsDivisor + currentLine * ((int)rbmfHeader.charHeight + charsDivisor); spriteFont.charRecs[i].width = (int)rbmfCharWidthData[i]; spriteFont.charRecs[i].height = (int)rbmfHeader.charHeight; - + // NOTE: On image based fonts (XNA style), character offsets and xAdvance are not required (set to 0) spriteFont.charOffsets[i] = (Vector2){ 0.0f, 0.0f }; spriteFont.charAdvanceX[i] = 0; @@ -720,7 +720,7 @@ static SpriteFont LoadRBMF(const char *fileName) } else currentPosX = testPosX; } - + spriteFont.size = spriteFont.charRecs[0].height; TraceLog(INFO, "[%s] rBMF file loaded correctly as SpriteFont", fileName); @@ -738,20 +738,20 @@ static SpriteFont LoadRBMF(const char *fileName) static SpriteFont LoadBMFont(const char *fileName) { #define MAX_BUFFER_SIZE 256 - + SpriteFont font = { 0 }; font.texture.id = 0; - + char buffer[MAX_BUFFER_SIZE]; char *searchPoint = NULL; - + int fontSize = 0; int texWidth, texHeight; char texFileName[128]; int numChars = 0; int base; // Useless data - + FILE *fntFile; fntFile = fopen(fileName, "rt"); @@ -766,42 +766,42 @@ static SpriteFont LoadBMFont(const char *fileName) fgets(buffer, MAX_BUFFER_SIZE, fntFile); //searchPoint = strstr(buffer, "size"); //sscanf(searchPoint, "size=%i", &fontSize); - + fgets(buffer, MAX_BUFFER_SIZE, fntFile); searchPoint = strstr(buffer, "lineHeight"); sscanf(searchPoint, "lineHeight=%i base=%i scaleW=%i scaleH=%i", &fontSize, &base, &texWidth, &texHeight); - + TraceLog(DEBUG, "[%s] Font size: %i", fileName, fontSize); TraceLog(DEBUG, "[%s] Font texture scale: %ix%i", fileName, texWidth, texHeight); - + fgets(buffer, MAX_BUFFER_SIZE, fntFile); searchPoint = strstr(buffer, "file"); sscanf(searchPoint, "file=\"%128[^\"]\"", texFileName); - + TraceLog(DEBUG, "[%s] Font texture filename: %s", fileName, texFileName); - + fgets(buffer, MAX_BUFFER_SIZE, fntFile); searchPoint = strstr(buffer, "count"); sscanf(searchPoint, "count=%i", &numChars); - + TraceLog(DEBUG, "[%s] Font num chars: %i", fileName, numChars); - + // Compose correct path using route of .fnt file (fileName) and texFileName char *texPath = NULL; char *lastSlash = NULL; lastSlash = strrchr(fileName, '/'); - + // NOTE: We need some extra space to avoid memory corruption on next allocations! texPath = malloc(strlen(fileName) - strlen(lastSlash) + strlen(texFileName) + 4); - + // NOTE: strcat() and strncat() required a '\0' terminated string to work! *texPath = '\0'; strncat(texPath, fileName, strlen(fileName) - strlen(lastSlash) + 1); strncat(texPath, texFileName, strlen(texFileName)); TraceLog(DEBUG, "[%s] Font texture loading path: %s", fileName, texPath); - + font.texture = LoadTexture(texPath); font.size = fontSize; font.numChars = numChars; @@ -809,35 +809,35 @@ static SpriteFont LoadBMFont(const char *fileName) font.charRecs = (Rectangle *)malloc(numChars*sizeof(Rectangle)); font.charOffsets = (Vector2 *)malloc(numChars*sizeof(Vector2)); font.charAdvanceX = (int *)malloc(numChars*sizeof(int)); - + free(texPath); - + int charId, charX, charY, charWidth, charHeight, charOffsetX, charOffsetY, charAdvanceX; - + bool unorderedChars = false; int firstChar = 0; - + for (int i = 0; i < numChars; i++) { fgets(buffer, MAX_BUFFER_SIZE, fntFile); - sscanf(buffer, "char id=%i x=%i y=%i width=%i height=%i xoffset=%i yoffset=%i xadvance=%i", + sscanf(buffer, "char id=%i x=%i y=%i width=%i height=%i xoffset=%i yoffset=%i xadvance=%i", &charId, &charX, &charY, &charWidth, &charHeight, &charOffsetX, &charOffsetY, &charAdvanceX); - + if (i == 0) firstChar = charId; else if (i != (charId - firstChar)) unorderedChars = true; - + // Save data properly in sprite font font.charValues[i] = charId; font.charRecs[i] = (Rectangle){ charX, charY, charWidth, charHeight }; font.charOffsets[i] = (Vector2){ (float)charOffsetX, (float)charOffsetY }; font.charAdvanceX[i] = charAdvanceX; } - + fclose(fntFile); - + if (firstChar != FONT_FIRST_CHAR) TraceLog(WARNING, "BMFont not supported: expected SPACE(32) as first character, falling back to default font"); else if (unorderedChars) TraceLog(WARNING, "BMFont not supported: unordered chars data, falling back to default font"); - + // NOTE: Font data could be not ordered by charId: 32,33,34,35... raylib does not support unordered BMFonts if ((firstChar != FONT_FIRST_CHAR) || (unorderedChars) || (font.texture.id == 0)) { @@ -862,9 +862,9 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int firstChar, int stbtt_bakedchar *charData = (stbtt_bakedchar *)malloc(sizeof(stbtt_bakedchar)*numChars); SpriteFont font = { 0 }; - + FILE *ttfFile = fopen(fileName, "rb"); - + if (ttfFile == NULL) { TraceLog(WARNING, "[%s] FNT file could not be opened", fileName); @@ -877,11 +877,11 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int firstChar, int stbtt_BakeFontBitmap(ttfBuffer,0, fontSize, dataBitmap, FONT_TEXTURE_WIDTH, FONT_TEXTURE_HEIGHT, firstChar, numChars, charData); free(ttfBuffer); - + // Convert image data from grayscale to to UNCOMPRESSED_GRAY_ALPHA unsigned char *dataGrayAlpha = (unsigned char *)malloc(FONT_TEXTURE_WIDTH*FONT_TEXTURE_HEIGHT*sizeof(unsigned char)*2); // Two channels int k = 0; - + for (int i = 0; i < FONT_TEXTURE_WIDTH*FONT_TEXTURE_HEIGHT; i++) { dataGrayAlpha[k] = 255; @@ -889,9 +889,9 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int firstChar, int k += 2; } - + free(dataBitmap); - + // Sprite font generation from TTF extracted data Image image; image.width = FONT_TEXTURE_WIDTH; @@ -909,7 +909,7 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int firstChar, int font.charRecs = (Rectangle *)malloc(font.numChars*sizeof(Rectangle)); font.charOffsets = (Vector2 *)malloc(font.numChars*sizeof(Vector2)); font.charAdvanceX = (int *)malloc(font.numChars*sizeof(int)); - + for (int i = 0; i < font.numChars; i++) { font.charValues[i] = i + firstChar; @@ -918,11 +918,11 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int firstChar, int font.charRecs[i].y = (int)charData[i].y0; font.charRecs[i].width = (int)charData[i].x1 - (int)charData[i].x0; font.charRecs[i].height = (int)charData[i].y1 - (int)charData[i].y0; - + font.charOffsets[i] = (Vector2){ charData[i].xoff, charData[i].yoff }; font.charAdvanceX[i] = (int)charData[i].xadvance; } - + free(charData); return font; diff --git a/src/textures.c b/src/textures.c index c6b7e0bb..8f4fa301 100644 --- a/src/textures.c +++ b/src/textures.c @@ -33,7 +33,7 @@ #include // Required for: strcmp(), strrchr(), strncmp() #include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3 or ES2 - // Required: rlglLoadTexture() rlDeleteTextures(), + // Required: rlglLoadTexture() rlDeleteTextures(), // rlglGenerateMipmaps(), some funcs for DrawTexturePro() #include "utils.h" // rRES data decompression utility function @@ -44,7 +44,7 @@ // NOTE: Used to read image data (multiple formats support) #define STB_IMAGE_RESIZE_IMPLEMENTATION -#include "external/stb_image_resize.h" // Required for: stbir_resize_uint8() +#include "external/stb_image_resize.h" // Required for: stbir_resize_uint8() // NOTE: Used for image scaling on ImageResize() //---------------------------------------------------------------------------------- @@ -103,14 +103,14 @@ Image LoadImage(const char *fileName) int imgWidth = 0; int imgHeight = 0; int imgBpp = 0; - + // NOTE: Using stb_image to load images (Supports: BMP, TGA, PNG, JPG, ...) image.data = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 0); image.width = imgWidth; image.height = imgHeight; image.mipmaps = 1; - + if (imgBpp == 1) image.format = UNCOMPRESSED_GRAYSCALE; else if (imgBpp == 2) image.format = UNCOMPRESSED_GRAY_ALPHA; else if (imgBpp == 3) image.format = UNCOMPRESSED_R8G8B8; @@ -121,12 +121,12 @@ Image LoadImage(const char *fileName) else if (strcmp(GetExtension(fileName),"ktx") == 0) image = LoadKTX(fileName); else if (strcmp(GetExtension(fileName),"pvr") == 0) image = LoadPVR(fileName); else if (strcmp(GetExtension(fileName),"astc") == 0) image = LoadASTC(fileName); - + if (image.data != NULL) - { + { TraceLog(INFO, "[%s] Image loaded successfully (%ix%i)", fileName, image.width, image.height); } - else TraceLog(WARNING, "[%s] Image could not be loaded, file not recognized", fileName); + else TraceLog(WARNING, "[%s] Image could not be loaded, file not recognized", fileName); return image; } @@ -141,11 +141,11 @@ Image LoadImageEx(Color *pixels, int width, int height) image.height = height; image.mipmaps = 1; image.format = UNCOMPRESSED_R8G8B8A8; - + int k = 0; image.data = (unsigned char *)malloc(image.width*image.height*4*sizeof(unsigned char)); - + for (int i = 0; i < image.width*image.height*4; i += 4) { ((unsigned char *)image.data)[i] = pixels[k].r; @@ -180,7 +180,7 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int if (headerSize > 0) fseek(rawFile, headerSize, SEEK_SET); unsigned int size = width*height; - + switch (format) { case UNCOMPRESSED_GRAYSCALE: image.data = (unsigned char *)malloc(size); break; // 8 bit per pixel (no alpha) @@ -192,16 +192,16 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int case UNCOMPRESSED_R8G8B8A8: image.data = (unsigned char *)malloc(size*4); size *= 4; break; // 32 bpp default: TraceLog(WARNING, "Image format not suported"); break; } - + fread(image.data, size, 1, rawFile); - + // TODO: Check if data have been read - + image.width = width; image.height = height; image.mipmaps = 0; image.format = format; - + fclose(rawFile); } @@ -326,9 +326,9 @@ Texture2D LoadTexture(const char *fileName) Texture2D texture; Image image = LoadImage(fileName); - + if (image.data != NULL) - { + { texture = LoadTextureFromImage(image); UnloadImage(image); } @@ -350,9 +350,9 @@ Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat) texture.height = height; texture.mipmaps = 1; texture.format = textureFormat; - + texture.id = rlglLoadTexture(data, width, height, textureFormat, 1); - + return texture; } @@ -380,7 +380,7 @@ Texture2D LoadTextureFromImage(Image image) texture.height = 0; texture.mipmaps = 0; texture.format = 0; - + texture.id = rlglLoadTexture(image.data, image.width, image.height, image.format, image.mipmaps); texture.width = image.width; @@ -395,7 +395,7 @@ Texture2D LoadTextureFromImage(Image image) RenderTexture2D LoadRenderTexture(int width, int height) { RenderTexture2D target = rlglLoadRenderTexture(width, height); - + return target; } @@ -403,7 +403,7 @@ RenderTexture2D LoadRenderTexture(int width, int height) void UnloadImage(Image image) { free(image.data); - + // NOTE: It becomes anoying every time a texture is loaded //TraceLog(INFO, "Unloaded image data"); } @@ -414,7 +414,7 @@ void UnloadTexture(Texture2D texture) if (texture.id != 0) { rlDeleteTextures(texture.id); - + TraceLog(INFO, "[TEX ID %i] Unloaded texture data from VRAM (GPU)", texture.id); } } @@ -429,7 +429,7 @@ void UnloadRenderTexture(RenderTexture2D target) Color *GetImageData(Image image) { Color *pixels = (Color *)malloc(image.width*image.height*sizeof(Color)); - + int k = 0; for (int i = 0; i < image.width*image.height; i++) @@ -442,7 +442,7 @@ Color *GetImageData(Image image) pixels[i].g = ((unsigned char *)image.data)[k]; pixels[i].b = ((unsigned char *)image.data)[k]; pixels[i].a = 255; - + k++; } break; case UNCOMPRESSED_GRAY_ALPHA: @@ -451,7 +451,7 @@ Color *GetImageData(Image image) pixels[i].g = ((unsigned char *)image.data)[k]; pixels[i].b = ((unsigned char *)image.data)[k]; pixels[i].a = ((unsigned char *)image.data)[k + 1]; - + k += 2; } break; case UNCOMPRESSED_R5G5B5A1: @@ -462,7 +462,7 @@ Color *GetImageData(Image image) pixels[i].g = (unsigned char)((float)((pixel & 0b0000011111000000) >> 6)*(255/31)); pixels[i].b = (unsigned char)((float)((pixel & 0b0000000000111110) >> 1)*(255/31)); pixels[i].a = (unsigned char)((pixel & 0b0000000000000001)*255); - + k++; } break; case UNCOMPRESSED_R5G6B5: @@ -473,18 +473,18 @@ Color *GetImageData(Image image) pixels[i].g = (unsigned char)((float)((pixel & 0b0000011111100000) >> 5)*(255/63)); pixels[i].b = (unsigned char)((float)(pixel & 0b0000000000011111)*(255/31)); pixels[i].a = 255; - + k++; } break; case UNCOMPRESSED_R4G4B4A4: { unsigned short pixel = ((unsigned short *)image.data)[k]; - + pixels[i].r = (unsigned char)((float)((pixel & 0b1111000000000000) >> 12)*(255/15)); pixels[i].g = (unsigned char)((float)((pixel & 0b0000111100000000) >> 8)*(255/15)); pixels[i].b = (unsigned char)((float)((pixel & 0b0000000011110000) >> 4)*(255/15)); pixels[i].a = (unsigned char)((float)(pixel & 0b0000000000001111)*(255/15)); - + k++; } break; case UNCOMPRESSED_R8G8B8A8: @@ -493,7 +493,7 @@ Color *GetImageData(Image image) pixels[i].g = ((unsigned char *)image.data)[k + 1]; pixels[i].b = ((unsigned char *)image.data)[k + 2]; pixels[i].a = ((unsigned char *)image.data)[k + 3]; - + k += 4; } break; case UNCOMPRESSED_R8G8B8: @@ -502,11 +502,11 @@ Color *GetImageData(Image image) pixels[i].g = (unsigned char)((unsigned char *)image.data)[k + 1]; pixels[i].b = (unsigned char)((unsigned char *)image.data)[k + 2]; pixels[i].a = 255; - + k += 3; } break; default: TraceLog(WARNING, "Format not supported for pixel data retrieval"); break; - } + } } return pixels; @@ -522,7 +522,7 @@ Image GetTextureData(Texture2D texture) if (texture.format < 8) { image.data = rlglReadTexturePixels(texture); - + if (image.data != NULL) { image.width = texture.width; @@ -551,29 +551,29 @@ void ImageFormat(Image *image, int newFormat) if ((image->format < 8) && (newFormat < 8)) { Color *pixels = GetImageData(*image); - + free(image->data); - + image->format = newFormat; int k = 0; - + switch (image->format) { case UNCOMPRESSED_GRAYSCALE: { image->data = (unsigned char *)malloc(image->width*image->height*sizeof(unsigned char)); - + for (int i = 0; i < image->width*image->height; i++) { ((unsigned char *)image->data)[i] = (unsigned char)((float)pixels[i].r*0.299f + (float)pixels[i].g*0.587f + (float)pixels[i].b*0.114f); } - + } break; case UNCOMPRESSED_GRAY_ALPHA: { image->data = (unsigned char *)malloc(image->width*image->height*2*sizeof(unsigned char)); - + for (int i = 0; i < image->width*image->height*2; i += 2) { ((unsigned char *)image->data)[i] = (unsigned char)((float)pixels[k].r*0.299f + (float)pixels[k].g*0.587f + (float)pixels[k].b*0.114f); @@ -585,17 +585,17 @@ void ImageFormat(Image *image, int newFormat) case UNCOMPRESSED_R5G6B5: { image->data = (unsigned short *)malloc(image->width*image->height*sizeof(unsigned short)); - + unsigned char r = 0; unsigned char g = 0; unsigned char b = 0; - + for (int i = 0; i < image->width*image->height; i++) { r = (unsigned char)(round((float)pixels[k].r*31/255)); g = (unsigned char)(round((float)pixels[k].g*63/255)); b = (unsigned char)(round((float)pixels[k].b*31/255)); - + ((unsigned short *)image->data)[i] = (unsigned short)r << 11 | (unsigned short)g << 5 | (unsigned short)b; } @@ -603,7 +603,7 @@ void ImageFormat(Image *image, int newFormat) case UNCOMPRESSED_R8G8B8: { image->data = (unsigned char *)malloc(image->width*image->height*3*sizeof(unsigned char)); - + for (int i = 0; i < image->width*image->height*3; i += 3) { ((unsigned char *)image->data)[i] = pixels[k].r; @@ -615,49 +615,49 @@ void ImageFormat(Image *image, int newFormat) case UNCOMPRESSED_R5G5B5A1: { #define ALPHA_THRESHOLD 50 - + image->data = (unsigned short *)malloc(image->width*image->height*sizeof(unsigned short)); - + unsigned char r = 0; unsigned char g = 0; unsigned char b = 0; unsigned char a = 0; - + for (int i = 0; i < image->width*image->height; i++) { r = (unsigned char)(round((float)pixels[i].r*31/255)); g = (unsigned char)(round((float)pixels[i].g*31/255)); b = (unsigned char)(round((float)pixels[i].b*31/255)); a = (pixels[i].a > ALPHA_THRESHOLD) ? 1 : 0; - + ((unsigned short *)image->data)[i] = (unsigned short)r << 11 | (unsigned short)g << 6 | (unsigned short)b << 1 | (unsigned short)a; } - + } break; case UNCOMPRESSED_R4G4B4A4: { image->data = (unsigned short *)malloc(image->width*image->height*sizeof(unsigned short)); - + unsigned char r = 0; unsigned char g = 0; unsigned char b = 0; unsigned char a = 0; - + for (int i = 0; i < image->width*image->height; i++) { r = (unsigned char)(round((float)pixels[i].r*15/255)); g = (unsigned char)(round((float)pixels[i].g*15/255)); b = (unsigned char)(round((float)pixels[i].b*15/255)); a = (unsigned char)(round((float)pixels[i].a*15/255)); - + ((unsigned short *)image->data)[i] = (unsigned short)r << 12 | (unsigned short)g << 8| (unsigned short)b << 4| (unsigned short)a; } - + } break; case UNCOMPRESSED_R8G8B8A8: { image->data = (unsigned char *)malloc(image->width*image->height*4*sizeof(unsigned char)); - + for (int i = 0; i < image->width*image->height*4; i += 4) { ((unsigned char *)image->data)[i] = pixels[k].r; @@ -669,7 +669,7 @@ void ImageFormat(Image *image, int newFormat) } break; default: break; } - + free(pixels); } else TraceLog(WARNING, "Image data format is compressed, can not be converted"); @@ -677,7 +677,7 @@ void ImageFormat(Image *image, int newFormat) } // Dither image data to 16bpp or lower (Floyd-Steinberg dithering) -// NOTE: In case selected bpp do not represent an known 16bit format, +// NOTE: In case selected bpp do not represent an known 16bit format, // dithered data is stored in the LSB part of the unsigned short void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp) { @@ -694,14 +694,14 @@ void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp) else { Color *pixels = GetImageData(*image); - + free(image->data); // free old image data - + if ((image->format != UNCOMPRESSED_R8G8B8) && (image->format != UNCOMPRESSED_R8G8B8A8)) { TraceLog(WARNING, "Image format is already 16bpp or lower, dithering could have no effect"); } - + // Define new image format, check if desired bpp match internal known format if ((rBpp == 5) && (gBpp == 6) && (bBpp == 5) && (aBpp == 0)) image->format = UNCOMPRESSED_R5G6B5; else if ((rBpp == 5) && (gBpp == 5) && (bBpp == 5) && (aBpp == 1)) image->format = UNCOMPRESSED_R5G5B5A1; @@ -714,13 +714,13 @@ void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp) // NOTE: We will store the dithered data as unsigned short (16bpp) image->data = (unsigned short *)malloc(image->width*image->height*sizeof(unsigned short)); - + Color oldpixel = WHITE; Color newpixel = WHITE; - + int error_r, error_g, error_b; unsigned short pixel_r, pixel_g, pixel_b, pixel_a; // Used for 16bit pixel composition - + #define MIN(a,b) (((a)<(b))?(a):(b)) for (int y = 0; y < image->height; y++) @@ -728,7 +728,7 @@ void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp) for (int x = 0; x < image->width; x++) { oldpixel = pixels[y*image->width + x]; - + // NOTE: New pixel obtained by bits truncate, it would be better to round values (check ImageFormat()) newpixel.r = oldpixel.r>>(8 - rBpp); // R bits newpixel.g = oldpixel.g>>(8 - gBpp); // G bits @@ -740,7 +740,7 @@ void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp) error_r = (int)oldpixel.r - (int)(newpixel.r<<(8 - rBpp)); error_g = (int)oldpixel.g - (int)(newpixel.g<<(8 - gBpp)); error_b = (int)oldpixel.b - (int)(newpixel.b<<(8 - bBpp)); - + pixels[y*image->width + x] = newpixel; // NOTE: Some cases are out of the array and should be ignored @@ -750,21 +750,21 @@ void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp) pixels[y*image->width + x+1].g = MIN((int)pixels[y*image->width + x+1].g + (int)((float)error_g*7.0f/16), 0xff); pixels[y*image->width + x+1].b = MIN((int)pixels[y*image->width + x+1].b + (int)((float)error_b*7.0f/16), 0xff); } - + if ((x > 0) && (y < (image->height - 1))) { pixels[(y+1)*image->width + x-1].r = MIN((int)pixels[(y+1)*image->width + x-1].r + (int)((float)error_r*3.0f/16), 0xff); pixels[(y+1)*image->width + x-1].g = MIN((int)pixels[(y+1)*image->width + x-1].g + (int)((float)error_g*3.0f/16), 0xff); pixels[(y+1)*image->width + x-1].b = MIN((int)pixels[(y+1)*image->width + x-1].b + (int)((float)error_b*3.0f/16), 0xff); } - + if (y < (image->height - 1)) { pixels[(y+1)*image->width + x].r = MIN((int)pixels[(y+1)*image->width + x].r + (int)((float)error_r*5.0f/16), 0xff); pixels[(y+1)*image->width + x].g = MIN((int)pixels[(y+1)*image->width + x].g + (int)((float)error_g*5.0f/16), 0xff); pixels[(y+1)*image->width + x].b = MIN((int)pixels[(y+1)*image->width + x].b + (int)((float)error_b*5.0f/16), 0xff); } - + if ((x < (image->width - 1)) && (y < (image->height - 1))) { pixels[(y+1)*image->width + x+1].r = MIN((int)pixels[(y+1)*image->width + x+1].r + (int)((float)error_r*1.0f/16), 0xff); @@ -776,7 +776,7 @@ void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp) pixel_g = (unsigned short)newpixel.g; pixel_b = (unsigned short)newpixel.b; pixel_a = (unsigned short)newpixel.a; - + ((unsigned short *)image->data)[y*image->width + x] = (pixel_r<<(gBpp + bBpp + aBpp)) | (pixel_g<<(bBpp + aBpp)) | (pixel_b<width); int potHeight = GetNextPOT(image->height); @@ -816,13 +816,13 @@ void ImageToPOT(Image *image, Color fillColor) free(pixels); // Free pixels data free(image->data); // Free old image data - + int format = image->format; // Store image data format to reconvert later - + // TODO: Image width and height changes... do we want to store new values or keep the old ones? // NOTE: Issues when using image.width and image.height for sprite animations... *image = LoadImageEx(pixelsPOT, potWidth, potHeight); - + free(pixelsPOT); // Free POT pixels data ImageFormat(image, format); // Reconvert image to previous format @@ -833,9 +833,9 @@ void ImageToPOT(Image *image, Color fillColor) Image ImageCopy(Image image) { Image newImage; - + int size = image.width*image.height; - + switch (image.format) { case UNCOMPRESSED_GRAYSCALE: newImage.data = (unsigned char *)malloc(size); break; // 8 bit per pixel (no alpha) @@ -847,24 +847,24 @@ Image ImageCopy(Image image) case UNCOMPRESSED_R8G8B8A8: newImage.data = (unsigned char *)malloc(size*4); size *= 4; break; // 32 bpp default: TraceLog(WARNING, "Image format not suported for copy"); break; } - + if (newImage.data != NULL) { // NOTE: Size must be provided in bytes memcpy(newImage.data, image.data, size); - + newImage.width = image.width; newImage.height = image.height; newImage.mipmaps = image.mipmaps; newImage.format = image.format; } - + return newImage; } // Crop an image to area defined by a rectangle // NOTE: Security checks are performed in case rectangle goes out of bounds -void ImageCrop(Image *image, Rectangle crop) +void ImageCrop(Image *image, Rectangle crop) { // Security checks to make sure cropping rectangle is inside margins if ((crop.x + crop.width) > image->width) @@ -872,13 +872,13 @@ void ImageCrop(Image *image, Rectangle crop) crop.width = image->width - crop.x; TraceLog(WARNING, "Crop rectangle width out of bounds, rescaled crop width: %i", crop.width); } - + if ((crop.y + crop.height) > image->height) { crop.height = image->height - crop.y; TraceLog(WARNING, "Crop rectangle height out of bounds, rescaled crop height: %i", crop.height); } - + if ((crop.x < image->width) && (crop.y < image->height)) { // Start the cropping process @@ -903,7 +903,7 @@ void ImageCrop(Image *image, Rectangle crop) free(cropPixels); - // Reformat 32bit RGBA image to original format + // Reformat 32bit RGBA image to original format ImageFormat(image, format); } else @@ -916,7 +916,7 @@ void ImageCrop(Image *image, Rectangle crop) // NOTE: Uses stb default scaling filters (both bicubic): // STBIR_DEFAULT_FILTER_UPSAMPLE STBIR_FILTER_CATMULLROM // STBIR_DEFAULT_FILTER_DOWNSAMPLE STBIR_FILTER_MITCHELL (high-quality Catmull-Rom) -void ImageResize(Image *image, int newWidth, int newHeight) +void ImageResize(Image *image, int newWidth, int newHeight) { // Get data as Color pixels array to work with it Color *pixels = GetImageData(*image); @@ -930,81 +930,81 @@ void ImageResize(Image *image, int newWidth, int newHeight) UnloadImage(*image); *image = LoadImageEx(output, newWidth, newHeight); - ImageFormat(image, format); // Reformat 32bit RGBA image to original format - + ImageFormat(image, format); // Reformat 32bit RGBA image to original format + free(output); free(pixels); } // Resize and image to new size using Nearest-Neighbor scaling algorithm -void ImageResizeNN(Image *image,int newWidth,int newHeight) +void ImageResizeNN(Image *image,int newWidth,int newHeight) { Color *pixels = GetImageData(*image); Color *output = (Color *)malloc(newWidth*newHeight*sizeof(Color)); - + // EDIT: added +1 to account for an early rounding problem int x_ratio = (int)((image->width<<16)/newWidth) + 1; int y_ratio = (int)((image->height<<16)/newHeight) + 1; - + int x2, y2; - for (int i = 0; i < newHeight; i++) + for (int i = 0; i < newHeight; i++) { - for (int j = 0; j < newWidth; j++) + for (int j = 0; j < newWidth; j++) { x2 = ((j*x_ratio) >> 16); y2 = ((i*y_ratio) >> 16); - + output[(i*newWidth) + j] = pixels[(y2*image->width) + x2] ; - } - } + } + } int format = image->format; UnloadImage(*image); *image = LoadImageEx(output, newWidth, newHeight); - ImageFormat(image, format); // Reformat 32bit RGBA image to original format - + ImageFormat(image, format); // Reformat 32bit RGBA image to original format + free(output); free(pixels); } // Draw an image (source) within an image (destination) -void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec) +void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec) { // Security checks to avoid size and rectangle issues (out of bounds) // Check that srcRec is inside src image if (srcRec.x < 0) srcRec.x = 0; if (srcRec.y < 0) srcRec.y = 0; - + if ((srcRec.x + srcRec.width) > src.width) { srcRec.width = src.width - srcRec.x; TraceLog(WARNING, "Source rectangle width out of bounds, rescaled width: %i", srcRec.width); } - + if ((srcRec.y + srcRec.height) > src.height) { srcRec.height = src.height - srcRec.y; TraceLog(WARNING, "Source rectangle height out of bounds, rescaled height: %i", srcRec.height); } - + // Check that dstRec is inside dst image if (dstRec.x < 0) dstRec.x = 0; if (dstRec.y < 0) dstRec.y = 0; - + if ((dstRec.x + dstRec.width) > dst->width) { dstRec.width = dst->width - dstRec.x; TraceLog(WARNING, "Destination rectangle width out of bounds, rescaled width: %i", dstRec.width); } - + if ((dstRec.y + dstRec.height) > dst->height) { dstRec.height = dst->height - dstRec.y; TraceLog(WARNING, "Destination rectangle height out of bounds, rescaled height: %i", dstRec.height); } - + // Get dstination image data as Color pixels array to work with it Color *dstPixels = GetImageData(*dst); @@ -1012,14 +1012,14 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec) ImageCrop(&srcCopy, srcRec); // Crop source image to desired source rectangle // Scale source image in case destination rec size is different than source rec size - if ((dstRec.width != srcRec.width) || (dstRec.height != srcRec.height)) + if ((dstRec.width != srcRec.width) || (dstRec.height != srcRec.height)) { ImageResize(&srcCopy, dstRec.width, dstRec.height); } // Get source image data as Color array Color *srcPixels = GetImageData(srcCopy); - + UnloadImage(srcCopy); // Blit pixels, copy source image into destination @@ -1030,7 +1030,7 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec) dstPixels[j*dst->width + i] = srcPixels[(j - dstRec.y)*dstRec.width + (i - dstRec.x)]; } } - + UnloadImage(*dst); // NOTE: Only dst->data is unloaded *dst = LoadImageEx(dstPixels, dst->width, dst->height); @@ -1046,9 +1046,9 @@ Image ImageText(const char *text, int fontSize, Color color) int defaultFontSize = 10; // Default Font chars height in pixel if (fontSize < defaultFontSize) fontSize = defaultFontSize; int spacing = fontSize / defaultFontSize; - + Image imText = ImageTextEx(GetDefaultFont(), text, fontSize, spacing, color); - + return imText; } @@ -1062,19 +1062,19 @@ Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing // NOTE: GetTextureData() not available in OpenGL ES Image imFont = GetTextureData(font.texture); - + ImageFormat(&imFont, UNCOMPRESSED_R8G8B8A8); // Required for color tint ImageColorTint(&imFont, tint); // Apply color tint to font Color *fontPixels = GetImageData(imFont); - + // Create image to store text Color *pixels = (Color *)malloc(sizeof(Color)*(int)imSize.x*(int)imSize.y); - + for (int i = 0; i < length; i++) { Rectangle letterRec = font.charRecs[(int)text[i] - 32]; - + for (int y = letterRec.y; y < (letterRec.y + letterRec.height); y++) { for (int x = posX; x < (posX + letterRec.width); x++) @@ -1082,28 +1082,28 @@ Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing pixels[(y - letterRec.y)*(int)imSize.x + x] = fontPixels[y*font.texture.width + (x - posX + letterRec.x)]; } } - + posX += letterRec.width + spacing; } - + UnloadImage(imFont); - + Image imText = LoadImageEx(pixels, (int)imSize.x, (int)imSize.y); - + // Scale image depending on text size if (fontSize > imSize.y) { float scaleFactor = fontSize/imSize.y; TraceLog(INFO, "Scalefactor: %f", scaleFactor); - + // Using nearest-neighbor scaling algorithm for default font if (font.texture.id == GetDefaultFont().texture.id) ImageResizeNN(&imText, (int)(imSize.x*scaleFactor), (int)(imSize.y*scaleFactor)); else ImageResize(&imText, (int)(imSize.x*scaleFactor), (int)(imSize.y*scaleFactor)); } - + free(pixels); free(fontPixels); - + return imText; } @@ -1117,12 +1117,12 @@ void ImageDrawText(Image *dst, Vector2 position, const char *text, int fontSize, void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text, float fontSize, int spacing, Color color) { Image imText = ImageTextEx(font, text, fontSize, spacing, color); - + Rectangle srcRec = { 0, 0, imText.width, imText.height }; Rectangle dstRec = { (int)position.x, (int)position.y, imText.width, imText.height }; - + ImageDraw(dst, imText, srcRec, dstRec); - + UnloadImage(imText); } @@ -1131,7 +1131,7 @@ void ImageFlipVertical(Image *image) { Color *srcPixels = GetImageData(*image); Color *dstPixels = (Color *)malloc(sizeof(Color)*image->width*image->height); - + for (int y = 0; y < image->height; y++) { for (int x = 0; x < image->width; x++) @@ -1139,14 +1139,14 @@ void ImageFlipVertical(Image *image) dstPixels[y*image->width + x] = srcPixels[(image->height - 1 - y)*image->width + x]; } } - + Image processed = LoadImageEx(dstPixels, image->width, image->height); ImageFormat(&processed, image->format); UnloadImage(*image); - + free(srcPixels); free(dstPixels); - + image->data = processed.data; } @@ -1155,7 +1155,7 @@ void ImageFlipHorizontal(Image *image) { Color *srcPixels = GetImageData(*image); Color *dstPixels = (Color *)malloc(sizeof(Color)*image->width*image->height); - + for (int y = 0; y < image->height; y++) { for (int x = 0; x < image->width; x++) @@ -1163,14 +1163,14 @@ void ImageFlipHorizontal(Image *image) dstPixels[y*image->width + x] = srcPixels[y*image->width + (image->width - 1 - x)]; } } - + Image processed = LoadImageEx(dstPixels, image->width, image->height); ImageFormat(&processed, image->format); UnloadImage(*image); - + free(srcPixels); free(dstPixels); - + image->data = processed.data; } @@ -1178,12 +1178,12 @@ void ImageFlipHorizontal(Image *image) void ImageColorTint(Image *image, Color color) { Color *pixels = GetImageData(*image); - + float cR = (float)color.r/255; float cG = (float)color.g/255; float cB = (float)color.b/255; float cA = (float)color.a/255; - + for (int y = 0; y < image->height; y++) { for (int x = 0; x < image->width; x++) @@ -1204,7 +1204,7 @@ void ImageColorTint(Image *image, Color color) ImageFormat(&processed, image->format); UnloadImage(*image); free(pixels); - + image->data = processed.data; } @@ -1212,7 +1212,7 @@ void ImageColorTint(Image *image, Color color) void ImageColorInvert(Image *image) { Color *pixels = GetImageData(*image); - + for (int y = 0; y < image->height; y++) { for (int x = 0; x < image->width; x++) @@ -1222,12 +1222,12 @@ void ImageColorInvert(Image *image) pixels[y*image->width + x].b = 255 - pixels[y*image->width + x].b; } } - + Image processed = LoadImageEx(pixels, image->width, image->height); ImageFormat(&processed, image->format); UnloadImage(*image); free(pixels); - + image->data = processed.data; } @@ -1243,12 +1243,12 @@ void ImageColorContrast(Image *image, float contrast) { if (contrast < -100) contrast = -100; if (contrast > 100) contrast = 100; - + contrast = (100.0 + contrast)/100.0; contrast *= contrast; - + Color *pixels = GetImageData(*image); - + for (int y = 0; y < image->height; y++) { for (int x = 0; x < image->width; x++) @@ -1287,7 +1287,7 @@ void ImageColorContrast(Image *image, float contrast) ImageFormat(&processed, image->format); UnloadImage(*image); free(pixels); - + image->data = processed.data; } @@ -1297,9 +1297,9 @@ void ImageColorBrightness(Image *image, int brightness) { if (brightness < -255) brightness = -255; if (brightness > 255) brightness = 255; - + Color *pixels = GetImageData(*image); - + for (int y = 0; y < image->height; y++) { for (int x = 0; x < image->width; x++) @@ -1316,7 +1316,7 @@ void ImageColorBrightness(Image *image, int brightness) if (cB < 0) cB = 1; if (cB > 255) cB = 255; - + pixels[y*image->width + x].r = (unsigned char)cR; pixels[y*image->width + x].g = (unsigned char)cG; pixels[y*image->width + x].b = (unsigned char)cB; @@ -1327,7 +1327,7 @@ void ImageColorBrightness(Image *image, int brightness) ImageFormat(&processed, image->format); UnloadImage(*image); free(pixels); - + image->data = processed.data; } @@ -1396,7 +1396,7 @@ void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, V { if (sourceRec.width < 0) sourceRec.x -= sourceRec.width; if (sourceRec.height < 0) sourceRec.y -= sourceRec.height; - + rlEnableTexture(texture.id); rlPushMatrix(); @@ -1439,13 +1439,13 @@ static Image LoadDDS(const char *fileName) { // Required extension: // GL_EXT_texture_compression_s3tc - + // Supported tokens (defined by extensions) // GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 // GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 // GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 // GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 - + #define FOURCC_DXT1 0x31545844 // Equivalent to "DXT1" in ASCII #define FOURCC_DXT3 0x33545844 // Equivalent to "DXT3" in ASCII #define FOURCC_DXT5 0x35545844 // Equivalent to "DXT5" in ASCII @@ -1508,7 +1508,7 @@ static Image LoadDDS(const char *fileName) else { ddsHeader header; - + // Get the image header fread(&header, sizeof(ddsHeader), 1, ddsFile); @@ -1537,9 +1537,9 @@ static Image LoadDDS(const char *fileName) { image.data = (unsigned short *)malloc(image.width*image.height*sizeof(unsigned short)); fread(image.data, image.width*image.height*sizeof(unsigned short), 1, ddsFile); - + unsigned char alpha = 0; - + // NOTE: Data comes as A1R5G5B5, it must be reordered to R5G5B5A1 for (int i = 0; i < image.width*image.height; i++) { @@ -1554,9 +1554,9 @@ static Image LoadDDS(const char *fileName) { image.data = (unsigned short *)malloc(image.width*image.height*sizeof(unsigned short)); fread(image.data, image.width*image.height*sizeof(unsigned short), 1, ddsFile); - + unsigned char alpha = 0; - + // NOTE: Data comes as A4R4G4B4, it must be reordered R4G4B4A4 for (int i = 0; i < image.width*image.height; i++) { @@ -1564,7 +1564,7 @@ static Image LoadDDS(const char *fileName) ((unsigned short *)image.data)[i] = ((unsigned short *)image.data)[i] << 4; ((unsigned short *)image.data)[i] += alpha; } - + image.format = UNCOMPRESSED_R4G4B4A4; } } @@ -1574,14 +1574,14 @@ static Image LoadDDS(const char *fileName) // NOTE: not sure if this case exists... image.data = (unsigned char *)malloc(image.width*image.height*3*sizeof(unsigned char)); fread(image.data, image.width*image.height*3, 1, ddsFile); - + image.format = UNCOMPRESSED_R8G8B8; } else if (header.ddspf.flags == 0x41 && header.ddspf.rgbBitCount == 32) // DDS_RGBA, no compressed { image.data = (unsigned char *)malloc(image.width*image.height*4*sizeof(unsigned char)); fread(image.data, image.width*image.height*4, 1, ddsFile); - + unsigned char blue = 0; // NOTE: Data comes as A8R8G8B8, it must be reordered R8G8B8A8 (view next comment) @@ -1593,7 +1593,7 @@ static Image LoadDDS(const char *fileName) ((unsigned char *)image.data)[i] = ((unsigned char *)image.data)[i + 2]; ((unsigned char *)image.data)[i + 2] = blue; } - + image.format = UNCOMPRESSED_R8G8B8A8; } else if (((header.ddspf.flags == 0x04) || (header.ddspf.flags == 0x05)) && (header.ddspf.fourCC > 0)) // Compressed @@ -1603,7 +1603,7 @@ static Image LoadDDS(const char *fileName) // Calculate data size, including all mipmaps if (header.mipmapCount > 1) bufsize = header.pitchOrLinearSize*2; else bufsize = header.pitchOrLinearSize; - + TraceLog(DEBUG, "Pitch or linear size: %i", header.pitchOrLinearSize); image.data = (unsigned char*)malloc(bufsize*sizeof(unsigned char)); @@ -1625,7 +1625,7 @@ static Image LoadDDS(const char *fileName) } } } - + fclose(ddsFile); // Close file pointer } @@ -1640,9 +1640,9 @@ static Image LoadPKM(const char *fileName) // Required extensions: // GL_OES_compressed_ETC1_RGB8_texture (ETC1) (OpenGL ES 2.0) // GL_ARB_ES3_compatibility (ETC2/EAC) (OpenGL ES 3.0) - + // Supported tokens (defined by extensions) - // GL_ETC1_RGB8_OES 0x8D64 + // GL_ETC1_RGB8_OES 0x8D64 // GL_COMPRESSED_RGB8_ETC2 0x9274 // GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 @@ -1656,7 +1656,7 @@ static Image LoadPKM(const char *fileName) unsigned short origWidth; // Original width (big-endian) unsigned short origHeight; // Original height (big-endian) } pkmHeader; - + // Formats list // version 10: format: 0=ETC1_RGB, [1=ETC1_RGBA, 2=ETC1_RGB_MIP, 3=ETC1_RGBA_MIP] (not used) // version 20: format: 0=ETC1_RGB, 1=ETC2_RGB, 2=ETC2_RGBA_OLD, 3=ETC2_RGBA, 4=ETC2_RGBA1, 5=ETC2_R, 6=ETC2_RG, 7=ETC2_SIGNED_R, 8=ETC2_SIGNED_R @@ -1665,7 +1665,7 @@ static Image LoadPKM(const char *fileName) // NOTE: ETC is always 4bit per pixel (64 bit for each 4x4 block of pixels) Image image; - + image.data = NULL; image.width = 0; image.height = 0; @@ -1695,18 +1695,18 @@ static Image LoadPKM(const char *fileName) header.format = ((header.format & 0x00FF) << 8) | ((header.format & 0xFF00) >> 8); header.width = ((header.width & 0x00FF) << 8) | ((header.width & 0xFF00) >> 8); header.height = ((header.height & 0x00FF) << 8) | ((header.height & 0xFF00) >> 8); - + TraceLog(DEBUG, "PKM (ETC) image width: %i", header.width); TraceLog(DEBUG, "PKM (ETC) image height: %i", header.height); TraceLog(DEBUG, "PKM (ETC) image format: %i", header.format); - + image.width = header.width; image.height = header.height; image.mipmaps = 1; - + int bpp = 4; if (header.format == 3) bpp = 8; - + int size = image.width*image.height*bpp/8; // Total data size in bytes image.data = (unsigned char*)malloc(size * sizeof(unsigned char)); @@ -1717,7 +1717,7 @@ static Image LoadPKM(const char *fileName) else if (header.format == 1) image.format = COMPRESSED_ETC2_RGB; else if (header.format == 3) image.format = COMPRESSED_ETC2_EAC_RGBA; } - + fclose(pkmFile); // Close file pointer } @@ -1730,12 +1730,12 @@ static Image LoadKTX(const char *fileName) // Required extensions: // GL_OES_compressed_ETC1_RGB8_texture (ETC1) // GL_ARB_ES3_compatibility (ETC2/EAC) - + // Supported tokens (defined by extensions) // GL_ETC1_RGB8_OES 0x8D64 // GL_COMPRESSED_RGB8_ETC2 0x9274 // GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 - + // KTX file Header (64 bytes) // https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/ typedef struct { @@ -1754,16 +1754,16 @@ static Image LoadKTX(const char *fileName) unsigned int mipmapLevels; // Non-mipmapped textures = 1 unsigned int keyValueDataSize; // Used to encode any arbitrary data... } ktxHeader; - + // NOTE: Before start of every mipmap data block, we have: unsigned int dataSize - + Image image; image.width = 0; image.height = 0; image.mipmaps = 0; image.format = 0; - + FILE *ktxFile = fopen(fileName, "rb"); if (ktxFile == NULL) @@ -1783,22 +1783,22 @@ static Image LoadKTX(const char *fileName) TraceLog(WARNING, "[%s] KTX file does not seem to be a valid file", fileName); } else - { + { image.width = header.width; image.height = header.height; image.mipmaps = header.mipmapLevels; - + TraceLog(DEBUG, "KTX (ETC) image width: %i", header.width); TraceLog(DEBUG, "KTX (ETC) image height: %i", header.height); TraceLog(DEBUG, "KTX (ETC) image format: 0x%x", header.glInternalFormat); - + unsigned char unused; - + if (header.keyValueDataSize > 0) { for (int i = 0; i < header.keyValueDataSize; i++) fread(&unused, 1, 1, ktxFile); } - + int dataSize; fread(&dataSize, sizeof(unsigned int), 1, ktxFile); @@ -1810,10 +1810,10 @@ static Image LoadKTX(const char *fileName) else if (header.glInternalFormat == 0x9274) image.format = COMPRESSED_ETC2_RGB; else if (header.glInternalFormat == 0x9278) image.format = COMPRESSED_ETC2_EAC_RGBA; } - + fclose(ktxFile); // Close file pointer } - + return image; } @@ -1823,11 +1823,11 @@ static Image LoadPVR(const char *fileName) { // Required extension: // GL_IMG_texture_compression_pvrtc - + // Supported tokens (defined by extensions) // GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00 // GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02 - + #if 0 // Not used... // PVR file v2 Header (52 bytes) typedef struct { @@ -1864,7 +1864,7 @@ static Image LoadPVR(const char *fileName) unsigned int numMipmaps; unsigned int metaDataSize; } pvrHeaderV3; - + #if 0 // Not used... // Metadata (usually 15 bytes) typedef struct { @@ -1872,7 +1872,7 @@ static Image LoadPVR(const char *fileName) unsigned int key; unsigned int dataSize; // Not used? unsigned char *data; // Not used? - } pvrMetadata; + } pvrMetadata; #endif Image image; @@ -1895,15 +1895,15 @@ static Image LoadPVR(const char *fileName) unsigned char pvrVersion = 0; fread(&pvrVersion, sizeof(unsigned char), 1, pvrFile); fseek(pvrFile, 0, SEEK_SET); - + // Load different PVR data formats if (pvrVersion == 0x50) { pvrHeaderV3 header; - + // Get PVR image header fread(&header, sizeof(pvrHeaderV3), 1, pvrFile); - + if ((header.id[0] != 'P') || (header.id[1] != 'V') || (header.id[2] != 'R') || (header.id[3] != 3)) { TraceLog(WARNING, "[%s] PVR file does not seem to be a valid image", fileName); @@ -1913,7 +1913,7 @@ static Image LoadPVR(const char *fileName) image.width = header.width; image.height = header.height; image.mipmaps = header.numMipmaps; - + // Check data format if (((header.channels[0] == 'l') && (header.channels[1] == 0)) && (header.channelDepth[0] == 8)) image.format = UNCOMPRESSED_GRAYSCALE; else if (((header.channels[0] == 'l') && (header.channels[1] == 'a')) && ((header.channelDepth[0] == 8) && (header.channelDepth[1] == 8))) image.format = UNCOMPRESSED_GRAY_ALPHA; @@ -1933,14 +1933,14 @@ static Image LoadPVR(const char *fileName) } else if (header.channels[0] == 2) image.format = COMPRESSED_PVRT_RGB; else if (header.channels[0] == 3) image.format = COMPRESSED_PVRT_RGBA; - + // Skip meta data header unsigned char unused = 0; for (int i = 0; i < header.metaDataSize; i++) fread(&unused, sizeof(unsigned char), 1, pvrFile); - + // Calculate data size (depends on format) int bpp = 0; - + switch (image.format) { case UNCOMPRESSED_GRAYSCALE: bpp = 8; break; @@ -1954,7 +1954,7 @@ static Image LoadPVR(const char *fileName) case COMPRESSED_PVRT_RGBA: bpp = 4; break; default: break; } - + int dataSize = image.width*image.height*bpp/8; // Total data size in bytes image.data = (unsigned char*)malloc(dataSize*sizeof(unsigned char)); @@ -1976,11 +1976,11 @@ static Image LoadASTC(const char *fileName) // Required extensions: // GL_KHR_texture_compression_astc_hdr // GL_KHR_texture_compression_astc_ldr - + // Supported tokens (defined by extensions) // GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93b0 // GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93b7 - + // ASTC file Header (16 bytes) typedef struct { unsigned char id[4]; // Signature: 0x13 0xAB 0xA1 0x5C @@ -1999,7 +1999,7 @@ static Image LoadASTC(const char *fileName) image.height = 0; image.mipmaps = 0; image.format = 0; - + FILE *astcFile = fopen(fileName, "rb"); if (astcFile == NULL) @@ -2012,7 +2012,7 @@ static Image LoadASTC(const char *fileName) // Get ASTC image header fread(&header, sizeof(astcHeader), 1, astcFile); - + if ((header.id[3] != 0x5c) || (header.id[2] != 0xa1) || (header.id[1] != 0xab) || (header.id[0] != 0x13)) { TraceLog(WARNING, "[%s] ASTC file does not seem to be a valid image", fileName); @@ -2022,31 +2022,31 @@ static Image LoadASTC(const char *fileName) // NOTE: Assuming Little Endian (could it be wrong?) image.width = 0x00000000 | ((int)header.width[2] << 16) | ((int)header.width[1] << 8) | ((int)header.width[0]); image.height = 0x00000000 | ((int)header.height[2] << 16) | ((int)header.height[1] << 8) | ((int)header.height[0]); - + // NOTE: ASTC format only contains one mipmap level image.mipmaps = 1; - + TraceLog(DEBUG, "ASTC image width: %i", image.width); TraceLog(DEBUG, "ASTC image height: %i", image.height); TraceLog(DEBUG, "ASTC image blocks: %ix%i", header.blockX, header.blockY); - + // NOTE: Each block is always stored in 128bit so we can calculate the bpp int bpp = 128/(header.blockX*header.blockY); // NOTE: Currently we only support 2 blocks configurations: 4x4 and 8x8 - if ((bpp == 8) || (bpp == 2)) + if ((bpp == 8) || (bpp == 2)) { int dataSize = image.width*image.height*bpp/8; // Data size in bytes - + image.data = (unsigned char *)malloc(dataSize*sizeof(unsigned char)); fread(image.data, dataSize, 1, astcFile); - + if (bpp == 8) image.format = COMPRESSED_ASTC_4x4_RGBA; else if (bpp == 2) image.format = COMPRESSED_ASTC_4x4_RGBA; } else TraceLog(WARNING, "[%s] ASTC block size configuration not supported", fileName); } - + fclose(astcFile); } -- cgit v1.2.3 From 4770e2010d2451d28305bea874f81e50ed6560f5 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Fri, 26 Aug 2016 19:40:37 +0200 Subject: Review Android project --- src/android/jni/Android.mk | 3 +- src/core.c | 6 +- templates/android_project/AndroidManifest.xml | 5 +- templates/android_project/jni/Android.mk | 4 +- templates/android_project/jni/include/raylib.h | 721 +++++++++++++------------ templates/android_project/jni/libs/libraylib.a | Bin 1868146 -> 1858024 bytes 6 files changed, 388 insertions(+), 351 deletions(-) (limited to 'src/core.c') diff --git a/src/android/jni/Android.mk b/src/android/jni/Android.mk index 66851d08..687c6577 100644 --- a/src/android/jni/Android.mk +++ b/src/android/jni/Android.mk @@ -4,7 +4,7 @@ # # Static library compilation # -# Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +# Copyright (c) 2014-2016 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. @@ -42,7 +42,6 @@ LOCAL_SRC_FILES :=\ ../../textures.c \ ../../text.c \ ../../shapes.c \ - ../../gestures.c \ ../../models.c \ ../../utils.c \ ../../audio.c \ diff --git a/src/core.c b/src/core.c index a76fe0be..81c2942a 100644 --- a/src/core.c +++ b/src/core.c @@ -48,8 +48,10 @@ #define GESTURES_IMPLEMENTATION #include "gestures.h" // Gestures detection functionality -#define CAMERA_IMPLEMENTATION -#include "camera.h" // Camera system functionality +#if !defined(PLATFORM_ANDROID) + #define CAMERA_IMPLEMENTATION + #include "camera.h" // Camera system functionality +#endif #include // Standard input / output lib #include // Declares malloc() and free() for memory management, rand(), atexit() diff --git a/templates/android_project/AndroidManifest.xml b/templates/android_project/AndroidManifest.xml index 6755027e..1d30ab17 100644 --- a/templates/android_project/AndroidManifest.xml +++ b/templates/android_project/AndroidManifest.xml @@ -5,11 +5,12 @@ * This template has been created using raylib 1.2 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) * --> + diff --git a/templates/android_project/jni/Android.mk b/templates/android_project/jni/Android.mk index 15a21695..4a0bcb42 100644 --- a/templates/android_project/jni/Android.mk +++ b/templates/android_project/jni/Android.mk @@ -4,7 +4,7 @@ # # Game template makefile # -# Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +# Copyright (c) 2014-2016 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. @@ -27,7 +27,6 @@ LOCAL_PATH := $(call my-dir) # OpenAL module (prebuilt static library) -# NOTE: Shared library brokes the build! Why? #-------------------------------------------------------------------- include $(CLEAR_VARS) @@ -41,7 +40,6 @@ LOCAL_SRC_FILES := libs/libopenal.a LOCAL_EXPORT_C_INCLUDES := include # Build static library -#include $(PREBUILT_SHARED_LIBRARY) include $(PREBUILT_STATIC_LIBRARY) #-------------------------------------------------------------------- diff --git a/templates/android_project/jni/include/raylib.h b/templates/android_project/jni/include/raylib.h index 19c67712..68cddc5a 100644 --- a/templates/android_project/jni/include/raylib.h +++ b/templates/android_project/jni/include/raylib.h @@ -1,6 +1,6 @@ /********************************************************************************************** * -* raylib 1.5.0 (www.raylib.com) +* raylib 1.6.0 (www.raylib.com) * * A simple and easy-to-use library to learn videogames programming * @@ -81,6 +81,14 @@ typedef struct android_app; // Define android_app struct (android_native_app_glue.h) #endif +#if defined(_WIN32) && defined(BUILDING_DLL) + #define RLAPI __declspec(dllexport) // We are building raylib as a Win32 DLL +#elif defined(_WIN32) && defined(RAYLIB_DLL) + #define RLAPI __declspec(dllimport) // We are using raylib as a Win32 DLL +#else + #define RLAPI // We are building or using raylib as a static library (or Linux shared library) +#endif + //---------------------------------------------------------------------------------- // Some basic Defines //---------------------------------------------------------------------------------- @@ -185,17 +193,20 @@ #define GAMEPAD_PLAYER4 3 // Not supported // Gamepad Buttons -// NOTE: Adjusted for a PS3 USB Controller -#define GAMEPAD_BUTTON_A 2 -#define GAMEPAD_BUTTON_B 1 -#define GAMEPAD_BUTTON_X 3 -#define GAMEPAD_BUTTON_Y 4 -#define GAMEPAD_BUTTON_R1 7 -#define GAMEPAD_BUTTON_R2 5 -#define GAMEPAD_BUTTON_L1 6 -#define GAMEPAD_BUTTON_L2 8 -#define GAMEPAD_BUTTON_SELECT 9 -#define GAMEPAD_BUTTON_START 10 + +// PS3 USB Controller +#define GAMEPAD_PS3_BUTTON_A 2 +#define GAMEPAD_PS3_BUTTON_B 1 +#define GAMEPAD_PS3_BUTTON_X 3 +#define GAMEPAD_PS3_BUTTON_Y 4 +#define GAMEPAD_PS3_BUTTON_R1 7 +#define GAMEPAD_PS3_BUTTON_R2 5 +#define GAMEPAD_PS3_BUTTON_L1 6 +#define GAMEPAD_PS3_BUTTON_L2 8 +#define GAMEPAD_PS3_BUTTON_SELECT 9 +#define GAMEPAD_PS3_BUTTON_START 10 + +// TODO: Add PS3 d-pad axis // Xbox360 USB Controller Buttons #define GAMEPAD_XBOX_BUTTON_A 0 @@ -233,44 +244,56 @@ #define ANDROID_VOLUME_UP 24 #define ANDROID_VOLUME_DOWN 25 +// NOTE: MSC C++ compiler does not support compound literals (C99 feature) +// Plain structures in C++ (without constructors) can be initialized from { } initializers. +#ifdef __cplusplus + #define CLITERAL +#else + #define CLITERAL (Color) +#endif + // Some Basic Colors // NOTE: Custom raylib color palette for amazing visuals on WHITE background -#define LIGHTGRAY (Color){ 200, 200, 200, 255 } // Light Gray -#define GRAY (Color){ 130, 130, 130, 255 } // Gray -#define DARKGRAY (Color){ 80, 80, 80, 255 } // Dark Gray -#define YELLOW (Color){ 253, 249, 0, 255 } // Yellow -#define GOLD (Color){ 255, 203, 0, 255 } // Gold -#define ORANGE (Color){ 255, 161, 0, 255 } // Orange -#define PINK (Color){ 255, 109, 194, 255 } // Pink -#define RED (Color){ 230, 41, 55, 255 } // Red -#define MAROON (Color){ 190, 33, 55, 255 } // Maroon -#define GREEN (Color){ 0, 228, 48, 255 } // Green -#define LIME (Color){ 0, 158, 47, 255 } // Lime -#define DARKGREEN (Color){ 0, 117, 44, 255 } // Dark Green -#define SKYBLUE (Color){ 102, 191, 255, 255 } // Sky Blue -#define BLUE (Color){ 0, 121, 241, 255 } // Blue -#define DARKBLUE (Color){ 0, 82, 172, 255 } // Dark Blue -#define PURPLE (Color){ 200, 122, 255, 255 } // Purple -#define VIOLET (Color){ 135, 60, 190, 255 } // Violet -#define DARKPURPLE (Color){ 112, 31, 126, 255 } // Dark Purple -#define BEIGE (Color){ 211, 176, 131, 255 } // Beige -#define BROWN (Color){ 127, 106, 79, 255 } // Brown -#define DARKBROWN (Color){ 76, 63, 47, 255 } // Dark Brown - -#define WHITE (Color){ 255, 255, 255, 255 } // White -#define BLACK (Color){ 0, 0, 0, 255 } // Black -#define BLANK (Color){ 0, 0, 0, 0 } // Blank (Transparent) -#define MAGENTA (Color){ 255, 0, 255, 255 } // Magenta -#define RAYWHITE (Color){ 245, 245, 245, 255 } // My own White (raylib logo) +#define LIGHTGRAY CLITERAL{ 200, 200, 200, 255 } // Light Gray +#define GRAY CLITERAL{ 130, 130, 130, 255 } // Gray +#define DARKGRAY CLITERAL{ 80, 80, 80, 255 } // Dark Gray +#define YELLOW CLITERAL{ 253, 249, 0, 255 } // Yellow +#define GOLD CLITERAL{ 255, 203, 0, 255 } // Gold +#define ORANGE CLITERAL{ 255, 161, 0, 255 } // Orange +#define PINK CLITERAL{ 255, 109, 194, 255 } // Pink +#define RED CLITERAL{ 230, 41, 55, 255 } // Red +#define MAROON CLITERAL{ 190, 33, 55, 255 } // Maroon +#define GREEN CLITERAL{ 0, 228, 48, 255 } // Green +#define LIME CLITERAL{ 0, 158, 47, 255 } // Lime +#define DARKGREEN CLITERAL{ 0, 117, 44, 255 } // Dark Green +#define SKYBLUE CLITERAL{ 102, 191, 255, 255 } // Sky Blue +#define BLUE CLITERAL{ 0, 121, 241, 255 } // Blue +#define DARKBLUE CLITERAL{ 0, 82, 172, 255 } // Dark Blue +#define PURPLE CLITERAL{ 200, 122, 255, 255 } // Purple +#define VIOLET CLITERAL{ 135, 60, 190, 255 } // Violet +#define DARKPURPLE CLITERAL{ 112, 31, 126, 255 } // Dark Purple +#define BEIGE CLITERAL{ 211, 176, 131, 255 } // Beige +#define BROWN CLITERAL{ 127, 106, 79, 255 } // Brown +#define DARKBROWN CLITERAL{ 76, 63, 47, 255 } // Dark Brown + +#define WHITE CLITERAL{ 255, 255, 255, 255 } // White +#define BLACK CLITERAL{ 0, 0, 0, 255 } // Black +#define BLANK CLITERAL{ 0, 0, 0, 0 } // Blank (Transparent) +#define MAGENTA CLITERAL{ 255, 0, 255, 255 } // Magenta +#define RAYWHITE CLITERAL{ 245, 245, 245, 255 } // My own White (raylib logo) //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- #ifndef __cplusplus // Boolean type - #if !defined(_STDBOOL_H) - typedef enum { false, true } bool; - #define _STDBOOL_H + #ifndef __APPLE__ + #if !defined(_STDBOOL_H) + typedef enum { false, true } bool; + #define _STDBOOL_H + #endif + #else + #include #endif #endif @@ -393,7 +416,7 @@ typedef struct Mesh { // Shader type (generic shader) typedef struct Shader { unsigned int id; // Shader program id - + // Vertex attributes locations (default locations) int vertexLoc; // Vertex attribute location point (default-location = 0) int texcoordLoc; // Texcoord attribute location point (default-location = 1) @@ -405,7 +428,7 @@ typedef struct Shader { // Uniform locations int mvpLoc; // ModelView-Projection matrix uniform location point (vertex shader) int tintColorLoc; // Diffuse color uniform location point (fragment shader) - + // Texture map locations (generic for any kind of map) int mapTexture0Loc; // Map texture uniform location point (default-texture-unit = 0) int mapTexture1Loc; // Map texture uniform location point (default-texture-unit = 1) @@ -419,11 +442,11 @@ typedef struct Material { Texture2D texDiffuse; // Diffuse texture (binded to shader mapTexture0Loc) Texture2D texNormal; // Normal texture (binded to shader mapTexture1Loc) Texture2D texSpecular; // Specular texture (binded to shader mapTexture2Loc) - + Color colDiffuse; // Diffuse color Color colAmbient; // Ambient color Color colSpecular; // Specular color - + float glossiness; // Glossiness level (Ranges from 0 to 1000) } Material; @@ -439,14 +462,14 @@ typedef struct LightData { unsigned int id; // Light unique id bool enabled; // Light enabled int type; // Light type: LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT - + Vector3 position; // Light position Vector3 target; // Light target: LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction target) float radius; // Light attenuation radius light intensity reduced with distance (world distance) - + Color diffuse; // Light diffuse color float intensity; // Light intensity level - + float coneAngle; // Light cone max angle: LIGHT_SPOT } LightData, *Light; @@ -461,19 +484,35 @@ typedef struct Ray { // Sound source type typedef struct Sound { - unsigned int source; // Sound audio source id - unsigned int buffer; // Sound audio buffer id + unsigned int source; // OpenAL audio source id + unsigned int buffer; // OpenAL audio buffer id } Sound; // Wave type, defines audio wave data typedef struct Wave { + unsigned int sampleCount; // Number of samples + unsigned int sampleRate; // Frequency (samples per second) + unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported) + unsigned int channels; // Number of channels (1-mono, 2-stereo) void *data; // Buffer data pointer - unsigned int dataSize; // Data size in bytes - unsigned int sampleRate; // Samples per second to be played - short bitsPerSample; // Sample size in bits - short channels; } Wave; +// Music type (file streaming from memory) +// NOTE: Anything longer than ~10 seconds should be streamed +typedef struct MusicData *Music; + +// Audio stream type +// NOTE: Useful to create custom audio streams not bound to a specific file +typedef struct AudioStream { + unsigned int sampleRate; // Frequency (samples per second) + unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported) + unsigned int channels; // Number of channels (1-mono, 2-stereo) + + int format; // OpenAL audio format specifier + unsigned int source; // OpenAL audio source id + unsigned int buffers[2]; // OpenAL audio buffers (double buffering) +} AudioStream; + // Texture formats // NOTE: Support depends on OpenGL version and platform typedef enum { @@ -516,18 +555,6 @@ typedef enum { GESTURE_PINCH_OUT = 512 } Gestures; -// Touch action (fingers or mouse) -typedef enum { TOUCH_UP, TOUCH_DOWN, TOUCH_MOVE } TouchAction; - -// Gesture events -// NOTE: MAX_TOUCH_POINTS fixed to 2 -typedef struct GestureEvent { - int touchAction; - int pointCount; - int pointerId[MAX_TOUCH_POINTS]; - Vector2 position[MAX_TOUCH_POINTS]; -} GestureEvent; - // Camera system modes typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON } CameraMode; @@ -557,94 +584,94 @@ extern "C" { // Prevents name mangling of functions // Window and Graphics Device Functions (Module: core) //------------------------------------------------------------------------------------ #if defined(PLATFORM_ANDROID) -void InitWindow(int width, int height, struct android_app *state); // Init Android Activity and OpenGL Graphics +RLAPI void InitWindow(int width, int height, struct android_app *state); // Init Android Activity and OpenGL Graphics #elif defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB) -void InitWindow(int width, int height, const char *title); // Initialize Window and OpenGL Graphics +RLAPI void InitWindow(int width, int height, const char *title); // Initialize Window and OpenGL Graphics #endif -void CloseWindow(void); // Close Window and Terminate Context -bool WindowShouldClose(void); // Detect if KEY_ESCAPE pressed or Close icon pressed -bool IsWindowMinimized(void); // Detect if window has been minimized (or lost focus) -void ToggleFullscreen(void); // Fullscreen toggle (only PLATFORM_DESKTOP) -int GetScreenWidth(void); // Get current screen width -int GetScreenHeight(void); // Get current screen height - -void ShowCursor(void); // Shows cursor -void HideCursor(void); // Hides cursor -bool IsCursorHidden(void); // Returns true if cursor is not visible -void EnableCursor(void); // Enables cursor -void DisableCursor(void); // Disables cursor - -void ClearBackground(Color color); // Sets Background Color -void BeginDrawing(void); // Setup drawing canvas to start drawing -void EndDrawing(void); // End canvas drawing and Swap Buffers (Double Buffering) - -void Begin2dMode(Camera2D camera); // Initialize 2D mode with custom camera -void End2dMode(void); // Ends 2D mode custom camera usage -void Begin3dMode(Camera camera); // Initializes 3D mode for drawing (Camera setup) -void End3dMode(void); // Ends 3D mode and returns to default 2D orthographic mode -void BeginTextureMode(RenderTexture2D target); // Initializes render texture for drawing -void EndTextureMode(void); // Ends drawing to render texture - -Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Returns a ray trace from mouse position -Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Returns the screen space position from a 3d world space position -Matrix GetCameraMatrix(Camera camera); // Returns camera transform matrix (view matrix) - -void SetTargetFPS(int fps); // Set target FPS (maximum) -float GetFPS(void); // Returns current FPS -float GetFrameTime(void); // Returns time in seconds for one frame - -Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value -int GetHexValue(Color color); // Returns hexadecimal value for a Color -float *ColorToFloat(Color color); // Converts Color to float array and normalizes -float *VectorToFloat(Vector3 vec); // Converts Vector3 to float array -float *MatrixToFloat(Matrix mat); // Converts Matrix to float array - -int GetRandomValue(int min, int max); // Returns a random value between min and max (both included) -Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f - -void SetConfigFlags(char flags); // Setup some window configuration flags -void ShowLogo(void); // Activates raylib logo at startup (can be done with flags) - -bool IsFileDropped(void); // Check if a file have been dropped into window -char **GetDroppedFiles(int *count); // Retrieve dropped files into window -void ClearDroppedFiles(void); // Clear dropped files paths buffer - -void StorageSaveValue(int position, int value); // Storage save integer value (to defined position) -int StorageLoadValue(int position); // Storage load integer value (from defined position) +RLAPI void CloseWindow(void); // Close Window and Terminate Context +RLAPI bool WindowShouldClose(void); // Detect if KEY_ESCAPE pressed or Close icon pressed +RLAPI bool IsWindowMinimized(void); // Detect if window has been minimized (or lost focus) +RLAPI void ToggleFullscreen(void); // Fullscreen toggle (only PLATFORM_DESKTOP) +RLAPI int GetScreenWidth(void); // Get current screen width +RLAPI int GetScreenHeight(void); // Get current screen height + +RLAPI void ShowCursor(void); // Shows cursor +RLAPI void HideCursor(void); // Hides cursor +RLAPI bool IsCursorHidden(void); // Returns true if cursor is not visible +RLAPI void EnableCursor(void); // Enables cursor +RLAPI void DisableCursor(void); // Disables cursor + +RLAPI void ClearBackground(Color color); // Sets Background Color +RLAPI void BeginDrawing(void); // Setup drawing canvas to start drawing +RLAPI void EndDrawing(void); // End canvas drawing and Swap Buffers (Double Buffering) + +RLAPI void Begin2dMode(Camera2D camera); // Initialize 2D mode with custom camera +RLAPI void End2dMode(void); // Ends 2D mode custom camera usage +RLAPI void Begin3dMode(Camera camera); // Initializes 3D mode for drawing (Camera setup) +RLAPI void End3dMode(void); // Ends 3D mode and returns to default 2D orthographic mode +RLAPI void BeginTextureMode(RenderTexture2D target); // Initializes render texture for drawing +RLAPI void EndTextureMode(void); // Ends drawing to render texture + +RLAPI Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Returns a ray trace from mouse position +RLAPI Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Returns the screen space position from a 3d world space position +RLAPI Matrix GetCameraMatrix(Camera camera); // Returns camera transform matrix (view matrix) + +RLAPI void SetTargetFPS(int fps); // Set target FPS (maximum) +RLAPI float GetFPS(void); // Returns current FPS +RLAPI float GetFrameTime(void); // Returns time in seconds for one frame + +RLAPI Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value +RLAPI int GetHexValue(Color color); // Returns hexadecimal value for a Color +RLAPI float *ColorToFloat(Color color); // Converts Color to float array and normalizes +RLAPI float *VectorToFloat(Vector3 vec); // Converts Vector3 to float array +RLAPI float *MatrixToFloat(Matrix mat); // Converts Matrix to float array + +RLAPI int GetRandomValue(int min, int max); // Returns a random value between min and max (both included) +RLAPI Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f + +RLAPI void SetConfigFlags(char flags); // Setup some window configuration flags +RLAPI void ShowLogo(void); // Activates raylib logo at startup (can be done with flags) + +RLAPI bool IsFileDropped(void); // Check if a file have been dropped into window +RLAPI char **GetDroppedFiles(int *count); // Retrieve dropped files into window +RLAPI void ClearDroppedFiles(void); // Clear dropped files paths buffer + +RLAPI void StorageSaveValue(int position, int value); // Storage save integer value (to defined position) +RLAPI int StorageLoadValue(int position); // Storage load integer value (from defined position) //------------------------------------------------------------------------------------ // Input Handling Functions (Module: core) //------------------------------------------------------------------------------------ #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB) -bool IsKeyPressed(int key); // Detect if a key has been pressed once -bool IsKeyDown(int key); // Detect if a key is being pressed -bool IsKeyReleased(int key); // Detect if a key has been released once -bool IsKeyUp(int key); // Detect if a key is NOT being pressed -int GetKeyPressed(void); // Get latest key pressed -void SetExitKey(int key); // Set a custom key to exit program (default is ESC) - -bool IsGamepadAvailable(int gamepad); // Detect if a gamepad is available -float GetGamepadAxisMovement(int gamepad, int axis); // Return axis movement value for a gamepad axis -bool IsGamepadButtonPressed(int gamepad, int button); // Detect if a gamepad button has been pressed once -bool IsGamepadButtonDown(int gamepad, int button); // Detect if a gamepad button is being pressed -bool IsGamepadButtonReleased(int gamepad, int button); // Detect if a gamepad button has been released once -bool IsGamepadButtonUp(int gamepad, int button); // Detect if a gamepad button is NOT being pressed +RLAPI bool IsKeyPressed(int key); // Detect if a key has been pressed once +RLAPI bool IsKeyDown(int key); // Detect if a key is being pressed +RLAPI bool IsKeyReleased(int key); // Detect if a key has been released once +RLAPI bool IsKeyUp(int key); // Detect if a key is NOT being pressed +RLAPI int GetKeyPressed(void); // Get latest key pressed +RLAPI void SetExitKey(int key); // Set a custom key to exit program (default is ESC) + +RLAPI bool IsGamepadAvailable(int gamepad); // Detect if a gamepad is available +RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Return axis movement value for a gamepad axis +RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Detect if a gamepad button has been pressed once +RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Detect if a gamepad button is being pressed +RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Detect if a gamepad button has been released once +RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Detect if a gamepad button is NOT being pressed #endif -bool IsMouseButtonPressed(int button); // Detect if a mouse button has been pressed once -bool IsMouseButtonDown(int button); // Detect if a mouse button is being pressed -bool IsMouseButtonReleased(int button); // Detect if a mouse button has been released once -bool IsMouseButtonUp(int button); // Detect if a mouse button is NOT being pressed -int GetMouseX(void); // Returns mouse position X -int GetMouseY(void); // Returns mouse position Y -Vector2 GetMousePosition(void); // Returns mouse position XY -void SetMousePosition(Vector2 position); // Set mouse position XY -int GetMouseWheelMove(void); // Returns mouse wheel movement Y +RLAPI bool IsMouseButtonPressed(int button); // Detect if a mouse button has been pressed once +RLAPI bool IsMouseButtonDown(int button); // Detect if a mouse button is being pressed +RLAPI bool IsMouseButtonReleased(int button); // Detect if a mouse button has been released once +RLAPI bool IsMouseButtonUp(int button); // Detect if a mouse button is NOT being pressed +RLAPI int GetMouseX(void); // Returns mouse position X +RLAPI int GetMouseY(void); // Returns mouse position Y +RLAPI Vector2 GetMousePosition(void); // Returns mouse position XY +RLAPI void SetMousePosition(Vector2 position); // Set mouse position XY +RLAPI int GetMouseWheelMove(void); // Returns mouse wheel movement Y -int GetTouchX(void); // Returns touch position X for touch point 0 (relative to screen size) -int GetTouchY(void); // Returns touch position Y for touch point 0 (relative to screen size) -Vector2 GetTouchPosition(int index); // Returns touch position XY for a touch point index (relative to screen size) +RLAPI int GetTouchX(void); // Returns touch position X for touch point 0 (relative to screen size) +RLAPI int GetTouchY(void); // Returns touch position Y for touch point 0 (relative to screen size) +RLAPI Vector2 GetTouchPosition(int index); // Returns touch position XY for a touch point index (relative to screen size) #if defined(PLATFORM_ANDROID) bool IsButtonPressed(int button); // Detect if an android physic button has been pressed @@ -655,254 +682,264 @@ bool IsButtonReleased(int button); // Detect if an android //------------------------------------------------------------------------------------ // Gestures and Touch Handling Functions (Module: gestures) //------------------------------------------------------------------------------------ -void SetGesturesEnabled(unsigned int gestureFlags); // Enable a set of gestures using flags -bool IsGestureDetected(int gesture); // Check if a gesture have been detected -void ProcessGestureEvent(GestureEvent event); // Process gesture event and translate it into gestures -void UpdateGestures(void); // Update gestures detected (called automatically in PollInputEvents()) - -int GetTouchPointsCount(void); // Get touch points count -int GetGestureDetected(void); // Get latest detected gesture -float GetGestureHoldDuration(void); // Get gesture hold time in milliseconds -Vector2 GetGestureDragVector(void); // Get gesture drag vector -float GetGestureDragAngle(void); // Get gesture drag angle -Vector2 GetGesturePinchVector(void); // Get gesture pinch delta -float GetGesturePinchAngle(void); // Get gesture pinch angle +RLAPI void SetGesturesEnabled(unsigned int gestureFlags); // Enable a set of gestures using flags +RLAPI bool IsGestureDetected(int gesture); // Check if a gesture have been detected +RLAPI int GetGestureDetected(void); // Get latest detected gesture +RLAPI int GetTouchPointsCount(void); // Get touch points count +RLAPI float GetGestureHoldDuration(void); // Get gesture hold time in milliseconds +RLAPI Vector2 GetGestureDragVector(void); // Get gesture drag vector +RLAPI float GetGestureDragAngle(void); // Get gesture drag angle +RLAPI Vector2 GetGesturePinchVector(void); // Get gesture pinch delta +RLAPI float GetGesturePinchAngle(void); // Get gesture pinch angle //------------------------------------------------------------------------------------ // Camera System Functions (Module: camera) //------------------------------------------------------------------------------------ -void SetCameraMode(int mode); // Set camera mode (multiple camera modes available) -void UpdateCamera(Camera *camera); // Update camera (player position is ignored) -void UpdateCameraPlayer(Camera *camera, Vector3 *position); // Update camera and player position (1st person and 3rd person cameras) +RLAPI void SetCameraMode(int mode); // Set camera mode (multiple camera modes available) +RLAPI void UpdateCamera(Camera *camera); // Update camera (player position is ignored) +RLAPI void UpdateCameraPlayer(Camera *camera, Vector3 *position); // Update camera and player position (1st person and 3rd person cameras) -void SetCameraPosition(Vector3 position); // Set internal camera position -void SetCameraTarget(Vector3 target); // Set internal camera target -void SetCameraFovy(float fovy); // Set internal camera field-of-view-y +RLAPI void SetCameraPosition(Vector3 position); // Set internal camera position +RLAPI void SetCameraTarget(Vector3 target); // Set internal camera target +RLAPI void SetCameraFovy(float fovy); // Set internal camera field-of-view-y -void SetCameraPanControl(int panKey); // Set camera pan key to combine with mouse movement (free camera) -void SetCameraAltControl(int altKey); // Set camera alt key to combine with mouse movement (free camera) -void SetCameraSmoothZoomControl(int szKey); // Set camera smooth zoom key to combine with mouse (free camera) +RLAPI void SetCameraPanControl(int panKey); // Set camera pan key to combine with mouse movement (free camera) +RLAPI void SetCameraAltControl(int altKey); // Set camera alt key to combine with mouse movement (free camera) +RLAPI void SetCameraSmoothZoomControl(int szKey); // Set camera smooth zoom key to combine with mouse (free camera) -void SetCameraMoveControls(int frontKey, int backKey, - int leftKey, int rightKey, - int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras) -void SetCameraMouseSensitivity(float sensitivity); // Set camera mouse sensitivity (1st person and 3rd person cameras) +RLAPI void SetCameraMoveControls(int frontKey, int backKey, + int leftKey, int rightKey, + int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras) +RLAPI void SetCameraMouseSensitivity(float sensitivity); // Set camera mouse sensitivity (1st person and 3rd person cameras) //------------------------------------------------------------------------------------ // Basic Shapes Drawing Functions (Module: shapes) //------------------------------------------------------------------------------------ -void DrawPixel(int posX, int posY, Color color); // Draw a pixel -void DrawPixelV(Vector2 position, Color color); // Draw a pixel (Vector version) -void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line -void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (Vector version) -void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle -void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2); // Draw a gradient-filled circle -void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version) -void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline -void DrawRectangle(int posX, int posY, int width, int height, Color color); // Draw a color-filled rectangle -void DrawRectangleRec(Rectangle rec, Color color); // Draw a color-filled rectangle -void DrawRectangleGradient(int posX, int posY, int width, int height, Color color1, Color color2); // Draw a gradient-filled rectangle -void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version) -void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline -void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle -void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline -void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version) -void DrawPolyEx(Vector2 *points, int numPoints, Color color); // Draw a closed polygon defined by points -void DrawPolyExLines(Vector2 *points, int numPoints, Color color); // Draw polygon lines - -bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles -bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles -bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec); // Check collision between circle and rectangle -Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2); // Get collision rectangle for two rectangles collision -bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle -bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius); // Check if point is inside circle -bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3); // Check if point is inside a triangle +RLAPI void DrawPixel(int posX, int posY, Color color); // Draw a pixel +RLAPI void DrawPixelV(Vector2 position, Color color); // Draw a pixel (Vector version) +RLAPI void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line +RLAPI void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (Vector version) +RLAPI void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle +RLAPI void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2); // Draw a gradient-filled circle +RLAPI void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version) +RLAPI void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline +RLAPI void DrawRectangle(int posX, int posY, int width, int height, Color color); // Draw a color-filled rectangle +RLAPI void DrawRectangleRec(Rectangle rec, Color color); // Draw a color-filled rectangle +RLAPI void DrawRectangleGradient(int posX, int posY, int width, int height, Color color1, Color color2); // Draw a gradient-filled rectangle +RLAPI void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version) +RLAPI void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline +RLAPI void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle +RLAPI void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline +RLAPI void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version) +RLAPI void DrawPolyEx(Vector2 *points, int numPoints, Color color); // Draw a closed polygon defined by points +RLAPI void DrawPolyExLines(Vector2 *points, int numPoints, Color color); // Draw polygon lines + +RLAPI bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles +RLAPI bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles +RLAPI bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec); // Check collision between circle and rectangle +RLAPI Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2); // Get collision rectangle for two rectangles collision +RLAPI bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle +RLAPI bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius); // Check if point is inside circle +RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3); // Check if point is inside a triangle //------------------------------------------------------------------------------------ // Texture Loading and Drawing Functions (Module: textures) //------------------------------------------------------------------------------------ -Image LoadImage(const char *fileName); // Load an image into CPU memory (RAM) -Image LoadImageEx(Color *pixels, int width, int height); // Load image data from Color array data (RGBA - 32bit) -Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image data from RAW file -Image LoadImageFromRES(const char *rresName, int resId); // Load an image from rRES file (raylib Resource) -Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory -Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat); // Load a texture from raw data into GPU memory -Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource) -Texture2D LoadTextureFromImage(Image image); // Load a texture from image data -RenderTexture2D LoadRenderTexture(int width, int height); // Load a texture to be used for rendering -void UnloadImage(Image image); // Unload image from CPU memory (RAM) -void UnloadTexture(Texture2D texture); // Unload texture from GPU memory -void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory -Color *GetImageData(Image image); // Get pixel data from image as a Color struct array -Image GetTextureData(Texture2D texture); // Get pixel data from GPU texture and return an Image -void ImageToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two) -void ImageFormat(Image *image, int newFormat); // Convert image data to desired format -void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering) -Image ImageCopy(Image image); // Create an image duplicate (useful for transformations) -void ImageCrop(Image *image, Rectangle crop); // Crop an image to a defined rectangle -void ImageResize(Image *image, int newWidth, int newHeight); // Resize and image (bilinear filtering) -void ImageResizeNN(Image *image,int newWidth,int newHeight); // Resize and image (Nearest-Neighbor scaling algorithm) -Image ImageText(const char *text, int fontSize, Color color); // Create an image from text (default font) -Image ImageTextEx(SpriteFont font, const char *text, int fontSize, int spacing, Color tint); // Create an image from text (custom sprite font) -void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec); // Draw a source image within a destination image -void ImageDrawText(Image *dst, Vector2 position, const char *text, int fontSize, Color color); // Draw text (default font) within an image (destination) -void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text, int fontSize, int spacing, Color color); // Draw text (custom sprite font) within an image (destination) -void ImageFlipVertical(Image *image); // Flip image vertically -void ImageFlipHorizontal(Image *image); // Flip image horizontally -void ImageColorTint(Image *image, Color color); // Modify image color: tint -void ImageColorInvert(Image *image); // Modify image color: invert -void ImageColorGrayscale(Image *image); // Modify image color: grayscale -void ImageColorContrast(Image *image, float contrast); // Modify image color: contrast (-100 to 100) -void ImageColorBrightness(Image *image, int brightness); // Modify image color: brightness (-255 to 255) -void GenTextureMipmaps(Texture2D texture); // Generate GPU mipmaps for a texture -void UpdateTexture(Texture2D texture, void *pixels); // Update GPU texture with new data - -void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D -void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2 -void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters -void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint); // Draw a part of a texture defined by a rectangle -void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, // Draw a part of a texture defined by a rectangle with 'pro' parameters +RLAPI Image LoadImage(const char *fileName); // Load an image into CPU memory (RAM) +RLAPI Image LoadImageEx(Color *pixels, int width, int height); // Load image data from Color array data (RGBA - 32bit) +RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image data from RAW file +RLAPI Image LoadImageFromRES(const char *rresName, int resId); // Load an image from rRES file (raylib Resource) +RLAPI Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory +RLAPI Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat); // Load a texture from raw data into GPU memory +RLAPI Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource) +RLAPI Texture2D LoadTextureFromImage(Image image); // Load a texture from image data +RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load a texture to be used for rendering +RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM) +RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory +RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory +RLAPI Color *GetImageData(Image image); // Get pixel data from image as a Color struct array +RLAPI Image GetTextureData(Texture2D texture); // Get pixel data from GPU texture and return an Image +RLAPI void ImageToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two) +RLAPI void ImageFormat(Image *image, int newFormat); // Convert image data to desired format +RLAPI void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering) +RLAPI Image ImageCopy(Image image); // Create an image duplicate (useful for transformations) +RLAPI void ImageCrop(Image *image, Rectangle crop); // Crop an image to a defined rectangle +RLAPI void ImageResize(Image *image, int newWidth, int newHeight); // Resize and image (bilinear filtering) +RLAPI void ImageResizeNN(Image *image,int newWidth,int newHeight); // Resize and image (Nearest-Neighbor scaling algorithm) +RLAPI Image ImageText(const char *text, int fontSize, Color color); // Create an image from text (default font) +RLAPI Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing, Color tint); // Create an image from text (custom sprite font) +RLAPI void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec); // Draw a source image within a destination image +RLAPI void ImageDrawText(Image *dst, Vector2 position, const char *text, int fontSize, Color color); // Draw text (default font) within an image (destination) +RLAPI void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text, float fontSize, int spacing, Color color); // Draw text (custom sprite font) within an image (destination) +RLAPI void ImageFlipVertical(Image *image); // Flip image vertically +RLAPI void ImageFlipHorizontal(Image *image); // Flip image horizontally +RLAPI void ImageColorTint(Image *image, Color color); // Modify image color: tint +RLAPI void ImageColorInvert(Image *image); // Modify image color: invert +RLAPI void ImageColorGrayscale(Image *image); // Modify image color: grayscale +RLAPI void ImageColorContrast(Image *image, float contrast); // Modify image color: contrast (-100 to 100) +RLAPI void ImageColorBrightness(Image *image, int brightness); // Modify image color: brightness (-255 to 255) +RLAPI void GenTextureMipmaps(Texture2D texture); // Generate GPU mipmaps for a texture +RLAPI void UpdateTexture(Texture2D texture, void *pixels); // Update GPU texture with new data + +RLAPI void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D +RLAPI void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2 +RLAPI void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters +RLAPI void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint); // Draw a part of a texture defined by a rectangle +RLAPI void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, // Draw a part of a texture defined by a rectangle with 'pro' parameters float rotation, Color tint); //------------------------------------------------------------------------------------ // Font Loading and Text Drawing Functions (Module: text) //------------------------------------------------------------------------------------ -SpriteFont GetDefaultFont(void); // Get the default SpriteFont -SpriteFont LoadSpriteFont(const char *fileName); // Load a SpriteFont image into GPU memory -void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory +RLAPI SpriteFont GetDefaultFont(void); // Get the default SpriteFont +RLAPI SpriteFont LoadSpriteFont(const char *fileName); // Load a SpriteFont image into GPU memory +RLAPI void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory -void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) -void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters - int fontSize, int spacing, Color tint); -int MeasureText(const char *text, int fontSize); // Measure string width for default font -Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int spacing); // Measure string size for SpriteFont +RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) +RLAPI void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters + float fontSize, int spacing, Color tint); +RLAPI int MeasureText(const char *text, int fontSize); // Measure string width for default font +RLAPI Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int spacing); // Measure string size for SpriteFont -void DrawFPS(int posX, int posY); // Shows current FPS on top-left corner -const char *FormatText(const char *text, ...); // Formatting of text with variables to 'embed' -const char *SubText(const char *text, int position, int length); // Get a piece of a text string +RLAPI void DrawFPS(int posX, int posY); // Shows current FPS on top-left corner +RLAPI const char *FormatText(const char *text, ...); // Formatting of text with variables to 'embed' +RLAPI const char *SubText(const char *text, int position, int length); // Get a piece of a text string //------------------------------------------------------------------------------------ // Basic 3d Shapes Drawing Functions (Module: models) //------------------------------------------------------------------------------------ -void DrawCube(Vector3 position, float width, float height, float lenght, Color color); // Draw cube -void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version) -void DrawCubeWires(Vector3 position, float width, float height, float lenght, Color color); // Draw cube wires -void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float lenght, Color color); // Draw cube textured -void DrawSphere(Vector3 centerPos, float radius, Color color); // Draw sphere -void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters -void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires -void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone -void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires -void DrawPlane(Vector3 centerPos, Vector2 size, Color color); // Draw a plane XZ -void DrawRay(Ray ray, Color color); // Draw a ray line -void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0)) -void DrawGizmo(Vector3 position); // Draw simple gizmo -void DrawLight(Light light); // Draw light in 3D world -void Draw3DLine(Vector3 startPos, Vector3 endPos, Color color); // Draw a line in 3D world space -void Draw3DCircle(Vector3 center, float radius, float rotationAngle, Vector3 rotation, Color color); // Draw a circle in 3D world space +RLAPI void DrawLine3D(Vector3 startPos, Vector3 endPos, Color color); // Draw a line in 3D world space +RLAPI void DrawCircle3D(Vector3 center, float radius, float rotationAngle, Vector3 rotation, Color color); // Draw a circle in 3D world space +RLAPI void DrawCube(Vector3 position, float width, float height, float length, Color color); // Draw cube +RLAPI void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version) +RLAPI void DrawCubeWires(Vector3 position, float width, float height, float length, Color color); // Draw cube wires +RLAPI void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float length, Color color); // Draw cube textured +RLAPI void DrawSphere(Vector3 centerPos, float radius, Color color); // Draw sphere +RLAPI void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters +RLAPI void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires +RLAPI void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone +RLAPI void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires +RLAPI void DrawPlane(Vector3 centerPos, Vector2 size, Color color); // Draw a plane XZ +RLAPI void DrawRay(Ray ray, Color color); // Draw a ray line +RLAPI void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0)) +RLAPI void DrawGizmo(Vector3 position); // Draw simple gizmo +RLAPI void DrawLight(Light light); // Draw light in 3D world //DrawTorus(), DrawTeapot() are useless... //------------------------------------------------------------------------------------ // Model 3d Loading and Drawing Functions (Module: models) //------------------------------------------------------------------------------------ -Model LoadModel(const char *fileName); // Load a 3d model (.OBJ) -Model LoadModelEx(Mesh data, bool dynamic); // Load a 3d model (from mesh data) -Model LoadModelFromRES(const char *rresName, int resId); // Load a 3d model from rRES file (raylib Resource) -Model LoadHeightmap(Image heightmap, Vector3 size); // Load a heightmap image as a 3d model -Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based) -void UnloadModel(Model model); // Unload 3d model from memory - -Material LoadMaterial(const char *fileName); // Load material data (from file) -Material LoadDefaultMaterial(void); // Load default material (uses default models shader) -Material LoadStandardMaterial(void); // Load standard material (uses material attributes and lighting shader) -void UnloadMaterial(Material material); // Unload material textures from VRAM - -void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set) -void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters -void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set) -void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters -void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires) - -void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture -void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec - -BoundingBox CalculateBoundingBox(Mesh mesh); // Calculate mesh bounding box limits -bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); // Detect collision between two spheres -bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Detect collision between two bounding boxes -bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere -bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius); // Detect collision between ray and sphere -bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, Vector3 *collisionPoint); // Detect collision between ray and sphere with extended parameters and collision point detection -bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Detect collision between ray and box -Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *playerPosition, float radius); // Detect collision of player radius with cubicmap +RLAPI Model LoadModel(const char *fileName); // Load a 3d model (.OBJ) +RLAPI Model LoadModelEx(Mesh data, bool dynamic); // Load a 3d model (from mesh data) +RLAPI Model LoadModelFromRES(const char *rresName, int resId); // Load a 3d model from rRES file (raylib Resource) +RLAPI Model LoadHeightmap(Image heightmap, Vector3 size); // Load a heightmap image as a 3d model +RLAPI Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based) +RLAPI void UnloadModel(Model model); // Unload 3d model from memory + +RLAPI Mesh GenMeshCube(float width, float height, float depth); // Generate mesh: cube + +RLAPI Material LoadMaterial(const char *fileName); // Load material data (from file) +RLAPI Material LoadDefaultMaterial(void); // Load default material (uses default models shader) +RLAPI Material LoadStandardMaterial(void); // Load standard material (uses material attributes and lighting shader) +RLAPI void UnloadMaterial(Material material); // Unload material textures from VRAM + +RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set) +RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters +RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set) +RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters +RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires) + +RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture +RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec + +RLAPI BoundingBox CalculateBoundingBox(Mesh mesh); // Calculate mesh bounding box limits +RLAPI bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); // Detect collision between two spheres +RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Detect collision between two bounding boxes +RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere +RLAPI bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius); // Detect collision between ray and sphere +RLAPI bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, Vector3 *collisionPoint); // Detect collision between ray and sphere with extended parameters and collision point detection +RLAPI bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Detect collision between ray and box +RLAPI Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *playerPosition, float radius); // Detect collision of player radius with cubicmap // NOTE: Return the normal vector of the impacted surface //------------------------------------------------------------------------------------ // Shaders System Functions (Module: rlgl) // NOTE: This functions are useless when using OpenGL 1.1 //------------------------------------------------------------------------------------ -Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations -void UnloadShader(Shader shader); // Unload a custom shader from memory +RLAPI Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations +RLAPI void UnloadShader(Shader shader); // Unload a custom shader from memory -Shader GetDefaultShader(void); // Get default shader -Shader GetStandardShader(void); // Get standard shader -Texture2D GetDefaultTexture(void); // Get default texture +RLAPI Shader GetDefaultShader(void); // Get default shader +RLAPI Shader GetStandardShader(void); // Get standard shader +RLAPI Texture2D GetDefaultTexture(void); // Get default texture -int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location -void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float) -void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // Set shader uniform value (int) -void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // Set shader uniform value (matrix 4x4) +RLAPI int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location +RLAPI void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float) +RLAPI void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // Set shader uniform value (int) +RLAPI void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // Set shader uniform value (matrix 4x4) -void SetMatrixProjection(Matrix proj); // Set a custom projection matrix (replaces internal projection matrix) -void SetMatrixModelview(Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix) +RLAPI void SetMatrixProjection(Matrix proj); // Set a custom projection matrix (replaces internal projection matrix) +RLAPI void SetMatrixModelview(Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix) -void BeginShaderMode(Shader shader); // Begin custom shader drawing -void EndShaderMode(void); // End custom shader drawing (use default shader) -void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied) -void EndBlendMode(void); // End blending mode (reset to default: alpha blending) +RLAPI void BeginShaderMode(Shader shader); // Begin custom shader drawing +RLAPI void EndShaderMode(void); // End custom shader drawing (use default shader) +RLAPI void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied) +RLAPI void EndBlendMode(void); // End blending mode (reset to default: alpha blending) -Light CreateLight(int type, Vector3 position, Color diffuse); // Create a new light, initialize it and add to pool -void DestroyLight(Light light); // Destroy a light and take it out of the list +RLAPI Light CreateLight(int type, Vector3 position, Color diffuse); // Create a new light, initialize it and add to pool +RLAPI void DestroyLight(Light light); // Destroy a light and take it out of the list //------------------------------------------------------------------------------------ // VR experience Functions (Module: rlgl) // NOTE: This functions are useless when using OpenGL 1.1 //------------------------------------------------------------------------------------ -void InitVrDevice(int vdDevice); // Init VR device -void CloseVrDevice(void); // Close VR device -void UpdateVrTracking(void); // Update VR tracking (position and orientation) -void BeginVrDrawing(void); // Begin VR drawing configuration -void EndVrDrawing(void); // End VR drawing process (and desktop mirror) -bool IsVrDeviceReady(void); // Detect if VR device (or simulator) is ready -void ToggleVrMode(void); // Enable/Disable VR experience (device or simulator) +RLAPI void InitVrDevice(int vdDevice); // Init VR device +RLAPI void CloseVrDevice(void); // Close VR device +RLAPI bool IsVrDeviceReady(void); // Detect if VR device (or simulator) is ready +RLAPI void UpdateVrTracking(void); // Update VR tracking (position and orientation) +RLAPI void ToggleVrMode(void); // Enable/Disable VR experience (device or simulator) //------------------------------------------------------------------------------------ // Audio Loading and Playing Functions (Module: audio) //------------------------------------------------------------------------------------ -void InitAudioDevice(void); // Initialize audio device and context -void CloseAudioDevice(void); // Close the audio device and context (and music stream) -bool IsAudioDeviceReady(void); // True if call to InitAudioDevice() was successful and CloseAudioDevice() has not been called yet - -Sound LoadSound(char *fileName); // Load sound to memory -Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data -Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource) -void UnloadSound(Sound sound); // Unload sound -void PlaySound(Sound sound); // Play a sound -void PauseSound(Sound sound); // Pause a sound -void StopSound(Sound sound); // Stop playing a sound -bool IsSoundPlaying(Sound sound); // Check if a sound is currently playing -void SetSoundVolume(Sound sound, float volume); // Set volume for a sound (1.0 is max level) -void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level) - -int PlayMusicStream(int index, char *fileName); // Start music playing (open stream) -void UpdateMusicStream(int index); // Updates buffers for music streaming -void StopMusicStream(int index); // Stop music playing (close stream) -void PauseMusicStream(int index); // Pause music playing -void ResumeMusicStream(int index); // Resume playing paused music -bool IsMusicPlaying(int index); // Check if music is playing -void SetMusicVolume(int index, float volume); // Set volume for music (1.0 is max level) -void SetMusicPitch(int index, float pitch); // Set pitch for a music (1.0 is base level) -float GetMusicTimeLength(int index); // Get current music time length (in seconds) -float GetMusicTimePlayed(int index); // Get current music time played (in seconds) -int GetMusicStreamCount(void); // Get number of streams loaded +RLAPI void InitAudioDevice(void); // Initialize audio device and context +RLAPI void CloseAudioDevice(void); // Close the audio device and context (and music stream) +RLAPI bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully + +RLAPI Sound LoadSound(char *fileName); // Load sound to memory +RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data +RLAPI Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource) +RLAPI void UnloadSound(Sound sound); // Unload sound +RLAPI void PlaySound(Sound sound); // Play a sound +RLAPI void PauseSound(Sound sound); // Pause a sound +RLAPI void ResumeSound(Sound sound); // Resume a paused sound +RLAPI void StopSound(Sound sound); // Stop playing a sound +RLAPI bool IsSoundPlaying(Sound sound); // Check if a sound is currently playing +RLAPI void SetSoundVolume(Sound sound, float volume); // Set volume for a sound (1.0 is max level) +RLAPI void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level) + +RLAPI Music LoadMusicStream(char *fileName); // Load music stream from file +RLAPI void UnloadMusicStream(Music music); // Unload music stream +RLAPI void PlayMusicStream(Music music); // Start music playing (open stream) +RLAPI void UpdateMusicStream(Music music); // Updates buffers for music streaming +RLAPI void StopMusicStream(Music music); // Stop music playing (close stream) +RLAPI void PauseMusicStream(Music music); // Pause music playing +RLAPI void ResumeMusicStream(Music music); // Resume playing paused music +RLAPI bool IsMusicPlaying(Music music); // Check if music is playing +RLAPI void SetMusicVolume(Music music, float volume); // Set volume for music (1.0 is max level) +RLAPI void SetMusicPitch(Music music, float pitch); // Set pitch for a music (1.0 is base level) +RLAPI float GetMusicTimeLength(Music music); // Get music time length (in seconds) +RLAPI float GetMusicTimePlayed(Music music); // Get current music time played (in seconds) + +RLAPI AudioStream InitAudioStream(unsigned int sampleRate, + unsigned int sampleSize, + unsigned int channels); // Init audio stream (to stream audio pcm data) +RLAPI void UpdateAudioStream(AudioStream stream, void *data, int numSamples); // Update audio stream buffers with data +RLAPI void CloseAudioStream(AudioStream stream); // Close audio stream and free memory +RLAPI bool IsAudioBufferProcessed(AudioStream stream); // Check if any audio stream buffers requires refill +RLAPI void PlayAudioStream(AudioStream stream); // Play audio stream +RLAPI void PauseAudioStream(AudioStream stream); // Pause audio stream +RLAPI void ResumeAudioStream(AudioStream stream); // Resume audio stream +RLAPI void StopAudioStream(AudioStream stream); // Stop audio stream #ifdef __cplusplus } diff --git a/templates/android_project/jni/libs/libraylib.a b/templates/android_project/jni/libs/libraylib.a index 3ee2746d..24344d0c 100644 Binary files a/templates/android_project/jni/libs/libraylib.a and b/templates/android_project/jni/libs/libraylib.a differ -- cgit v1.2.3 From a9ab516dae83d95a8701160bb7dcc72917e2d2ab Mon Sep 17 00:00:00 2001 From: raysan5 Date: Wed, 31 Aug 2016 10:27:29 +0200 Subject: Formatting tweaks --- src/audio.c | 4 ++-- src/core.c | 2 +- src/models.c | 12 ++++++------ src/text.c | 18 +++++++++--------- src/textures.c | 2 +- 5 files changed, 19 insertions(+), 19 deletions(-) (limited to 'src/core.c') diff --git a/src/audio.c b/src/audio.c index 3bace5f7..ea14d77d 100644 --- a/src/audio.c +++ b/src/audio.c @@ -1068,7 +1068,7 @@ static void UnloadWave(Wave wave) const char *GetExtension(const char *fileName) { const char *dot = strrchr(fileName, '.'); - if(!dot || dot == fileName) return ""; + if (!dot || dot == fileName) return ""; return (dot + 1); } @@ -1083,7 +1083,7 @@ void TraceLog(int msgType, const char *text, ...) traceDebugMsgs = 0; #endif - switch(msgType) + switch (msgType) { case INFO: fprintf(stdout, "INFO: "); break; case ERROR: fprintf(stdout, "ERROR: "); break; diff --git a/src/core.c b/src/core.c index 81c2942a..b9ffe87b 100644 --- a/src/core.c +++ b/src/core.c @@ -2451,7 +2451,7 @@ static EM_BOOL EmscriptenInputCallback(int eventType, const EmscriptenTouchEvent 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) + for (int i = 0; i < event->numTouches; ++i) { const EmscriptenTouchPoint *t = &event->touches[i]; diff --git a/src/models.c b/src/models.c index 55de3d4f..25eb1fe0 100644 --- a/src/models.c +++ b/src/models.c @@ -270,25 +270,25 @@ void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float hei rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Right Of The Texture and Quad rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left Of The Texture and Quad // Back Face - rlNormal3f( 0.0f, 0.0f,-1.0f); // Normal Pointing Away From Viewer + rlNormal3f(0.0f, 0.0f,-1.0f); // Normal Pointing Away From Viewer rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Right Of The Texture and Quad rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Right Of The Texture and Quad rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Left Of The Texture and Quad rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Left Of The Texture and Quad // Top Face - rlNormal3f( 0.0f, 1.0f, 0.0f); // Normal Pointing Up + rlNormal3f(0.0f, 1.0f, 0.0f); // Normal Pointing Up rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left Of The Texture and Quad rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x-width/2, y+height/2, z+length/2); // Bottom Left Of The Texture and Quad rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x+width/2, y+height/2, z+length/2); // Bottom Right Of The Texture and Quad rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right Of The Texture and Quad // Bottom Face - rlNormal3f( 0.0f,-1.0f, 0.0f); // Normal Pointing Down + rlNormal3f(0.0f,-1.0f, 0.0f); // Normal Pointing Down rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x-width/2, y-height/2, z-length/2); // Top Right Of The Texture and Quad rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x+width/2, y-height/2, z-length/2); // Top Left Of The Texture and Quad rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Left Of The Texture and Quad rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Right Of The Texture and Quad // Right face - rlNormal3f( 1.0f, 0.0f, 0.0f); // Normal Pointing Right + rlNormal3f(1.0f, 0.0f, 0.0f); // Normal Pointing Right rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right Of The Texture and Quad rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right Of The Texture and Quad rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Left Of The Texture and Quad @@ -1905,14 +1905,14 @@ static Mesh LoadOBJ(const char *fileName) } else if (dataType == 'n') // Read normals { - fscanf(objFile, "%f %f %f", &midNormals[countNormals].x, &midNormals[countNormals].y, &midNormals[countNormals].z ); + fscanf(objFile, "%f %f %f", &midNormals[countNormals].x, &midNormals[countNormals].y, &midNormals[countNormals].z); countNormals++; fscanf(objFile, "%c", &dataType); } else // Read vertex { - fscanf(objFile, "%f %f %f", &midVertices[countVertex].x, &midVertices[countVertex].y, &midVertices[countVertex].z ); + fscanf(objFile, "%f %f %f", &midVertices[countVertex].x, &midVertices[countVertex].y, &midVertices[countVertex].z); countVertex++; fscanf(objFile, "%c", &dataType); diff --git a/src/text.c b/src/text.c index 3d28fc3c..d00f01d7 100644 --- a/src/text.c +++ b/src/text.c @@ -319,7 +319,7 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float // NOTE: Some ugly hacks are made to support Latin-1 Extended characters directly // written in C code files (codified by default as UTF-8) - for(int i = 0; i < length; i++) + for (int i = 0; i < length; i++) { // TODO: Right now we are supposing characters that follow a continous order and start at FONT_FIRST_CHAR, // this sytem can be improved to support any characters order and init value... @@ -514,9 +514,9 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar) Color *pixels = GetImageData(image); // Parse image data to get charSpacing and lineSpacing - for(y = 0; y < image.height; y++) + for (y = 0; y < image.height; y++) { - for(x = 0; x < image.width; x++) + for (x = 0; x < image.width; x++) { if (!COLOR_EQUAL(pixels[y*image.width + x], key)) break; } @@ -529,7 +529,7 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar) int charHeight = 0; int j = 0; - while(!COLOR_EQUAL(pixels[(lineSpacing + j)*image.width + charSpacing], key)) j++; + while (!COLOR_EQUAL(pixels[(lineSpacing + j)*image.width + charSpacing], key)) j++; charHeight = j; @@ -539,9 +539,9 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar) int xPosToRead = charSpacing; // Parse image data to get rectangle sizes - while((lineSpacing + lineToRead * (charHeight + lineSpacing)) < image.height) + while ((lineSpacing + lineToRead * (charHeight + lineSpacing)) < image.height) { - while((xPosToRead < image.width) && + while ((xPosToRead < image.width) && !COLOR_EQUAL((pixels[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*image.width + xPosToRead]), key)) { tempCharValues[index] = firstChar + index; @@ -552,7 +552,7 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar) int charWidth = 0; - while(!COLOR_EQUAL(pixels[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*image.width + xPosToRead + charWidth], key)) charWidth++; + while (!COLOR_EQUAL(pixels[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*image.width + xPosToRead + charWidth], key)) charWidth++; tempCharRecs[index].width = charWidth; @@ -648,11 +648,11 @@ static SpriteFont LoadRBMF(const char *fileName) rbmfFileData = (unsigned int *)malloc(numPixelBits * sizeof(unsigned int)); - for(int i = 0; i < numPixelBits; i++) fread(&rbmfFileData[i], sizeof(unsigned int), 1, rbmfFile); + for (int i = 0; i < numPixelBits; i++) fread(&rbmfFileData[i], sizeof(unsigned int), 1, rbmfFile); rbmfCharWidthData = (unsigned char *)malloc(spriteFont.numChars * sizeof(unsigned char)); - for(int i = 0; i < spriteFont.numChars; i++) fread(&rbmfCharWidthData[i], sizeof(unsigned char), 1, rbmfFile); + for (int i = 0; i < spriteFont.numChars; i++) fread(&rbmfCharWidthData[i], sizeof(unsigned char), 1, rbmfFile); // Re-construct image from rbmfFileData //----------------------------------------- diff --git a/src/textures.c b/src/textures.c index 8f4fa301..4d9fc6b0 100644 --- a/src/textures.c +++ b/src/textures.c @@ -1612,7 +1612,7 @@ static Image LoadDDS(const char *fileName) image.mipmaps = header.mipmapCount; - switch(header.ddspf.fourCC) + switch (header.ddspf.fourCC) { case FOURCC_DXT1: { -- cgit v1.2.3 From 7f0880a73580c14312e18966d8aae568b7a3f7cb Mon Sep 17 00:00:00 2001 From: raysan5 Date: Mon, 12 Sep 2016 19:36:41 +0200 Subject: Review spacing formatting raylib uses spaces between '+' and '-' signs but not between '*' and '/' signs, it's a chosen convention --- src/audio.c | 2 +- src/core.c | 2 +- src/models.c | 144 ++++++++++++++++++++++++++++++--------------------------- src/rlgl.c | 8 ++-- src/shapes.c | 10 ++-- src/text.c | 20 ++++---- src/textures.c | 4 +- 7 files changed, 99 insertions(+), 91 deletions(-) (limited to 'src/core.c') diff --git a/src/audio.c b/src/audio.c index fa18f7c8..06bf55d4 100644 --- a/src/audio.c +++ b/src/audio.c @@ -482,7 +482,7 @@ void PlaySound(Sound sound) //int sampleRate; //alGetBufferi(sound.buffer, AL_FREQUENCY, &sampleRate); // AL_CHANNELS, AL_BITS (bps) - //float seconds = (float)byteOffset / sampleRate; // Number of seconds since the beginning of the sound + //float seconds = (float)byteOffset/sampleRate; // Number of seconds since the beginning of the sound //or //float result; //alGetSourcef(sound.source, AL_SEC_OFFSET, &result); // AL_SAMPLE_OFFSET diff --git a/src/core.c b/src/core.c index b9ffe87b..d5b07e7a 100644 --- a/src/core.c +++ b/src/core.c @@ -1016,7 +1016,7 @@ Vector2 GetWorldToScreen(Vector3 position, Camera camera) QuaternionTransform(&worldPos, matProj); // Calculate normalized device coordinates (inverted y) - Vector3 ndcPos = { worldPos.x / worldPos.w, -worldPos.y / worldPos.w, worldPos.z / worldPos.z }; + Vector3 ndcPos = { worldPos.x/worldPos.w, -worldPos.y/worldPos.w, worldPos.z/worldPos.z }; // Calculate 2d screen position vector Vector2 screenPosition = { (ndcPos.x + 1.0f)/2.0f*(float)GetScreenWidth(), (ndcPos.y + 1.0f)/2.0f*(float)GetScreenHeight() }; diff --git a/src/models.c b/src/models.c index 25eb1fe0..8195c5f6 100644 --- a/src/models.c +++ b/src/models.c @@ -88,7 +88,7 @@ void DrawCircle3D(Vector3 center, float radius, float rotationAngle, Vector3 rot rlColor4ub(color.r, color.g, color.b, color.a); rlVertex3f(sin(DEG2RAD*i)*radius, cos(DEG2RAD*i)*radius, 0.0f); - rlVertex3f(sin(DEG2RAD*(i + 10)) * radius, cos(DEG2RAD*(i + 10)) * radius, 0.0f); + rlVertex3f(sin(DEG2RAD*(i + 10))*radius, cos(DEG2RAD*(i + 10))*radius, 0.0f); } rlEnd(); rlPopMatrix(); @@ -325,25 +325,25 @@ void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color { for (int j = 0; j < slices; j++) { - rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*i)) * sin(DEG2RAD*(j*360/slices)), + rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*i))*sin(DEG2RAD*(j*360/slices)), sin(DEG2RAD*(270+(180/(rings + 1))*i)), - cos(DEG2RAD*(270+(180/(rings + 1))*i)) * cos(DEG2RAD*(j*360/slices))); - rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1))) * sin(DEG2RAD*((j+1)*360/slices)), + cos(DEG2RAD*(270+(180/(rings + 1))*i))*cos(DEG2RAD*(j*360/slices))); + rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sin(DEG2RAD*((j+1)*360/slices)), sin(DEG2RAD*(270+(180/(rings + 1))*(i+1))), - cos(DEG2RAD*(270+(180/(rings + 1))*(i+1))) * cos(DEG2RAD*((j+1)*360/slices))); - rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1))) * sin(DEG2RAD*(j*360/slices)), + cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cos(DEG2RAD*((j+1)*360/slices))); + rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sin(DEG2RAD*(j*360/slices)), sin(DEG2RAD*(270+(180/(rings + 1))*(i+1))), - cos(DEG2RAD*(270+(180/(rings + 1))*(i+1))) * cos(DEG2RAD*(j*360/slices))); + cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cos(DEG2RAD*(j*360/slices))); - rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*i)) * sin(DEG2RAD*(j*360/slices)), + rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*i))*sin(DEG2RAD*(j*360/slices)), sin(DEG2RAD*(270+(180/(rings + 1))*i)), - cos(DEG2RAD*(270+(180/(rings + 1))*i)) * cos(DEG2RAD*(j*360/slices))); - rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i))) * sin(DEG2RAD*((j+1)*360/slices)), + cos(DEG2RAD*(270+(180/(rings + 1))*i))*cos(DEG2RAD*(j*360/slices))); + rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i)))*sin(DEG2RAD*((j+1)*360/slices)), sin(DEG2RAD*(270+(180/(rings + 1))*(i))), - cos(DEG2RAD*(270+(180/(rings + 1))*(i))) * cos(DEG2RAD*((j+1)*360/slices))); - rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1))) * sin(DEG2RAD*((j+1)*360/slices)), + cos(DEG2RAD*(270+(180/(rings + 1))*(i)))*cos(DEG2RAD*((j+1)*360/slices))); + rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sin(DEG2RAD*((j+1)*360/slices)), sin(DEG2RAD*(270+(180/(rings + 1))*(i+1))), - cos(DEG2RAD*(270+(180/(rings + 1))*(i+1))) * cos(DEG2RAD*((j+1)*360/slices))); + cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cos(DEG2RAD*((j+1)*360/slices))); } } rlEnd(); @@ -364,26 +364,26 @@ void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Col { for (int j = 0; j < slices; j++) { - rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*i)) * sin(DEG2RAD*(j*360/slices)), + rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*i))*sin(DEG2RAD*(j*360/slices)), sin(DEG2RAD*(270+(180/(rings + 1))*i)), - cos(DEG2RAD*(270+(180/(rings + 1))*i)) * cos(DEG2RAD*(j*360/slices))); - rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1))) * sin(DEG2RAD*((j+1)*360/slices)), + cos(DEG2RAD*(270+(180/(rings + 1))*i))*cos(DEG2RAD*(j*360/slices))); + rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sin(DEG2RAD*((j+1)*360/slices)), sin(DEG2RAD*(270+(180/(rings + 1))*(i+1))), - cos(DEG2RAD*(270+(180/(rings + 1))*(i+1))) * cos(DEG2RAD*((j+1)*360/slices))); + cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cos(DEG2RAD*((j+1)*360/slices))); - rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1))) * sin(DEG2RAD*((j+1)*360/slices)), + rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sin(DEG2RAD*((j+1)*360/slices)), sin(DEG2RAD*(270+(180/(rings + 1))*(i+1))), - cos(DEG2RAD*(270+(180/(rings + 1))*(i+1))) * cos(DEG2RAD*((j+1)*360/slices))); - rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1))) * sin(DEG2RAD*(j*360/slices)), + cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cos(DEG2RAD*((j+1)*360/slices))); + rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sin(DEG2RAD*(j*360/slices)), sin(DEG2RAD*(270+(180/(rings + 1))*(i+1))), - cos(DEG2RAD*(270+(180/(rings + 1))*(i+1))) * cos(DEG2RAD*(j*360/slices))); + cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cos(DEG2RAD*(j*360/slices))); - rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1))) * sin(DEG2RAD*(j*360/slices)), + rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sin(DEG2RAD*(j*360/slices)), sin(DEG2RAD*(270+(180/(rings + 1))*(i+1))), - cos(DEG2RAD*(270+(180/(rings + 1))*(i+1))) * cos(DEG2RAD*(j*360/slices))); - rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*i)) * sin(DEG2RAD*(j*360/slices)), + cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cos(DEG2RAD*(j*360/slices))); + rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*i))*sin(DEG2RAD*(j*360/slices)), sin(DEG2RAD*(270+(180/(rings + 1))*i)), - cos(DEG2RAD*(270+(180/(rings + 1))*i)) * cos(DEG2RAD*(j*360/slices))); + cos(DEG2RAD*(270+(180/(rings + 1))*i))*cos(DEG2RAD*(j*360/slices))); } } rlEnd(); @@ -407,21 +407,21 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h // Draw Body ------------------------------------------------------------------------------------- for (int i = 0; i < 360; i += 360/sides) { - rlVertex3f(sin(DEG2RAD*i) * radiusBottom, 0, cos(DEG2RAD*i) * radiusBottom); //Bottom Left - rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusBottom, 0, cos(DEG2RAD*(i+360/sides)) * radiusBottom); //Bottom Right - rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusTop, height, cos(DEG2RAD*(i+360/sides)) * radiusTop); //Top Right + rlVertex3f(sin(DEG2RAD*i)*radiusBottom, 0, cos(DEG2RAD*i)*radiusBottom); //Bottom Left + rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusBottom, 0, cos(DEG2RAD*(i+360/sides))*radiusBottom); //Bottom Right + rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusTop, height, cos(DEG2RAD*(i+360/sides))*radiusTop); //Top Right - rlVertex3f(sin(DEG2RAD*i) * radiusTop, height, cos(DEG2RAD*i) * radiusTop); //Top Left - rlVertex3f(sin(DEG2RAD*i) * radiusBottom, 0, cos(DEG2RAD*i) * radiusBottom); //Bottom Left - rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusTop, height, cos(DEG2RAD*(i+360/sides)) * radiusTop); //Top Right + rlVertex3f(sin(DEG2RAD*i)*radiusTop, height, cos(DEG2RAD*i)*radiusTop); //Top Left + rlVertex3f(sin(DEG2RAD*i)*radiusBottom, 0, cos(DEG2RAD*i)*radiusBottom); //Bottom Left + rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusTop, height, cos(DEG2RAD*(i+360/sides))*radiusTop); //Top Right } // Draw Cap -------------------------------------------------------------------------------------- for (int i = 0; i < 360; i += 360/sides) { rlVertex3f(0, height, 0); - rlVertex3f(sin(DEG2RAD*i) * radiusTop, height, cos(DEG2RAD*i) * radiusTop); - rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusTop, height, cos(DEG2RAD*(i+360/sides)) * radiusTop); + rlVertex3f(sin(DEG2RAD*i)*radiusTop, height, cos(DEG2RAD*i)*radiusTop); + rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusTop, height, cos(DEG2RAD*(i+360/sides))*radiusTop); } } else @@ -430,8 +430,8 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h for (int i = 0; i < 360; i += 360/sides) { rlVertex3f(0, height, 0); - rlVertex3f(sin(DEG2RAD*i) * radiusBottom, 0, cos(DEG2RAD*i) * radiusBottom); - rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusBottom, 0, cos(DEG2RAD*(i+360/sides)) * radiusBottom); + rlVertex3f(sin(DEG2RAD*i)*radiusBottom, 0, cos(DEG2RAD*i)*radiusBottom); + rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusBottom, 0, cos(DEG2RAD*(i+360/sides))*radiusBottom); } } @@ -439,8 +439,8 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h for (int i = 0; i < 360; i += 360/sides) { rlVertex3f(0, 0, 0); - rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusBottom, 0, cos(DEG2RAD*(i+360/sides)) * radiusBottom); - rlVertex3f(sin(DEG2RAD*i) * radiusBottom, 0, cos(DEG2RAD*i) * radiusBottom); + rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusBottom, 0, cos(DEG2RAD*(i+360/sides))*radiusBottom); + rlVertex3f(sin(DEG2RAD*i)*radiusBottom, 0, cos(DEG2RAD*i)*radiusBottom); } rlEnd(); rlPopMatrix(); @@ -460,17 +460,17 @@ void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, fl for (int i = 0; i < 360; i += 360/sides) { - rlVertex3f(sin(DEG2RAD*i) * radiusBottom, 0, cos(DEG2RAD*i) * radiusBottom); - rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusBottom, 0, cos(DEG2RAD*(i+360/sides)) * radiusBottom); + rlVertex3f(sin(DEG2RAD*i)*radiusBottom, 0, cos(DEG2RAD*i)*radiusBottom); + rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusBottom, 0, cos(DEG2RAD*(i+360/sides))*radiusBottom); - rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusBottom, 0, cos(DEG2RAD*(i+360/sides)) * radiusBottom); - rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusTop, height, cos(DEG2RAD*(i+360/sides)) * radiusTop); + rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusBottom, 0, cos(DEG2RAD*(i+360/sides))*radiusBottom); + rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusTop, height, cos(DEG2RAD*(i+360/sides))*radiusTop); - rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusTop, height, cos(DEG2RAD*(i+360/sides)) * radiusTop); - rlVertex3f(sin(DEG2RAD*i) * radiusTop, height, cos(DEG2RAD*i) * radiusTop); + rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusTop, height, cos(DEG2RAD*(i+360/sides))*radiusTop); + rlVertex3f(sin(DEG2RAD*i)*radiusTop, height, cos(DEG2RAD*i)*radiusTop); - rlVertex3f(sin(DEG2RAD*i) * radiusTop, height, cos(DEG2RAD*i) * radiusTop); - rlVertex3f(sin(DEG2RAD*i) * radiusBottom, 0, cos(DEG2RAD*i) * radiusBottom); + rlVertex3f(sin(DEG2RAD*i)*radiusTop, height, cos(DEG2RAD*i)*radiusTop); + rlVertex3f(sin(DEG2RAD*i)*radiusBottom, 0, cos(DEG2RAD*i)*radiusBottom); } rlEnd(); rlPopMatrix(); @@ -516,7 +516,7 @@ void DrawRay(Ray ray, Color color) // Draw a grid centered at (0, 0, 0) void DrawGrid(int slices, float spacing) { - int halfSlices = slices / 2; + int halfSlices = slices/2; rlBegin(RL_LINES); for (int i = -halfSlices; i <= halfSlices; i++) @@ -577,22 +577,30 @@ void DrawLight(Light light) { case LIGHT_POINT: { - DrawSphereWires(light->position, 0.3f*light->intensity, 4, 8, (light->enabled ? light->diffuse : BLACK)); - DrawCircle3D(light->position, light->radius, 0.0f, (Vector3){ 0, 0, 0 }, (light->enabled ? light->diffuse : BLACK)); - DrawCircle3D(light->position, light->radius, 90.0f, (Vector3){ 1, 0, 0 }, (light->enabled ? light->diffuse : BLACK)); - DrawCircle3D(light->position, light->radius, 90.0f, (Vector3){ 0, 1, 0 }, (light->enabled ? light->diffuse : BLACK)); + DrawSphereWires(light->position, 0.3f*light->intensity, 8, 8, (light->enabled ? light->diffuse : GRAY)); + + DrawCircle3D(light->position, light->radius, 0.0f, (Vector3){ 0, 0, 0 }, (light->enabled ? light->diffuse : GRAY)); + DrawCircle3D(light->position, light->radius, 90.0f, (Vector3){ 1, 0, 0 }, (light->enabled ? light->diffuse : GRAY)); + DrawCircle3D(light->position, light->radius, 90.0f, (Vector3){ 0, 1, 0 }, (light->enabled ? light->diffuse : GRAY)); } break; case LIGHT_DIRECTIONAL: { - DrawLine3D(light->position, light->target, (light->enabled ? light->diffuse : BLACK)); - DrawSphereWires(light->position, 0.3f*light->intensity, 4, 8, (light->enabled ? light->diffuse : BLACK)); - DrawCubeWires(light->target, 0.3f, 0.3f, 0.3f, (light->enabled ? light->diffuse : BLACK)); + DrawLine3D(light->position, light->target, (light->enabled ? light->diffuse : GRAY)); + + DrawSphereWires(light->position, 0.3f*light->intensity, 8, 8, (light->enabled ? light->diffuse : GRAY)); + DrawCubeWires(light->target, 0.3f, 0.3f, 0.3f, (light->enabled ? light->diffuse : GRAY)); } break; case LIGHT_SPOT: { - DrawLine3D(light->position, light->target, (light->enabled ? light->diffuse : BLACK)); - DrawCylinderWires(light->position, 0.0f, 0.3f*light->coneAngle/50, 0.6f, 5, (light->enabled ? light->diffuse : BLACK)); - DrawCubeWires(light->target, 0.3f, 0.3f, 0.3f, (light->enabled ? light->diffuse : BLACK)); + DrawLine3D(light->position, light->target, (light->enabled ? light->diffuse : GRAY)); + + Vector3 dir = VectorSubtract(light->target, light->position); + VectorNormalize(&dir); + + DrawCircle3D(light->position, 0.5f, 0.0f, dir, (light->enabled ? light->diffuse : GRAY)); + + //DrawCylinderWires(light->position, 0.0f, 0.3f*light->coneAngle/50, 0.6f, 5, (light->enabled ? light->diffuse : GRAY)); + DrawCubeWires(light->target, 0.3f, 0.3f, 0.3f, (light->enabled ? light->diffuse : GRAY)); } break; default: break; } @@ -1361,19 +1369,19 @@ void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vec rlColor4ub(tint.r, tint.g, tint.b, tint.a); // Bottom-left corner for texture and quad - rlTexCoord2f((float)sourceRec.x / texture.width, (float)sourceRec.y / texture.height); + rlTexCoord2f((float)sourceRec.x/texture.width, (float)sourceRec.y/texture.height); rlVertex3f(a.x, a.y, a.z); // Top-left corner for texture and quad - rlTexCoord2f((float)sourceRec.x / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height); + rlTexCoord2f((float)sourceRec.x/texture.width, (float)(sourceRec.y + sourceRec.height)/texture.height); rlVertex3f(d.x, d.y, d.z); // Top-right corner for texture and quad - rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height); + rlTexCoord2f((float)(sourceRec.x + sourceRec.width)/texture.width, (float)(sourceRec.y + sourceRec.height)/texture.height); rlVertex3f(c.x, c.y, c.z); // Bottom-right corner for texture and quad - rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)sourceRec.y / texture.height); + rlTexCoord2f((float)(sourceRec.x + sourceRec.width)/texture.width, (float)sourceRec.y/texture.height); rlVertex3f(b.x, b.y, b.z); rlEnd(); @@ -1693,8 +1701,8 @@ Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *p else playerPosition->z = locationCellY + mapPosition.z - (CUBIC_MAP_HALF_BLOCK_SIZE - radius); // Return ricochet - if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius / 3) && - ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius / 3)) + if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius/3) && + ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius/3)) { impactDirection = (Vector3){ 1.0f, 0.0f, 1.0f }; } @@ -1716,8 +1724,8 @@ Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *p else playerPosition->z = locationCellY + mapPosition.z + (CUBIC_MAP_HALF_BLOCK_SIZE - radius); // Return ricochet - if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius / 3) && - ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius / 3)) + if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius/3) && + ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius/3)) { impactDirection = (Vector3){ 1.0f, 0.0f, 1.0f }; } @@ -1739,8 +1747,8 @@ Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *p else playerPosition->z = locationCellY + mapPosition.z - (CUBIC_MAP_HALF_BLOCK_SIZE - radius); // Return ricochet - if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius / 3) && - ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius / 3)) + if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius/3) && + ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius/3)) { impactDirection = (Vector3){ 1.0f, 0.0f, 1.0f }; } @@ -1762,8 +1770,8 @@ Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *p else playerPosition->z = locationCellY + mapPosition.z + (CUBIC_MAP_HALF_BLOCK_SIZE - radius); // Return ricochet - if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius / 3) && - ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius / 3)) + if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius/3) && + ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius/3)) { impactDirection = (Vector3){ 1.0f, 0.0f, 1.0f }; } diff --git a/src/rlgl.c b/src/rlgl.c index 518f2a66..244de52c 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -708,7 +708,7 @@ void rlVertex3f(float x, float y, float z) case RL_LINES: { // Verify that MAX_LINES_BATCH limit not reached - if (lines.vCounter / 2 < MAX_LINES_BATCH) + if (lines.vCounter/2 < MAX_LINES_BATCH) { lines.vertices[3*lines.vCounter] = x; lines.vertices[3*lines.vCounter + 1] = y; @@ -722,7 +722,7 @@ void rlVertex3f(float x, float y, float z) case RL_TRIANGLES: { // Verify that MAX_TRIANGLES_BATCH limit not reached - if (triangles.vCounter / 3 < MAX_TRIANGLES_BATCH) + if (triangles.vCounter/3 < MAX_TRIANGLES_BATCH) { triangles.vertices[3*triangles.vCounter] = x; triangles.vertices[3*triangles.vCounter + 1] = y; @@ -736,7 +736,7 @@ void rlVertex3f(float x, float y, float z) case RL_QUADS: { // Verify that MAX_QUADS_BATCH limit not reached - if (quads.vCounter / 4 < MAX_QUADS_BATCH) + if (quads.vCounter/4 < MAX_QUADS_BATCH) { quads.vertices[3*quads.vCounter] = x; quads.vertices[3*quads.vCounter + 1] = y; @@ -3542,7 +3542,7 @@ static void DrawDefaultBuffers(int eyesCount) for (int i = 0; i < drawsCounter; i++) { quadsCount = draws[i].vertexCount/4; - numIndicesToProcess = quadsCount*6; // Get number of Quads * 6 index by Quad + numIndicesToProcess = quadsCount*6; // Get number of Quads*6 index by Quad //TraceLog(DEBUG, "Quads to render: %i - Vertex Count: %i", quadsCount, draws[i].vertexCount); diff --git a/src/shapes.c b/src/shapes.c index d9b172f1..6200a823 100644 --- a/src/shapes.c +++ b/src/shapes.c @@ -113,7 +113,7 @@ void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Co rlColor4ub(color2.r, color2.g, color2.b, color2.a); rlVertex2f(centerX + sin(DEG2RAD*i)*radius, centerY + cos(DEG2RAD*i)*radius); rlColor4ub(color2.r, color2.g, color2.b, color2.a); - rlVertex2f(centerX + sin(DEG2RAD*(i + 10)) * radius, centerY + cos(DEG2RAD*(i + 10))*radius); + rlVertex2f(centerX + sin(DEG2RAD*(i + 10))*radius, centerY + cos(DEG2RAD*(i + 10))*radius); } rlEnd(); } @@ -131,7 +131,7 @@ void DrawCircleV(Vector2 center, float radius, Color color) rlVertex2i(center.x, center.y); rlVertex2f(center.x + sin(DEG2RAD*i)*radius, center.y + cos(DEG2RAD*i)*radius); - rlVertex2f(center.x + sin(DEG2RAD*(i + 10)) * radius, center.y + cos(DEG2RAD*(i + 10)) * radius); + rlVertex2f(center.x + sin(DEG2RAD*(i + 10))*radius, center.y + cos(DEG2RAD*(i + 10))*radius); } rlEnd(); } @@ -146,8 +146,8 @@ void DrawCircleV(Vector2 center, float radius, Color color) rlVertex2i(center.x, center.y); rlVertex2f(center.x + sin(DEG2RAD*i)*radius, center.y + cos(DEG2RAD*i)*radius); - rlVertex2f(center.x + sin(DEG2RAD*(i + 10)) * radius, center.y + cos(DEG2RAD*(i + 10)) * radius); - rlVertex2f(center.x + sin(DEG2RAD*(i + 20)) * radius, center.y + cos(DEG2RAD*(i + 20)) * radius); + rlVertex2f(center.x + sin(DEG2RAD*(i + 10))*radius, center.y + cos(DEG2RAD*(i + 10))*radius); + rlVertex2f(center.x + sin(DEG2RAD*(i + 20))*radius, center.y + cos(DEG2RAD*(i + 20))*radius); } rlEnd(); @@ -165,7 +165,7 @@ void DrawCircleLines(int centerX, int centerY, float radius, Color color) for (int i = 0; i < 360; i += 10) { rlVertex2f(centerX + sin(DEG2RAD*i)*radius, centerY + cos(DEG2RAD*i)*radius); - rlVertex2f(centerX + sin(DEG2RAD*(i + 10)) * radius, centerY + cos(DEG2RAD*(i + 10))*radius); + rlVertex2f(centerX + sin(DEG2RAD*(i + 10))*radius, centerY + cos(DEG2RAD*(i + 10))*radius); } rlEnd(); } diff --git a/src/text.c b/src/text.c index d00f01d7..c538ea56 100644 --- a/src/text.c +++ b/src/text.c @@ -201,7 +201,7 @@ extern void LoadDefaultFont(void) defaultFont.charValues[i] = FONT_FIRST_CHAR + i; // First char is 32 defaultFont.charRecs[i].x = currentPosX; - defaultFont.charRecs[i].y = charsDivisor + currentLine * (charsHeight + charsDivisor); + defaultFont.charRecs[i].y = charsDivisor + currentLine*(charsHeight + charsDivisor); defaultFont.charRecs[i].width = charsWidth[i]; defaultFont.charRecs[i].height = charsHeight; @@ -297,7 +297,7 @@ void DrawText(const char *text, int posX, int posY, int fontSize, Color color) int defaultFontSize = 10; // Default Font chars height in pixel if (fontSize < defaultFontSize) fontSize = defaultFontSize; - int spacing = fontSize / defaultFontSize; + int spacing = fontSize/defaultFontSize; DrawTextEx(defaultFont, text, position, (float)fontSize, spacing, color); } @@ -408,7 +408,7 @@ int MeasureText(const char *text, int fontSize) int defaultFontSize = 10; // Default Font chars height in pixel if (fontSize < defaultFontSize) fontSize = defaultFontSize; - int spacing = fontSize / defaultFontSize; + int spacing = fontSize/defaultFontSize; vec = MeasureTextEx(defaultFont, text, fontSize, spacing); @@ -539,7 +539,7 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar) int xPosToRead = charSpacing; // Parse image data to get rectangle sizes - while ((lineSpacing + lineToRead * (charHeight + lineSpacing)) < image.height) + while ((lineSpacing + lineToRead*(charHeight + lineSpacing)) < image.height) { while ((xPosToRead < image.width) && !COLOR_EQUAL((pixels[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*image.width + xPosToRead]), key)) @@ -547,7 +547,7 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar) tempCharValues[index] = firstChar + index; tempCharRecs[index].x = xPosToRead; - tempCharRecs[index].y = lineSpacing + lineToRead * (charHeight + lineSpacing); + tempCharRecs[index].y = lineSpacing + lineToRead*(charHeight + lineSpacing); tempCharRecs[index].height = charHeight; int charWidth = 0; @@ -646,11 +646,11 @@ static SpriteFont LoadRBMF(const char *fileName) int numPixelBits = rbmfHeader.imgWidth*rbmfHeader.imgHeight/32; - rbmfFileData = (unsigned int *)malloc(numPixelBits * sizeof(unsigned int)); + rbmfFileData = (unsigned int *)malloc(numPixelBits*sizeof(unsigned int)); for (int i = 0; i < numPixelBits; i++) fread(&rbmfFileData[i], sizeof(unsigned int), 1, rbmfFile); - rbmfCharWidthData = (unsigned char *)malloc(spriteFont.numChars * sizeof(unsigned char)); + rbmfCharWidthData = (unsigned char *)malloc(spriteFont.numChars*sizeof(unsigned char)); for (int i = 0; i < spriteFont.numChars; i++) fread(&rbmfCharWidthData[i], sizeof(unsigned char), 1, rbmfFile); @@ -701,7 +701,7 @@ static SpriteFont LoadRBMF(const char *fileName) spriteFont.charValues[i] = (int)rbmfHeader.firstChar + i; spriteFont.charRecs[i].x = currentPosX; - spriteFont.charRecs[i].y = charsDivisor + currentLine * ((int)rbmfHeader.charHeight + charsDivisor); + spriteFont.charRecs[i].y = charsDivisor + currentLine*((int)rbmfHeader.charHeight + charsDivisor); spriteFont.charRecs[i].width = (int)rbmfCharWidthData[i]; spriteFont.charRecs[i].height = (int)rbmfHeader.charHeight; @@ -714,11 +714,11 @@ static SpriteFont LoadRBMF(const char *fileName) if (testPosX > spriteFont.texture.width) { currentLine++; - currentPosX = 2 * charsDivisor + (int)rbmfCharWidthData[i]; + currentPosX = 2*charsDivisor + (int)rbmfCharWidthData[i]; testPosX = currentPosX; spriteFont.charRecs[i].x = charsDivisor; - spriteFont.charRecs[i].y = charsDivisor + currentLine * (rbmfHeader.charHeight + charsDivisor); + spriteFont.charRecs[i].y = charsDivisor + currentLine*(rbmfHeader.charHeight + charsDivisor); } else currentPosX = testPosX; } diff --git a/src/textures.c b/src/textures.c index 15293371..d4dd2ac2 100644 --- a/src/textures.c +++ b/src/textures.c @@ -1765,7 +1765,7 @@ static Image LoadPKM(const char *fileName) int size = image.width*image.height*bpp/8; // Total data size in bytes - image.data = (unsigned char*)malloc(size * sizeof(unsigned char)); + image.data = (unsigned char*)malloc(size*sizeof(unsigned char)); fread(image.data, 1, size, pkmFile); @@ -1858,7 +1858,7 @@ static Image LoadKTX(const char *fileName) int dataSize; fread(&dataSize, sizeof(unsigned int), 1, ktxFile); - image.data = (unsigned char*)malloc(dataSize * sizeof(unsigned char)); + image.data = (unsigned char*)malloc(dataSize*sizeof(unsigned char)); fread(image.data, 1, dataSize, ktxFile); -- cgit v1.2.3 From 87fc7254e725f4e5c5137b31d1dfe56be8e22cf0 Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 23 Sep 2016 23:25:13 +0200 Subject: Corrected crashing bug! When SetTargetFPS(0) app crashes horribly (division by zero) --- src/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/core.c') diff --git a/src/core.c b/src/core.c index d5b07e7a..63c880f1 100644 --- a/src/core.c +++ b/src/core.c @@ -689,7 +689,8 @@ void EndTextureMode(void) // Set target FPS for the game void SetTargetFPS(int fps) { - targetTime = 1.0/(double)fps; + if (fps < 1) targetTime = 0.0; + else targetTime = 1.0/(double)fps; TraceLog(INFO, "Target time per frame: %02.03f milliseconds", (float)targetTime*1000); } -- cgit v1.2.3 From db6538859cd2fabb44f1f29cd87f5b498ca0c2c8 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 5 Oct 2016 00:48:44 +0200 Subject: Added flag to allow resizable window --- src/core.c | 21 +++++++++++++-------- src/raylib.h | 11 ++++++----- 2 files changed, 19 insertions(+), 13 deletions(-) (limited to 'src/core.c') diff --git a/src/core.c b/src/core.c index 63c880f1..0db1c573 100644 --- a/src/core.c +++ b/src/core.c @@ -1483,15 +1483,20 @@ static void InitGraphicsDevice(int width, int height) displayHeight = screenHeight; #endif // defined(PLATFORM_WEB) - glfwDefaultWindowHints(); // Set default windows hints + glfwDefaultWindowHints(); // Set default windows hints - glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Avoid window being resizable - //glfwWindowHint(GLFW_DECORATED, GL_TRUE); // Border and buttons on Window - //glfwWindowHint(GLFW_RED_BITS, 8); // Framebuffer red color component bits - //glfwWindowHint(GLFW_DEPTH_BITS, 16); // Depthbuffer bits (24 by default) - //glfwWindowHint(GLFW_REFRESH_RATE, 0); // Refresh rate for fullscreen window + if (configFlags & FLAG_RESIZABLE_WINDOW) + { + glfwWindowHint(GLFW_RESIZABLE, GL_TRUE); // Resizable window + } + else glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Avoid window being resizable + + //glfwWindowHint(GLFW_DECORATED, GL_TRUE); // Border and buttons on Window + //glfwWindowHint(GLFW_RED_BITS, 8); // Framebuffer red color component bits + //glfwWindowHint(GLFW_DEPTH_BITS, 16); // Depthbuffer bits (24 by default) + //glfwWindowHint(GLFW_REFRESH_RATE, 0); // Refresh rate for fullscreen window //glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API); // Default OpenGL API to use. Alternative: GLFW_OPENGL_ES_API - //glfwWindowHint(GLFW_AUX_BUFFERS, 0); // Number of auxiliar buffers + //glfwWindowHint(GLFW_AUX_BUFFERS, 0); // Number of auxiliar buffers // NOTE: When asking for an OpenGL context version, most drivers provide highest supported version // with forward compatibility to older OpenGL versions. @@ -1499,7 +1504,7 @@ static void InitGraphicsDevice(int width, int height) if (configFlags & FLAG_MSAA_4X_HINT) { - glfwWindowHint(GLFW_SAMPLES, 4); // Enables multisampling x4 (MSAA), default is 0 + glfwWindowHint(GLFW_SAMPLES, 4); // Enables multisampling x4 (MSAA), default is 0 TraceLog(INFO, "Trying to enable MSAA x4"); } diff --git a/src/raylib.h b/src/raylib.h index d022e8f5..e6e510a9 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -101,11 +101,12 @@ // raylib Config Flags #define FLAG_FULLSCREEN_MODE 1 -#define FLAG_SHOW_LOGO 2 -#define FLAG_SHOW_MOUSE_CURSOR 4 -#define FLAG_CENTERED_MODE 8 -#define FLAG_MSAA_4X_HINT 16 -#define FLAG_VSYNC_HINT 32 +#define FLAG_RESIZABLE_WINDOW 2 +#define FLAG_SHOW_LOGO 4 +#define FLAG_SHOW_MOUSE_CURSOR 8 +#define FLAG_CENTERED_MODE 16 +#define FLAG_MSAA_4X_HINT 32 +#define FLAG_VSYNC_HINT 64 // Keyboard Function Keys #define KEY_SPACE 32 -- cgit v1.2.3