summaryrefslogtreecommitdiffhomepage
path: root/src/core.c
diff options
context:
space:
mode:
authorRay <[email protected]>2016-10-16 18:24:13 +0200
committerGitHub <[email protected]>2016-10-16 18:24:13 +0200
commita9315fc422a3a036891f50f0c2be5059c3db8b31 (patch)
tree9f5213dac656079e2163bc5d091200dc837672b8 /src/core.c
parent53056f3e7e84e18b8ebfc4a2ab2f7f1fbe7ae36c (diff)
parent1c05017548ea21dd1a44c31e9fc80b8700891f11 (diff)
downloadraylib-a9315fc422a3a036891f50f0c2be5059c3db8b31.tar.gz
raylib-a9315fc422a3a036891f50f0c2be5059c3db8b31.zip
Merge pull request #189 from raysan5/develop
Develop branch integration
Diffstat (limited to 'src/core.c')
-rw-r--r--src/core.c577
1 files changed, 307 insertions, 270 deletions
diff --git a/src/core.c b/src/core.c
index a3253d79..3bd85fdd 100644
--- a/src/core.c
+++ b/src/core.c
@@ -18,6 +18,10 @@
*
* On PLATFORM_RPI, graphic device is managed by EGL and input system is coded in raw mode.
*
+* Module Configuration Flags:
+*
+* RL_LOAD_DEFAULT_FONT - Use external module functions to load default raylib font (module: text)
+*
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
@@ -39,13 +43,20 @@
#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
+
+#if !defined(PLATFORM_ANDROID)
+ #define CAMERA_IMPLEMENTATION
+ #include "camera.h" // Camera system functionality
+#endif
+
#include <stdio.h> // Standard input / output lib
#include <stdlib.h> // Declares malloc() and free() for memory management, rand(), atexit()
#include <stdint.h> // Required for typedef unsigned long long int uint64_t, used by hi-res timer
@@ -115,14 +126,16 @@
//#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)
#endif
+#define MAX_GAMEPADS 4 // 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)
+
+#define RL_LOAD_DEFAULT_FONT // Load default font on window initialization (module: text)
+
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
@@ -161,15 +174,11 @@ static int defaultKeyboardMode; // Used to store default keyboar
// Mouse input variables
static int mouseStream = -1; // Mouse device file descriptor
static bool mouseReady = false; // Flag to know if mouse is ready
-pthread_t mouseThreadId; // Mouse reading thread id
+static pthread_t mouseThreadId; // Mouse reading thread id
// Gamepad input variables
-static int gamepadStream[MAX_GAMEPADS] = { -1 }; // Gamepad device file descriptor (two gamepads supported)
-static bool gamepadReady[MAX_GAMEPADS] = { false }; // Flag to know if gamepad is ready (two gamepads supported)
-pthread_t gamepadThreadId; // Gamepad reading thread id
-
-int gamepadButtons[MAX_GAMEPADS][MAX_GAMEPAD_BUTTONS]; // Gamepad buttons state
-float gamepadAxisValues[MAX_GAMEPADS][MAX_GAMEPAD_AXIS]; // Gamepad axis state
+static int gamepadStream[MAX_GAMEPADS] = { -1 };// Gamepad device file descriptor
+static pthread_t gamepadThreadId; // Gamepad reading thread id
#endif
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
@@ -194,18 +203,23 @@ static Matrix downscaleView; // Matrix to downscale view (in case
static const char *windowTitle; // Window text title...
static bool cursorOnScreen = false; // Tracks if cursor is inside client area
-static char previousKeyState[512] = { 0 }; // Required to check if key pressed/released once
-static char currentKeyState[512] = { 0 }; // Required to check if key pressed/released once
-
-static char previousGamepadState[32] = {0}; // Required to check if gamepad btn pressed/released once
-static char currentGamepadState[32] = {0}; // Required to check if gamepad btn pressed/released once
+// Register keyboard states
+static char previousKeyState[512] = { 0 }; // Registers previous frame key state
+static char currentKeyState[512] = { 0 }; // Registers current frame key state
-static char previousMouseState[3] = { 0 }; // Required to check if mouse btn pressed/released once
-static char currentMouseState[3] = { 0 }; // Required to check if mouse btn pressed/released once
+// Register mouse states
+static char previousMouseState[3] = { 0 }; // Registers previous mouse button state
+static char currentMouseState[3] = { 0 }; // Registers current mouse button state
+static int previousMouseWheelY = 0; // Registers previous mouse wheel variation
+static int currentMouseWheelY = 0; // Registers current mouse wheel variation
-static int previousMouseWheelY = 0; // Required to track mouse wheel variation
-static int currentMouseWheelY = 0; // Required to track mouse wheel variation
+// Register gamepads states
+static bool gamepadReady[MAX_GAMEPADS] = { false }; // Flag to know if gamepad is ready
+static float gamepadAxisState[MAX_GAMEPADS][MAX_GAMEPAD_AXIS]; // Gamepad axis state
+static char previousGamepadState[MAX_GAMEPADS][MAX_GAMEPAD_BUTTONS] = { 0 };
+static char currentGamepadState[MAX_GAMEPADS][MAX_GAMEPAD_BUTTONS] = { 0 };
+// Keyboard configuration
static int exitKey = KEY_ESCAPE; // Default exit key (ESC)
static int lastKeyPressed = -1; // Register last key pressed
@@ -231,8 +245,10 @@ static bool showLogo = false; // Track if showing logo at init is
//----------------------------------------------------------------------------------
// Other Modules Functions Declaration (required by core)
//----------------------------------------------------------------------------------
+#if defined(RL_LOAD_DEFAULT_FONT)
extern void LoadDefaultFont(void); // [Module: text] Loads default font on InitWindow()
extern void UnloadDefaultFont(void); // [Module: text] Unloads default font from GPU memory
+#endif
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
@@ -293,7 +309,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;
@@ -301,9 +317,11 @@ void InitWindow(int width, int height, const char *title)
// Init graphics device (display device and OpenGL context)
InitGraphicsDevice(width, height);
- // Load default font for convenience
+#if defined(RL_LOAD_DEFAULT_FONT)
+ // Load default font
// NOTE: External function (defined in module: text)
LoadDefaultFont();
+#endif
// Init hi-res timer
InitTimer();
@@ -325,7 +343,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);
@@ -347,7 +365,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();
@@ -386,7 +404,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");
@@ -410,7 +428,9 @@ void InitWindow(int width, int height, struct android_app *state)
// Close Window and Terminate Context
void CloseWindow(void)
{
+#if defined(RL_LOAD_DEFAULT_FONT)
UnloadDefaultFont();
+#endif
rlglClose(); // De-init rlgl
@@ -439,7 +459,7 @@ void CloseWindow(void)
eglTerminate(display);
display = EGL_NO_DISPLAY;
- }
+ }
#endif
#if defined(PLATFORM_RPI)
@@ -519,7 +539,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
@@ -535,7 +555,7 @@ void EndDrawing(void)
SwapBuffers(); // Copy back buffer to front buffer
PollInputEvents(); // Poll user events
-
+
// Frame time control system
currentTime = GetTime();
drawTime = currentTime - previousTime;
@@ -567,9 +587,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));
}
@@ -585,14 +605,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);
@@ -607,15 +627,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
@@ -625,7 +645,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
}
@@ -637,16 +657,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)
@@ -664,10 +684,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);
@@ -679,7 +699,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);
}
@@ -693,7 +714,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;
@@ -727,7 +748,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)
@@ -791,7 +812,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};
@@ -833,9 +854,9 @@ void ClearDroppedFiles(void)
if (dropFilesCount > 0)
{
for (int i = 0; i < dropFilesCount; i++) free(dropFilesPath[i]);
-
+
free(dropFilesPath);
-
+
dropFilesCount = 0;
}
}
@@ -846,7 +867,7 @@ void ClearDroppedFiles(void)
void StorageSaveValue(int position, int value)
{
FILE *storageFile = NULL;
-
+
char path[128];
#if defined(PLATFORM_ANDROID)
strcpy(path, internalDataPath);
@@ -857,7 +878,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");
@@ -869,14 +890,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);
}
}
@@ -886,7 +907,7 @@ void StorageSaveValue(int position, int value)
int StorageLoadValue(int position)
{
int value = 0;
-
+
char path[128];
#if defined(PLATFORM_ANDROID)
strcpy(path, internalDataPath);
@@ -895,9 +916,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
@@ -906,42 +927,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.
@@ -949,10 +970,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);
@@ -961,56 +982,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 };
-
+ 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;
}
@@ -1136,34 +1157,32 @@ bool IsCursorHidden()
bool IsGamepadAvailable(int gamepad)
{
bool result = false;
-
-#if defined(PLATFORM_RPI)
+
if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad]) result = true;
-#else
- if (glfwJoystickPresent(gamepad) == 1) result = true;
-#endif
return result;
}
+// Return gamepad internal name id
+const char *GetGamepadName(int gamepad)
+{
+#if defined(PLATFORM_DESKTOP)
+ if (glfwJoystickPresent(gamepad) == 1) return glfwGetJoystickName(gamepad);
+ else return NULL;
+#else
+ return NULL;
+#endif
+}
+
// Return axis movement vector for a gamepad
float GetGamepadAxisMovement(int gamepad, int axis)
{
float value = 0;
-
-#if defined(PLATFORM_RPI)
- if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad])
+
+ if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (axis < MAX_GAMEPAD_AXIS))
{
- if (axis < MAX_GAMEPAD_AXIS) value = gamepadAxisValues[gamepad][axis];
+ value = gamepadAxisState[gamepad][axis];
}
-#else
- const float *axes;
- int axisCount = 0;
-
- axes = glfwGetJoystickAxes(gamepad, &axisCount);
-
- if (axis < axisCount) value = axes[axis];
-#endif
return value;
}
@@ -1172,15 +1191,10 @@ float GetGamepadAxisMovement(int gamepad, int axis)
bool IsGamepadButtonPressed(int gamepad, int button)
{
bool pressed = false;
-
- currentGamepadState[button] = IsGamepadButtonDown(gamepad, button);
-
- if (currentGamepadState[button] != previousGamepadState[button])
- {
- if (currentGamepadState[button]) pressed = true;
- previousGamepadState[button] = currentGamepadState[button];
- }
- else pressed = false;
+
+ if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
+ (currentGamepadState[gamepad][button] != previousGamepadState[gamepad][button]) &&
+ (currentGamepadState[gamepad][button] == 1)) pressed = true;
return pressed;
}
@@ -1189,21 +1203,10 @@ 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;
- else result = false;
-#else
- const unsigned char *buttons;
- int buttonsCount;
-
- buttons = glfwGetJoystickButtons(gamepad, &buttonsCount);
- if ((buttons != NULL) && (buttons[button] == GLFW_PRESS)) result = true;
- else result = false;
-#endif
-
+ if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
+ (currentGamepadState[gamepad][button] == 1)) result = true;
+
return result;
}
@@ -1211,15 +1214,10 @@ bool IsGamepadButtonDown(int gamepad, int button)
bool IsGamepadButtonReleased(int gamepad, int button)
{
bool released = false;
-
- currentGamepadState[button] = IsGamepadButtonUp(gamepad, button);
-
- if (currentGamepadState[button] != previousGamepadState[button])
- {
- if (currentGamepadState[button]) released = true;
- previousGamepadState[button] = currentGamepadState[button];
- }
- else released = false;
+
+ if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
+ (currentGamepadState[gamepad][button] != previousGamepadState[gamepad][button]) &&
+ (currentGamepadState[gamepad][button] == 0)) released = true;
return released;
}
@@ -1229,19 +1227,8 @@ bool IsGamepadButtonUp(int gamepad, int button)
{
bool result = false;
-#if defined(PLATFORM_RPI)
- // Get gamepad buttons information
- if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (gamepadButtons[gamepad][button] == 0)) result = true;
- else result = false;
-#else
- const unsigned char *buttons;
- int buttonsCount;
-
- buttons = glfwGetJoystickButtons(gamepad, &buttonsCount);
-
- if ((buttons != NULL) && (buttons[button] == GLFW_RELEASE)) result = true;
- else result = false;
-#endif
+ if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
+ (currentGamepadState[gamepad][button] == 0)) result = true;
return result;
}
@@ -1252,7 +1239,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
@@ -1266,13 +1253,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;
}
@@ -1280,7 +1267,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
@@ -1292,7 +1279,7 @@ bool IsMouseButtonReleased(int button)
bool IsMouseButtonUp(int button)
{
bool up = false;
-
+
#if !defined(PLATFORM_ANDROID)
if (GetMouseButtonStatus(button) == 0) up = true;
#endif
@@ -1377,7 +1364,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);
@@ -1472,23 +1459,28 @@ 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.
// 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
+ glfwWindowHint(GLFW_SAMPLES, 4); // Enables multisampling x4 (MSAA), default is 0
TraceLog(INFO, "Trying to enable MSAA x4");
}
@@ -1505,7 +1497,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
@@ -1515,9 +1507,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++)
{
@@ -1531,7 +1523,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,
@@ -1540,12 +1532,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);
}
@@ -1553,15 +1545,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;
@@ -1604,7 +1596,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()
@@ -1613,8 +1605,6 @@ static void InitGraphicsDevice(int width, int height)
glfwSwapInterval(1);
TraceLog(INFO, "Trying to enable VSYNC");
}
-
- //glfwGetFramebufferSize(window, &renderWidth, &renderHeight); // Get framebuffer size of current window
#endif // defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
@@ -1637,13 +1627,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?
@@ -1765,17 +1755,28 @@ 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);
-
+
+#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)
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)
@@ -1789,7 +1790,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))
{
@@ -1928,7 +1929,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;
@@ -1950,8 +1951,45 @@ static void PollInputEvents(void)
previousMouseWheelY = currentMouseWheelY;
currentMouseWheelY = 0;
+
+ // Register gamepads buttons events
+ for (int i = 0; i < MAX_GAMEPADS; i++)
+ {
+ if (glfwJoystickPresent(i)) // Check if gamepad is available
+ {
+ gamepadReady[i] = true;
+
+ // Register previous gamepad states
+ for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) previousGamepadState[i][k] = currentGamepadState[i][k];
+
+ // Get current gamepad state
+ // NOTE: There is no callback available, so we get it manually
+ const unsigned char *buttons;
+ int buttonsCount;
+
+ buttons = glfwGetJoystickButtons(i, &buttonsCount);
+
+ for (int k = 0; (buttons != NULL) && (k < buttonsCount) && (buttonsCount < MAX_GAMEPAD_BUTTONS); k++)
+ {
+ if (buttons[i] == GLFW_PRESS) currentGamepadState[i][k] = 1;
+ else currentGamepadState[i][k] = 0;
+ }
+
+ // Get current axis state
+ const float *axes;
+ int axisCount = 0;
+
+ axes = glfwGetJoystickAxes(i, &axisCount);
+
+ for (int k = 0; (axes != NULL) && (k < axisCount) && (k < MAX_GAMEPAD_AXIS); k++)
+ {
+ gamepadAxisState[i][k] = axes[k];
+ }
+ }
+ else gamepadReady[i] = false;
+ }
- glfwPollEvents(); // Register keyboard/mouse events... and window events!
+ glfwPollEvents(); // Register keyboard/mouse events (callbacks)... and window events!
#endif
#if defined(PLATFORM_ANDROID)
@@ -2008,7 +2046,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);
@@ -2043,12 +2081,9 @@ 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
+ else
{
currentKeyState[key] = action;
if (action == GLFW_PRESS) lastKeyPressed = key;
@@ -2059,27 +2094,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();
@@ -2098,20 +2133,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
@@ -2152,7 +2187,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
}
@@ -2171,9 +2206,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
@@ -2223,9 +2258,11 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
// Init graphics device (display device and OpenGL context)
InitGraphicsDevice(screenWidth, screenHeight);
- // Load default font for convenience
+ #if defined(RL_LOAD_DEFAULT_FONT)
+ // Load default font
// NOTE: External function (defined in module: text)
LoadDefaultFont();
+ #endif
// TODO: GPU assets reload in case of lost focus (lost context)
// NOTE: This problem has been solved just unbinding and rebinding context from display
@@ -2235,7 +2272,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]);
}
@@ -2278,7 +2315,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");
@@ -2315,7 +2352,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)
@@ -2323,7 +2360,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);
@@ -2332,7 +2369,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
@@ -2344,7 +2381,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
// NOTE: AndroidManifest.xml must have <activity android:configChanges="orientation|keyboardHidden|screenSize" >
// 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!
@@ -2356,36 +2393,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);
@@ -2396,13 +2433,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);
@@ -2411,7 +2448,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;
@@ -2431,33 +2468,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)
+ 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!
@@ -2468,12 +2505,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
@@ -2519,7 +2556,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)
@@ -2535,7 +2572,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
@@ -2550,7 +2587,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");
@@ -2584,7 +2621,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;
}
@@ -2601,7 +2638,7 @@ static void ProcessKeyboard(void)
i += 3; // Jump to next key
}
-
+
// NOTE: Some keys are not directly keymapped (CTRL, ALT, SHIFT)
}
}
@@ -2611,7 +2648,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))
{
@@ -2620,10 +2657,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)
}
@@ -2633,7 +2670,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);
}
@@ -2663,14 +2700,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;
@@ -2679,7 +2716,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;
@@ -2687,27 +2724,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;
}
@@ -2721,12 +2758,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");
@@ -2744,7 +2781,7 @@ static void InitGamepad(void)
else TraceLog(INFO, "Gamepad device initialized successfully");
}
}
- }
+ }
}
// Process Gamepad (/dev/input/js0)
@@ -2763,7 +2800,7 @@ static void *GamepadThread(void *arg)
// Read gamepad event
struct js_event gamepadEvent;
-
+
while (!windowShouldClose)
{
for (int i = 0; i < MAX_GAMEPADS; i++)
@@ -2771,26 +2808,26 @@ 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;
+ currentGamepadState[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
- gamepadAxisValues[i][gamepadEvent.number] = (float)gamepadEvent.value/32768;
+ gamepadAxisState[i][gamepadEvent.number] = (float)gamepadEvent.value/32768;
}
}
}