summaryrefslogtreecommitdiff
path: root/libs/raylib/src/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/raylib/src/core.c')
-rw-r--r--libs/raylib/src/core.c2250
1 files changed, 1145 insertions, 1105 deletions
diff --git a/libs/raylib/src/core.c b/libs/raylib/src/core.c
index bf36d06..b3010ce 100644
--- a/libs/raylib/src/core.c
+++ b/libs/raylib/src/core.c
@@ -82,6 +82,9 @@
* provided by stb_image and stb_image_write libraries, so, those libraries must be enabled on textures module
* for linkage
*
+* #define SUPPORT_DATA_STORAGE
+* Support saving binary data automatically to a generated storage.data file. This file is managed internally.
+*
* DEPENDENCIES:
* rglfw - Manage graphic device, OpenGL context and inputs on PLATFORM_DESKTOP (Windows, Linux, OSX. FreeBSD, OpenBSD, NetBSD, DragonFly)
* raymath - 3D math functionality (Vector2, Vector3, Matrix, Quaternion)
@@ -116,9 +119,11 @@
#if !defined(EXTERNAL_CONFIG_FLAGS)
#include "config.h" // Defines module configuration flags
#else
- #define RAYLIB_VERSION "2.6-dev"
+ #define RAYLIB_VERSION "3.0"
#endif
+#include "utils.h" // Required for: TRACELOG macros
+
#if (defined(__linux__) || defined(PLATFORM_WEB)) && _POSIX_C_SOURCE < 199309L
#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 199309L // Required for CLOCK_MONOTONIC if compiled with c99 without gnu ext.
@@ -130,8 +135,6 @@
#define RLGL_IMPLEMENTATION
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2
-#include "utils.h" // Required for: fopen() Android mapping
-
#if defined(SUPPORT_GESTURES_SYSTEM)
#define GESTURES_IMPLEMENTATION
#include "gestures.h" // Gestures detection functionality
@@ -143,6 +146,9 @@
#endif
#if defined(SUPPORT_GIF_RECORDING)
+ #define RGIF_MALLOC RL_MALLOC
+ #define RGIF_FREE RL_FREE
+
#define RGIF_IMPLEMENTATION
#include "external/rgif.h" // Support GIF recording
#endif
@@ -151,17 +157,18 @@
#define SUPPORT_HIGH_DPI // Force HighDPI support on macOS
#endif
-#include <stdio.h> // Standard input / output lib
-#include <stdlib.h> // Required for: malloc(), free(), rand(), atexit()
-#include <stdint.h> // Required for: typedef unsigned long long int uint64_t, used by hi-res timer
-#include <time.h> // Required for: time() - Android/RPI hi-res timer (NOTE: Linux only!)
-#include <math.h> // Required for: tan() [Used in BeginMode3D() to set perspective]
-#include <string.h> // Required for: strrchr(), strcmp()
-//#include <errno.h> // Macros for reporting and retrieving error conditions through error codes
-#include <ctype.h> // Required for: tolower() [Used in IsFileExtension()]
-#include <sys/stat.h> // Required for stat() [Used in GetLastWriteTime()]
+#include <stdlib.h> // Required for: srand(), rand(), atexit()
+#include <stdio.h> // Required for: sprintf() [Used in OpenURL()]
+#include <string.h> // Required for: strrchr(), strcmp(), strlen()
+#include <time.h> // Required for: time() [Used in InitTimer()]
+#include <math.h> // Required for: tan() [Used in BeginMode3D()]
+
+#include <sys/stat.h> // Required for: stat() [Used in GetFileModTime()]
#if (defined(PLATFORM_DESKTOP) || defined(PLATFORM_UWP)) && defined(_WIN32) && (defined(_MSC_VER) || defined(__TINYC__))
+ #define DIRENT_MALLOC RL_MALLOC
+ #define DIRENT_FREE RL_FREE
+
#include "external/dirent.h" // Required for: DIR, opendir(), closedir() [Used in GetDirectoryFiles()]
#else
#include <dirent.h> // Required for: DIR, opendir(), closedir() [Used in GetDirectoryFiles()]
@@ -173,7 +180,7 @@
#define CHDIR _chdir
#include <io.h> // Required for _access() [Used in FileExists()]
#else
- #include "unistd.h" // Required for: getch(), chdir() (POSIX), access()
+ #include <unistd.h> // Required for: getch(), chdir() (POSIX), access()
#define GETCWD getcwd
#define CHDIR chdir
#endif
@@ -211,8 +218,7 @@
#endif
#if defined(__linux__)
- #include <linux/limits.h> // for NAME_MAX and PATH_MAX defines
- #define MAX_FILEPATH_LENGTH PATH_MAX // Use Linux define (4096)
+ #define MAX_FILEPATH_LENGTH 4096 // Use Linux PATH_MAX value
#else
#define MAX_FILEPATH_LENGTH 512 // Use common value
#endif
@@ -222,33 +228,33 @@
#include <android/window.h> // Defines AWINDOW_FLAG_FULLSCREEN and others
#include <android_native_app_glue.h> // Defines basic app state struct and manages activity
- #include <EGL/egl.h> // Khronos EGL library - Native platform display device control functions
- #include <GLES2/gl2.h> // Khronos OpenGL ES 2.0 library
+ #include <EGL/egl.h> // Khronos EGL library - Native platform display device control functions
+ #include <GLES2/gl2.h> // Khronos OpenGL ES 2.0 library
#endif
#if defined(PLATFORM_RPI)
- #include <fcntl.h> // POSIX file control definitions - open(), creat(), fcntl()
- #include <unistd.h> // POSIX standard function definitions - read(), close(), STDIN_FILENO
- #include <termios.h> // POSIX terminal control definitions - tcgetattr(), tcsetattr()
- #include <pthread.h> // POSIX threads management (mouse input)
- #include <dirent.h> // POSIX directory browsing
+ #include <fcntl.h> // POSIX file control definitions - open(), creat(), fcntl()
+ #include <unistd.h> // POSIX standard function definitions - read(), close(), STDIN_FILENO
+ #include <termios.h> // POSIX terminal control definitions - tcgetattr(), tcsetattr()
+ #include <pthread.h> // POSIX threads management (inputs reading)
+ #include <dirent.h> // POSIX directory browsing
- #include <sys/ioctl.h> // UNIX System call for device-specific input/output operations - ioctl()
- #include <linux/kd.h> // Linux: KDSKBMODE, K_MEDIUMRAM constants definition
- #include <linux/input.h> // Linux: Keycodes constants definition (KEY_A, ...)
- #include <linux/joystick.h> // Linux: Joystick support library
+ #include <sys/ioctl.h> // UNIX System call for device-specific input/output operations - ioctl()
+ #include <linux/kd.h> // Linux: KDSKBMODE, K_MEDIUMRAM constants definition
+ #include <linux/input.h> // Linux: Keycodes constants definition (KEY_A, ...)
+ #include <linux/joystick.h> // Linux: Joystick support library
- #include "bcm_host.h" // Raspberry Pi VideoCore IV access functions
+ #include "bcm_host.h" // Raspberry Pi VideoCore IV access functions
- #include "EGL/egl.h" // Khronos EGL library - Native platform display device control functions
- #include "EGL/eglext.h" // Khronos EGL library - Extensions
- #include "GLES2/gl2.h" // Khronos OpenGL ES 2.0 library
+ #include "EGL/egl.h" // Khronos EGL library - Native platform display device control functions
+ #include "EGL/eglext.h" // Khronos EGL library - Extensions
+ #include "GLES2/gl2.h" // Khronos OpenGL ES 2.0 library
#endif
#if defined(PLATFORM_UWP)
- #include "EGL/egl.h" // Khronos EGL library - Native platform display device control functions
- #include "EGL/eglext.h" // Khronos EGL library - Extensions
- #include "GLES2/gl2.h" // Khronos OpenGL ES 2.0 library
+ #include "EGL/egl.h" // Khronos EGL library - Native platform display device control functions
+ #include "EGL/eglext.h" // Khronos EGL library - Extensions
+ #include "GLES2/gl2.h" // Khronos OpenGL ES 2.0 library
#endif
#if defined(PLATFORM_WEB)
@@ -286,166 +292,167 @@
#endif
#define MAX_GAMEPADS 4 // Max number of gamepads supported
-#define MAX_GAMEPAD_BUTTONS 32 // Max bumber of buttons supported (per gamepad)
#define MAX_GAMEPAD_AXIS 8 // Max number of axis supported (per gamepad)
+#define MAX_GAMEPAD_BUTTONS 32 // Max bumber of buttons supported (per gamepad)
#define MAX_CHARS_QUEUE 16 // Max number of characters in the input queue
-#define STORAGE_FILENAME "storage.data"
+#if defined(SUPPORT_DATA_STORAGE)
+ #define STORAGE_DATA_FILE "storage.data"
+#endif
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
#if defined(PLATFORM_RPI)
typedef struct {
- pthread_t threadId; // Event reading thread id
- int fd; // File descriptor to the device it is assigned to
- int eventNum; // Number of 'event<N>' device
- Rectangle absRange; // Range of values for absolute pointing devices (touchscreens)
- int touchSlot; // Hold the touch slot number of the currently being sent multitouch block
- bool isMouse; // True if device supports relative X Y movements
- bool isTouch; // True if device supports absolute X Y movements and has BTN_TOUCH
- bool isMultitouch; // True if device supports multiple absolute movevents and has BTN_TOUCH
- bool isKeyboard; // True if device has letter keycodes
- bool isGamepad; // True if device has gamepad buttons
+ pthread_t threadId; // Event reading thread id
+ int fd; // File descriptor to the device it is assigned to
+ int eventNum; // Number of 'event<N>' device
+ Rectangle absRange; // Range of values for absolute pointing devices (touchscreens)
+ int touchSlot; // Hold the touch slot number of the currently being sent multitouch block
+ bool isMouse; // True if device supports relative X Y movements
+ bool isTouch; // True if device supports absolute X Y movements and has BTN_TOUCH
+ bool isMultitouch; // True if device supports multiple absolute movevents and has BTN_TOUCH
+ bool isKeyboard; // True if device has letter keycodes
+ bool isGamepad; // True if device has gamepad buttons
} InputEventWorker;
-typedef struct{
- int Contents[8];
- char Head;
- char Tail;
+typedef struct {
+ int contents[8]; // Key events FIFO contents (8 positions)
+ char head; // Key events FIFO head position
+ char tail; // Key events FIFO tail position
} KeyEventFifo;
#endif
-//----------------------------------------------------------------------------------
-// Global Variables Definition
-//----------------------------------------------------------------------------------
+typedef struct { int x; int y; } Point;
+typedef struct { unsigned int width; unsigned int height; } Size;
-// Window/Graphics variables
-//-----------------------------------------------------------------------------------
+#if defined(PLATFORM_UWP)
+extern EGLNativeWindowType handle; // Native window handler for UWP (external, defined in UWP App)
+#endif
+
+// Core global state context data
+typedef struct CoreData {
+ struct {
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
-static GLFWwindow *window; // Native window (graphic device)
+ GLFWwindow *handle; // Native window handle (graphic device)
#endif
#if defined(PLATFORM_RPI)
-static EGL_DISPMANX_WINDOW_T window; // Native window (graphic device)
-#endif
-#if defined(PLATFORM_UWP)
-extern EGLNativeWindowType window; // Native window handler for UWP (external, defined in UWP App)
+ // NOTE: RPI4 does not support Dispmanx anymore, system should be redesigned
+ EGL_DISPMANX_WINDOW_T handle; // Native window handle (graphic device)
#endif
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_UWP)
-static EGLDisplay display; // Native display device (physical screen connection)
-static EGLSurface surface; // Surface to draw on, framebuffers (connected to context)
-static EGLContext context; // Graphic context, mode in which drawing can be done
-static EGLConfig config; // Graphic config
-static uint64_t baseTime = 0; // Base time measure for hi-res timer
-static bool windowShouldClose = false; // Flag to set window for closing
-#endif
-
-static const char *windowTitle = NULL; // Window text title...
-static bool windowReady = false; // Check if window has been initialized successfully
-static bool windowMinimized = false; // Check if window has been minimized
-static bool windowResized = false; // Check if window has been resized
-static bool fullscreenMode = false; // Check if fullscreen mode (useful only for PLATFORM_DESKTOP)
-static bool alwaysRun = false; // Keep window update/draw running on minimized
-
-static int windowPositionX, windowPositionY; // Window position on screen (required on fullscreen toggle)
-static int displayWidth, displayHeight; // Display width and height (monitor, device-screen, LCD, ...)
-static int screenWidth, screenHeight; // Screen width and height (used render area)
-static int renderWidth, renderHeight; // Framebuffer width and height (render area, including black bars if required)
-static int currentWidth, currentHeight; // Current render width and height, it could change on BeginTextureMode()
-static int renderOffsetX = 0; // Offset X from render area (must be divided by 2)
-static int renderOffsetY = 0; // Offset Y from render area (must be divided by 2)
-static Matrix screenScaling = { 0 }; // Matrix to scale screen (framebuffer rendering)
-//-----------------------------------------------------------------------------------
-
+ EGLDisplay device; // Native display device (physical screen connection)
+ EGLSurface surface; // Surface to draw on, framebuffers (connected to context)
+ EGLContext context; // Graphic context, mode in which drawing can be done
+ EGLConfig config; // Graphic config
+#endif
+ unsigned int flags; // Configuration flags (bit based)
+ const char *title; // Window text title const pointer
+ bool ready; // Flag to check if window has been initialized successfully
+ bool minimized; // Flag to check if window has been minimized
+ bool resized; // Flag to check if window has been resized
+ bool fullscreen; // Flag to check if fullscreen mode required
+ bool alwaysRun; // Flag to keep window update/draw running on minimized
+ bool shouldClose; // Flag to set window for closing
+
+ Point position; // Window position on screen (required on fullscreen toggle)
+ Size display; // Display width and height (monitor, device-screen, LCD, ...)
+ Size screen; // Screen width and height (used render area)
+ Size currentFbo; // Current render width and height, it could change on BeginTextureMode()
+ Size render; // Framebuffer width and height (render area, including black bars if required)
+ Point renderOffset; // Offset from render area (must be divided by 2)
+ Matrix screenScale; // Matrix to scale screen (framebuffer rendering)
+
+ char **dropFilesPath; // Store dropped files paths as strings
+ int dropFilesCount; // Count dropped files strings
+
+ } Window;
#if defined(PLATFORM_ANDROID)
-static struct android_app *androidApp; // Android activity
-static struct android_poll_source *source; // Android events polling source
-static int ident, events; // Android ALooper_pollAll() variables
-static const char *internalDataPath = NULL; // Android internal data path to write data (/data/data/<package>/files)
-
-static bool appEnabled = true; // Used to detec if app is active
-static bool contextRebindRequired = false; // Used to know context rebind required
-#endif
-
-// Input system variables
-//-----------------------------------------------------------------------------------
-// Keyboard states
-static char previousKeyState[512] = { 0 }; // Registers previous frame key state
-static char currentKeyState[512] = { 0 }; // Registers current frame key state
-static int exitKey = KEY_ESCAPE; // Default exit key (ESC)
-
-static unsigned int keyPressedQueue[MAX_CHARS_QUEUE] = { 0 }; // Input characters queue
-static int keyPressedQueueCount = 0; // Input characters queue count
-
+ struct {
+ bool appEnabled; // Flag to detect if app is active ** = true
+ struct android_app *app; // Android activity
+ struct android_poll_source *source; // Android events polling source
+ const char *internalDataPath; // Android internal data path to write data (/data/data/<package>/files)
+ bool contextRebindRequired; // Used to know context rebind required
+ } Android;
+#endif
+ struct {
#if defined(PLATFORM_RPI)
-// NOTE: For keyboard we will use the standard input (but reconfigured...)
-static struct termios defaultKeyboardSettings; // Used to store default keyboard settings
-static int defaultKeyboardMode = 0; // Used to store default keyboard mode
-#endif
-
-// Mouse states
-static Vector2 mousePosition = { 0.0f, 0.0f }; // Mouse position on screen
-static Vector2 mouseScale = { 1.0f, 1.0f }; // Mouse scaling
-static Vector2 mouseOffset = { 0.0f, 0.0f }; // Mouse offset
-static bool cursorHidden = false; // Track if cursor is hidden
-static bool cursorOnScreen = false; // Tracks if cursor is inside client area
-static Vector2 touchPosition[MAX_TOUCH_POINTS]; // Touch position on screen
-
-#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB) || defined(PLATFORM_UWP)
-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
+ InputEventWorker eventWorker[10]; // List of worker threads for every monitored "/dev/input/event<N>"
#endif
+ struct {
+ int exitKey; // Default exit key
+ char currentKeyState[512]; // Registers current frame key state
+ char previousKeyState[512]; // Registers previous frame key state
+ int keyPressedQueue[MAX_CHARS_QUEUE]; // Input characters queue
+ int keyPressedQueueCount; // Input characters queue count
#if defined(PLATFORM_RPI)
-static char currentMouseStateEvdev[3] = { 0 }; // Holds the new mouse state for the next polling event to grab (Can't be written directly due to multithreading, app could miss the update)
-static InputEventWorker eventWorkers[10]; // List of worker threads for every monitored "/dev/input/event<N>"
-static KeyEventFifo lastKeyPressedEvdev = { 0 }; // Buffer for holding keydown events as they arrive (Needed due to multitreading of event workers)
-static char currentKeyStateEvdev[512] = { 0 }; // Registers current frame key state from event based driver (Needs to be seperate because the legacy console based method clears keys on every frame)
-#endif
-
+ int defaultMode; // Default keyboard mode
+ struct termios defaultSettings; // Default keyboard settings
+ KeyEventFifo lastKeyPressed; // Buffer for holding keydown events as they arrive (Needed due to multitreading of event workers)
+#endif
+ } Keyboard;
+ struct {
+ Vector2 position; // Mouse position on screen
+ Vector2 offset; // Mouse offset
+ Vector2 scale; // Mouse scaling
+
+ bool cursorHidden; // Track if cursor is hidden
+ bool cursorOnScreen; // Tracks if cursor is inside client area
#if defined(PLATFORM_WEB)
-static bool toggleCursorLock = false; // Ask for cursor pointer lock on next click
+ bool cursorLockRequired; // Ask for cursor pointer lock on next click
#endif
-
-// Gamepads states
-static int lastGamepadButtonPressed = -1; // Register last gamepad button pressed
-static int gamepadAxisCount = 0; // Register number of available gamepad axis
-
+ char currentButtonState[3]; // Registers current mouse button state
+ char previousButtonState[3]; // Registers previous mouse button state
+ int currentWheelMove; // Registers current mouse wheel variation
+ int previousWheelMove; // Registers previous mouse wheel variation
+#if defined(PLATFORM_RPI)
+ char currentButtonStateEvdev[3]; // Holds the new mouse state for the next polling event to grab (Can't be written directly due to multithreading, app could miss the update)
+#endif
+ } Mouse;
+ struct {
+ Vector2 position[MAX_TOUCH_POINTS]; // Touch position on screen
+ char currentTouchState[MAX_TOUCH_POINTS]; // Registers current touch state
+ char previousTouchState[MAX_TOUCH_POINTS]; // Registers previous touch state
+ } Touch;
+ struct {
+ int lastButtonPressed; // Register last gamepad button pressed
+ int axisCount; // Register number of available gamepad axis
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB) || defined(PLATFORM_UWP)
-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]; // Previous gamepad buttons state
-static char currentGamepadState[MAX_GAMEPADS][MAX_GAMEPAD_BUTTONS]; // Current gamepad buttons state
+ bool ready[MAX_GAMEPADS]; // Flag to know if gamepad is ready
+ float axisState[MAX_GAMEPADS][MAX_GAMEPAD_AXIS]; // Gamepad axis state
+ char currentState[MAX_GAMEPADS][MAX_GAMEPAD_BUTTONS]; // Current gamepad buttons state
+ char previousState[MAX_GAMEPADS][MAX_GAMEPAD_BUTTONS]; // Previous gamepad buttons state
#endif
-
#if defined(PLATFORM_RPI)
-static int gamepadStream[MAX_GAMEPADS] = { -1 };// Gamepad device file descriptor
-static pthread_t gamepadThreadId; // Gamepad reading thread id
-static char gamepadName[64]; // Gamepad name holder
+ pthread_t threadId; // Gamepad reading thread id
+ int streamId[MAX_GAMEPADS]; // Gamepad device file descriptor
+ char name[64]; // Gamepad name holder
+#endif
+ } Gamepad;
+ } Input;
+ struct {
+ double current; // Current time measure
+ double previous; // Previous time measure
+ double update; // Time measure for frame update
+ double draw; // Time measure for frame draw
+ double frame; // Time measure for one frame
+ double target; // Desired time for one frame, if 0 not applied
+#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_UWP)
+ unsigned long long base; // Base time measure for hi-res timer
#endif
-//-----------------------------------------------------------------------------------
-
-// Timming system variables
-//-----------------------------------------------------------------------------------
-static double currentTime = 0.0; // Current time measure
-static double previousTime = 0.0; // Previous time measure
-static double updateTime = 0.0; // Time measure for frame update
-static double drawTime = 0.0; // Time measure for frame draw
-static double frameTime = 0.0; // Time measure for one frame
-static double targetTime = 0.0; // Desired time for one frame, if 0 not applied
-//-----------------------------------------------------------------------------------
+ } Time;
+} CoreData;
-// Config internal variables
-//-----------------------------------------------------------------------------------
-static unsigned int configFlags = 0; // Configuration flags (bit based)
-
-static char **dropFilesPath; // Store dropped files paths as strings
-static int dropFilesCount = 0; // Count dropped files strings
+//----------------------------------------------------------------------------------
+// Global Variables Definition
+//----------------------------------------------------------------------------------
+static CoreData CORE = { 0 }; // Global CORE state context
-static char **dirFilesPath; // Store directory files paths as strings
+static char **dirFilesPath = NULL; // Store directory files paths as strings
static int dirFilesCount = 0; // Count directory files strings
#if defined(SUPPORT_SCREEN_CAPTURE)
@@ -477,8 +484,6 @@ static void SwapBuffers(void); // Copy back buffer to f
static void InitTimer(void); // Initialize timer
static void Wait(float ms); // Wait for some milliseconds (stop program execution)
-static bool GetKeyStatus(int key); // Returns if a key has been pressed
-static bool GetMouseButtonStatus(int button); // Returns if a mouse button has been pressed
static int GetGamepadButton(int button); // Get gamepad button generic to all platforms
static int GetGamepadAxis(int axis); // Get gamepad axis generic to all platforms
static void PollInputEvents(void); // Register user events
@@ -502,7 +507,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
#endif
#if defined(PLATFORM_WEB)
-static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const EmscriptenFullscreenChangeEvent *e, void *userData);
+static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const EmscriptenFullscreenChangeEvent *event, void *userData);
static EM_BOOL EmscriptenKeyboardCallback(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData);
static EM_BOOL EmscriptenMouseCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData);
static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData);
@@ -544,7 +549,7 @@ extern int main(int argc, char *argv[]);
void android_main(struct android_app *app)
{
char arg0[] = "raylib"; // NOTE: argv[] are mutable
- androidApp = app;
+ CORE.Android.app = app;
// TODO: Should we maybe report != 0 return codes somewhere?
(void)main(1, (char *[]) { arg0, NULL });
@@ -553,18 +558,19 @@ void android_main(struct android_app *app)
// TODO: Add this to header (if apps really need it)
struct android_app *GetAndroidApp(void)
{
- return androidApp;
+ return CORE.Android.app;
}
#endif
#if defined(PLATFORM_RPI) && !defined(SUPPORT_SSH_KEYBOARD_RPI)
// Init terminal (block echo and signal short cuts)
static void InitTerminal(void)
{
- TraceLog(LOG_INFO, "Reconfigure Terminal ...");
+ TRACELOG(LOG_INFO, "RPI: Reconfiguring terminal...");
+
// Save terminal keyboard settings and reconfigure terminal with new settings
struct termios keyboardNewSettings;
- tcgetattr(STDIN_FILENO, &defaultKeyboardSettings); // Get current keyboard settings
- keyboardNewSettings = defaultKeyboardSettings;
+ tcgetattr(STDIN_FILENO, &CORE.Input.Keyboard.defaultSettings); // Get current keyboard settings
+ keyboardNewSettings = CORE.Input.Keyboard.defaultSettings;
// New terminal settings for keyboard: turn off buffering (non-canonical mode), echo
// NOTE: ISIG controls if ^C and ^Z generate break signals or not
@@ -576,16 +582,12 @@ static void InitTerminal(void)
tcsetattr(STDIN_FILENO, TCSANOW, &keyboardNewSettings);
// Save old keyboard mode to restore it at the end
- if (ioctl(STDIN_FILENO, KDGKBMODE, &defaultKeyboardMode) < 0)
+ if (ioctl(STDIN_FILENO, KDGKBMODE, &CORE.Input.Keyboard.defaultMode) < 0)
{
// NOTE: It could mean we are using a remote keyboard through ssh or from the desktop
- TraceLog(LOG_WARNING, "Could not change keyboard mode (Not a local Terminal)");
- }
- else
- {
-
- ioctl(STDIN_FILENO, KDSKBMODE, K_XLATE);
+ TRACELOG(LOG_WARNING, "RPI: Failed to change keyboard mode (not a local terminal)");
}
+ else ioctl(STDIN_FILENO, KDSKBMODE, K_XLATE);
// Register terminal restore when program finishes
atexit(RestoreTerminal);
@@ -593,90 +595,106 @@ static void InitTerminal(void)
// Restore terminal
static void RestoreTerminal(void)
{
- TraceLog(LOG_INFO, "Restore Terminal ...");
+ TRACELOG(LOG_INFO, "RPI: Restoring terminal...");
// Reset to default keyboard settings
- tcsetattr(STDIN_FILENO, TCSANOW, &defaultKeyboardSettings);
+ tcsetattr(STDIN_FILENO, TCSANOW, &CORE.Input.Keyboard.defaultSettings);
// Reconfigure keyboard to default mode
- ioctl(STDIN_FILENO, KDSKBMODE, defaultKeyboardMode);
+ ioctl(STDIN_FILENO, KDSKBMODE, CORE.Input.Keyboard.defaultMode);
}
#endif
// Initialize window and OpenGL context
// NOTE: data parameter could be used to pass any kind of required data to the initialization
void InitWindow(int width, int height, const char *title)
{
- TraceLog(LOG_INFO, "Initializing raylib %s", RAYLIB_VERSION);
+ TRACELOG(LOG_INFO, "Initializing raylib %s", RAYLIB_VERSION);
+
+ CORE.Window.title = title;
+
+ // Initialize required global values different than 0
+ CORE.Input.Keyboard.exitKey = KEY_ESCAPE;
+ CORE.Input.Mouse.scale = (Vector2){ 1.0f, 1.0f };
+ CORE.Input.Gamepad.lastButtonPressed = -1;
- windowTitle = title;
#if defined(PLATFORM_ANDROID)
- screenWidth = width;
- screenHeight = height;
- currentWidth = width;
- currentHeight = height;
+ CORE.Window.screen.width = width;
+ CORE.Window.screen.height = height;
+ CORE.Window.currentFbo.width = width;
+ CORE.Window.currentFbo.height = height;
// Input data is android app pointer
- internalDataPath = androidApp->activity->internalDataPath;
+ CORE.Android.internalDataPath = CORE.Android.app->activity->internalDataPath;
// Set desired windows flags before initializing anything
- ANativeActivity_setWindowFlags(androidApp->activity, AWINDOW_FLAG_FULLSCREEN, 0); //AWINDOW_FLAG_SCALED, AWINDOW_FLAG_DITHER
- //ANativeActivity_setWindowFlags(androidApp->activity, AWINDOW_FLAG_FORCE_NOT_FULLSCREEN, AWINDOW_FLAG_FULLSCREEN);
+ ANativeActivity_setWindowFlags(CORE.Android.app->activity, AWINDOW_FLAG_FULLSCREEN, 0); //AWINDOW_FLAG_SCALED, AWINDOW_FLAG_DITHER
- int orientation = AConfiguration_getOrientation(androidApp->config);
+ int orientation = AConfiguration_getOrientation(CORE.Android.app->config);
- if (orientation == ACONFIGURATION_ORIENTATION_PORT) TraceLog(LOG_INFO, "PORTRAIT window orientation");
- else if (orientation == ACONFIGURATION_ORIENTATION_LAND) TraceLog(LOG_INFO, "LANDSCAPE window orientation");
+ if (orientation == ACONFIGURATION_ORIENTATION_PORT) TRACELOG(LOG_INFO, "ANDROID: Window orientation set as portrait");
+ else if (orientation == ACONFIGURATION_ORIENTATION_LAND) TRACELOG(LOG_INFO, "ANDROID: Window orientation set as landscape");
// TODO: Automatic orientation doesn't seem to work
if (width <= height)
{
- AConfiguration_setOrientation(androidApp->config, ACONFIGURATION_ORIENTATION_PORT);
- TraceLog(LOG_WARNING, "Window set to portraid mode");
+ AConfiguration_setOrientation(CORE.Android.app->config, ACONFIGURATION_ORIENTATION_PORT);
+ TRACELOG(LOG_WARNING, "ANDROID: Window orientation changed to portrait");
}
else
{
- AConfiguration_setOrientation(androidApp->config, ACONFIGURATION_ORIENTATION_LAND);
- TraceLog(LOG_WARNING, "Window set to landscape mode");
+ AConfiguration_setOrientation(CORE.Android.app->config, ACONFIGURATION_ORIENTATION_LAND);
+ TRACELOG(LOG_WARNING, "ANDROID: Window orientation changed to landscape");
}
- //AConfiguration_getDensity(androidApp->config);
- //AConfiguration_getKeyboard(androidApp->config);
- //AConfiguration_getScreenSize(androidApp->config);
- //AConfiguration_getScreenLong(androidApp->config);
+ //AConfiguration_getDensity(CORE.Android.app->config);
+ //AConfiguration_getKeyboard(CORE.Android.app->config);
+ //AConfiguration_getScreenSize(CORE.Android.app->config);
+ //AConfiguration_getScreenLong(CORE.Android.app->config);
+
+ CORE.Android.app->onAppCmd = AndroidCommandCallback;
+ CORE.Android.app->onInputEvent = AndroidInputCallback;
- androidApp->onAppCmd = AndroidCommandCallback;
- androidApp->onInputEvent = AndroidInputCallback;
+ InitAssetManager(CORE.Android.app->activity->assetManager, CORE.Android.app->activity->internalDataPath);
- InitAssetManager(androidApp->activity->assetManager);
+ TRACELOG(LOG_INFO, "ANDROID: App initialized successfully");
- TraceLog(LOG_INFO, "Android app initialized successfully");
+ // Android ALooper_pollAll() variables
+ int pollResult = 0;
+ int pollEvents = 0;
// Wait for window to be initialized (display and context)
- while (!windowReady)
+ while (!CORE.Window.ready)
{
// Process events loop
- while ((ident = ALooper_pollAll(0, NULL, &events, (void**)&source)) >= 0)
+ while ((pollResult = ALooper_pollAll(0, NULL, &pollEvents, (void**)&CORE.Android.source)) >= 0)
{
// Process this event
- if (source != NULL) source->process(androidApp, source);
+ if (CORE.Android.source != NULL) CORE.Android.source->process(CORE.Android.app, CORE.Android.source);
// NOTE: Never close window, native activity is controlled by the system!
- //if (androidApp->destroyRequested != 0) windowShouldClose = true;
+ //if (CORE.Android.app->destroyRequested != 0) CORE.Window.shouldClose = true;
}
}
#else
// Init graphics device (display device and OpenGL context)
// NOTE: returns true if window and graphic device has been initialized successfully
- windowReady = InitGraphicsDevice(width, height);
- if (!windowReady) return;
+ CORE.Window.ready = InitGraphicsDevice(width, height);
+ if (!CORE.Window.ready) return;
// Init hi-res timer
InitTimer();
#if defined(SUPPORT_DEFAULT_FONT)
// Load default font
- // NOTE: External function (defined in module: text)
+ // NOTE: External functions (defined in module: text)
LoadFontDefault();
+ Rectangle rec = GetFontDefault().recs[95];
+ // NOTE: We setup a 1px padding on char rectangle to avoid pixel bleeding on MSAA filtering
+ SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2 });
+#endif
+#if defined(PLATFORM_DESKTOP) && defined(SUPPORT_HIGH_DPI)
+ // Set default font texture filter for HighDPI (blurry)
+ SetTextureFilter(GetFontDefault().texture, FILTER_BILINEAR);
#endif
#if defined(PLATFORM_RPI)
@@ -691,7 +709,8 @@ void InitWindow(int width, int height, const char *title)
#endif
#if defined(PLATFORM_WEB)
- emscripten_set_fullscreenchange_callback(0, 0, 1, EmscriptenFullscreenChangeCallback);
+ // Detect fullscreen change events
+ emscripten_set_fullscreenchange_callback("#canvas", NULL, 1, EmscriptenFullscreenChangeCallback);
// Support keyboard events
emscripten_set_keypress_callback("#canvas", NULL, 1, EmscriptenKeyboardCallback);
@@ -710,8 +729,8 @@ void InitWindow(int width, int height, const char *title)
emscripten_set_gamepaddisconnected_callback(NULL, 1, EmscriptenGamepadCallback);
#endif
- mousePosition.x = (float)screenWidth/2.0f;
- mousePosition.y = (float)screenHeight/2.0f;
+ CORE.Input.Mouse.position.x = (float)CORE.Window.screen.width/2.0f;
+ CORE.Input.Mouse.position.y = (float)CORE.Window.screen.height/2.0f;
#endif // PLATFORM_ANDROID
}
@@ -733,7 +752,7 @@ void CloseWindow(void)
rlglClose(); // De-init rlgl
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
- glfwDestroyWindow(window);
+ glfwDestroyWindow(CORE.Window.handle);
glfwTerminate();
#endif
@@ -743,52 +762,52 @@ void CloseWindow(void)
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_UWP)
// Close surface, context and display
- if (display != EGL_NO_DISPLAY)
+ if (CORE.Window.device != EGL_NO_DISPLAY)
{
- eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglMakeCurrent(CORE.Window.device, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- if (surface != EGL_NO_SURFACE)
+ if (CORE.Window.surface != EGL_NO_SURFACE)
{
- eglDestroySurface(display, surface);
- surface = EGL_NO_SURFACE;
+ eglDestroySurface(CORE.Window.device, CORE.Window.surface);
+ CORE.Window.surface = EGL_NO_SURFACE;
}
- if (context != EGL_NO_CONTEXT)
+ if (CORE.Window.context != EGL_NO_CONTEXT)
{
- eglDestroyContext(display, context);
- context = EGL_NO_CONTEXT;
+ eglDestroyContext(CORE.Window.device, CORE.Window.context);
+ CORE.Window.context = EGL_NO_CONTEXT;
}
- eglTerminate(display);
- display = EGL_NO_DISPLAY;
+ eglTerminate(CORE.Window.device);
+ CORE.Window.device = EGL_NO_DISPLAY;
}
#endif
#if defined(PLATFORM_RPI)
// Wait for mouse and gamepad threads to finish before closing
// NOTE: Those threads should already have finished at this point
- // because they are controlled by windowShouldClose variable
+ // because they are controlled by CORE.Window.shouldClose variable
- windowShouldClose = true; // Added to force threads to exit when the close window is called
+ CORE.Window.shouldClose = true; // Added to force threads to exit when the close window is called
- for (int i = 0; i < sizeof(eventWorkers)/sizeof(InputEventWorker); ++i)
+ for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i)
{
- if (eventWorkers[i].threadId)
+ if (CORE.Input.eventWorker[i].threadId)
{
- pthread_join(eventWorkers[i].threadId, NULL);
+ pthread_join(CORE.Input.eventWorker[i].threadId, NULL);
}
}
- if (gamepadThreadId) pthread_join(gamepadThreadId, NULL);
+ if (CORE.Input.Gamepad.threadId) pthread_join(CORE.Input.Gamepad.threadId, NULL);
#endif
- TraceLog(LOG_INFO, "Window closed successfully");
+ TRACELOG(LOG_INFO, "Window closed successfully");
}
// Check if window has been initialized successfully
bool IsWindowReady(void)
{
- return windowReady;
+ return CORE.Window.ready;
}
// Check if KEY_ESCAPE pressed or Close icon pressed
@@ -805,18 +824,20 @@ bool WindowShouldClose(void)
#endif
#if defined(PLATFORM_DESKTOP)
- if (windowReady)
+ if (CORE.Window.ready)
{
// While window minimized, stop loop execution
- while (!alwaysRun && windowMinimized) glfwWaitEvents();
+ while (!CORE.Window.alwaysRun && CORE.Window.minimized) glfwWaitEvents();
+
+ CORE.Window.shouldClose = glfwWindowShouldClose(CORE.Window.handle);
- return (glfwWindowShouldClose(window));
+ return CORE.Window.shouldClose;
}
else return true;
#endif
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_UWP)
- if (windowReady) return windowShouldClose;
+ if (CORE.Window.ready) return CORE.Window.shouldClose;
else return true;
#endif
}
@@ -825,7 +846,7 @@ bool WindowShouldClose(void)
bool IsWindowMinimized(void)
{
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) || defined(PLATFORM_UWP)
- return windowMinimized;
+ return CORE.Window.minimized;
#else
return false;
#endif
@@ -835,7 +856,7 @@ bool IsWindowMinimized(void)
bool IsWindowResized(void)
{
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) || defined(PLATFORM_UWP)
- return windowResized;
+ return CORE.Window.resized;
#else
return false;
#endif
@@ -845,43 +866,52 @@ bool IsWindowResized(void)
bool IsWindowHidden(void)
{
#if defined(PLATFORM_DESKTOP)
- return (glfwGetWindowAttrib(window, GLFW_VISIBLE) == GL_FALSE);
+ return (glfwGetWindowAttrib(CORE.Window.handle, GLFW_VISIBLE) == GL_FALSE);
#endif
return false;
}
+// Check if window is currently fullscreen
+bool IsWindowFullscreen(void)
+{
+ return CORE.Window.fullscreen;
+}
+
// Toggle fullscreen mode (only PLATFORM_DESKTOP)
void ToggleFullscreen(void)
{
-#if defined(PLATFORM_DESKTOP)
- fullscreenMode = !fullscreenMode; // Toggle fullscreen flag
+ CORE.Window.fullscreen = !CORE.Window.fullscreen; // Toggle fullscreen flag
+#if defined(PLATFORM_DESKTOP)
// NOTE: glfwSetWindowMonitor() doesn't work properly (bugs)
- if (fullscreenMode)
+ if (CORE.Window.fullscreen)
{
// Store previous window position (in case we exit fullscreen)
- glfwGetWindowPos(window, &windowPositionX, &windowPositionY);
+ glfwGetWindowPos(CORE.Window.handle, &CORE.Window.position.x, &CORE.Window.position.y);
GLFWmonitor *monitor = glfwGetPrimaryMonitor();
if (!monitor)
{
- TraceLog(LOG_WARNING, "Failed to get monitor");
- glfwSetWindowMonitor(window, glfwGetPrimaryMonitor(), 0, 0, screenWidth, screenHeight, GLFW_DONT_CARE);
+ TRACELOG(LOG_WARNING, "GLFW: Failed to get monitor");
+ glfwSetWindowMonitor(CORE.Window.handle, glfwGetPrimaryMonitor(), 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
return;
}
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
- glfwSetWindowMonitor(window, glfwGetPrimaryMonitor(), 0, 0, screenWidth, screenHeight, mode->refreshRate);
-
+ glfwSetWindowMonitor(CORE.Window.handle, glfwGetPrimaryMonitor(), 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, mode->refreshRate);
+
// Try to enable GPU V-Sync, so frames are limited to screen refresh rate (60Hz -> 60 FPS)
// NOTE: V-Sync can be enabled by graphic driver configuration
- if (configFlags & FLAG_VSYNC_HINT) glfwSwapInterval(1);
+ if (CORE.Window.flags & FLAG_VSYNC_HINT) glfwSwapInterval(1);
}
- else glfwSetWindowMonitor(window, NULL, windowPositionX, windowPositionY, screenWidth, screenHeight, GLFW_DONT_CARE);
+ else glfwSetWindowMonitor(CORE.Window.handle, NULL, CORE.Window.position.x, CORE.Window.position.y, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
+#endif
+#if defined(PLATFORM_WEB)
+ if (CORE.Window.fullscreen) EM_ASM(Module.requestFullscreen(false, false););
+ else EM_ASM(document.exitFullscreen(););
#endif
-
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
- TraceLog(LOG_WARNING, "Could not toggle to windowed mode");
+ TRACELOG(LOG_WARNING, "SYSTEM: Failed to toggle to windowed mode");
#endif
}
@@ -900,18 +930,18 @@ void SetWindowIcon(Image image)
// NOTE 1: We only support one image icon
// NOTE 2: The specified image data is copied before this function returns
- glfwSetWindowIcon(window, 1, icon);
+ glfwSetWindowIcon(CORE.Window.handle, 1, icon);
}
- else TraceLog(LOG_WARNING, "Window icon image must be in R8G8B8A8 pixel format");
+ else TRACELOG(LOG_WARNING, "GLFW: Window icon image must be in R8G8B8A8 pixel format");
#endif
}
// Set title for window (only PLATFORM_DESKTOP)
void SetWindowTitle(const char *title)
{
- windowTitle = title;
+ CORE.Window.title = title;
#if defined(PLATFORM_DESKTOP)
- glfwSetWindowTitle(window, title);
+ glfwSetWindowTitle(CORE.Window.handle, title);
#endif
}
@@ -919,7 +949,7 @@ void SetWindowTitle(const char *title)
void SetWindowPosition(int x, int y)
{
#if defined(PLATFORM_DESKTOP)
- glfwSetWindowPos(window, x, y);
+ glfwSetWindowPos(CORE.Window.handle, x, y);
#endif
}
@@ -927,17 +957,17 @@ void SetWindowPosition(int x, int y)
void SetWindowMonitor(int monitor)
{
#if defined(PLATFORM_DESKTOP)
- int monitorCount;
+ int monitorCount = 0;
GLFWmonitor **monitors = glfwGetMonitors(&monitorCount);
if ((monitor >= 0) && (monitor < monitorCount))
{
- TraceLog(LOG_INFO, "Selected fullscreen monitor: [%i] %s", monitor, glfwGetMonitorName(monitors[monitor]));
+ TRACELOG(LOG_INFO, "GLFW: Selected fullscreen monitor: [%i] %s", monitor, glfwGetMonitorName(monitors[monitor]));
const GLFWvidmode *mode = glfwGetVideoMode(monitors[monitor]);
- glfwSetWindowMonitor(window, monitors[monitor], 0, 0, mode->width, mode->height, mode->refreshRate);
+ glfwSetWindowMonitor(CORE.Window.handle, monitors[monitor], 0, 0, mode->width, mode->height, mode->refreshRate);
}
- else TraceLog(LOG_WARNING, "Selected monitor not found");
+ else TRACELOG(LOG_WARNING, "GLFW: Failed to find selected monitor");
#endif
}
@@ -946,7 +976,7 @@ void SetWindowMinSize(int width, int height)
{
#if defined(PLATFORM_DESKTOP)
const GLFWvidmode *mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
- glfwSetWindowSizeLimits(window, width, height, mode->width, mode->height);
+ glfwSetWindowSizeLimits(CORE.Window.handle, width, height, mode->width, mode->height);
#endif
}
@@ -955,7 +985,15 @@ void SetWindowMinSize(int width, int height)
void SetWindowSize(int width, int height)
{
#if defined(PLATFORM_DESKTOP)
- glfwSetWindowSize(window, width, height);
+ glfwSetWindowSize(CORE.Window.handle, width, height);
+#endif
+#if defined(PLATFORM_WEB)
+ emscripten_set_canvas_size(width, height); // DEPRECATED!
+
+ // TODO: Below functions should be used to replace previous one but
+ // they do not seem to work properly
+ //emscripten_set_canvas_element_size("canvas", width, height);
+ //emscripten_set_element_css_size("canvas", width, height);
#endif
}
@@ -963,7 +1001,7 @@ void SetWindowSize(int width, int height)
void UnhideWindow(void)
{
#if defined(PLATFORM_DESKTOP)
- glfwShowWindow(window);
+ glfwShowWindow(CORE.Window.handle);
#endif
}
@@ -971,20 +1009,20 @@ void UnhideWindow(void)
void HideWindow(void)
{
#if defined(PLATFORM_DESKTOP)
- glfwHideWindow(window);
+ glfwHideWindow(CORE.Window.handle);
#endif
}
// Get current screen width
int GetScreenWidth(void)
{
- return screenWidth;
+ return CORE.Window.screen.width;
}
// Get current screen height
int GetScreenHeight(void)
{
- return screenHeight;
+ return CORE.Window.screen.height;
}
// Get native window handle
@@ -992,7 +1030,7 @@ void *GetWindowHandle(void)
{
#if defined(PLATFORM_DESKTOP) && defined(_WIN32)
// NOTE: Returned handle is: void *HWND (windows.h)
- return glfwGetWin32Window(window);
+ return glfwGetWin32Window(CORE.Window.handle);
#elif defined(__linux__)
// NOTE: Returned handle is: unsigned long Window (X.h)
// typedef unsigned long XID;
@@ -1031,7 +1069,7 @@ int GetMonitorWidth(int monitor)
const GLFWvidmode *mode = glfwGetVideoMode(monitors[monitor]);
return mode->width;
}
- else TraceLog(LOG_WARNING, "Selected monitor not found");
+ else TRACELOG(LOG_WARNING, "GLFW: Failed to find selected monitor");
#endif
return 0;
}
@@ -1048,7 +1086,7 @@ int GetMonitorHeight(int monitor)
const GLFWvidmode *mode = glfwGetVideoMode(monitors[monitor]);
return mode->height;
}
- else TraceLog(LOG_WARNING, "Selected monitor not found");
+ else TRACELOG(LOG_WARNING, "GLFW: Failed to find selected monitor");
#endif
return 0;
}
@@ -1066,7 +1104,7 @@ int GetMonitorPhysicalWidth(int monitor)
glfwGetMonitorPhysicalSize(monitors[monitor], &physicalWidth, NULL);
return physicalWidth;
}
- else TraceLog(LOG_WARNING, "Selected monitor not found");
+ else TRACELOG(LOG_WARNING, "GLFW: Failed to find selected monitor");
#endif
return 0;
}
@@ -1084,7 +1122,7 @@ int GetMonitorPhysicalHeight(int monitor)
glfwGetMonitorPhysicalSize(monitors[monitor], NULL, &physicalHeight);
return physicalHeight;
}
- else TraceLog(LOG_WARNING, "Selected monitor not found");
+ else TRACELOG(LOG_WARNING, "GLFW: Failed to find selected monitor");
#endif
return 0;
}
@@ -1095,7 +1133,7 @@ Vector2 GetWindowPosition(void)
int x = 0;
int y = 0;
#if defined(PLATFORM_DESKTOP)
- glfwGetWindowPos(window, &x, &y);
+ glfwGetWindowPos(CORE.Window.handle, &x, &y);
#endif
return (Vector2){ (float)x, (float)y };
}
@@ -1111,7 +1149,7 @@ const char *GetMonitorName(int monitor)
{
return glfwGetMonitorName(monitors[monitor]);
}
- else TraceLog(LOG_WARNING, "Selected monitor not found");
+ else TRACELOG(LOG_WARNING, "GLFW: Failed to find selected monitor");
#endif
return "";
}
@@ -1121,7 +1159,7 @@ const char *GetMonitorName(int monitor)
const char *GetClipboardText(void)
{
#if defined(PLATFORM_DESKTOP)
- return glfwGetClipboardString(window);
+ return glfwGetClipboardString(CORE.Window.handle);
#else
return NULL;
#endif
@@ -1131,7 +1169,7 @@ const char *GetClipboardText(void)
void SetClipboardText(const char *text)
{
#if defined(PLATFORM_DESKTOP)
- glfwSetClipboardString(window, text);
+ glfwSetClipboardString(CORE.Window.handle, text);
#endif
}
@@ -1139,68 +1177,68 @@ void SetClipboardText(const char *text)
void ShowCursor(void)
{
#if defined(PLATFORM_DESKTOP)
- glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
+ glfwSetInputMode(CORE.Window.handle, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
#endif
#if defined(PLATFORM_UWP)
UWPMessage *msg = CreateUWPMessage();
msg->type = UWP_MSG_SHOW_MOUSE;
SendMessageToUWP(msg);
#endif
- cursorHidden = false;
+ CORE.Input.Mouse.cursorHidden = false;
}
// Hides mouse cursor
void HideCursor(void)
{
#if defined(PLATFORM_DESKTOP)
- glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
+ glfwSetInputMode(CORE.Window.handle, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
#endif
#if defined(PLATFORM_UWP)
UWPMessage *msg = CreateUWPMessage();
msg->type = UWP_MSG_HIDE_MOUSE;
SendMessageToUWP(msg);
#endif
- cursorHidden = true;
+ CORE.Input.Mouse.cursorHidden = true;
}
// Check if cursor is not visible
bool IsCursorHidden(void)
{
- return cursorHidden;
+ return CORE.Input.Mouse.cursorHidden;
}
// Enables cursor (unlock cursor)
void EnableCursor(void)
{
#if defined(PLATFORM_DESKTOP)
- glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
+ glfwSetInputMode(CORE.Window.handle, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
#endif
#if defined(PLATFORM_WEB)
- toggleCursorLock = true;
+ CORE.Input.Mouse.cursorLockRequired = true;
#endif
#if defined(PLATFORM_UWP)
UWPMessage *msg = CreateUWPMessage();
msg->type = UWP_MSG_LOCK_MOUSE;
SendMessageToUWP(msg);
#endif
- cursorHidden = false;
+ CORE.Input.Mouse.cursorHidden = false;
}
// Disables cursor (lock cursor)
void DisableCursor(void)
{
#if defined(PLATFORM_DESKTOP)
- glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
+ glfwSetInputMode(CORE.Window.handle, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
#endif
#if defined(PLATFORM_WEB)
- toggleCursorLock = true;
+ CORE.Input.Mouse.cursorLockRequired = true;
#endif
#if defined(PLATFORM_UWP)
UWPMessage *msg = CreateUWPMessage();
msg->type = UWP_MSG_UNLOCK_MOUSE;
SendMessageToUWP(msg);
#endif
- cursorHidden = true;
+ CORE.Input.Mouse.cursorHidden = true;
}
// Set background color (framebuffer clear color)
@@ -1213,12 +1251,12 @@ void ClearBackground(Color color)
// Setup canvas (framebuffer) to start drawing
void BeginDrawing(void)
{
- currentTime = GetTime(); // Number of elapsed seconds since InitTimer()
- updateTime = currentTime - previousTime;
- previousTime = currentTime;
+ CORE.Time.current = GetTime(); // Number of elapsed seconds since InitTimer()
+ CORE.Time.update = CORE.Time.current - CORE.Time.previous;
+ CORE.Time.previous = CORE.Time.current;
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
- rlMultMatrixf(MatrixToFloat(screenScaling)); // Apply screen scaling
+ rlMultMatrixf(MatrixToFloat(CORE.Window.screenScale)); // Apply screen scaling
//rlTranslatef(0.375, 0.375, 0); // HACK to have 2D pixel-perfect drawing on OpenGL 1.1
// NOTE: Not required with OpenGL 3.3+
@@ -1230,13 +1268,12 @@ void EndDrawing(void)
#if defined(PLATFORM_RPI) && defined(SUPPORT_MOUSE_CURSOR_RPI)
// On RPI native mode we have no system mouse cursor, so,
// we draw a small rectangle for user reference
- DrawRectangle(mousePosition.x, mousePosition.y, 3, 3, MAROON);
+ DrawRectangle(CORE.Input.Mouse.position.x, CORE.Input.Mouse.position.y, 3, 3, MAROON);
#endif
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
#if defined(SUPPORT_GIF_RECORDING)
-
#define GIF_RECORD_FRAMERATE 10
if (gifRecording)
@@ -1248,16 +1285,16 @@ void EndDrawing(void)
{
// Get image data for the current frame (from backbuffer)
// NOTE: This process is very slow... :(
- unsigned char *screenData = rlReadScreenPixels(screenWidth, screenHeight);
- GifWriteFrame(screenData, screenWidth, screenHeight, 10, 8, false);
+ unsigned char *screenData = rlReadScreenPixels(CORE.Window.screen.width, CORE.Window.screen.height);
+ GifWriteFrame(screenData, CORE.Window.screen.width, CORE.Window.screen.height, 10, 8, false);
RL_FREE(screenData); // Free image data
}
if (((gifFramesCounter/15)%2) == 1)
{
- DrawCircle(30, screenHeight - 20, 10, RED);
- DrawText("RECORDING", 50, screenHeight - 25, 10, MAROON);
+ DrawCircle(30, CORE.Window.screen.height - 20, 10, RED);
+ DrawText("RECORDING", 50, CORE.Window.screen.height - 25, 10, MAROON);
}
rlglDraw(); // Draw RECORDING message
@@ -1266,28 +1303,28 @@ void EndDrawing(void)
SwapBuffers(); // Copy back buffer to front buffer
PollInputEvents(); // Poll user events
-
+
// Frame time control system
- currentTime = GetTime();
- drawTime = currentTime - previousTime;
- previousTime = currentTime;
+ CORE.Time.current = GetTime();
+ CORE.Time.draw = CORE.Time.current - CORE.Time.previous;
+ CORE.Time.previous = CORE.Time.current;
+
+ CORE.Time.frame = CORE.Time.update + CORE.Time.draw;
- frameTime = updateTime + drawTime;
-
// Wait for some milliseconds...
- if (frameTime < targetTime)
+ if (CORE.Time.frame < CORE.Time.target)
{
- Wait((float)(targetTime - frameTime)*1000.0f);
+ Wait((float)(CORE.Time.target - CORE.Time.frame)*1000.0f);
+
+ CORE.Time.current = GetTime();
+ double waitTime = CORE.Time.current - CORE.Time.previous;
+ CORE.Time.previous = CORE.Time.current;
- currentTime = GetTime();
- double waitTime = currentTime - previousTime;
- previousTime = currentTime;
+ CORE.Time.frame += waitTime; // Total frame time: update + draw + wait
- frameTime += waitTime; // Total frame time: update + draw + wait
-
- //SetWindowTitle(FormatText("Update: %f, Draw: %f, Req.Wait: %f, Real.Wait: %f, Total: %f, Target: %f\n",
- // (float)updateTime, (float)drawTime, (float)(targetTime - (updateTime + drawTime)),
- // (float)waitTime, (float)frameTime, (float)targetTime));
+ //SetWindowTitle(FormatText("Update: %f, Draw: %f, Req.Wait: %f, Real.Wait: %f, Total: %f, Target: %f\n",
+ // (float)CORE.Time.update, (float)CORE.Time.draw, (float)(CORE.Time.target - (CORE.Time.update + CORE.Time.draw)),
+ // (float)waitTime, (float)CORE.Time.frame, (float)CORE.Time.target));
}
}
@@ -1298,11 +1335,11 @@ void BeginMode2D(Camera2D camera)
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
- // Apply screen scaling if required
- rlMultMatrixf(MatrixToFloat(screenScaling));
-
// Apply 2d camera transformation to modelview
rlMultMatrixf(MatrixToFloat(GetCameraMatrix2D(camera)));
+
+ // Apply screen scaling if required
+ rlMultMatrixf(MatrixToFloat(CORE.Window.screenScale));
}
// Ends 2D mode with custom camera
@@ -1311,7 +1348,7 @@ void EndMode2D(void)
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
- rlMultMatrixf(MatrixToFloat(screenScaling)); // Apply screen scaling if required
+ rlMultMatrixf(MatrixToFloat(CORE.Window.screenScale)); // Apply screen scaling if required
}
// Initializes 3D mode with custom camera (3D)
@@ -1323,7 +1360,7 @@ void BeginMode3D(Camera3D camera)
rlPushMatrix(); // Save previous matrix, which contains the settings for the 2d ortho projection
rlLoadIdentity(); // Reset current matrix (PROJECTION)
- float aspect = (float)currentWidth/(float)currentHeight;
+ float aspect = (float)CORE.Window.currentFbo.width/(float)CORE.Window.currentFbo.height;
if (camera.type == CAMERA_PERSPECTIVE)
{
@@ -1331,7 +1368,7 @@ void BeginMode3D(Camera3D camera)
double top = 0.01*tan(camera.fovy*0.5*DEG2RAD);
double right = top*aspect;
- rlFrustum(-right, right, -top, top, 0.01, 1000.0);
+ rlFrustum(-right, right, -top, top, DEFAULT_NEAR_CULL_DISTANCE, DEFAULT_FAR_CULL_DISTANCE);
}
else if (camera.type == CAMERA_ORTHOGRAPHIC)
{
@@ -1339,7 +1376,7 @@ void BeginMode3D(Camera3D camera)
double top = camera.fovy/2.0;
double right = top*aspect;
- rlOrtho(-right,right,-top,top, 0.01, 1000.0);
+ rlOrtho(-right, right, -top,top, DEFAULT_NEAR_CULL_DISTANCE, DEFAULT_FAR_CULL_DISTANCE);
}
// NOTE: zNear and zFar values are important when computing depth buffer values
@@ -1365,7 +1402,7 @@ void EndMode3D(void)
rlMatrixMode(RL_MODELVIEW); // Get back to modelview matrix
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
- rlMultMatrixf(MatrixToFloat(screenScaling)); // Apply screen scaling if required
+ rlMultMatrixf(MatrixToFloat(CORE.Window.screenScale)); // Apply screen scaling if required
rlDisableDepthTest(); // Disable DEPTH_TEST for 2D
}
@@ -1394,8 +1431,8 @@ void BeginTextureMode(RenderTexture2D target)
// Setup current width/height for proper aspect ratio
// calculation when using BeginMode3D()
- currentWidth = target.texture.width;
- currentHeight = target.texture.height;
+ CORE.Window.currentFbo.width = target.texture.width;
+ CORE.Window.currentFbo.height = target.texture.height;
}
// Ends drawing to render texture
@@ -1406,11 +1443,11 @@ void EndTextureMode(void)
rlDisableRenderTexture(); // Disable render target
// Set viewport to default framebuffer size
- SetupViewport(renderWidth, renderHeight);
+ SetupViewport(CORE.Window.render.width, CORE.Window.render.height);
// Reset current screen size
- currentWidth = GetScreenWidth();
- currentHeight = GetScreenHeight();
+ CORE.Window.currentFbo.width = GetScreenWidth();
+ CORE.Window.currentFbo.height = GetScreenHeight();
}
// Begin scissor mode (define screen area for following drawing)
@@ -1431,14 +1468,14 @@ void EndScissorMode(void)
}
// Returns a ray trace from mouse position
-Ray GetMouseRay(Vector2 mousePosition, Camera camera)
+Ray GetMouseRay(Vector2 mouse, 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 x = (2.0f*mouse.x)/(float)GetScreenWidth() - 1.0f;
+ float y = 1.0f - (2.0f*mouse.y)/(float)GetScreenHeight();
float z = 1.0f;
// Store values in a vector
@@ -1452,11 +1489,11 @@ Ray GetMouseRay(Vector2 mousePosition, Camera camera)
if (camera.type == CAMERA_PERSPECTIVE)
{
// Calculate projection matrix from perspective
- matProj = MatrixPerspective(camera.fovy*DEG2RAD, ((double)GetScreenWidth()/(double)GetScreenHeight()), 0.01, 1000.0);
+ matProj = MatrixPerspective(camera.fovy*DEG2RAD, ((double)GetScreenWidth()/(double)GetScreenHeight()), DEFAULT_NEAR_CULL_DISTANCE, DEFAULT_FAR_CULL_DISTANCE);
}
else if (camera.type == CAMERA_ORTHOGRAPHIC)
{
- float aspect = (float)screenWidth/(float)screenHeight;
+ float aspect = (float)CORE.Window.screen.width/(float)CORE.Window.screen.height;
double top = camera.fovy/2.0;
double right = top*aspect;
@@ -1522,22 +1559,30 @@ Matrix GetCameraMatrix2D(Camera2D camera)
// Returns the screen space position from a 3d world space position
Vector2 GetWorldToScreen(Vector3 position, Camera camera)
{
+ Vector2 screenPosition = GetWorldToScreenEx(position, camera, GetScreenWidth(), GetScreenHeight());
+
+ return screenPosition;
+}
+
+// Returns size position for a 3d world space position (useful for texture drawing)
+Vector2 GetWorldToScreenEx(Vector3 position, Camera camera, int width, int height)
+{
// Calculate projection matrix (from perspective instead of frustum
Matrix matProj = MatrixIdentity();
if (camera.type == CAMERA_PERSPECTIVE)
{
// Calculate projection matrix from perspective
- matProj = MatrixPerspective(camera.fovy*DEG2RAD, ((double)GetScreenWidth()/(double)GetScreenHeight()), 0.01, 1000.0);
+ matProj = MatrixPerspective(camera.fovy * DEG2RAD, ((double)width/(double)height), DEFAULT_NEAR_CULL_DISTANCE, DEFAULT_FAR_CULL_DISTANCE);
}
else if (camera.type == CAMERA_ORTHOGRAPHIC)
{
- float aspect = (float)screenWidth/(float)screenHeight;
+ float aspect = (float)CORE.Window.screen.width/(float)CORE.Window.screen.height;
double top = camera.fovy/2.0;
double right = top*aspect;
// Calculate projection matrix from orthographic
- matProj = MatrixOrtho(-right, right, -top, top, 0.01, 1000.0);
+ matProj = MatrixOrtho(-right, right, -top, top, DEFAULT_NEAR_CULL_DISTANCE, DEFAULT_FAR_CULL_DISTANCE);
}
// Calculate view matrix from camera look at (and transpose it)
@@ -1556,7 +1601,7 @@ Vector2 GetWorldToScreen(Vector3 position, Camera camera)
Vector3 ndcPos = { worldPos.x/worldPos.w, -worldPos.y/worldPos.w, worldPos.z/worldPos.w };
// Calculate 2d screen position vector
- Vector2 screenPosition = { (ndcPos.x + 1.0f)/2.0f*(float)GetScreenWidth(), (ndcPos.y + 1.0f)/2.0f*(float)GetScreenHeight() };
+ Vector2 screenPosition = { (ndcPos.x + 1.0f)/2.0f*(float)width, (ndcPos.y + 1.0f)/2.0f*(float)height };
return screenPosition;
}
@@ -1582,22 +1627,43 @@ Vector2 GetScreenToWorld2D(Vector2 position, Camera2D camera)
// Set target FPS (maximum)
void SetTargetFPS(int fps)
{
- if (fps < 1) targetTime = 0.0;
- else targetTime = 1.0/(double)fps;
+ if (fps < 1) CORE.Time.target = 0.0;
+ else CORE.Time.target = 1.0/(double)fps;
- TraceLog(LOG_INFO, "Target time per frame: %02.03f milliseconds", (float)targetTime*1000);
+ TRACELOG(LOG_INFO, "TIMER: Target time per frame: %02.03f milliseconds", (float)CORE.Time.target*1000);
}
// Returns current FPS
+// NOTE: We calculate an average framerate
int GetFPS(void)
{
- return (int)roundf(1.0f/GetFrameTime());
+ #define FPS_CAPTURE_FRAMES_COUNT 30 // 30 captures
+ #define FPS_AVERAGE_TIME_SECONDS 0.5f // 500 millisecondes
+ #define FPS_STEP (FPS_AVERAGE_TIME_SECONDS/FPS_CAPTURE_FRAMES_COUNT)
+
+ static int index = 0;
+ static float history[FPS_CAPTURE_FRAMES_COUNT] = { 0 };
+ static float average = 0, last = 0;
+ float fpsFrame = GetFrameTime();
+
+ if (fpsFrame == 0) return 0;
+
+ if ((GetTime() - last) > FPS_STEP)
+ {
+ last = GetTime();
+ index = (index + 1)%FPS_CAPTURE_FRAMES_COUNT;
+ average -= history[index];
+ history[index] = fpsFrame/FPS_CAPTURE_FRAMES_COUNT;
+ average += history[index];
+ }
+
+ return (int)roundf(1.0f/average);
}
// Returns time in seconds for last frame drawn
float GetFrameTime(void)
{
- return (float)frameTime;
+ return (float)CORE.Time.frame;
}
// Get elapsed time measure in seconds since InitTimer()
@@ -1612,14 +1678,14 @@ double GetTime(void)
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
- uint64_t time = (uint64_t)ts.tv_sec*1000000000LLU + (uint64_t)ts.tv_nsec;
+ unsigned long long int time = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec;
- return (double)(time - baseTime)*1e-9; // Elapsed time since InitTimer()
+ return (double)(time - CORE.Time.base)*1e-9; // Elapsed time since InitTimer()
#endif
#if defined(PLATFORM_UWP)
// Updated through messages
- return currentTime;
+ return CORE.Time.current;
#endif
}
@@ -1659,8 +1725,8 @@ Color ColorFromNormalized(Vector4 normalized)
// NOTE: Hue is returned as degrees [0..360]
Vector3 ColorToHSV(Color color)
{
+ Vector3 hsv = { 0 };
Vector3 rgb = { (float)color.r/255.0f, (float)color.g/255.0f, (float)color.b/255.0f };
- Vector3 hsv = { 0.0f, 0.0f, 0.0f };
float min, max, delta;
min = rgb.x < rgb.y? rgb.x : rgb.y;
@@ -1780,25 +1846,25 @@ Color Fade(Color color, float alpha)
// Setup window configuration flags (view FLAGS)
void SetConfigFlags(unsigned int flags)
{
- configFlags = flags;
+ CORE.Window.flags = flags;
- if (configFlags & FLAG_FULLSCREEN_MODE) fullscreenMode = true;
- if (configFlags & FLAG_WINDOW_ALWAYS_RUN) alwaysRun = true;
+ if (CORE.Window.flags & FLAG_FULLSCREEN_MODE) CORE.Window.fullscreen = true;
+ if (CORE.Window.flags & FLAG_WINDOW_ALWAYS_RUN) CORE.Window.alwaysRun = true;
}
-// NOTE TraceLog() function is located in [utils.h]
+// NOTE TRACELOG() function is located in [utils.h]
// Takes a screenshot of current screen (saved a .png)
// NOTE: This function could work in any platform but some platforms: PLATFORM_ANDROID and PLATFORM_WEB
// have their own internal file-systems, to dowload image to user file-system some additional mechanism is required
void TakeScreenshot(const char *fileName)
{
- unsigned char *imgData = rlReadScreenPixels(renderWidth, renderHeight);
- Image image = { imgData, renderWidth, renderHeight, 1, UNCOMPRESSED_R8G8B8A8 };
+ unsigned char *imgData = rlReadScreenPixels(CORE.Window.render.width, CORE.Window.render.height);
+ Image image = { imgData, CORE.Window.render.width, CORE.Window.render.height, 1, UNCOMPRESSED_R8G8B8A8 };
char path[512] = { 0 };
#if defined(PLATFORM_ANDROID)
- strcpy(path, internalDataPath);
+ strcpy(path, CORE.Android.internalDataPath);
strcat(path, "/");
strcat(path, fileName);
#else
@@ -1814,7 +1880,8 @@ void TakeScreenshot(const char *fileName)
emscripten_run_script(TextFormat("saveFileFromMEMFSToDisk('%s','%s')", GetFileName(path), GetFileName(path)));
#endif
- TraceLog(LOG_INFO, "Screenshot taken: %s", path);
+ // TODO: Verification required for log
+ TRACELOG(LOG_INFO, "SYSTEM: [%s] Screenshot taken successfully", path);
}
// Check if the file exists
@@ -1842,7 +1909,7 @@ bool IsFileExtension(const char *fileName, const char *ext)
{
int extCount = 0;
const char **checkExts = TextSplit(ext, ';', &extCount);
-
+
char fileExtLower[16] = { 0 };
strcpy(fileExtLower, TextToLower(fileExt));
@@ -1931,16 +1998,36 @@ const char *GetFileNameWithoutExt(const char *filePath)
// Get directory for a given filePath
const char *GetDirectoryPath(const char *filePath)
{
+/*
+ // NOTE: Directory separator is different in Windows and other platforms,
+ // fortunately, Windows also support the '/' separator, that's the one should be used
+ #if defined(_WIN32)
+ char separator = '\\';
+ #else
+ char separator = '/';
+ #endif
+*/
const char *lastSlash = NULL;
static char dirPath[MAX_FILEPATH_LENGTH];
memset(dirPath, 0, MAX_FILEPATH_LENGTH);
- lastSlash = strprbrk(filePath, "\\/");
- if (!lastSlash) return NULL;
+ // In case provided path does not contains a root drive letter (C:\, D:\),
+ // we add the current directory path to dirPath
+ if (filePath[1] != ':')
+ {
+ // For security, we set starting path to current directory,
+ // obtained path will be concated to this
+ dirPath[0] = '.';
+ dirPath[1] = '/';
+ }
- // NOTE: Be careful, strncpy() is not safe, it does not care about '\0'
- strncpy(dirPath, filePath, strlen(filePath) - (strlen(lastSlash) - 1));
- dirPath[strlen(filePath) - strlen(lastSlash)] = '\0'; // Add '\0' manually
+ lastSlash = strprbrk(filePath, "\\/");
+ if (lastSlash)
+ {
+ // NOTE: Be careful, strncpy() is not safe, it does not care about '\0'
+ strncpy(dirPath + ((filePath[1] != ':')? 2 : 0), filePath, strlen(filePath) - (strlen(lastSlash) - 1));
+ dirPath[strlen(filePath) - strlen(lastSlash) + ((filePath[1] != ':')? 2 : 0)] = '\0'; // Add '\0' manually
+ }
return dirPath;
}
@@ -1991,7 +2078,7 @@ char **GetDirectoryFiles(const char *dirPath, int *fileCount)
for (int i = 0; i < MAX_DIRECTORY_FILES; i++) dirFilesPath[i] = (char *)RL_MALLOC(sizeof(char)*MAX_FILEPATH_LENGTH);
int counter = 0;
- struct dirent *ent;
+ struct dirent *entity;
DIR *dir = opendir(dirPath);
if (dir != NULL) // It's a directory
@@ -2000,15 +2087,15 @@ char **GetDirectoryFiles(const char *dirPath, int *fileCount)
// first one to count files and second one to read names
// That way we can allocate required memory, instead of a limited pool
- while ((ent = readdir(dir)) != NULL)
+ while ((entity = readdir(dir)) != NULL)
{
- strcpy(dirFilesPath[counter], ent->d_name);
+ strcpy(dirFilesPath[counter], entity->d_name);
counter++;
}
closedir(dir);
}
- else TraceLog(LOG_WARNING, "Can not open directory...\n"); // Maybe it's a file...
+ else TRACELOG(LOG_WARNING, "FILEIO: Failed to open requested directory"); // Maybe it's a file...
dirFilesCount = counter;
*fileCount = dirFilesCount;
@@ -2025,7 +2112,7 @@ void ClearDirectoryFiles(void)
RL_FREE(dirFilesPath);
}
-
+
dirFilesCount = 0;
}
@@ -2038,27 +2125,27 @@ bool ChangeDirectory(const char *dir)
// Check if a file has been dropped into window
bool IsFileDropped(void)
{
- if (dropFilesCount > 0) return true;
+ if (CORE.Window.dropFilesCount > 0) return true;
else return false;
}
// Get dropped files names
char **GetDroppedFiles(int *count)
{
- *count = dropFilesCount;
- return dropFilesPath;
+ *count = CORE.Window.dropFilesCount;
+ return CORE.Window.dropFilesPath;
}
// Clear dropped files paths buffer
void ClearDroppedFiles(void)
{
- if (dropFilesCount > 0)
+ if (CORE.Window.dropFilesCount > 0)
{
- for (int i = 0; i < dropFilesCount; i++) RL_FREE(dropFilesPath[i]);
+ for (int i = 0; i < CORE.Window.dropFilesCount; i++) RL_FREE(CORE.Window.dropFilesPath[i]);
- RL_FREE(dropFilesPath);
+ RL_FREE(CORE.Window.dropFilesPath);
- dropFilesCount = 0;
+ CORE.Window.dropFilesCount = 0;
}
}
@@ -2105,80 +2192,106 @@ unsigned char *DecompressData(unsigned char *compData, int compDataLength, int *
// Save integer value to storage file (to defined position)
// NOTE: Storage positions is directly related to file memory layout (4 bytes each integer)
-void StorageSaveValue(int position, int value)
+void SaveStorageValue(unsigned int position, int value)
{
- FILE *storageFile = NULL;
-
+#if defined(SUPPORT_DATA_STORAGE)
char path[512] = { 0 };
#if defined(PLATFORM_ANDROID)
- strcpy(path, internalDataPath);
+ strcpy(path, CORE.Android.internalDataPath);
strcat(path, "/");
- strcat(path, STORAGE_FILENAME);
+ strcat(path, STORAGE_DATA_FILE);
#else
- strcpy(path, STORAGE_FILENAME);
+ strcpy(path, STORAGE_DATA_FILE);
#endif
- // Try open existing file to append data
- storageFile = fopen(path, "rb+");
-
- // If file doesn't exist, create a new storage data file
- if (!storageFile) storageFile = fopen(path, "wb");
+ unsigned int dataSize = 0;
+ unsigned int newDataSize = 0;
+ unsigned char *fileData = LoadFileData(path, &dataSize);
+ unsigned char *newFileData = NULL;
- if (!storageFile) TraceLog(LOG_WARNING, "Storage data file could not be created");
- else
+ if (fileData != NULL)
{
- // Get file size
- fseek(storageFile, 0, SEEK_END);
- int fileSize = ftell(storageFile); // Size in bytes
- fseek(storageFile, 0, SEEK_SET);
+ if (dataSize <= (position*sizeof(int)))
+ {
+ // Increase data size up to position and store value
+ newDataSize = (position + 1)*sizeof(int);
+ newFileData = (unsigned char *)RL_REALLOC(fileData, newDataSize);
- if (fileSize < (position*sizeof(int))) TraceLog(LOG_WARNING, "Storage position could not be found");
+ if (newFileData != NULL)
+ {
+ // RL_REALLOC succeded
+ int *dataPtr = (int *)newFileData;
+ dataPtr[position] = value;
+ }
+ else
+ {
+ // RL_REALLOC failed
+ TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to realloc data (%u), position in bytes (%u) bigger than actual file size", path, dataSize, position*sizeof(int));
+
+ // We store the old size of the file
+ newFileData = fileData;
+ newDataSize = dataSize;
+ }
+ }
else
{
- fseek(storageFile, (position*sizeof(int)), SEEK_SET);
- fwrite(&value, 1, sizeof(int), storageFile);
+ // Store the old size of the file
+ newFileData = fileData;
+ newDataSize = dataSize;
+
+ // Replace value on selected position
+ int *dataPtr = (int *)newFileData;
+ dataPtr[position] = value;
}
- fclose(storageFile);
+ SaveFileData(path, newFileData, newDataSize);
+ RL_FREE(newFileData);
+ }
+ else
+ {
+ TRACELOG(LOG_INFO, "FILEIO: [%s] File not found, creating it", path);
+
+ dataSize = (position + 1)*sizeof(int);
+ fileData = (unsigned char *)RL_MALLOC(dataSize);
+ int *dataPtr = (int *)fileData;
+ dataPtr[position] = value;
+
+ SaveFileData(path, fileData, dataSize);
+ RL_FREE(fileData);
}
+#endif
}
// Load integer value from storage file (from defined position)
// NOTE: If requested position could not be found, value 0 is returned
-int StorageLoadValue(int position)
+int LoadStorageValue(unsigned int position)
{
int value = 0;
-
+#if defined(SUPPORT_DATA_STORAGE)
char path[512] = { 0 };
#if defined(PLATFORM_ANDROID)
- strcpy(path, internalDataPath);
+ strcpy(path, CORE.Android.internalDataPath);
strcat(path, "/");
- strcat(path, STORAGE_FILENAME);
+ strcat(path, STORAGE_DATA_FILE);
#else
- strcpy(path, STORAGE_FILENAME);
+ strcpy(path, STORAGE_DATA_FILE);
#endif
- // Try open existing file to append data
- FILE *storageFile = fopen(path, "rb");
+ unsigned int dataSize = 0;
+ unsigned char *fileData = LoadFileData(path, &dataSize);
- if (!storageFile) TraceLog(LOG_WARNING, "Storage data file could not be found");
- else
+ if (fileData != NULL)
{
- // Get file size
- fseek(storageFile, 0, SEEK_END);
- int fileSize = ftell(storageFile); // Size in bytes
- rewind(storageFile);
-
- if (fileSize < (position*4)) TraceLog(LOG_WARNING, "Storage position could not be found");
+ if (dataSize < (position*4)) TRACELOG(LOG_WARNING, "SYSTEM: Failed to find storage position");
else
{
- fseek(storageFile, (position*4), SEEK_SET);
- fread(&value, 4, 1, storageFile); // Read 1 element of 4 bytes size
+ int *dataPtr = (int *)fileData;
+ value = dataPtr[position];
}
- fclose(storageFile);
+ RL_FREE(fileData);
}
-
+#endif
return value;
}
@@ -2193,21 +2306,25 @@ void OpenURL(const char *url)
// sorry for the inconvenience when you hit this point...
if (strchr(url, '\'') != NULL)
{
- TraceLog(LOG_WARNING, "Provided URL does not seem to be valid.");
+ TRACELOG(LOG_WARNING, "SYSTEM: Provided URL is not valid");
}
else
{
+#if defined(PLATFORM_DESKTOP)
char *cmd = (char *)RL_CALLOC(strlen(url) + 10, sizeof(char));
-
-#if defined(_WIN32)
+ #if defined(_WIN32)
sprintf(cmd, "explorer %s", url);
-#elif defined(__linux__)
+ #elif defined(__linux__)
sprintf(cmd, "xdg-open '%s'", url); // Alternatives: firefox, x-www-browser
-#elif defined(__APPLE__)
+ #elif defined(__APPLE__)
sprintf(cmd, "open '%s'", url);
-#endif
+ #endif
system(cmd);
RL_FREE(cmd);
+#endif
+#if defined(PLATFORM_WEB)
+ emscripten_run_script(TextFormat("window.open('%s', '_blank')", url));
+#endif
}
}
@@ -2219,7 +2336,7 @@ bool IsKeyPressed(int key)
{
bool pressed = false;
- if ((currentKeyState[key] != previousKeyState[key]) && (currentKeyState[key] == 1)) pressed = true;
+ if ((CORE.Input.Keyboard.previousKeyState[key] == 0) && (CORE.Input.Keyboard.currentKeyState[key] == 1)) pressed = true;
else pressed = false;
return pressed;
@@ -2228,7 +2345,7 @@ bool IsKeyPressed(int key)
// Detect if a key is being pressed (key held down)
bool IsKeyDown(int key)
{
- if (GetKeyStatus(key) == 1) return true;
+ if (CORE.Input.Keyboard.currentKeyState[key] == 1) return true;
else return false;
}
@@ -2237,7 +2354,7 @@ bool IsKeyReleased(int key)
{
bool released = false;
- if ((currentKeyState[key] != previousKeyState[key]) && (currentKeyState[key] == 0)) released = true;
+ if ((CORE.Input.Keyboard.previousKeyState[key] == 1) && (CORE.Input.Keyboard.currentKeyState[key] == 0)) released = true;
else released = false;
return released;
@@ -2246,7 +2363,7 @@ bool IsKeyReleased(int key)
// Detect if a key is NOT being pressed (key not held down)
bool IsKeyUp(int key)
{
- if (GetKeyStatus(key) == 0) return true;
+ if (CORE.Input.Keyboard.currentKeyState[key] == 0) return true;
else return false;
}
@@ -2255,17 +2372,17 @@ int GetKeyPressed(void)
{
int value = 0;
- if (keyPressedQueueCount > 0)
+ if (CORE.Input.Keyboard.keyPressedQueueCount > 0)
{
// Get character from the queue head
- value = keyPressedQueue[0];
+ value = CORE.Input.Keyboard.keyPressedQueue[0];
// Shift elements 1 step toward the head.
- for (int i = 0; i < (keyPressedQueueCount - 1); i++) keyPressedQueue[i] = keyPressedQueue[i + 1];
+ for (int i = 0; i < (CORE.Input.Keyboard.keyPressedQueueCount - 1); i++) CORE.Input.Keyboard.keyPressedQueue[i] = CORE.Input.Keyboard.keyPressedQueue[i + 1];
// Reset last character in the queue
- keyPressedQueue[keyPressedQueueCount] = 0;
- keyPressedQueueCount--;
+ CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = 0;
+ CORE.Input.Keyboard.keyPressedQueueCount--;
}
return value;
@@ -2276,7 +2393,7 @@ int GetKeyPressed(void)
void SetExitKey(int key)
{
#if !defined(PLATFORM_ANDROID)
- exitKey = key;
+ CORE.Input.Keyboard.exitKey = key;
#endif
}
@@ -2288,7 +2405,7 @@ bool IsGamepadAvailable(int gamepad)
bool result = false;
#if !defined(PLATFORM_ANDROID)
- if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad]) result = true;
+ if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad]) result = true;
#endif
return result;
@@ -2300,10 +2417,10 @@ bool IsGamepadName(int gamepad, const char *name)
bool result = false;
#if !defined(PLATFORM_ANDROID)
- const char *gamepadName = NULL;
+ const char *currentName = NULL;
- if (gamepadReady[gamepad]) gamepadName = GetGamepadName(gamepad);
- if ((name != NULL) && (gamepadName != NULL)) result = (strcmp(name, gamepadName) == 0);
+ if (CORE.Input.Gamepad.ready[gamepad]) currentName = GetGamepadName(gamepad);
+ if ((name != NULL) && (currentName != NULL)) result = (strcmp(name, currentName) == 0);
#endif
return result;
@@ -2313,12 +2430,12 @@ bool IsGamepadName(int gamepad, const char *name)
const char *GetGamepadName(int gamepad)
{
#if defined(PLATFORM_DESKTOP)
- if (gamepadReady[gamepad]) return glfwGetJoystickName(gamepad);
+ if (CORE.Input.Gamepad.ready[gamepad]) return glfwGetJoystickName(gamepad);
else return NULL;
#elif defined(PLATFORM_RPI)
- if (gamepadReady[gamepad]) ioctl(gamepadStream[gamepad], JSIOCGNAME(64), &gamepadName);
+ if (CORE.Input.Gamepad.ready[gamepad]) ioctl(CORE.Input.Gamepad.streamId[gamepad], JSIOCGNAME(64), &CORE.Input.Gamepad.name);
- return gamepadName;
+ return CORE.Input.Gamepad.name;
#else
return NULL;
#endif
@@ -2329,10 +2446,10 @@ int GetGamepadAxisCount(int gamepad)
{
#if defined(PLATFORM_RPI)
int axisCount = 0;
- if (gamepadReady[gamepad]) ioctl(gamepadStream[gamepad], JSIOCGAXES, &axisCount);
- gamepadAxisCount = axisCount;
+ if (CORE.Input.Gamepad.ready[gamepad]) ioctl(CORE.Input.Gamepad.streamId[gamepad], JSIOCGAXES, &axisCount);
+ CORE.Input.Gamepad.axisCount = axisCount;
#endif
- return gamepadAxisCount;
+ return CORE.Input.Gamepad.axisCount;
}
// Return axis movement vector for a gamepad
@@ -2341,7 +2458,7 @@ float GetGamepadAxisMovement(int gamepad, int axis)
float value = 0;
#if !defined(PLATFORM_ANDROID)
- if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (axis < MAX_GAMEPAD_AXIS)) value = gamepadAxisState[gamepad][axis];
+ if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (axis < MAX_GAMEPAD_AXIS)) value = CORE.Input.Gamepad.axisState[gamepad][axis];
#endif
return value;
@@ -2353,9 +2470,9 @@ bool IsGamepadButtonPressed(int gamepad, int button)
bool pressed = false;
#if !defined(PLATFORM_ANDROID)
- if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
- (currentGamepadState[gamepad][button] != previousGamepadState[gamepad][button]) &&
- (currentGamepadState[gamepad][button] == 1)) pressed = true;
+ if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
+ (CORE.Input.Gamepad.currentState[gamepad][button] != CORE.Input.Gamepad.previousState[gamepad][button]) &&
+ (CORE.Input.Gamepad.currentState[gamepad][button] == 1)) pressed = true;
#endif
return pressed;
@@ -2367,8 +2484,8 @@ bool IsGamepadButtonDown(int gamepad, int button)
bool result = false;
#if !defined(PLATFORM_ANDROID)
- if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
- (currentGamepadState[gamepad][button] == 1)) result = true;
+ if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
+ (CORE.Input.Gamepad.currentState[gamepad][button] == 1)) result = true;
#endif
return result;
@@ -2380,9 +2497,9 @@ bool IsGamepadButtonReleased(int gamepad, int button)
bool released = false;
#if !defined(PLATFORM_ANDROID)
- if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
- (currentGamepadState[gamepad][button] != previousGamepadState[gamepad][button]) &&
- (currentGamepadState[gamepad][button] == 0)) released = true;
+ if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
+ (CORE.Input.Gamepad.currentState[gamepad][button] != CORE.Input.Gamepad.previousState[gamepad][button]) &&
+ (CORE.Input.Gamepad.currentState[gamepad][button] == 0)) released = true;
#endif
return released;
@@ -2394,8 +2511,8 @@ bool IsGamepadButtonUp(int gamepad, int button)
bool result = false;
#if !defined(PLATFORM_ANDROID)
- if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
- (currentGamepadState[gamepad][button] == 0)) result = true;
+ if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
+ (CORE.Input.Gamepad.currentState[gamepad][button] == 0)) result = true;
#endif
return result;
@@ -2404,7 +2521,7 @@ bool IsGamepadButtonUp(int gamepad, int button)
// Get the last gamepad button pressed
int GetGamepadButtonPressed(void)
{
- return lastGamepadButtonPressed;
+ return CORE.Input.Gamepad.lastButtonPressed;
}
// Detect if a mouse button has been pressed once
@@ -2412,19 +2529,11 @@ bool IsMouseButtonPressed(int button)
{
bool pressed = false;
-// TODO: Review, gestures could be not supported despite being on Android platform!
-#if defined(PLATFORM_ANDROID)
- if (IsGestureDetected(GESTURE_TAP)) pressed = true;
-#else
- if ((currentMouseState[button] != previousMouseState[button]) && (currentMouseState[button] == 1)) pressed = true;
-#endif
+ if ((CORE.Input.Mouse.currentButtonState[button] == 1) && (CORE.Input.Mouse.previousButtonState[button] == 0)) pressed = true;
+
+ // Map touches to mouse buttons checking
+ if ((CORE.Input.Touch.currentTouchState[button] == 1) && (CORE.Input.Touch.previousTouchState[button] == 0)) pressed = true;
-/*
-#if defined(PLATFORM_WEB)
- Vector2 pos = GetTouchPosition(0);
- if ((pos.x > 0) && (pos.y > 0)) pressed = true; // There was a touch!
-#endif
-*/
return pressed;
}
@@ -2433,11 +2542,10 @@ 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
+ if (CORE.Input.Mouse.currentButtonState[button] == 1) down = true;
+
+ // Map touches to mouse buttons checking
+ if (CORE.Input.Touch.currentTouchState[button] == 1) down = true;
return down;
}
@@ -2447,9 +2555,10 @@ bool IsMouseButtonReleased(int button)
{
bool released = false;
-#if !defined(PLATFORM_ANDROID)
- if ((currentMouseState[button] != previousMouseState[button]) && (currentMouseState[button] == 0)) released = true;
-#endif
+ if ((CORE.Input.Mouse.currentButtonState[button] == 0) && (CORE.Input.Mouse.previousButtonState[button] == 1)) released = true;
+
+ // Map touches to mouse buttons checking
+ if ((CORE.Input.Touch.currentTouchState[button] == 0) && (CORE.Input.Touch.previousTouchState[button] == 1)) released = true;
return released;
}
@@ -2457,22 +2566,16 @@ bool IsMouseButtonReleased(int button)
// Detect if a mouse button is NOT being pressed
bool IsMouseButtonUp(int button)
{
- bool up = false;
-
-#if !defined(PLATFORM_ANDROID)
- if (GetMouseButtonStatus(button) == 0) up = true;
-#endif
-
- return up;
+ return !IsMouseButtonDown(button);
}
// Returns mouse position X
int GetMouseX(void)
{
#if defined(PLATFORM_ANDROID)
- return (int)touchPosition[0].x;
+ return (int)CORE.Input.Touch.position[0].x;
#else
- return (int)((mousePosition.x + mouseOffset.x)*mouseScale.x);
+ return (int)((CORE.Input.Mouse.position.x + CORE.Input.Mouse.offset.x)*CORE.Input.Mouse.scale.x);
#endif
}
@@ -2480,46 +2583,40 @@ int GetMouseX(void)
int GetMouseY(void)
{
#if defined(PLATFORM_ANDROID)
- return (int)touchPosition[0].y;
+ return (int)CORE.Input.Touch.position[0].y;
#else
- return (int)((mousePosition.y + mouseOffset.y)*mouseScale.y);
+ return (int)((CORE.Input.Mouse.position.y + CORE.Input.Mouse.offset.y)*CORE.Input.Mouse.scale.y);
#endif
}
// Returns mouse position XY
Vector2 GetMousePosition(void)
{
- Vector2 position = { 0.0f, 0.0f };
+ Vector2 position = { 0 };
-#if defined(PLATFORM_ANDROID)
+#if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB)
position = GetTouchPosition(0);
#else
- position = (Vector2){ (mousePosition.x + mouseOffset.x)*mouseScale.x, (mousePosition.y + mouseOffset.y)*mouseScale.y };
+ position.x = (CORE.Input.Mouse.position.x + CORE.Input.Mouse.offset.x)*CORE.Input.Mouse.scale.x;
+ position.y = (CORE.Input.Mouse.position.y + CORE.Input.Mouse.offset.y)*CORE.Input.Mouse.scale.y;
#endif
-/*
-#if defined(PLATFORM_WEB)
- Vector2 pos = GetTouchPosition(0);
- // Touch position has priority over mouse position
- if ((pos.x > 0) && (pos.y > 0)) position = pos; // There was a touch!
-#endif
-*/
return position;
}
// Set mouse position XY
void SetMousePosition(int x, int y)
{
- mousePosition = (Vector2){ (float)x, (float)y };
+ CORE.Input.Mouse.position = (Vector2){ (float)x, (float)y };
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
// NOTE: emscripten not implemented
- glfwSetCursorPos(window, mousePosition.x, mousePosition.y);
+ glfwSetCursorPos(CORE.Window.handle, CORE.Input.Mouse.position.x, CORE.Input.Mouse.position.y);
#endif
#if defined(PLATFORM_UWP)
UWPMessage *msg = CreateUWPMessage();
msg->type = UWP_MSG_SET_MOUSE_LOCATION;
- msg->paramVector0.x = mousePosition.x;
- msg->paramVector0.y = mousePosition.y;
+ msg->paramVector0.x = CORE.Input.Mouse.position.x;
+ msg->paramVector0.y = CORE.Input.Mouse.position.y;
SendMessageToUWP(msg);
#endif
}
@@ -2528,14 +2625,14 @@ void SetMousePosition(int x, int y)
// NOTE: Useful when rendering to different size targets
void SetMouseOffset(int offsetX, int offsetY)
{
- mouseOffset = (Vector2){ (float)offsetX, (float)offsetY };
+ CORE.Input.Mouse.offset = (Vector2){ (float)offsetX, (float)offsetY };
}
// Set mouse scaling
// NOTE: Useful when rendering to different size targets
void SetMouseScale(float scaleX, float scaleY)
{
- mouseScale = (Vector2){ scaleX, scaleY };
+ CORE.Input.Mouse.scale = (Vector2){ scaleX, scaleY };
}
// Returns mouse wheel movement Y
@@ -2544,9 +2641,9 @@ int GetMouseWheelMove(void)
#if defined(PLATFORM_ANDROID)
return 0;
#elif defined(PLATFORM_WEB)
- return previousMouseWheelY/100;
+ return CORE.Input.Mouse.previousWheelMove/100;
#else
- return previousMouseWheelY;
+ return CORE.Input.Mouse.previousWheelMove;
#endif
}
@@ -2554,7 +2651,7 @@ int GetMouseWheelMove(void)
int GetTouchX(void)
{
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB)
- return (int)touchPosition[0].x;
+ return (int)CORE.Input.Touch.position[0].x;
#else // PLATFORM_DESKTOP, PLATFORM_RPI
return GetMouseX();
#endif
@@ -2564,7 +2661,7 @@ int GetTouchX(void)
int GetTouchY(void)
{
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB)
- return (int)touchPosition[0].y;
+ return (int)CORE.Input.Touch.position[0].y;
#else // PLATFORM_DESKTOP, PLATFORM_RPI
return GetMouseY();
#endif
@@ -2576,32 +2673,27 @@ 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(LOG_WARNING, "Required touch point out of range (Max touch points: %i)", MAX_TOUCH_POINTS);
+#if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB) || defined(PLATFORM_RPI)
+ if (index < MAX_TOUCH_POINTS) position = CORE.Input.Touch.position[index];
+ else TRACELOG(LOG_WARNING, "INPUT: Required touch point out of range (Max touch points: %i)", MAX_TOUCH_POINTS);
- if ((screenWidth > displayWidth) || (screenHeight > displayHeight))
+ #if defined(PLATFORM_ANDROID)
+ if ((CORE.Window.screen.width > CORE.Window.display.width) || (CORE.Window.screen.height > CORE.Window.display.height))
{
- // TODO: Review touch position scaling for screenSize vs displaySize
- position.x = position.x*((float)screenWidth/(float)(displayWidth - renderOffsetX)) - renderOffsetX/2;
- position.y = position.y*((float)screenHeight/(float)(displayHeight - renderOffsetY)) - renderOffsetY/2;
+ position.x = position.x*((float)CORE.Window.screen.width/(float)(CORE.Window.display.width - CORE.Window.renderOffset.x)) - CORE.Window.renderOffset.x/2;
+ position.y = position.y*((float)CORE.Window.screen.height/(float)(CORE.Window.display.height - CORE.Window.renderOffset.y)) - CORE.Window.renderOffset.y/2;
}
else
{
- position.x = position.x*((float)renderWidth/(float)displayWidth) - renderOffsetX/2;
- position.y = position.y*((float)renderHeight/(float)displayHeight) - renderOffsetY/2;
+ position.x = position.x*((float)CORE.Window.render.width/(float)CORE.Window.display.width) - CORE.Window.renderOffset.x/2;
+ position.y = position.y*((float)CORE.Window.render.height/(float)CORE.Window.display.height) - CORE.Window.renderOffset.y/2;
}
-#elif defined(PLATFORM_RPI)
-
- position = touchPosition[index];
-
-#else // PLATFORM_DESKTOP
+ #endif
+#elif defined(PLATFORM_DESKTOP)
// TODO: GLFW is not supporting multi-touch input just yet
-
// https://www.codeproject.com/Articles/668404/Programming-for-Multi-Touch
// https://docs.microsoft.com/en-us/windows/win32/wintouch/getting-started-with-multi-touch-messages
-
if (index == 0) position = GetMousePosition();
#endif
@@ -2618,12 +2710,12 @@ Vector2 GetTouchPosition(int index)
// NOTE: returns false in case graphic device could not be created
static bool InitGraphicsDevice(int width, int height)
{
- screenWidth = width; // User desired width
- screenHeight = height; // User desired height
+ CORE.Window.screen.width = width; // User desired width
+ CORE.Window.screen.height = height; // User desired height
- screenScaling = MatrixIdentity(); // No draw scaling required by default
+ CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default
- // NOTE: Framebuffer (render area - renderWidth, renderHeight) could include black bars...
+ // NOTE: Framebuffer (render area - CORE.Window.render.width, CORE.Window.render.height) could include black bars...
// ...in top-down or left-right to match display aspect ratio (no weird scalings)
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
@@ -2635,7 +2727,7 @@ static bool InitGraphicsDevice(int width, int height)
if (!glfwInit())
{
- TraceLog(LOG_WARNING, "Failed to initialize GLFW");
+ TRACELOG(LOG_WARNING, "GLFW: Failed to initialize GLFW");
return false;
}
@@ -2645,22 +2737,22 @@ static bool InitGraphicsDevice(int width, int height)
GLFWmonitor *monitor = glfwGetPrimaryMonitor();
if (!monitor)
{
- TraceLog(LOG_WARNING, "Failed to get monitor");
+ TRACELOG(LOG_WARNING, "GLFW: Failed to get primary monitor");
return false;
}
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
- displayWidth = mode->width;
- displayHeight = mode->height;
+ CORE.Window.display.width = mode->width;
+ CORE.Window.display.height = mode->height;
// Screen size security check
- if (screenWidth <= 0) screenWidth = displayWidth;
- if (screenHeight <= 0) screenHeight = displayHeight;
+ if (CORE.Window.screen.width <= 0) CORE.Window.screen.width = CORE.Window.display.width;
+ if (CORE.Window.screen.height <= 0) CORE.Window.screen.height = CORE.Window.display.height;
#endif // PLATFORM_DESKTOP
#if defined(PLATFORM_WEB)
- displayWidth = screenWidth;
- displayHeight = screenHeight;
+ CORE.Window.display.width = CORE.Window.screen.width;
+ CORE.Window.display.height = CORE.Window.screen.height;
#endif // PLATFORM_WEB
glfwDefaultWindowHints(); // Set default windows hints:
@@ -2673,26 +2765,28 @@ static bool InitGraphicsDevice(int width, int height)
//glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API); // OpenGL API to use. Alternative: GLFW_OPENGL_ES_API
//glfwWindowHint(GLFW_AUX_BUFFERS, 0); // Number of auxiliar buffers
#if defined(PLATFORM_DESKTOP) && defined(SUPPORT_HIGH_DPI)
- // NOTE: If using external GLFW, it requires latest GLFW 3.3 for this functionality
+ // Resize window content area based on the monitor content scale.
+ // NOTE: This hint only has an effect on platforms where screen coordinates and pixels always map 1:1 such as Windows and X11.
+ // On platforms like macOS the resolution of the framebuffer is changed independently of the window size.
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE); // Scale content area based on the monitor content scale where window is placed on
#endif
// Check some Window creation flags
- if (configFlags & FLAG_WINDOW_HIDDEN) glfwWindowHint(GLFW_VISIBLE, GL_FALSE); // Visible window
+ if (CORE.Window.flags & FLAG_WINDOW_HIDDEN) glfwWindowHint(GLFW_VISIBLE, GL_FALSE); // Visible window
else glfwWindowHint(GLFW_VISIBLE, GL_TRUE); // Window initially hidden
- if (configFlags & FLAG_WINDOW_RESIZABLE) glfwWindowHint(GLFW_RESIZABLE, GL_TRUE); // Resizable window
+ if (CORE.Window.flags & FLAG_WINDOW_RESIZABLE) glfwWindowHint(GLFW_RESIZABLE, GL_TRUE); // Resizable window
else glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Avoid window being resizable
- if (configFlags & FLAG_WINDOW_UNDECORATED) glfwWindowHint(GLFW_DECORATED, GLFW_FALSE); // Border and buttons on Window
+ if (CORE.Window.flags & FLAG_WINDOW_UNDECORATED) glfwWindowHint(GLFW_DECORATED, GLFW_FALSE); // Border and buttons on Window
else glfwWindowHint(GLFW_DECORATED, GLFW_TRUE); // Decorated window
// FLAG_WINDOW_TRANSPARENT not supported on HTML5 and not included in any released GLFW version yet
#if defined(GLFW_TRANSPARENT_FRAMEBUFFER)
- if (configFlags & FLAG_WINDOW_TRANSPARENT) glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE); // Transparent framebuffer
+ if (CORE.Window.flags & FLAG_WINDOW_TRANSPARENT) glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE); // Transparent framebuffer
else glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_FALSE); // Opaque framebuffer
#endif
- if (configFlags & FLAG_MSAA_4X_HINT) glfwWindowHint(GLFW_SAMPLES, 4); // Tries to enable multisampling x4 (MSAA), default is 0
+ if (CORE.Window.flags & FLAG_MSAA_4X_HINT) glfwWindowHint(GLFW_SAMPLES, 4); // Tries to enable multisampling x4 (MSAA), default is 0
// NOTE: When asking for an OpenGL context version, most drivers provide highest supported version
// with forward compatibility to older OpenGL versions.
@@ -2729,28 +2823,28 @@ static bool InitGraphicsDevice(int width, int height)
#endif
}
- if (fullscreenMode)
+ if (CORE.Window.fullscreen)
{
// remember center for switchinging from fullscreen to window
- windowPositionX = displayWidth/2 - screenWidth/2;
- windowPositionY = displayHeight/2 - screenHeight/2;
+ CORE.Window.position.x = CORE.Window.display.width/2 - CORE.Window.screen.width/2;
+ CORE.Window.position.y = CORE.Window.display.height/2 - CORE.Window.screen.height/2;
- if (windowPositionX < 0) windowPositionX = 0;
- if (windowPositionY < 0) windowPositionY = 0;
+ if (CORE.Window.position.x < 0) CORE.Window.position.x = 0;
+ if (CORE.Window.position.y < 0) CORE.Window.position.y = 0;
- // Obtain recommended displayWidth/displayHeight from a valid videomode for the monitor
+ // Obtain recommended CORE.Window.display.width/CORE.Window.display.height from a valid videomode for the monitor
int count = 0;
const GLFWvidmode *modes = glfwGetVideoModes(glfwGetPrimaryMonitor(), &count);
- // Get closest video mode to desired screenWidth/screenHeight
+ // Get closest video mode to desired CORE.Window.screen.width/CORE.Window.screen.height
for (int i = 0; i < count; i++)
{
- if (modes[i].width >= screenWidth)
+ if (modes[i].width >= CORE.Window.screen.width)
{
- if (modes[i].height >= screenHeight)
+ if (modes[i].height >= CORE.Window.screen.height)
{
- displayWidth = modes[i].width;
- displayHeight = modes[i].height;
+ CORE.Window.display.width = modes[i].width;
+ CORE.Window.display.height = modes[i].height;
break;
}
}
@@ -2758,13 +2852,13 @@ static bool InitGraphicsDevice(int width, int height)
#if defined(PLATFORM_DESKTOP)
// If we are windowed fullscreen, ensures that window does not minimize when focus is lost
- if ((screenHeight == displayHeight) && (screenWidth == displayWidth))
+ if ((CORE.Window.screen.height == CORE.Window.display.height) && (CORE.Window.screen.width == CORE.Window.display.width))
{
glfwWindowHint(GLFW_AUTO_ICONIFY, 0);
}
#endif
- TraceLog(LOG_WARNING, "Closest fullscreen videomode: %i x %i", displayWidth, displayHeight);
+ TRACELOG(LOG_WARNING, "SYSTEM: Closest fullscreen videomode: %i x %i", CORE.Window.display.width, CORE.Window.display.height);
// NOTE: ISSUE: Closest videomode could not match monitor aspect-ratio, for example,
// for a desired screen size of 800x450 (16:9), closest supported videomode is 800x600 (4:3),
@@ -2773,66 +2867,66 @@ static bool InitGraphicsDevice(int width, int height)
// Try to setup the most appropiate fullscreen framebuffer for the requested screenWidth/screenHeight
// It considers device display resolution mode and setups a framebuffer with black bars if required (render size/offset)
- // Modified global variables: screenWidth/screenHeight - renderWidth/renderHeight - renderOffsetX/renderOffsetY - screenScaling
+ // Modified global variables: CORE.Window.screen.width/CORE.Window.screen.height - CORE.Window.render.width/CORE.Window.render.height - CORE.Window.renderOffset.x/CORE.Window.renderOffset.y - CORE.Window.screenScale
// TODO: It is a quite cumbersome solution to display size vs requested size, it should be reviewed or removed...
// HighDPI monitors are properly considered in a following similar function: SetupViewport()
- SetupFramebuffer(displayWidth, displayHeight);
+ SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);
- window = glfwCreateWindow(displayWidth, displayHeight, windowTitle, glfwGetPrimaryMonitor(), NULL);
+ CORE.Window.handle = glfwCreateWindow(CORE.Window.display.width, CORE.Window.display.height, CORE.Window.title, glfwGetPrimaryMonitor(), NULL);
// NOTE: Full-screen change, not working properly...
- //glfwSetWindowMonitor(window, glfwGetPrimaryMonitor(), 0, 0, screenWidth, screenHeight, GLFW_DONT_CARE);
+ //glfwSetWindowMonitor(CORE.Window.handle, glfwGetPrimaryMonitor(), 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
}
else
{
// No-fullscreen window creation
- window = glfwCreateWindow(screenWidth, screenHeight, windowTitle, NULL, NULL);
+ CORE.Window.handle = glfwCreateWindow(CORE.Window.screen.width, CORE.Window.screen.height, CORE.Window.title, NULL, NULL);
- if (window)
+ if (CORE.Window.handle)
{
#if defined(PLATFORM_DESKTOP)
// Center window on screen
- int windowPosX = displayWidth/2 - screenWidth/2;
- int windowPosY = displayHeight/2 - screenHeight/2;
+ int windowPosX = CORE.Window.display.width/2 - CORE.Window.screen.width/2;
+ int windowPosY = CORE.Window.display.height/2 - CORE.Window.screen.height/2;
if (windowPosX < 0) windowPosX = 0;
if (windowPosY < 0) windowPosY = 0;
- glfwSetWindowPos(window, windowPosX, windowPosY);
+ glfwSetWindowPos(CORE.Window.handle, windowPosX, windowPosY);
#endif
- renderWidth = screenWidth;
- renderHeight = screenHeight;
+ CORE.Window.render.width = CORE.Window.screen.width;
+ CORE.Window.render.height = CORE.Window.screen.height;
}
}
- if (!window)
+ if (!CORE.Window.handle)
{
glfwTerminate();
- TraceLog(LOG_WARNING, "GLFW Failed to initialize Window");
+ TRACELOG(LOG_WARNING, "GLFW: Failed to initialize Window");
return false;
}
else
{
- TraceLog(LOG_INFO, "Display device initialized successfully");
+ TRACELOG(LOG_INFO, "DISPLAY: Device initialized successfully");
#if defined(PLATFORM_DESKTOP)
- TraceLog(LOG_INFO, "Display size: %i x %i", displayWidth, displayHeight);
+ TRACELOG(LOG_INFO, " > Display size: %i x %i", CORE.Window.display.width, CORE.Window.display.height);
#endif
- TraceLog(LOG_INFO, "Render size: %i x %i", renderWidth, renderHeight);
- TraceLog(LOG_INFO, "Screen size: %i x %i", screenWidth, screenHeight);
- TraceLog(LOG_INFO, "Viewport offsets: %i, %i", renderOffsetX, renderOffsetY);
+ TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height);
+ TRACELOG(LOG_INFO, " > Screen size: %i x %i", CORE.Window.screen.width, CORE.Window.screen.height);
+ TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y);
}
- glfwSetWindowSizeCallback(window, WindowSizeCallback); // NOTE: Resizing not allowed by default!
- glfwSetCursorEnterCallback(window, CursorEnterCallback);
- glfwSetKeyCallback(window, KeyCallback);
- glfwSetMouseButtonCallback(window, MouseButtonCallback);
- glfwSetCursorPosCallback(window, MouseCursorPosCallback); // Track mouse position changes
- glfwSetCharCallback(window, CharCallback);
- glfwSetScrollCallback(window, ScrollCallback);
- glfwSetWindowIconifyCallback(window, WindowIconifyCallback);
- glfwSetDropCallback(window, WindowDropCallback);
+ glfwSetWindowSizeCallback(CORE.Window.handle, WindowSizeCallback); // NOTE: Resizing not allowed by default!
+ glfwSetCursorEnterCallback(CORE.Window.handle, CursorEnterCallback);
+ glfwSetKeyCallback(CORE.Window.handle, KeyCallback);
+ glfwSetMouseButtonCallback(CORE.Window.handle, MouseButtonCallback);
+ glfwSetCursorPosCallback(CORE.Window.handle, MouseCursorPosCallback); // Track mouse position changes
+ glfwSetCharCallback(CORE.Window.handle, CharCallback);
+ glfwSetScrollCallback(CORE.Window.handle, ScrollCallback);
+ glfwSetWindowIconifyCallback(CORE.Window.handle, WindowIconifyCallback);
+ glfwSetDropCallback(CORE.Window.handle, WindowDropCallback);
- glfwMakeContextCurrent(window);
+ glfwMakeContextCurrent(CORE.Window.handle);
#if !defined(PLATFORM_WEB)
glfwSwapInterval(0); // No V-Sync by default
@@ -2846,20 +2940,20 @@ static bool InitGraphicsDevice(int width, int height)
// Try to enable GPU V-Sync, so frames are limited to screen refresh rate (60Hz -> 60 FPS)
// NOTE: V-Sync can be enabled by graphic driver configuration
- if (configFlags & FLAG_VSYNC_HINT)
+ if (CORE.Window.flags & FLAG_VSYNC_HINT)
{
// WARNING: It seems to hits a critical render path in Intel HD Graphics
glfwSwapInterval(1);
- TraceLog(LOG_INFO, "Trying to enable VSYNC");
+ TRACELOG(LOG_INFO, "DISPLAY: Trying to enable VSYNC");
}
#endif // PLATFORM_DESKTOP || PLATFORM_WEB
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_UWP)
- fullscreenMode = true;
+ CORE.Window.fullscreen = true;
// Screen size security check
- if (screenWidth <= 0) screenWidth = displayWidth;
- if (screenHeight <= 0) screenHeight = displayHeight;
+ if (CORE.Window.screen.width <= 0) CORE.Window.screen.width = CORE.Window.display.width;
+ if (CORE.Window.screen.height <= 0) CORE.Window.screen.height = CORE.Window.display.height;
#if defined(PLATFORM_RPI)
bcm_host_init();
@@ -2874,11 +2968,11 @@ static bool InitGraphicsDevice(int width, int height)
EGLint samples = 0;
EGLint sampleBuffer = 0;
- if (configFlags & FLAG_MSAA_4X_HINT)
+ if (CORE.Window.flags & FLAG_MSAA_4X_HINT)
{
samples = 4;
sampleBuffer = 1;
- TraceLog(LOG_INFO, "Trying to enable MSAA x4");
+ TRACELOG(LOG_INFO, "DISPLAY: Trying to enable MSAA x4");
}
const EGLint framebufferAttribs[] =
@@ -2952,13 +3046,11 @@ static bool InitGraphicsDevice(int width, int height)
EGL_NONE,
};
- EGLConfig config = NULL;
-
// eglGetPlatformDisplayEXT is an alternative to eglGetDisplay. It allows us to pass in display attributes, used to configure D3D11.
PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)(eglGetProcAddress("eglGetPlatformDisplayEXT"));
if (!eglGetPlatformDisplayEXT)
{
- TraceLog(LOG_WARNING, "Failed to get function eglGetPlatformDisplayEXT");
+ TRACELOG(LOG_WARNING, "DISPLAY: Failed to get function eglGetPlatformDisplayEXT");
return false;
}
@@ -2973,46 +3065,46 @@ static bool InitGraphicsDevice(int width, int height)
//
// This tries to initialize EGL to D3D11 Feature Level 10_0+. See above comment for details.
- display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, defaultDisplayAttributes);
- if (display == EGL_NO_DISPLAY)
+ CORE.Window.device = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, defaultDisplayAttributes);
+ if (CORE.Window.device == EGL_NO_DISPLAY)
{
- TraceLog(LOG_WARNING, "Failed to initialize EGL display");
+ TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
return false;
}
- if (eglInitialize(display, NULL, NULL) == EGL_FALSE)
+ if (eglInitialize(CORE.Window.device, NULL, NULL) == EGL_FALSE)
{
// This tries to initialize EGL to D3D11 Feature Level 9_3, if 10_0+ is unavailable (e.g. on some mobile devices).
- display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, fl9_3DisplayAttributes);
- if (display == EGL_NO_DISPLAY)
+ CORE.Window.device = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, fl9_3DisplayAttributes);
+ if (CORE.Window.device == EGL_NO_DISPLAY)
{
- TraceLog(LOG_WARNING, "Failed to initialize EGL display");
+ TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
return false;
}
- if (eglInitialize(display, NULL, NULL) == EGL_FALSE)
+ if (eglInitialize(CORE.Window.device, NULL, NULL) == EGL_FALSE)
{
// This initializes EGL to D3D11 Feature Level 11_0 on WARP, if 9_3+ is unavailable on the default GPU.
- display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, warpDisplayAttributes);
- if (display == EGL_NO_DISPLAY)
+ CORE.Window.device = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, warpDisplayAttributes);
+ if (CORE.Window.device == EGL_NO_DISPLAY)
{
- TraceLog(LOG_WARNING, "Failed to initialize EGL display");
+ TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
return false;
}
- if (eglInitialize(display, NULL, NULL) == EGL_FALSE)
+ if (eglInitialize(CORE.Window.device, NULL, NULL) == EGL_FALSE)
{
// If all of the calls to eglInitialize returned EGL_FALSE then an error has occurred.
- TraceLog(LOG_WARNING, "Failed to initialize EGL");
+ TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
return false;
}
}
}
EGLint numConfigs = 0;
- if ((eglChooseConfig(display, framebufferAttribs, &config, 1, &numConfigs) == EGL_FALSE) || (numConfigs == 0))
+ if ((eglChooseConfig(CORE.Window.device, framebufferAttribs, &CORE.Window.config, 1, &numConfigs) == EGL_FALSE) || (numConfigs == 0))
{
- TraceLog(LOG_WARNING, "Failed to choose first EGLConfig");
+ TRACELOG(LOG_WARNING, "DISPLAY: Failed to choose first EGL configuration");
return false;
}
@@ -3046,55 +3138,55 @@ static bool InitGraphicsDevice(int width, int height)
//https://stackoverflow.com/questions/46550182/how-to-create-eglsurface-using-c-winrt-and-angle
- //surface = eglCreateWindowSurface(display, config, reinterpret_cast<IInspectable*>(surfaceCreationProperties), surfaceAttributes);
- surface = eglCreateWindowSurface(display, config, window, surfaceAttributes);
- if (surface == EGL_NO_SURFACE)
+ //CORE.Window.surface = eglCreateWindowSurface(CORE.Window.device, CORE.Window.config, reinterpret_cast<IInspectable*>(surfaceCreationProperties), surfaceAttributes);
+ CORE.Window.surface = eglCreateWindowSurface(CORE.Window.device, CORE.Window.config, handle, surfaceAttributes);
+ if (CORE.Window.surface == EGL_NO_SURFACE)
{
- TraceLog(LOG_WARNING, "Failed to create EGL fullscreen surface");
+ TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL fullscreen surface");
return false;
}
- context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
- if (context == EGL_NO_CONTEXT)
+ CORE.Window.context = eglCreateContext(CORE.Window.device, CORE.Window.config, EGL_NO_CONTEXT, contextAttribs);
+ if (CORE.Window.context == EGL_NO_CONTEXT)
{
- TraceLog(LOG_WARNING, "Failed to create EGL context");
+ TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL context");
return false;
}
- // Get EGL display window size
- eglQuerySurface(display, surface, EGL_WIDTH, &screenWidth);
- eglQuerySurface(display, surface, EGL_HEIGHT, &screenHeight);
+ // Get EGL device window size
+ eglQuerySurface(CORE.Window.device, CORE.Window.surface, EGL_WIDTH, &CORE.Window.screen.width);
+ eglQuerySurface(CORE.Window.device, CORE.Window.surface, EGL_HEIGHT, &CORE.Window.screen.height);
#else // PLATFORM_ANDROID, PLATFORM_RPI
EGLint numConfigs;
- // Get an EGL display connection
- display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- if (display == EGL_NO_DISPLAY)
+ // Get an EGL device connection
+ CORE.Window.device = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (CORE.Window.device == EGL_NO_DISPLAY)
{
- TraceLog(LOG_WARNING, "Failed to initialize EGL display");
+ TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
return false;
}
- // Initialize the EGL display connection
- if (eglInitialize(display, NULL, NULL) == EGL_FALSE)
+ // Initialize the EGL device connection
+ if (eglInitialize(CORE.Window.device, NULL, NULL) == EGL_FALSE)
{
// If all of the calls to eglInitialize returned EGL_FALSE then an error has occurred.
- TraceLog(LOG_WARNING, "Failed to initialize EGL");
+ TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
return false;
}
// Get an appropriate EGL framebuffer configuration
- eglChooseConfig(display, framebufferAttribs, &config, 1, &numConfigs);
+ eglChooseConfig(CORE.Window.device, framebufferAttribs, &CORE.Window.config, 1, &numConfigs);
// Set rendering API
eglBindAPI(EGL_OPENGL_ES_API);
// Create an EGL rendering context
- context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
- if (context == EGL_NO_CONTEXT)
+ CORE.Window.context = eglCreateContext(CORE.Window.device, CORE.Window.config, EGL_NO_CONTEXT, contextAttribs);
+ if (CORE.Window.context == EGL_NO_CONTEXT)
{
- TraceLog(LOG_WARNING, "Failed to create EGL context");
+ TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL context");
return false;
}
#endif
@@ -3104,45 +3196,43 @@ static bool InitGraphicsDevice(int width, int height)
#if defined(PLATFORM_ANDROID)
EGLint displayFormat;
- displayWidth = ANativeWindow_getWidth(androidApp->window);
- displayHeight = ANativeWindow_getHeight(androidApp->window);
-
// EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is guaranteed to be accepted by ANativeWindow_setBuffersGeometry()
// As soon as we picked a EGLConfig, we can safely reconfigure the ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID
- eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &displayFormat);
+ eglGetConfigAttrib(CORE.Window.device, CORE.Window.config, EGL_NATIVE_VISUAL_ID, &displayFormat);
// At this point we need to manage render size vs screen size
- // NOTE: This function use and modify global module variables: screenWidth/screenHeight and renderWidth/renderHeight and screenScaling
- SetupFramebuffer(displayWidth, displayHeight);
+ // NOTE: This function use and modify global module variables: CORE.Window.screen.width/CORE.Window.screen.height and CORE.Window.render.width/CORE.Window.render.height and CORE.Window.screenScale
+ SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);
- ANativeWindow_setBuffersGeometry(androidApp->window, renderWidth, renderHeight, displayFormat);
- //ANativeWindow_setBuffersGeometry(androidApp->window, 0, 0, displayFormat); // Force use of native display size
+ ANativeWindow_setBuffersGeometry(CORE.Android.app->window, CORE.Window.render.width, CORE.Window.render.height, displayFormat);
+ //ANativeWindow_setBuffersGeometry(CORE.Android.app->window, 0, 0, displayFormat); // Force use of native display size
- surface = eglCreateWindowSurface(display, config, androidApp->window, NULL);
+ CORE.Window.surface = eglCreateWindowSurface(CORE.Window.device, CORE.Window.config, CORE.Android.app->window, NULL);
#endif // PLATFORM_ANDROID
#if defined(PLATFORM_RPI)
- graphics_get_display_size(0, &displayWidth, &displayHeight);
+ graphics_get_display_size(0, &CORE.Window.display.width, &CORE.Window.display.height);
// At this point we need to manage render size vs screen size
- // NOTE: This function use and modify global module variables: screenWidth/screenHeight and renderWidth/renderHeight and screenScaling
- SetupFramebuffer(displayWidth, displayHeight);
+ // NOTE: This function use and modify global module variables: CORE.Window.screen.width/CORE.Window.screen.height and CORE.Window.render.width/CORE.Window.render.height and CORE.Window.screenScale
+ SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);
dstRect.x = 0;
dstRect.y = 0;
- dstRect.width = displayWidth;
- dstRect.height = displayHeight;
+ dstRect.width = CORE.Window.display.width;
+ dstRect.height = CORE.Window.display.height;
srcRect.x = 0;
srcRect.y = 0;
- srcRect.width = renderWidth << 16;
- srcRect.height = renderHeight << 16;
+ srcRect.width = CORE.Window.render.width << 16;
+ srcRect.height = CORE.Window.render.height << 16;
// NOTE: RPI dispmanx windowing system takes care of srcRec scaling to dstRec by hardware (no cost)
// Take care that renderWidth/renderHeight fit on displayWidth/displayHeight aspect ratio
VC_DISPMANX_ALPHA_T alpha;
alpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS;
+ //alpha.flags = DISPMANX_FLAGS_ALPHA_FROM_SOURCE; // TODO: Allow transparent framebuffer! -> FLAG_WINDOW_TRANSPARENT
alpha.opacity = 255; // Set transparency level for framebuffer, requires EGLAttrib: EGL_TRANSPARENT_TYPE
alpha.mask = 0;
@@ -3152,65 +3242,64 @@ static bool InitGraphicsDevice(int width, int height)
dispmanElement = vc_dispmanx_element_add(dispmanUpdate, dispmanDisplay, 0/*layer*/, &dstRect, 0/*src*/,
&srcRect, DISPMANX_PROTECTION_NONE, &alpha, 0/*clamp*/, DISPMANX_NO_ROTATE);
- window.element = dispmanElement;
- window.width = renderWidth;
- window.height = renderHeight;
+ CORE.Window.handle.element = dispmanElement;
+ CORE.Window.handle.width = CORE.Window.render.width;
+ CORE.Window.handle.height = CORE.Window.render.height;
vc_dispmanx_update_submit_sync(dispmanUpdate);
- surface = eglCreateWindowSurface(display, config, &window, NULL);
+ CORE.Window.surface = eglCreateWindowSurface(CORE.Window.device, CORE.Window.config, &CORE.Window.handle, NULL);
//---------------------------------------------------------------------------------
#endif // PLATFORM_RPI
// There must be at least one frame displayed before the buffers are swapped
- //eglSwapInterval(display, 1);
+ //eglSwapInterval(CORE.Window.device, 1);
- if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE)
+ if (eglMakeCurrent(CORE.Window.device, CORE.Window.surface, CORE.Window.surface, CORE.Window.context) == EGL_FALSE)
{
- TraceLog(LOG_WARNING, "Unable to attach EGL rendering context to EGL surface");
+ TRACELOG(LOG_WARNING, "DISPLAY: Failed to attach EGL rendering context to EGL surface");
return false;
}
else
{
// Grab the width and height of the surface
- //eglQuerySurface(display, surface, EGL_WIDTH, &renderWidth);
- //eglQuerySurface(display, surface, EGL_HEIGHT, &renderHeight);
-
- TraceLog(LOG_INFO, "Display device initialized successfully");
- TraceLog(LOG_INFO, "Display size: %i x %i", displayWidth, displayHeight);
- TraceLog(LOG_INFO, "Render size: %i x %i", renderWidth, renderHeight);
- TraceLog(LOG_INFO, "Screen size: %i x %i", screenWidth, screenHeight);
- TraceLog(LOG_INFO, "Viewport offsets: %i, %i", renderOffsetX, renderOffsetY);
+ //eglQuerySurface(CORE.Window.device, CORE.Window.surface, EGL_WIDTH, &CORE.Window.render.width);
+ //eglQuerySurface(CORE.Window.device, CORE.Window.surface, EGL_HEIGHT, &CORE.Window.render.height);
+
+ TRACELOG(LOG_INFO, "DISPLAY: Device initialized successfully");
+ TRACELOG(LOG_INFO, " > Display size: %i x %i", CORE.Window.display.width, CORE.Window.display.height);
+ TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height);
+ TRACELOG(LOG_INFO, " > Screen size: %i x %i", CORE.Window.screen.width, CORE.Window.screen.height);
+ TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y);
}
#endif // PLATFORM_ANDROID || PLATFORM_RPI
// Initialize OpenGL context (states and resources)
- // NOTE: screenWidth and screenHeight not used, just stored as globals in rlgl
- rlglInit(screenWidth, screenHeight);
+ // NOTE: CORE.Window.screen.width and CORE.Window.screen.height not used, just stored as globals in rlgl
+ rlglInit(CORE.Window.screen.width, CORE.Window.screen.height);
- int fbWidth = renderWidth;
- int fbHeight = renderHeight;
+ int fbWidth = CORE.Window.render.width;
+ int fbHeight = CORE.Window.render.height;
#if defined(PLATFORM_DESKTOP) && defined(SUPPORT_HIGH_DPI)
- glfwGetFramebufferSize(window, &fbWidth, &fbHeight);
+ glfwGetFramebufferSize(CORE.Window.handle, &fbWidth, &fbHeight);
// Screen scaling matrix is required in case desired screen area is different than display area
- screenScaling = MatrixScale((float)fbWidth/screenWidth, (float)fbHeight/screenHeight, 1.0f);
+ CORE.Window.screenScale = MatrixScale((float)fbWidth/CORE.Window.screen.width, (float)fbHeight/CORE.Window.screen.height, 1.0f);
#if !defined(__APPLE__)
- SetMouseScale((float)screenWidth/fbWidth, (float)screenHeight/fbHeight);
-#endif
- SetTextureFilter(GetFontDefault().texture, FILTER_BILINEAR);
+ SetMouseScale((float)CORE.Window.screen.width/fbWidth, (float)CORE.Window.screen.height/fbHeight);
+#endif
#endif // PLATFORM_DESKTOP && SUPPORT_HIGH_DPI
// Setup default viewport
SetupViewport(fbWidth, fbHeight);
- currentWidth = screenWidth;
- currentHeight = screenHeight;
+ CORE.Window.currentFbo.width = CORE.Window.screen.width;
+ CORE.Window.currentFbo.height = CORE.Window.screen.height;
ClearBackground(RAYWHITE); // Default background color for raylib games :P
#if defined(PLATFORM_ANDROID)
- windowReady = true; // IMPORTANT!
+ CORE.Window.ready = true;
#endif
return true;
}
@@ -3218,94 +3307,94 @@ static bool InitGraphicsDevice(int width, int height)
// Set viewport for a provided width and height
static void SetupViewport(int width, int height)
{
- renderWidth = width;
- renderHeight = height;
+ CORE.Window.render.width = width;
+ CORE.Window.render.height = height;
// Set viewport width and height
// NOTE: We consider render size and offset in case black bars are required and
// render area does not match full display area (this situation is only applicable on fullscreen mode)
- rlViewport(renderOffsetX/2, renderOffsetY/2, renderWidth - renderOffsetX, renderHeight - renderOffsetY);
+ rlViewport(CORE.Window.renderOffset.x/2, CORE.Window.renderOffset.y/2, CORE.Window.render.width - CORE.Window.renderOffset.x, CORE.Window.render.height - CORE.Window.renderOffset.y);
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, renderWidth, renderHeight, 0, 0.0f, 1.0f);
+ rlOrtho(0, CORE.Window.render.width, CORE.Window.render.height, 0, 0.0f, 1.0f);
rlMatrixMode(RL_MODELVIEW); // Switch back to MODELVIEW matrix
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
}
// Compute framebuffer size relative to screen size and display size
-// NOTE: Global variables renderWidth/renderHeight and renderOffsetX/renderOffsetY can be modified
+// NOTE: Global variables CORE.Window.render.width/CORE.Window.render.height and CORE.Window.renderOffset.x/CORE.Window.renderOffset.y can be modified
static void SetupFramebuffer(int width, int height)
{
- // Calculate renderWidth and renderHeight, we have the display size (input params) and the desired screen size (global var)
- if ((screenWidth > displayWidth) || (screenHeight > displayHeight))
+ // Calculate CORE.Window.render.width and CORE.Window.render.height, we have the display size (input params) and the desired screen size (global var)
+ if ((CORE.Window.screen.width > CORE.Window.display.width) || (CORE.Window.screen.height > CORE.Window.display.height))
{
- TraceLog(LOG_WARNING, "DOWNSCALING: Required screen size (%ix%i) is bigger than display size (%ix%i)", screenWidth, screenHeight, displayWidth, displayHeight);
+ TRACELOG(LOG_WARNING, "DISPLAY: Downscaling required: Screen size (%ix%i) is bigger than display size (%ix%i)", CORE.Window.screen.width, CORE.Window.screen.height, CORE.Window.display.width, CORE.Window.display.height);
// Downscaling to fit display with border-bars
- float widthRatio = (float)displayWidth/(float)screenWidth;
- float heightRatio = (float)displayHeight/(float)screenHeight;
+ float widthRatio = (float)CORE.Window.display.width/(float)CORE.Window.screen.width;
+ float heightRatio = (float)CORE.Window.display.height/(float)CORE.Window.screen.height;
if (widthRatio <= heightRatio)
{
- renderWidth = displayWidth;
- renderHeight = (int)round((float)screenHeight*widthRatio);
- renderOffsetX = 0;
- renderOffsetY = (displayHeight - renderHeight);
+ CORE.Window.render.width = CORE.Window.display.width;
+ CORE.Window.render.height = (int)round((float)CORE.Window.screen.height*widthRatio);
+ CORE.Window.renderOffset.x = 0;
+ CORE.Window.renderOffset.y = (CORE.Window.display.height - CORE.Window.render.height);
}
else
{
- renderWidth = (int)round((float)screenWidth*heightRatio);
- renderHeight = displayHeight;
- renderOffsetX = (displayWidth - renderWidth);
- renderOffsetY = 0;
+ CORE.Window.render.width = (int)round((float)CORE.Window.screen.width*heightRatio);
+ CORE.Window.render.height = CORE.Window.display.height;
+ CORE.Window.renderOffset.x = (CORE.Window.display.width - CORE.Window.render.width);
+ CORE.Window.renderOffset.y = 0;
}
// Screen scaling required
- float scaleRatio = (float)renderWidth/(float)screenWidth;
- screenScaling = MatrixScale(scaleRatio, scaleRatio, 1.0f);
+ float scaleRatio = (float)CORE.Window.render.width/(float)CORE.Window.screen.width;
+ CORE.Window.screenScale = MatrixScale(scaleRatio, scaleRatio, 1.0f);
// NOTE: We render to full display resolution!
// We just need to calculate above parameters for downscale matrix and offsets
- renderWidth = displayWidth;
- renderHeight = displayHeight;
+ CORE.Window.render.width = CORE.Window.display.width;
+ CORE.Window.render.height = CORE.Window.display.height;
- TraceLog(LOG_WARNING, "Downscale matrix generated, content will be rendered at: %i x %i", renderWidth, renderHeight);
+ TRACELOG(LOG_WARNING, "DISPLAY: Downscale matrix generated, content will be rendered at (%ix%i)", CORE.Window.render.width, CORE.Window.render.height);
}
- else if ((screenWidth < displayWidth) || (screenHeight < displayHeight))
+ else if ((CORE.Window.screen.width < CORE.Window.display.width) || (CORE.Window.screen.height < CORE.Window.display.height))
{
// Required screen size is smaller than display size
- TraceLog(LOG_INFO, "UPSCALING: Required screen size: %i x %i -> Display size: %i x %i", screenWidth, screenHeight, displayWidth, displayHeight);
+ TRACELOG(LOG_INFO, "DISPLAY: Upscaling required: Screen size (%ix%i) smaller than display size (%ix%i)", CORE.Window.screen.width, CORE.Window.screen.height, CORE.Window.display.width, CORE.Window.display.height);
// Upscaling to fit display with border-bars
- float displayRatio = (float)displayWidth/(float)displayHeight;
- float screenRatio = (float)screenWidth/(float)screenHeight;
+ float displayRatio = (float)CORE.Window.display.width/(float)CORE.Window.display.height;
+ float screenRatio = (float)CORE.Window.screen.width/(float)CORE.Window.screen.height;
if (displayRatio <= screenRatio)
{
- renderWidth = screenWidth;
- renderHeight = (int)round((float)screenWidth/displayRatio);
- renderOffsetX = 0;
- renderOffsetY = (renderHeight - screenHeight);
+ CORE.Window.render.width = CORE.Window.screen.width;
+ CORE.Window.render.height = (int)round((float)CORE.Window.screen.width/displayRatio);
+ CORE.Window.renderOffset.x = 0;
+ CORE.Window.renderOffset.y = (CORE.Window.render.height - CORE.Window.screen.height);
}
else
{
- renderWidth = (int)round((float)screenHeight*displayRatio);
- renderHeight = screenHeight;
- renderOffsetX = (renderWidth - screenWidth);
- renderOffsetY = 0;
+ CORE.Window.render.width = (int)round((float)CORE.Window.screen.height*displayRatio);
+ CORE.Window.render.height = CORE.Window.screen.height;
+ CORE.Window.renderOffset.x = (CORE.Window.render.width - CORE.Window.screen.width);
+ CORE.Window.renderOffset.y = 0;
}
}
- else // screen == display
+ else
{
- renderWidth = screenWidth;
- renderHeight = screenHeight;
- renderOffsetX = 0;
- renderOffsetY = 0;
+ CORE.Window.render.width = CORE.Window.screen.width;
+ CORE.Window.render.height = CORE.Window.screen.height;
+ CORE.Window.renderOffset.x = 0;
+ CORE.Window.renderOffset.y = 0;
}
}
@@ -3323,12 +3412,12 @@ static void InitTimer(void)
if (clock_gettime(CLOCK_MONOTONIC, &now) == 0) // Success
{
- baseTime = (uint64_t)now.tv_sec*1000000000LLU + (uint64_t)now.tv_nsec;
+ CORE.Time.base = (unsigned long long int)now.tv_sec*1000000000LLU + (unsigned long long int)now.tv_nsec;
}
- else TraceLog(LOG_WARNING, "No hi-resolution timer available");
+ else TRACELOG(LOG_WARNING, "TIMER: Hi-resolution timer not available");
#endif
- previousTime = GetTime(); // Get time as double
+ CORE.Time.previous = GetTime(); // Get time as double
}
// Wait for some milliseconds (stop program execution)
@@ -3365,43 +3454,13 @@ static void Wait(float ms)
#elif defined(__APPLE__)
usleep(ms*1000.0f);
#endif
-
+
#if defined(SUPPORT_HALFBUSY_WAIT_LOOP)
while (GetTime() < destTime) { }
#endif
#endif
}
-// Get one key state
-static bool GetKeyStatus(int key)
-{
-#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
- return glfwGetKey(window, key);
-#elif defined(PLATFORM_ANDROID)
- // NOTE: Android supports up to 260 keys
- if (key < 0 || key > 260) return false;
- else return currentKeyState[key];
-#elif defined(PLATFORM_RPI) || defined(PLATFORM_UWP)
- // NOTE: Keys states are filled in PollInputEvents()
- if (key < 0 || key > 511) return false;
- else return currentKeyState[key];
-#endif
-}
-
-// Get one mouse button state
-static bool GetMouseButtonStatus(int button)
-{
-#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
- return glfwGetMouseButton(window, button);
-#elif defined(PLATFORM_ANDROID)
- // TODO: Check for virtual mouse?
- return false;
-#elif defined(PLATFORM_RPI) || defined(PLATFORM_UWP)
- // NOTE: Mouse buttons states are filled in PollInputEvents()
- return currentMouseState[button];
-#endif
-}
-
// Get gamepad button generic to all platforms
static int GetGamepadButton(int button)
{
@@ -3505,53 +3564,54 @@ static void PollInputEvents(void)
#endif
// Reset key pressed registered
- keyPressedQueueCount = 0;
+ CORE.Input.Keyboard.keyPressedQueueCount = 0;
#if !defined(PLATFORM_RPI)
// Reset last gamepad button/axis registered state
- lastGamepadButtonPressed = -1;
- gamepadAxisCount = 0;
+ CORE.Input.Gamepad.lastButtonPressed = -1;
+ CORE.Input.Gamepad.axisCount = 0;
#endif
#if defined(PLATFORM_RPI)
// Register previous keys states
- for (int i = 0; i < 512; i++)previousKeyState[i] = currentKeyState[i];
+ for (int i = 0; i < 512; i++) CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i];
// Grab a keypress from the evdev fifo if avalable
- if (lastKeyPressedEvdev.Head != lastKeyPressedEvdev.Tail)
+ if (CORE.Input.Keyboard.lastKeyPressed.head != CORE.Input.Keyboard.lastKeyPressed.tail)
{
- keyPressedQueue[keyPressedQueueCount] = lastKeyPressedEvdev.Contents[lastKeyPressedEvdev.Tail]; // Read the key from the buffer
- keyPressedQueueCount++;
-
- lastKeyPressedEvdev.Tail = (lastKeyPressedEvdev.Tail + 1) & 0x07; // Increment the tail pointer forwards and binary wraparound after 7 (fifo is 8 elements long)
+ CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = CORE.Input.Keyboard.lastKeyPressed.contents[CORE.Input.Keyboard.lastKeyPressed.tail]; // Read the key from the buffer
+ CORE.Input.Keyboard.keyPressedQueueCount++;
+
+ CORE.Input.Keyboard.lastKeyPressed.tail = (CORE.Input.Keyboard.lastKeyPressed.tail + 1) & 0x07; // Increment the tail pointer forwards and binary wraparound after 7 (fifo is 8 elements long)
}
// Register previous mouse states
- previousMouseWheelY = currentMouseWheelY;
- currentMouseWheelY = 0;
+ CORE.Input.Mouse.previousWheelMove = CORE.Input.Mouse.currentWheelMove;
+ CORE.Input.Mouse.currentWheelMove = 0;
for (int i = 0; i < 3; i++)
{
- previousMouseState[i] = currentMouseState[i];
- currentMouseState[i] = currentMouseStateEvdev[i];
+ CORE.Input.Mouse.previousButtonState[i] = CORE.Input.Mouse.currentButtonState[i];
+ CORE.Input.Mouse.currentButtonState[i] = CORE.Input.Mouse.currentButtonStateEvdev[i];
}
#endif
#if defined(PLATFORM_UWP)
// Register previous keys states
- for (int i = 0; i < 512; i++) previousKeyState[i] = currentKeyState[i];
+ for (int i = 0; i < 512; i++) CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i];
for (int i = 0; i < MAX_GAMEPADS; i++)
{
- if (gamepadReady[i])
+ if (CORE.Input.Gamepad.ready[i])
{
- for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) previousGamepadState[i][k] = currentGamepadState[i][k];
+ for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) CORE.Input.Gamepad.previousState[i][k] = CORE.Input.Gamepad.currentState[i][k];
}
}
// Register previous mouse states
- previousMouseWheelY = currentMouseWheelY;
- currentMouseWheelY = 0;
- for (int i = 0; i < 3; i++) previousMouseState[i] = currentMouseState[i];
+ CORE.Input.Mouse.previousWheelMove = CORE.Input.Mouse.currentWheelMove;
+ CORE.Input.Mouse.currentWheelMove = 0;
+
+ for (int i = 0; i < 3; i++) CORE.Input.Mouse.previousButtonState[i] = CORE.Input.Mouse.currentButtonState[i];
// Loop over pending messages
while (HasMessageFromUWP())
@@ -3633,40 +3693,40 @@ static void PollInputEvents(void)
default: break;
}
- if (actualKey > -1) currentKeyState[actualKey] = msg->paramChar0;
+ if (actualKey > -1) CORE.Input.Keyboard.currentKeyState[actualKey] = msg->paramChar0;
} break;
- case UWP_MSG_REGISTER_CLICK: currentMouseState[msg->paramInt0] = msg->paramChar0; break;
- case UWP_MSG_SCROLL_WHEEL_UPDATE: currentMouseWheelY += msg->paramInt0; break;
- case UWP_MSG_UPDATE_MOUSE_LOCATION: mousePosition = msg->paramVector0; break;
- case UWP_MSG_SET_GAMEPAD_ACTIVE: if (msg->paramInt0 < MAX_GAMEPADS) gamepadReady[msg->paramInt0] = msg->paramBool0; break;
+ case UWP_MSG_REGISTER_CLICK: CORE.Input.Mouse.currentButtonState[msg->paramInt0] = msg->paramChar0; break;
+ case UWP_MSG_SCROLL_WHEEL_UPDATE: CORE.Input.Mouse.currentWheelMove += msg->paramInt0; break;
+ case UWP_MSG_UPDATE_MOUSE_LOCATION: CORE.Input.Mouse.position = msg->paramVector0; break;
+ case UWP_MSG_SET_GAMEPAD_ACTIVE: if (msg->paramInt0 < MAX_GAMEPADS) CORE.Input.Gamepad.ready[msg->paramInt0] = msg->paramBool0; break;
case UWP_MSG_SET_GAMEPAD_BUTTON:
{
- if ((msg->paramInt0 < MAX_GAMEPADS) && (msg->paramInt1 < MAX_GAMEPAD_BUTTONS)) currentGamepadState[msg->paramInt0][msg->paramInt1] = msg->paramChar0;
+ if ((msg->paramInt0 < MAX_GAMEPADS) && (msg->paramInt1 < MAX_GAMEPAD_BUTTONS)) CORE.Input.Gamepad.currentState[msg->paramInt0][msg->paramInt1] = msg->paramChar0;
} break;
case UWP_MSG_SET_GAMEPAD_AXIS:
{
- if ((msg->paramInt0 < MAX_GAMEPADS) && (msg->paramInt1 < MAX_GAMEPAD_AXIS)) gamepadAxisState[msg->paramInt0][msg->paramInt1] = msg->paramFloat0;
+ if ((msg->paramInt0 < MAX_GAMEPADS) && (msg->paramInt1 < MAX_GAMEPAD_AXIS)) CORE.Input.Gamepad.axisState[msg->paramInt0][msg->paramInt1] = msg->paramFloat0;
// Register buttons for 2nd triggers
- currentGamepadState[msg->paramInt0][GAMEPAD_BUTTON_LEFT_TRIGGER_2] = (char)(gamepadAxisState[msg->paramInt0][GAMEPAD_AXIS_LEFT_TRIGGER] > 0.1);
- currentGamepadState[msg->paramInt0][GAMEPAD_BUTTON_RIGHT_TRIGGER_2] = (char)(gamepadAxisState[msg->paramInt0][GAMEPAD_AXIS_RIGHT_TRIGGER] > 0.1);
+ CORE.Input.Gamepad.currentState[msg->paramInt0][GAMEPAD_BUTTON_LEFT_TRIGGER_2] = (char)(CORE.Input.Gamepad.axisState[msg->paramInt0][GAMEPAD_AXIS_LEFT_TRIGGER] > 0.1);
+ CORE.Input.Gamepad.currentState[msg->paramInt0][GAMEPAD_BUTTON_RIGHT_TRIGGER_2] = (char)(CORE.Input.Gamepad.axisState[msg->paramInt0][GAMEPAD_AXIS_RIGHT_TRIGGER] > 0.1);
} break;
case UWP_MSG_SET_DISPLAY_DIMS:
{
- displayWidth = msg->paramVector0.x;
- displayHeight = msg->paramVector0.y;
+ CORE.Window.display.width = msg->paramVector0.x;
+ CORE.Window.display.height = msg->paramVector0.y;
} break;
case UWP_MSG_HANDLE_RESIZE:
{
- eglQuerySurface(display, surface, EGL_WIDTH, &screenWidth);
- eglQuerySurface(display, surface, EGL_HEIGHT, &screenHeight);
+ eglQuerySurface(CORE.Window.device, CORE.Window.surface, EGL_WIDTH, &CORE.Window.screen.width);
+ eglQuerySurface(CORE.Window.device, CORE.Window.surface, EGL_HEIGHT, &CORE.Window.screen.height);
// If window is resized, viewport and projection matrix needs to be re-calculated
- rlViewport(0, 0, screenWidth, screenHeight); // Set viewport width and height
+ rlViewport(0, 0, CORE.Window.screen.width, CORE.Window.screen.height); // Set viewport width and height
rlMatrixMode(RL_PROJECTION); // Switch to PROJECTION matrix
rlLoadIdentity(); // Reset current matrix (PROJECTION)
- rlOrtho(0, screenWidth, screenHeight, 0, 0.0f, 1.0f); // Orthographic projection mode with top-left corner at (0,0)
+ rlOrtho(0, CORE.Window.screen.width, CORE.Window.screen.height, 0, 0.0f, 1.0f); // Orthographic projection mode with top-left corner at (0,0)
rlMatrixMode(RL_MODELVIEW); // Switch back to MODELVIEW matrix
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
rlClearScreenBuffers(); // Clear screen buffers (color and depth)
@@ -3674,15 +3734,15 @@ static void PollInputEvents(void)
// Window size must be updated to be used on 3D mode to get new aspect ratio (BeginMode3D())
// NOTE: Be careful! GLFW3 will choose the closest fullscreen resolution supported by current monitor,
// for example, if reescaling back to 800x450 (desired), it could set 720x480 (closest fullscreen supported)
- currentWidth = screenWidth;
- currentHeight = screenHeight;
+ CORE.Window.currentFbo.width = CORE.Window.screen.width;
+ CORE.Window.currentFbo.height = CORE.Window.screen.height;
// NOTE: Postprocessing texture is not scaled to new size
- windowResized = true;
+ CORE.Window.resized = true;
} break;
- case UWP_MSG_SET_GAME_TIME: currentTime = msg->paramDouble0; break;
+ case UWP_MSG_SET_GAME_TIME: CORE.Time.current = msg->paramDouble0; break;
default: break;
}
@@ -3691,43 +3751,38 @@ static void PollInputEvents(void)
#endif // PLATFORM_UWP
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
- // Mouse input polling
- double mouseX;
- double mouseY;
-
- glfwGetCursorPos(window, &mouseX, &mouseY);
-
- mousePosition.x = (float)mouseX;
- mousePosition.y = (float)mouseY;
-
- // Keyboard input polling (automatically managed by GLFW3 through callback)
+ // Keyboard/Mouse input polling (automatically managed by GLFW3 through callback)
// Register previous keys states
- for (int i = 0; i < 512; i++) previousKeyState[i] = currentKeyState[i];
+ for (int i = 0; i < 512; i++) CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i];
// Register previous mouse states
- for (int i = 0; i < 3; i++) previousMouseState[i] = currentMouseState[i];
+ for (int i = 0; i < 3; i++) CORE.Input.Mouse.previousButtonState[i] = CORE.Input.Mouse.currentButtonState[i];
- previousMouseWheelY = currentMouseWheelY;
- currentMouseWheelY = 0;
+ // Register previous mouse wheel state
+ CORE.Input.Mouse.previousWheelMove = CORE.Input.Mouse.currentWheelMove;
+ CORE.Input.Mouse.currentWheelMove = 0;
#endif
+ // Register previous touch states
+ for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.previousTouchState[i] = CORE.Input.Touch.currentTouchState[i];
+
#if defined(PLATFORM_DESKTOP)
// Check if gamepads are ready
// NOTE: We do it here in case of disconnection
for (int i = 0; i < MAX_GAMEPADS; i++)
{
- if (glfwJoystickPresent(i)) gamepadReady[i] = true;
- else gamepadReady[i] = false;
+ if (glfwJoystickPresent(i)) CORE.Input.Gamepad.ready[i] = true;
+ else CORE.Input.Gamepad.ready[i] = false;
}
// Register gamepads buttons events
for (int i = 0; i < MAX_GAMEPADS; i++)
{
- if (gamepadReady[i]) // Check if gamepad is available
+ if (CORE.Input.Gamepad.ready[i]) // Check if gamepad is available
{
// Register previous gamepad states
- for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) previousGamepadState[i][k] = currentGamepadState[i][k];
+ for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) CORE.Input.Gamepad.previousState[i][k] = CORE.Input.Gamepad.currentState[i][k];
// Get current gamepad state
// NOTE: There is no callback available, so we get it manually
@@ -3742,10 +3797,10 @@ static void PollInputEvents(void)
if (buttons[k] == GLFW_PRESS)
{
- currentGamepadState[i][button] = 1;
- lastGamepadButtonPressed = button;
+ CORE.Input.Gamepad.currentState[i][button] = 1;
+ CORE.Input.Gamepad.lastButtonPressed = button;
}
- else currentGamepadState[i][button] = 0;
+ else CORE.Input.Gamepad.currentState[i][button] = 0;
}
// Get current axis state
@@ -3754,18 +3809,18 @@ static void PollInputEvents(void)
for (int k = 0; (axes != NULL) && (k < GLFW_GAMEPAD_AXIS_LAST + 1) && (k < MAX_GAMEPAD_AXIS); k++)
{
const int axis = GetGamepadAxis(k);
- gamepadAxisState[i][axis] = axes[k];
+ CORE.Input.Gamepad.axisState[i][axis] = axes[k];
}
// Register buttons for 2nd triggers (because GLFW doesn't count these as buttons but rather axis)
- currentGamepadState[i][GAMEPAD_BUTTON_LEFT_TRIGGER_2] = (char)(gamepadAxisState[i][GAMEPAD_AXIS_LEFT_TRIGGER] > 0.1);
- currentGamepadState[i][GAMEPAD_BUTTON_RIGHT_TRIGGER_2] = (char)(gamepadAxisState[i][GAMEPAD_AXIS_RIGHT_TRIGGER] > 0.1);
+ CORE.Input.Gamepad.currentState[i][GAMEPAD_BUTTON_LEFT_TRIGGER_2] = (char)(CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_LEFT_TRIGGER] > 0.1);
+ CORE.Input.Gamepad.currentState[i][GAMEPAD_BUTTON_RIGHT_TRIGGER_2] = (char)(CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_RIGHT_TRIGGER] > 0.1);
- gamepadAxisCount = GLFW_GAMEPAD_AXIS_LAST;
+ CORE.Input.Gamepad.axisCount = GLFW_GAMEPAD_AXIS_LAST;
}
}
- windowResized = false;
+ CORE.Window.resized = false;
#if defined(SUPPORT_EVENTS_WAITING)
glfwWaitEvents();
@@ -3784,7 +3839,7 @@ static void PollInputEvents(void)
for (int i = 0; (i < numGamepads) && (i < MAX_GAMEPADS); i++)
{
// Register previous gamepad button states
- for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) previousGamepadState[i][k] = currentGamepadState[i][k];
+ for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) CORE.Input.Gamepad.previousState[i][k] = CORE.Input.Gamepad.currentState[i][k];
EmscriptenGamepadEvent gamepadState;
@@ -3798,22 +3853,22 @@ static void PollInputEvents(void)
const GamepadButton button = GetGamepadButton(j);
if (gamepadState.digitalButton[j] == 1)
{
- currentGamepadState[i][button] = 1;
- lastGamepadButtonPressed = button;
+ CORE.Input.Gamepad.currentState[i][button] = 1;
+ CORE.Input.Gamepad.lastButtonPressed = button;
}
- else currentGamepadState[i][button] = 0;
+ else CORE.Input.Gamepad.currentState[i][button] = 0;
- //TraceLog(LOG_DEBUG, "Gamepad %d, button %d: Digital: %d, Analog: %g", gamepadState.index, j, gamepadState.digitalButton[j], gamepadState.analogButton[j]);
+ //TRACELOGD("INPUT: Gamepad %d, button %d: Digital: %d, Analog: %g", gamepadState.index, j, gamepadState.digitalButton[j], gamepadState.analogButton[j]);
}
// Register axis data for every connected gamepad
for (int j = 0; (j < gamepadState.numAxes) && (j < MAX_GAMEPAD_AXIS); j++)
{
const int axis = GetGamepadAxis(j);
- gamepadAxisState[i][axis] = gamepadState.axis[j];
+ CORE.Input.Gamepad.axisState[i][axis] = gamepadState.axis[j];
}
- gamepadAxisCount = gamepadState.numAxes;
+ CORE.Input.Gamepad.axisCount = gamepadState.numAxes;
}
}
#endif
@@ -3821,20 +3876,24 @@ static void PollInputEvents(void)
#if defined(PLATFORM_ANDROID)
// Register previous keys states
// NOTE: Android supports up to 260 keys
- for (int i = 0; i < 260; i++) previousKeyState[i] = currentKeyState[i];
+ for (int i = 0; i < 260; i++) CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i];
+
+ // Android ALooper_pollAll() variables
+ int pollResult = 0;
+ int pollEvents = 0;
// Poll Events (registered events)
- // NOTE: Activity is paused if not enabled (appEnabled)
- while ((ident = ALooper_pollAll(appEnabled? 0 : -1, NULL, &events,(void**)&source)) >= 0)
+ // NOTE: Activity is paused if not enabled (CORE.Android.appEnabled)
+ while ((pollResult = ALooper_pollAll(CORE.Android.appEnabled? 0 : -1, NULL, &pollEvents, (void**)&CORE.Android.source)) >= 0)
{
// Process this event
- if (source != NULL) source->process(androidApp, source);
+ if (CORE.Android.source != NULL) CORE.Android.source->process(CORE.Android.app, CORE.Android.source);
// NOTE: Never close window, native activity is controlled by the system!
- if (androidApp->destroyRequested != 0)
+ if (CORE.Android.app->destroyRequested != 0)
{
- //windowShouldClose = true;
- //ANativeActivity_finish(androidApp->activity);
+ //CORE.Window.shouldClose = true;
+ //ANativeActivity_finish(CORE.Android.app->activity);
}
}
#endif
@@ -3853,11 +3912,11 @@ static void PollInputEvents(void)
static void SwapBuffers(void)
{
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
- glfwSwapBuffers(window);
+ glfwSwapBuffers(CORE.Window.handle);
#endif
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_UWP)
- eglSwapBuffers(display, surface);
+ eglSwapBuffers(CORE.Window.device, CORE.Window.surface);
#endif
}
@@ -3865,21 +3924,21 @@ static void SwapBuffers(void)
// GLFW3 Error Callback, runs on GLFW3 error
static void ErrorCallback(int error, const char *description)
{
- TraceLog(LOG_WARNING, "[GLFW3 Error] Code: %i Decription: %s", error, description);
+ TRACELOG(LOG_WARNING, "GLFW: Error: %i Description: %s", error, description);
}
// GLFW3 Srolling Callback, runs on mouse wheel
static void ScrollCallback(GLFWwindow *window, double xoffset, double yoffset)
{
- currentMouseWheelY = (int)yoffset;
+ CORE.Input.Mouse.currentWheelMove = (int)yoffset;
}
// GLFW3 Keyboard Callback, runs on key pressed
static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
{
- if (key == exitKey && action == GLFW_PRESS)
+ if (key == CORE.Input.Keyboard.exitKey && action == GLFW_PRESS)
{
- glfwSetWindowShouldClose(window, GLFW_TRUE);
+ glfwSetWindowShouldClose(CORE.Window.handle, GLFW_TRUE);
// NOTE: Before closing window, while loop must be left!
}
@@ -3899,7 +3958,7 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
emscripten_run_script(TextFormat("saveFileFromMEMFSToDisk('%s','%s')", TextFormat("screenrec%03i.gif", screenshotCounter - 1), TextFormat("screenrec%03i.gif", screenshotCounter - 1)));
#endif
- TraceLog(LOG_INFO, "End animated GIF recording");
+ TRACELOG(LOG_INFO, "SYSTEM: Finish animated GIF recording");
}
else
{
@@ -3908,7 +3967,7 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
char path[512] = { 0 };
#if defined(PLATFORM_ANDROID)
- strcpy(path, internalDataPath);
+ strcpy(path, CORE.Android.internalDataPath);
strcat(path, TextFormat("./screenrec%03i.gif", screenshotCounter));
#else
strcpy(path, TextFormat("./screenrec%03i.gif", screenshotCounter));
@@ -3916,10 +3975,10 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
// NOTE: delay represents the time between frames in the gif, if we capture a gif frame every
// 10 game frames and each frame trakes 16.6ms (60fps), delay between gif frames should be ~16.6*10.
- GifBegin(path, screenWidth, screenHeight, (int)(GetFrameTime()*10.0f), 8, false);
+ GifBegin(path, CORE.Window.screen.width, CORE.Window.screen.height, (int)(GetFrameTime()*10.0f), 8, false);
screenshotCounter++;
- TraceLog(LOG_INFO, "Begin animated GIF recording: %s", TextFormat("screenrec%03i.gif", screenshotCounter));
+ TRACELOG(LOG_INFO, "SYSTEM: Start animated GIF recording: %s", TextFormat("screenrec%03i.gif", screenshotCounter));
}
}
else
@@ -3931,22 +3990,29 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
}
#endif // SUPPORT_SCREEN_CAPTURE
}
- else currentKeyState[key] = action;
+ else
+ {
+ // WARNING: GLFW could return GLFW_REPEAT, we need to consider it as 1
+ // to work properly with our implementation (IsKeyDown/IsKeyUp checks)
+ if (action == GLFW_RELEASE) CORE.Input.Keyboard.currentKeyState[key] = 0;
+ else CORE.Input.Keyboard.currentKeyState[key] = 1;
+ }
}
// GLFW3 Mouse Button Callback, runs on mouse button pressed
static void MouseButtonCallback(GLFWwindow *window, int button, int action, int mods)
{
- previousMouseState[button] = currentMouseState[button];
- currentMouseState[button] = action;
+ // WARNING: GLFW could only return GLFW_PRESS (1) or GLFW_RELEASE (0) for now,
+ // but future releases may add more actions (i.e. GLFW_REPEAT)
+ CORE.Input.Mouse.currentButtonState[button] = action;
#if defined(SUPPORT_GESTURES_SYSTEM) && defined(SUPPORT_MOUSE_GESTURES)
// Process mouse events as touches to be able to use mouse-gestures
- GestureEvent gestureEvent;
+ GestureEvent gestureEvent = { 0 };
// Register touch actions
- if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) gestureEvent.touchAction = TOUCH_DOWN;
- else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) gestureEvent.touchAction = TOUCH_UP;
+ if ((CORE.Input.Mouse.currentButtonState[button] == 1) && (CORE.Input.Mouse.previousButtonState[button] == 0)) gestureEvent.touchAction = TOUCH_DOWN;
+ else if ((CORE.Input.Mouse.currentButtonState[button] == 0) && (CORE.Input.Mouse.previousButtonState[button] == 1)) gestureEvent.touchAction = TOUCH_UP;
// NOTE: TOUCH_MOVE event is registered in MouseCursorPosCallback()
@@ -3959,7 +4025,7 @@ static void MouseButtonCallback(GLFWwindow *window, int button, int action, int
// Register touch points position, only one point registered
gestureEvent.position[0] = GetMousePosition();
- // Normalize gestureEvent.position[0] for screenWidth and screenHeight
+ // Normalize gestureEvent.position[0] for CORE.Window.screen.width and CORE.Window.screen.height
gestureEvent.position[0].x /= (float)GetScreenWidth();
gestureEvent.position[0].y /= (float)GetScreenHeight();
@@ -3971,9 +4037,13 @@ static void MouseButtonCallback(GLFWwindow *window, int button, int action, int
// GLFW3 Cursor Position Callback, runs on mouse move
static void MouseCursorPosCallback(GLFWwindow *window, double x, double y)
{
+ CORE.Input.Mouse.position.x = (float)x;
+ CORE.Input.Mouse.position.y = (float)y;
+ CORE.Input.Touch.position[0] = CORE.Input.Mouse.position;
+
#if defined(SUPPORT_GESTURES_SYSTEM) && defined(SUPPORT_MOUSE_GESTURES)
// Process mouse events as touches to be able to use mouse-gestures
- GestureEvent gestureEvent;
+ GestureEvent gestureEvent = { 0 };
gestureEvent.touchAction = TOUCH_MOVE;
@@ -3984,11 +4054,9 @@ static void MouseCursorPosCallback(GLFWwindow *window, double x, double y)
gestureEvent.pointCount = 1;
// Register touch points position, only one point registered
- gestureEvent.position[0] = (Vector2){ (float)x, (float)y };
-
- touchPosition[0] = gestureEvent.position[0];
+ gestureEvent.position[0] = CORE.Input.Touch.position[0];
- // Normalize gestureEvent.position[0] for screenWidth and screenHeight
+ // Normalize gestureEvent.position[0] for CORE.Window.screen.width and CORE.Window.screen.height
gestureEvent.position[0].x /= (float)GetScreenWidth();
gestureEvent.position[0].y /= (float)GetScreenHeight();
@@ -4006,19 +4074,19 @@ static void CharCallback(GLFWwindow *window, unsigned int key)
// Ref: https://www.glfw.org/docs/latest/input_guide.html#input_char
// Check if there is space available in the queue
- if (keyPressedQueueCount < MAX_CHARS_QUEUE)
+ if (CORE.Input.Keyboard.keyPressedQueueCount < MAX_CHARS_QUEUE)
{
// Add character to the queue
- keyPressedQueue[keyPressedQueueCount] = key;
- keyPressedQueueCount++;
+ CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = key;
+ CORE.Input.Keyboard.keyPressedQueueCount++;
}
}
// GLFW3 CursorEnter Callback, when cursor enters the window
static void CursorEnterCallback(GLFWwindow *window, int enter)
{
- if (enter == true) cursorOnScreen = true;
- else cursorOnScreen = false;
+ if (enter == true) CORE.Input.Mouse.cursorOnScreen = true;
+ else CORE.Input.Mouse.cursorOnScreen = false;
}
// GLFW3 WindowSize Callback, runs when window is resized
@@ -4028,21 +4096,21 @@ static void WindowSizeCallback(GLFWwindow *window, int width, int height)
SetupViewport(width, height); // Reset viewport and projection matrix for new size
// Set current screen size
- screenWidth = width;
- screenHeight = height;
- currentWidth = width;
- currentHeight = height;
+ CORE.Window.screen.width = width;
+ CORE.Window.screen.height = height;
+ CORE.Window.currentFbo.width = width;
+ CORE.Window.currentFbo.height = height;
// NOTE: Postprocessing texture is not scaled to new size
- windowResized = true;
+ CORE.Window.resized = true;
}
// GLFW3 WindowIconify Callback, runs when window is minimized/restored
static void WindowIconifyCallback(GLFWwindow *window, int iconified)
{
- if (iconified) windowMinimized = true; // The window was iconified
- else windowMinimized = false; // The window was restored
+ if (iconified) CORE.Window.minimized = true; // The window was iconified
+ else CORE.Window.minimized = false; // The window was restored
}
// GLFW3 Window Drop Callback, runs when drop files into window
@@ -4052,20 +4120,20 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths
{
ClearDroppedFiles();
- dropFilesPath = (char **)RL_MALLOC(sizeof(char *)*count);
+ CORE.Window.dropFilesPath = (char **)RL_MALLOC(sizeof(char *)*count);
for (int i = 0; i < count; i++)
{
- dropFilesPath[i] = (char *)RL_MALLOC(sizeof(char)*MAX_FILEPATH_LENGTH);
- strcpy(dropFilesPath[i], paths[i]);
+ CORE.Window.dropFilesPath[i] = (char *)RL_MALLOC(sizeof(char)*MAX_FILEPATH_LENGTH);
+ strcpy(CORE.Window.dropFilesPath[i], paths[i]);
}
- dropFilesCount = count;
+ CORE.Window.dropFilesCount = count;
}
#endif
#if defined(PLATFORM_ANDROID)
-// Android: Process activity lifecycle commands
+// ANDROID: Process activity lifecycle commands
static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
{
switch (cmd)
@@ -4073,35 +4141,32 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
case APP_CMD_START:
{
//rendering = true;
- TraceLog(LOG_INFO, "APP_CMD_START");
- } break;
- case APP_CMD_RESUME:
- {
- TraceLog(LOG_INFO, "APP_CMD_RESUME");
} break;
+ case APP_CMD_RESUME: break;
case APP_CMD_INIT_WINDOW:
{
- TraceLog(LOG_INFO, "APP_CMD_INIT_WINDOW");
-
if (app->window != NULL)
{
- if (contextRebindRequired)
+ if (CORE.Android.contextRebindRequired)
{
// Reset screen scaling to full display size
EGLint displayFormat;
- eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &displayFormat);
- ANativeWindow_setBuffersGeometry(app->window, renderWidth, renderHeight, displayFormat);
+ eglGetConfigAttrib(CORE.Window.device, CORE.Window.config, EGL_NATIVE_VISUAL_ID, &displayFormat);
+ ANativeWindow_setBuffersGeometry(app->window, CORE.Window.render.width, CORE.Window.render.height, displayFormat);
// Recreate display surface and re-attach OpenGL context
- surface = eglCreateWindowSurface(display, config, app->window, NULL);
- eglMakeCurrent(display, surface, surface, context);
+ CORE.Window.surface = eglCreateWindowSurface(CORE.Window.device, CORE.Window.config, app->window, NULL);
+ eglMakeCurrent(CORE.Window.device, CORE.Window.surface, CORE.Window.surface, CORE.Window.context);
- contextRebindRequired = false;
+ CORE.Android.contextRebindRequired = false;
}
else
{
+ CORE.Window.display.width = ANativeWindow_getWidth(CORE.Android.app->window);
+ CORE.Window.display.height = ANativeWindow_getHeight(CORE.Android.app->window);
+
// Init graphics device (display device and OpenGL context)
- InitGraphicsDevice(screenWidth, screenHeight);
+ InitGraphicsDevice(CORE.Window.screen.width, CORE.Window.screen.height);
// Init hi-res timer
InitTimer();
@@ -4110,6 +4175,9 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
// Load default font
// NOTE: External function (defined in module: text)
LoadFontDefault();
+ Rectangle rec = GetFontDefault().recs[95];
+ // NOTE: We setup a 1px padding on char rectangle to avoid pixel bleeding on MSAA filtering
+ SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2 });
#endif
// TODO: GPU assets reload in case of lost focus (lost context)
@@ -4131,19 +4199,13 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
} break;
case APP_CMD_GAINED_FOCUS:
{
- TraceLog(LOG_INFO, "APP_CMD_GAINED_FOCUS");
- appEnabled = true;
+ CORE.Android.appEnabled = true;
//ResumeMusicStream();
} break;
- case APP_CMD_PAUSE:
- {
- TraceLog(LOG_INFO, "APP_CMD_PAUSE");
- } break;
+ case APP_CMD_PAUSE: break;
case APP_CMD_LOST_FOCUS:
{
- //DrawFrame();
- TraceLog(LOG_INFO, "APP_CMD_LOST_FOCUS");
- appEnabled = false;
+ CORE.Android.appEnabled = false;
//PauseMusicStream();
} break;
case APP_CMD_TERM_WINDOW:
@@ -4151,77 +4213,64 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
// Dettach OpenGL context and destroy display surface
// NOTE 1: Detaching context before destroying display surface avoids losing our resources (textures, shaders, VBOs...)
// NOTE 2: In some cases (too many context loaded), OS could unload context automatically... :(
- eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- eglDestroySurface(display, surface);
+ eglMakeCurrent(CORE.Window.device, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglDestroySurface(CORE.Window.device, CORE.Window.surface);
- contextRebindRequired = true;
-
- TraceLog(LOG_INFO, "APP_CMD_TERM_WINDOW");
- } break;
- case APP_CMD_SAVE_STATE:
- {
- TraceLog(LOG_INFO, "APP_CMD_SAVE_STATE");
- } break;
- case APP_CMD_STOP:
- {
- TraceLog(LOG_INFO, "APP_CMD_STOP");
+ CORE.Android.contextRebindRequired = true;
} break;
+ case APP_CMD_SAVE_STATE: break;
+ case APP_CMD_STOP: break;
case APP_CMD_DESTROY:
{
// TODO: Finish activity?
- //ANativeActivity_finish(androidApp->activity);
-
- TraceLog(LOG_INFO, "APP_CMD_DESTROY");
+ //ANativeActivity_finish(CORE.Android.app->activity);
} break;
case APP_CMD_CONFIG_CHANGED:
{
- //AConfiguration_fromAssetManager(androidApp->config, androidApp->activity->assetManager);
- //print_cur_config(androidApp);
+ //AConfiguration_fromAssetManager(CORE.Android.app->config, CORE.Android.app->activity->assetManager);
+ //print_cur_config(CORE.Android.app);
// Check screen orientation here!
-
- TraceLog(LOG_INFO, "APP_CMD_CONFIG_CHANGED");
} break;
default: break;
}
}
-// Android: Get input events
+// ANDROID: Get input events
static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
{
// If additional inputs are required check:
// https://developer.android.com/ndk/reference/group/input
+ // https://developer.android.com/training/game-controllers/controller-input
int type = AInputEvent_getType(event);
+ int source = AInputEvent_getSource(event);
if (type == AINPUT_EVENT_TYPE_MOTION)
{
- // Get first touch position
- touchPosition[0].x = AMotionEvent_getX(event, 0);
- touchPosition[0].y = AMotionEvent_getY(event, 0);
+ if ((source & AINPUT_SOURCE_JOYSTICK) == AINPUT_SOURCE_JOYSTICK || (source & AINPUT_SOURCE_GAMEPAD) == AINPUT_SOURCE_GAMEPAD)
+ {
+ // Get first touch position
+ CORE.Input.Touch.position[0].x = AMotionEvent_getX(event, 0);
+ CORE.Input.Touch.position[0].y = AMotionEvent_getY(event, 0);
- // Get second touch position
- touchPosition[1].x = AMotionEvent_getX(event, 1);
- touchPosition[1].y = AMotionEvent_getY(event, 1);
+ // Get second touch position
+ CORE.Input.Touch.position[1].x = AMotionEvent_getX(event, 1);
+ CORE.Input.Touch.position[1].y = AMotionEvent_getY(event, 1);
- // Useful functions for gamepad inputs:
- //AMotionEvent_getAction()
- //AMotionEvent_getAxisValue()
- //AMotionEvent_getButtonState()
+ int32_t keycode = AKeyEvent_getKeyCode(event);
+ if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN)
+ {
+ CORE.Input.Keyboard.currentKeyState[keycode] = 1; // Key down
- // Gamepad dpad button presses capturing
- // TODO: That's weird, key input (or button)
- // shouldn't come as a TYPE_MOTION event...
- int32_t keycode = AKeyEvent_getKeyCode(event);
- if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN)
- {
- currentKeyState[keycode] = 1; // Key down
-
- keyPressedQueue[keyPressedQueueCount] = keycode;
- keyPressedQueueCount++;
- }
- else currentKeyState[keycode] = 0; // Key up
+ CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = keycode;
+ CORE.Input.Keyboard.keyPressedQueueCount++;
+ }
+ else CORE.Input.Keyboard.currentKeyState[keycode] = 0; // Key up
+ // Stop processing gamepad buttons
+ return 1;
+ }
}
else if (type == AINPUT_EVENT_TYPE_KEY)
{
@@ -4232,12 +4281,12 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
// NOTE: Android key action is 0 for down and 1 for up
if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN)
{
- currentKeyState[keycode] = 1; // Key down
-
- keyPressedQueue[keyPressedQueueCount] = keycode;
- keyPressedQueueCount++;
+ CORE.Input.Keyboard.currentKeyState[keycode] = 1; // Key down
+
+ CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = keycode;
+ CORE.Input.Keyboard.keyPressedQueueCount++;
}
- else currentKeyState[keycode] = 0; // Key up
+ else CORE.Input.Keyboard.currentKeyState[keycode] = 0; // Key up
if (keycode == AKEYCODE_POWER)
{
@@ -4258,12 +4307,27 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
// Set default OS behaviour
return 0;
}
+
+ return 0;
}
+ CORE.Input.Touch.position[0].x = AMotionEvent_getX(event, 0);
+ CORE.Input.Touch.position[0].y = AMotionEvent_getY(event, 0);
+
int32_t action = AMotionEvent_getAction(event);
unsigned int flags = action & AMOTION_EVENT_ACTION_MASK;
+ if (flags == AMOTION_EVENT_ACTION_DOWN || flags == AMOTION_EVENT_ACTION_MOVE)
+ {
+ CORE.Input.Touch.currentTouchState[MOUSE_LEFT_BUTTON] = 1;
+ }
+ else if (flags == AMOTION_EVENT_ACTION_UP)
+ {
+ CORE.Input.Touch.currentTouchState[MOUSE_LEFT_BUTTON] = 0;
+ }
+
#if defined(SUPPORT_GESTURES_SYSTEM)
+
GestureEvent gestureEvent;
// Register touch actions
@@ -4298,17 +4362,6 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
// Gesture data is sent to gestures system for processing
ProcessGestureEvent(gestureEvent);
}
-#else
- // Support only simple touch position
- if (flags == AMOTION_EVENT_ACTION_DOWN)
- {
- // Get first touch position
- touchPosition[0].x = AMotionEvent_getX(event, 0);
- touchPosition[0].y = AMotionEvent_getY(event, 0);
-
- touchPosition[0].x /= (float)GetScreenWidth();
- touchPosition[0].y /= (float)GetScreenHeight();
- }
#endif
return 0;
@@ -4316,24 +4369,25 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
#endif
#if defined(PLATFORM_WEB)
-
// Register fullscreen change events
-static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const EmscriptenFullscreenChangeEvent *e, void *userData)
+static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const EmscriptenFullscreenChangeEvent *event, void *userData)
{
- //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
+ //isFullscreen: int event->isFullscreen
+ //fullscreenEnabled: int event->fullscreenEnabled
+ //fs element nodeName: (char *) event->nodeName
+ //fs element id: (char *) event->id
+ //Current element size: (int) event->elementWidth, (int) event->elementHeight
+ //Screen size:(int) event->screenWidth, (int) event->screenHeight
- if (e->isFullscreen)
+ if (event->isFullscreen)
{
- TraceLog(LOG_INFO, "Canvas scaled to fullscreen. ElementSize: (%ix%i), ScreenSize(%ix%i)", e->elementWidth, e->elementHeight, e->screenWidth, e->screenHeight);
+ CORE.Window.fullscreen = true;
+ TRACELOG(LOG_INFO, "WEB: Canvas scaled to fullscreen. ElementSize: (%ix%i), ScreenSize(%ix%i)", event->elementWidth, event->elementHeight, event->screenWidth, event->screenHeight);
}
else
{
- TraceLog(LOG_INFO, "Canvas scaled to windowed. ElementSize: (%ix%i), ScreenSize(%ix%i)", e->elementWidth, e->elementHeight, e->screenWidth, e->screenHeight);
+ CORE.Window.fullscreen = false;
+ TRACELOG(LOG_INFO, "WEB: Canvas scaled to windowed. ElementSize: (%ix%i), ScreenSize(%ix%i)", event->elementWidth, event->elementHeight, event->screenWidth, event->screenHeight);
}
// TODO: Depending on scaling factor (screen vs element), calculate factor to scale mouse/touch input
@@ -4356,7 +4410,7 @@ static EM_BOOL EmscriptenKeyboardCallback(int eventType, const EmscriptenKeyboar
static EM_BOOL EmscriptenMouseCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData)
{
// Lock mouse pointer when click on screen
- if ((eventType == EMSCRIPTEN_EVENT_CLICK) && toggleCursorLock)
+ if ((eventType == EMSCRIPTEN_EVENT_CLICK) && CORE.Input.Mouse.cursorLockRequired)
{
EmscriptenPointerlockChangeEvent plce;
emscripten_get_pointerlock_status(&plce);
@@ -4366,10 +4420,10 @@ static EM_BOOL EmscriptenMouseCallback(int eventType, const EmscriptenMouseEvent
{
emscripten_exit_pointerlock();
emscripten_get_pointerlock_status(&plce);
- //if (plce.isActive) TraceLog(LOG_WARNING, "Pointer lock exit did not work!");
+ //if (plce.isActive) TRACELOG(LOG_WARNING, "Pointer lock exit did not work!");
}
- toggleCursorLock = false;
+ CORE.Input.Mouse.cursorLockRequired = false;
}
return 0;
@@ -4378,32 +4432,14 @@ static EM_BOOL EmscriptenMouseCallback(int eventType, const EmscriptenMouseEvent
// Register touch input events
static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData)
{
- /*
for (int i = 0; i < touchEvent->numTouches; i++)
{
- long x, y, id;
-
- if (!touchEvent->touches[i].isChanged) continue;
-
- id = touchEvent->touches[i].identifier;
- x = touchEvent->touches[i].canvasX;
- y = touchEvent->touches[i].canvasY;
+ if (eventType == EMSCRIPTEN_EVENT_TOUCHSTART) CORE.Input.Touch.currentTouchState[i] = 1;
+ else if (eventType == EMSCRIPTEN_EVENT_TOUCHEND) CORE.Input.Touch.currentTouchState[i] = 0;
}
- TraceLog(LOG_DEBUG, "%s, numTouches: %d %s%s%s%s", 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];
-
- TraceLog(LOG_DEBUG, " %ld: screen: (%ld,%ld), client: (%ld,%ld), page: (%ld,%ld), isChanged: %d, onTarget: %d, canvas: (%ld, %ld)",
- t->identifier, t->screenX, t->screenY, t->clientX, t->clientY, t->pageX, t->pageY, t->isChanged, t->onTarget, t->canvasX, t->canvasY);
- }
- */
-
#if defined(SUPPORT_GESTURES_SYSTEM)
- GestureEvent gestureEvent;
+ GestureEvent gestureEvent = { 0 };
// Register touch actions
if (eventType == EMSCRIPTEN_EVENT_TOUCHSTART) gestureEvent.touchAction = TOUCH_DOWN;
@@ -4419,21 +4455,23 @@ static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent
// Register touch points position
// NOTE: Only two points registered
- // TODO: Touch data should be scaled accordingly!
- //gestureEvent.position[0] = (Vector2){ touchEvent->touches[0].canvasX, touchEvent->touches[0].canvasY };
- //gestureEvent.position[1] = (Vector2){ touchEvent->touches[1].canvasX, touchEvent->touches[1].canvasY };
gestureEvent.position[0] = (Vector2){ touchEvent->touches[0].targetX, touchEvent->touches[0].targetY };
gestureEvent.position[1] = (Vector2){ touchEvent->touches[1].targetX, touchEvent->touches[1].targetY };
- touchPosition[0] = gestureEvent.position[0];
- touchPosition[1] = gestureEvent.position[1];
+ double canvasWidth, canvasHeight;
+ // NOTE: emscripten_get_canvas_element_size() returns canvas.width and canvas.height but
+ // we are looking for actual CSS size: canvas.style.width and canvas.style.height
+ //EMSCRIPTEN_RESULT res = emscripten_get_canvas_element_size("#canvas", &canvasWidth, &canvasHeight);
+ emscripten_get_element_css_size("#canvas", &canvasWidth, &canvasHeight);
- // Normalize gestureEvent.position[x] for screenWidth and screenHeight
- gestureEvent.position[0].x /= (float)GetScreenWidth();
- gestureEvent.position[0].y /= (float)GetScreenHeight();
+ // Normalize gestureEvent.position[x] for CORE.Window.screen.width and CORE.Window.screen.height
+ gestureEvent.position[0].x *= ((float)GetScreenWidth()/(float)canvasWidth);
+ gestureEvent.position[0].y *= ((float)GetScreenHeight()/(float)canvasHeight);
+ gestureEvent.position[1].x *= ((float)GetScreenWidth()/(float)canvasWidth);
+ gestureEvent.position[1].y *= ((float)GetScreenHeight()/(float)canvasHeight);
- gestureEvent.position[1].x /= (float)GetScreenWidth();
- gestureEvent.position[1].y /= (float)GetScreenHeight();
+ CORE.Input.Touch.position[0] = gestureEvent.position[0];
+ CORE.Input.Touch.position[1] = gestureEvent.position[1];
// Gesture data is sent to gestures system for processing
ProcessGestureEvent(gestureEvent);
@@ -4442,10 +4480,15 @@ static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent
if (eventType == EMSCRIPTEN_EVENT_TOUCHSTART)
{
// Get first touch position
- touchPosition[0] = (Vector2){ touchEvent->touches[0].targetX, touchEvent->touches[0].targetY };
+ CORE.Input.Touch.position[0] = (Vector2){ touchEvent->touches[0].targetX, touchEvent->touches[0].targetY };
- touchPosition[0].x /= (float)GetScreenWidth();
- touchPosition[0].y /= (float)GetScreenHeight();
+ double canvasWidth, canvasHeight;
+ //EMSCRIPTEN_RESULT res = emscripten_get_canvas_element_size("#canvas", &canvasWidth, &canvasHeight);
+ emscripten_get_element_css_size("#canvas", &canvasWidth, &canvasHeight);
+
+ // Normalize gestureEvent.position[x] for screenWidth and screenHeight
+ CORE.Input.Touch.position[0].x *= ((float)GetScreenWidth()/(float)canvasWidth);
+ CORE.Input.Touch.position[0].y *= ((float)GetScreenHeight()/(float)canvasHeight);
}
#endif
@@ -4456,16 +4499,16 @@ static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent
static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData)
{
/*
- TraceLog(LOG_DEBUG, "%s: timeStamp: %g, connected: %d, index: %ld, numAxes: %d, numButtons: %d, id: \"%s\", mapping: \"%s\"",
+ TRACELOGD("%s: timeStamp: %g, connected: %d, index: %ld, numAxes: %d, numButtons: %d, id: \"%s\", mapping: \"%s\"",
eventType != 0? emscripten_event_type_to_string(eventType) : "Gamepad state",
gamepadEvent->timestamp, gamepadEvent->connected, gamepadEvent->index, gamepadEvent->numAxes, gamepadEvent->numButtons, gamepadEvent->id, gamepadEvent->mapping);
- for (int i = 0; i < gamepadEvent->numAxes; ++i) TraceLog(LOG_DEBUG, "Axis %d: %g", i, gamepadEvent->axis[i]);
- for (int i = 0; i < gamepadEvent->numButtons; ++i) TraceLog(LOG_DEBUG, "Button %d: Digital: %d, Analog: %g", i, gamepadEvent->digitalButton[i], gamepadEvent->analogButton[i]);
+ for (int i = 0; i < gamepadEvent->numAxes; ++i) TRACELOGD("Axis %d: %g", i, gamepadEvent->axis[i]);
+ for (int i = 0; i < gamepadEvent->numButtons; ++i) TRACELOGD("Button %d: Digital: %d, Analog: %g", i, gamepadEvent->digitalButton[i], gamepadEvent->analogButton[i]);
*/
- if ((gamepadEvent->connected) && (gamepadEvent->index < MAX_GAMEPADS)) gamepadReady[gamepadEvent->index] = true;
- else gamepadReady[gamepadEvent->index] = false;
+ if ((gamepadEvent->connected) && (gamepadEvent->index < MAX_GAMEPADS)) CORE.Input.Gamepad.ready[gamepadEvent->index] = true;
+ else CORE.Input.Gamepad.ready[gamepadEvent->index] = false;
// TODO: Test gamepadEvent->index
@@ -4487,8 +4530,8 @@ static void InitKeyboard(void)
// Save terminal keyboard settings and reconfigure terminal with new settings
struct termios keyboardNewSettings;
- tcgetattr(STDIN_FILENO, &defaultKeyboardSettings); // Get current keyboard settings
- keyboardNewSettings = defaultKeyboardSettings;
+ tcgetattr(STDIN_FILENO, &CORE.Input.Keyboard.defaultSettings); // Get current keyboard settings
+ keyboardNewSettings = CORE.Input.Keyboard.defaultSettings;
// New terminal settings for keyboard: turn off buffering (non-canonical mode), echo and key processing
// NOTE: ISIG controls if ^C and ^Z generate break signals or not
@@ -4503,10 +4546,10 @@ static void InitKeyboard(void)
// NOTE: Reading directly from stdin will give chars already key-mapped by kernel to ASCII or UNICODE
// Save old keyboard mode to restore it at the end
- if (ioctl(STDIN_FILENO, KDGKBMODE, &defaultKeyboardMode) < 0)
+ if (ioctl(STDIN_FILENO, KDGKBMODE, &CORE.Input.Keyboard.defaultMode) < 0)
{
// NOTE: It could mean we are using a remote keyboard through ssh!
- TraceLog(LOG_WARNING, "Could not change keyboard mode (SSH keyboard?)");
+ TRACELOG(LOG_WARNING, "RPI: Failed to change keyboard mode (SSH keyboard?)");
}
else
{
@@ -4536,22 +4579,20 @@ static void ProcessKeyboard(void)
bufferByteCount = read(STDIN_FILENO, keysBuffer, MAX_KEYBUFFER_SIZE); // POSIX system call
// Reset pressed keys array (it will be filled below)
- for (int i = 0; i < 512; i++) currentKeyState[i] = 0;
+ for (int i = 0; i < 512; i++) CORE.Input.Keyboard.currentKeyState[i] = 0;
// Check keys from event input workers (This is the new keyboard reading method)
- for (int i = 0; i < 512; i++) currentKeyState[i] = currentKeyStateEvdev[i];
+ //for (int i = 0; i < 512; i++) CORE.Input.Keyboard.currentKeyState[i] = CORE.Input.Keyboard.currentKeyStateEvdev[i];
// Fill all read bytes (looking for keys)
for (int i = 0; i < bufferByteCount; i++)
{
- TraceLog(LOG_DEBUG, "Bytes on keysBuffer: %i", bufferByteCount);
-
// NOTE: If (key == 0x1b), depending on next key, it could be a special keymap code!
// Up -> 1b 5b 41 / Left -> 1b 5b 44 / Right -> 1b 5b 43 / Down -> 1b 5b 42
if (keysBuffer[i] == 0x1b)
{
// Detect ESC to stop program
- if (bufferByteCount == 1) currentKeyState[256] = 1; // raylib key: KEY_ESCAPE
+ if (bufferByteCount == 1) CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey] = 1;
else
{
if (keysBuffer[i + 1] == 0x5b) // Special function key
@@ -4561,18 +4602,18 @@ static void ProcessKeyboard(void)
// Process special function keys (F1 - F12)
switch (keysBuffer[i + 3])
{
- case 0x41: currentKeyState[290] = 1; break; // raylib KEY_F1
- case 0x42: currentKeyState[291] = 1; break; // raylib KEY_F2
- case 0x43: currentKeyState[292] = 1; break; // raylib KEY_F3
- case 0x44: currentKeyState[293] = 1; break; // raylib KEY_F4
- case 0x45: currentKeyState[294] = 1; break; // raylib KEY_F5
- case 0x37: currentKeyState[295] = 1; break; // raylib KEY_F6
- case 0x38: currentKeyState[296] = 1; break; // raylib KEY_F7
- case 0x39: currentKeyState[297] = 1; break; // raylib KEY_F8
- case 0x30: currentKeyState[298] = 1; break; // raylib KEY_F9
- case 0x31: currentKeyState[299] = 1; break; // raylib KEY_F10
- case 0x33: currentKeyState[300] = 1; break; // raylib KEY_F11
- case 0x34: currentKeyState[301] = 1; break; // raylib KEY_F12
+ case 0x41: CORE.Input.Keyboard.currentKeyState[290] = 1; break; // raylib KEY_F1
+ case 0x42: CORE.Input.Keyboard.currentKeyState[291] = 1; break; // raylib KEY_F2
+ case 0x43: CORE.Input.Keyboard.currentKeyState[292] = 1; break; // raylib KEY_F3
+ case 0x44: CORE.Input.Keyboard.currentKeyState[293] = 1; break; // raylib KEY_F4
+ case 0x45: CORE.Input.Keyboard.currentKeyState[294] = 1; break; // raylib KEY_F5
+ case 0x37: CORE.Input.Keyboard.currentKeyState[295] = 1; break; // raylib KEY_F6
+ case 0x38: CORE.Input.Keyboard.currentKeyState[296] = 1; break; // raylib KEY_F7
+ case 0x39: CORE.Input.Keyboard.currentKeyState[297] = 1; break; // raylib KEY_F8
+ case 0x30: CORE.Input.Keyboard.currentKeyState[298] = 1; break; // raylib KEY_F9
+ case 0x31: CORE.Input.Keyboard.currentKeyState[299] = 1; break; // raylib KEY_F10
+ case 0x33: CORE.Input.Keyboard.currentKeyState[300] = 1; break; // raylib KEY_F11
+ case 0x34: CORE.Input.Keyboard.currentKeyState[301] = 1; break; // raylib KEY_F12
default: break;
}
@@ -4583,10 +4624,10 @@ static void ProcessKeyboard(void)
{
switch (keysBuffer[i + 2])
{
- case 0x41: currentKeyState[265] = 1; break; // raylib KEY_UP
- case 0x42: currentKeyState[264] = 1; break; // raylib KEY_DOWN
- case 0x43: currentKeyState[262] = 1; break; // raylib KEY_RIGHT
- case 0x44: currentKeyState[263] = 1; break; // raylib KEY_LEFT
+ case 0x41: CORE.Input.Keyboard.currentKeyState[265] = 1; break; // raylib KEY_UP
+ case 0x42: CORE.Input.Keyboard.currentKeyState[264] = 1; break; // raylib KEY_DOWN
+ case 0x43: CORE.Input.Keyboard.currentKeyState[262] = 1; break; // raylib KEY_RIGHT
+ case 0x44: CORE.Input.Keyboard.currentKeyState[263] = 1; break; // raylib KEY_LEFT
default: break;
}
@@ -4599,40 +4640,38 @@ static void ProcessKeyboard(void)
}
else if (keysBuffer[i] == 0x0a) // raylib KEY_ENTER (don't mix with <linux/input.h> KEY_*)
{
- currentKeyState[257] = 1;
-
- keyPressedQueue[keyPressedQueueCount] = 257; // Add keys pressed into queue
- keyPressedQueueCount++;
+ CORE.Input.Keyboard.currentKeyState[257] = 1;
+
+ CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = 257; // Add keys pressed into queue
+ CORE.Input.Keyboard.keyPressedQueueCount++;
}
else if (keysBuffer[i] == 0x7f) // raylib KEY_BACKSPACE
- {
- currentKeyState[259] = 1;
-
- keyPressedQueue[keyPressedQueueCount] = 257; // Add keys pressed into queue
- keyPressedQueueCount++;
+ {
+ CORE.Input.Keyboard.currentKeyState[259] = 1;
+
+ CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = 257; // Add keys pressed into queue
+ CORE.Input.Keyboard.keyPressedQueueCount++;
}
else
{
- TraceLog(LOG_DEBUG, "Pressed key (ASCII): 0x%02x", keysBuffer[i]);
-
// Translate lowercase a-z letters to A-Z
if ((keysBuffer[i] >= 97) && (keysBuffer[i] <= 122))
{
- currentKeyState[(int)keysBuffer[i] - 32] = 1;
+ CORE.Input.Keyboard.currentKeyState[(int)keysBuffer[i] - 32] = 1;
}
- else currentKeyState[(int)keysBuffer[i]] = 1;
+ else CORE.Input.Keyboard.currentKeyState[(int)keysBuffer[i]] = 1;
- keyPressedQueue[keyPressedQueueCount] = keysBuffer[i]; // Add keys pressed into queue
- keyPressedQueueCount++;
+ CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = keysBuffer[i]; // Add keys pressed into queue
+ CORE.Input.Keyboard.keyPressedQueueCount++;
}
}
// Check exit key (same functionality as GLFW3 KeyCallback())
- if (currentKeyState[exitKey] == 1) windowShouldClose = true;
+ if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey] == 1) CORE.Window.shouldClose = true;
#if defined(SUPPORT_SCREEN_CAPTURE)
// Check screen capture key (raylib key: KEY_F12)
- if (currentKeyState[301] == 1)
+ if (CORE.Input.Keyboard.currentKeyState[301] == 1)
{
TakeScreenshot(FormatText("screenshot%03i.png", screenshotCounter));
screenshotCounter++;
@@ -4644,10 +4683,10 @@ static void ProcessKeyboard(void)
static void RestoreKeyboard(void)
{
// Reset to default keyboard settings
- tcsetattr(STDIN_FILENO, TCSANOW, &defaultKeyboardSettings);
+ tcsetattr(STDIN_FILENO, TCSANOW, &CORE.Input.Keyboard.defaultSettings);
// Reconfigure keyboard to default mode
- ioctl(STDIN_FILENO, KDSKBMODE, defaultKeyboardMode);
+ ioctl(STDIN_FILENO, KDSKBMODE, CORE.Input.Keyboard.defaultMode);
}
#endif //SUPPORT_SSH_KEYBOARD_RPI
@@ -4661,14 +4700,16 @@ static void InitEvdevInput(void)
// Reset variables
for (int i = 0; i < MAX_TOUCH_POINTS; ++i)
{
- touchPosition[i].x = -1;
- touchPosition[i].y = -1;
+ CORE.Input.Touch.position[i].x = -1;
+ CORE.Input.Touch.position[i].y = -1;
}
+
// Reset keypress buffer
- lastKeyPressedEvdev.Head = 0;
- lastKeyPressedEvdev.Tail = 0;
+ CORE.Input.Keyboard.lastKeyPressed.head = 0;
+ CORE.Input.Keyboard.lastKeyPressed.tail = 0;
+
// Reset keyboard key state
- for (int i = 0; i < 512; i++) currentKeyStateEvdev[i] = 0;
+ for (int i = 0; i < 512; i++) CORE.Input.Keyboard.currentKeyState[i] = 0;
// Open the linux directory of "/dev/input"
directory = opendir(DEFAULT_EVDEV_PATH);
@@ -4686,7 +4727,7 @@ static void InitEvdevInput(void)
closedir(directory);
}
- else TraceLog(LOG_WARNING, "Unable to open linux event directory: %s", DEFAULT_EVDEV_PATH);
+ else TRACELOG(LOG_WARNING, "RPI: Failed to open linux event directory: %s", DEFAULT_EVDEV_PATH);
}
// Identifies a input device and spawns a thread to handle it if needed
@@ -4715,9 +4756,9 @@ static void EventThreadSpawn(char *device)
// Open the device and allocate worker
//-------------------------------------------------------------------------------------------------------
// Find a free spot in the workers array
- for (int i = 0; i < sizeof(eventWorkers)/sizeof(InputEventWorker); ++i)
+ for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i)
{
- if (eventWorkers[i].threadId == 0)
+ if (CORE.Input.eventWorker[i].threadId == 0)
{
freeWorkerId = i;
break;
@@ -4727,12 +4768,12 @@ static void EventThreadSpawn(char *device)
// Select the free worker from array
if (freeWorkerId >= 0)
{
- worker = &(eventWorkers[freeWorkerId]); // Grab a pointer to the worker
+ worker = &(CORE.Input.eventWorker[freeWorkerId]); // Grab a pointer to the worker
memset(worker, 0, sizeof(InputEventWorker)); // Clear the worker
}
else
{
- TraceLog(LOG_WARNING, "Error creating input device thread for [%s]: Out of worker slots", device);
+ TRACELOG(LOG_WARNING, "RPI: Failed to create input device thread for %s, out of worker slots", device);
return;
}
@@ -4740,7 +4781,7 @@ static void EventThreadSpawn(char *device)
fd = open(device, O_RDONLY | O_NONBLOCK);
if (fd < 0)
{
- TraceLog(LOG_WARNING, "Error creating input device thread for [%s]: Can't open device (Error: %d)", device, worker->fd);
+ TRACELOG(LOG_WARNING, "RPI: Failed to open input device (error: %d)", device, worker->fd);
return;
}
worker->fd = fd;
@@ -4840,8 +4881,8 @@ static void EventThreadSpawn(char *device)
//-------------------------------------------------------------------------------------------------------
if (worker->isTouch || worker->isMouse || worker->isKeyboard)
{
- // Looks like a interesting device
- TraceLog(LOG_INFO, "Opening input device [%s] (%s%s%s%s%s)", device,
+ // Looks like an interesting device
+ TRACELOG(LOG_INFO, "RPI: Opening input device: %s (%s%s%s%s%s)", device,
worker->isMouse? "mouse " : "",
worker->isMultitouch? "multitouch " : "",
worker->isTouch? "touchscreen " : "",
@@ -4852,7 +4893,7 @@ static void EventThreadSpawn(char *device)
int error = pthread_create(&worker->threadId, NULL, &EventThread, (void *)worker);
if (error != 0)
{
- TraceLog(LOG_WARNING, "Error creating input device thread for [%s]: Can't create thread (Error: %d)", device, error);
+ TRACELOG(LOG_WARNING, "RPI: Failed to create input device thread: %s (error: %d)", device, error);
worker->threadId = 0;
close(fd);
}
@@ -4861,21 +4902,21 @@ static void EventThreadSpawn(char *device)
// Find touchscreen with the highest index
int maxTouchNumber = -1;
- for (int i = 0; i < sizeof(eventWorkers)/sizeof(InputEventWorker); ++i)
+ for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i)
{
- if (eventWorkers[i].isTouch && (eventWorkers[i].eventNum > maxTouchNumber)) maxTouchNumber = eventWorkers[i].eventNum;
+ if (CORE.Input.eventWorker[i].isTouch && (CORE.Input.eventWorker[i].eventNum > maxTouchNumber)) maxTouchNumber = CORE.Input.eventWorker[i].eventNum;
}
// Find toucnscreens with lower indexes
- for (int i = 0; i < sizeof(eventWorkers)/sizeof(InputEventWorker); ++i)
+ for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i)
{
- if (eventWorkers[i].isTouch && (eventWorkers[i].eventNum < maxTouchNumber))
+ if (CORE.Input.eventWorker[i].isTouch && (CORE.Input.eventWorker[i].eventNum < maxTouchNumber))
{
- if (eventWorkers[i].threadId != 0)
+ if (CORE.Input.eventWorker[i].threadId != 0)
{
- TraceLog(LOG_WARNING, "Duplicate touchscreen found, killing touchscreen on event: %d", i);
- pthread_cancel(eventWorkers[i].threadId);
- close(eventWorkers[i].fd);
+ TRACELOG(LOG_WARNING, "RPI: Found duplicate touchscreen, killing touchscreen on event: %d", i);
+ pthread_cancel(CORE.Input.eventWorker[i].threadId);
+ close(CORE.Input.eventWorker[i].fd);
}
}
}
@@ -4915,7 +4956,7 @@ static void *EventThread(void *arg)
bool gestureUpdate = false;
int keycode;
- while (!windowShouldClose)
+ while (!CORE.Window.shouldClose)
{
// Try to read data from the device and only continue if successful
if (read(worker->fd, &event, sizeof(event)) == (int)sizeof(event))
@@ -4925,8 +4966,8 @@ static void *EventThread(void *arg)
{
if (event.code == REL_X)
{
- mousePosition.x += event.value;
- touchPosition[0].x = mousePosition.x;
+ CORE.Input.Mouse.position.x += event.value;
+ CORE.Input.Touch.position[0].x = CORE.Input.Mouse.position.x;
#if defined(SUPPORT_GESTURES_SYSTEM)
touchAction = TOUCH_MOVE;
@@ -4936,8 +4977,8 @@ static void *EventThread(void *arg)
if (event.code == REL_Y)
{
- mousePosition.y += event.value;
- touchPosition[0].y = mousePosition.y;
+ CORE.Input.Mouse.position.y += event.value;
+ CORE.Input.Touch.position[0].y = CORE.Input.Mouse.position.y;
#if defined(SUPPORT_GESTURES_SYSTEM)
touchAction = TOUCH_MOVE;
@@ -4945,7 +4986,7 @@ static void *EventThread(void *arg)
#endif
}
- if (event.code == REL_WHEEL) currentMouseWheelY += event.value;
+ if (event.code == REL_WHEEL) CORE.Input.Mouse.currentWheelMove += event.value;
}
// Absolute movement parsing
@@ -4954,7 +4995,7 @@ static void *EventThread(void *arg)
// Basic movement
if (event.code == ABS_X)
{
- mousePosition.x = (event.value - worker->absRange.x)*screenWidth/worker->absRange.width; // Scale acording to absRange
+ CORE.Input.Mouse.position.x = (event.value - worker->absRange.x)*CORE.Window.screen.width/worker->absRange.width; // Scale acording to absRange
#if defined(SUPPORT_GESTURES_SYSTEM)
touchAction = TOUCH_MOVE;
@@ -4964,7 +5005,7 @@ static void *EventThread(void *arg)
if (event.code == ABS_Y)
{
- mousePosition.y = (event.value - worker->absRange.y)*screenHeight/worker->absRange.height; // Scale acording to absRange
+ CORE.Input.Mouse.position.y = (event.value - worker->absRange.y)*CORE.Window.screen.height/worker->absRange.height; // Scale acording to absRange
#if defined(SUPPORT_GESTURES_SYSTEM)
touchAction = TOUCH_MOVE;
@@ -4977,12 +5018,12 @@ static void *EventThread(void *arg)
if (event.code == ABS_MT_POSITION_X)
{
- if (worker->touchSlot < MAX_TOUCH_POINTS) touchPosition[worker->touchSlot].x = (event.value - worker->absRange.x)*screenWidth/worker->absRange.width; // Scale acording to absRange
+ if (worker->touchSlot < MAX_TOUCH_POINTS) CORE.Input.Touch.position[worker->touchSlot].x = (event.value - worker->absRange.x)*CORE.Window.screen.width/worker->absRange.width; // Scale acording to absRange
}
if (event.code == ABS_MT_POSITION_Y)
{
- if (worker->touchSlot < MAX_TOUCH_POINTS) touchPosition[worker->touchSlot].y = (event.value - worker->absRange.y)*screenHeight/worker->absRange.height; // Scale acording to absRange
+ if (worker->touchSlot < MAX_TOUCH_POINTS) CORE.Input.Touch.position[worker->touchSlot].y = (event.value - worker->absRange.y)*CORE.Window.screen.height/worker->absRange.height; // Scale acording to absRange
}
if (event.code == ABS_MT_TRACKING_ID)
@@ -4990,8 +5031,8 @@ static void *EventThread(void *arg)
if ((event.value < 0) && (worker->touchSlot < MAX_TOUCH_POINTS))
{
// Touch has ended for this point
- touchPosition[worker->touchSlot].x = -1;
- touchPosition[worker->touchSlot].y = -1;
+ CORE.Input.Touch.position[worker->touchSlot].x = -1;
+ CORE.Input.Touch.position[worker->touchSlot].y = -1;
}
}
}
@@ -5002,7 +5043,7 @@ static void *EventThread(void *arg)
// Mouse button parsing
if ((event.code == BTN_TOUCH) || (event.code == BTN_LEFT))
{
- currentMouseStateEvdev[MOUSE_LEFT_BUTTON] = event.value;
+ CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_LEFT_BUTTON] = event.value;
#if defined(SUPPORT_GESTURES_SYSTEM)
if (event.value > 0) touchAction = TOUCH_DOWN;
@@ -5011,9 +5052,8 @@ static void *EventThread(void *arg)
#endif
}
- if (event.code == BTN_RIGHT) currentMouseStateEvdev[MOUSE_RIGHT_BUTTON] = event.value;
-
- if (event.code == BTN_MIDDLE) currentMouseStateEvdev[MOUSE_MIDDLE_BUTTON] = event.value;
+ if (event.code == BTN_RIGHT) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_RIGHT_BUTTON] = event.value;
+ if (event.code == BTN_MIDDLE) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_MIDDLE_BUTTON] = event.value;
// Keyboard button parsing
if ((event.code >= 1) && (event.code <= 255)) //Keyboard keys appear for codes 1 to 255
@@ -5021,49 +5061,49 @@ static void *EventThread(void *arg)
keycode = keymap_US[event.code & 0xFF]; // The code we get is a scancode so we look up the apropriate keycode
// Make sure we got a valid keycode
- if ((keycode > 0) && (keycode < sizeof(currentKeyState)))
+ if ((keycode > 0) && (keycode < sizeof(CORE.Input.Keyboard.currentKeyState)))
{
/* Disabled buffer !!
// Store the key information for raylib to later use
- currentKeyStateEvdev[keycode] = event.value;
+ CORE.Input.Keyboard.currentKeyState[keycode] = event.value;
if (event.value > 0)
{
// Add the key int the fifo
- lastKeyPressedEvdev.Contents[lastKeyPressedEvdev.Head] = keycode; // Put the data at the front of the fifo snake
- lastKeyPressedEvdev.Head = (lastKeyPressedEvdev.Head + 1) & 0x07; // Increment the head pointer forwards and binary wraparound after 7 (fifo is 8 elements long)
+ CORE.Input.Keyboard.lastKeyPressed.contents[CORE.Input.Keyboard.lastKeyPressed.head] = keycode; // Put the data at the front of the fifo snake
+ CORE.Input.Keyboard.lastKeyPressed.head = (CORE.Input.Keyboard.lastKeyPressed.head + 1) & 0x07; // Increment the head pointer forwards and binary wraparound after 7 (fifo is 8 elements long)
// TODO: This fifo is not fully threadsafe with multiple writers, so multiple keyboards hitting a key at the exact same time could miss a key (double write to head before it was incremented)
}
*/
- currentKeyState[keycode] = event.value;
- if (event.value == 1)
+ CORE.Input.Keyboard.currentKeyState[keycode] = event.value;
+ if (event.value == 1)
{
- keyPressedQueue[keyPressedQueueCount] = keycode; // Register last key pressed
- keyPressedQueueCount++;
+ CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = keycode; // Register last key pressed
+ CORE.Input.Keyboard.keyPressedQueueCount++;
}
#if defined(SUPPORT_SCREEN_CAPTURE)
// Check screen capture key (raylib key: KEY_F12)
- if (currentKeyState[301] == 1)
+ if (CORE.Input.Keyboard.currentKeyState[301] == 1)
{
TakeScreenshot(FormatText("screenshot%03i.png", screenshotCounter));
screenshotCounter++;
}
#endif
- if (currentKeyState[exitKey] == 1) windowShouldClose = true;
+ if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey] == 1) CORE.Window.shouldClose = true;
- TraceLog(LOG_DEBUG, "KEY%s ScanCode: %4i KeyCode: %4i",event.value == 0 ? "UP":"DOWN", event.code, keycode);
+ TRACELOGD("RPI: KEY_%s ScanCode: %4i KeyCode: %4i", event.value == 0 ? "UP":"DOWN", event.code, keycode);
}
}
}
// Screen confinement
- if (mousePosition.x < 0) mousePosition.x = 0;
- if (mousePosition.x > screenWidth/mouseScale.x) mousePosition.x = screenWidth/mouseScale.x;
+ if (CORE.Input.Mouse.position.x < 0) CORE.Input.Mouse.position.x = 0;
+ if (CORE.Input.Mouse.position.x > CORE.Window.screen.width/CORE.Input.Mouse.scale.x) CORE.Input.Mouse.position.x = CORE.Window.screen.width/CORE.Input.Mouse.scale.x;
- if (mousePosition.y < 0) mousePosition.y = 0;
- if (mousePosition.y > screenHeight/mouseScale.y) mousePosition.y = screenHeight/mouseScale.y;
+ if (CORE.Input.Mouse.position.y < 0) CORE.Input.Mouse.position.y = 0;
+ if (CORE.Input.Mouse.position.y > CORE.Window.screen.height/CORE.Input.Mouse.scale.y) CORE.Input.Mouse.position.y = CORE.Window.screen.height/CORE.Input.Mouse.scale.y;
// Gesture update
if (gestureUpdate)
@@ -5074,20 +5114,20 @@ static void *EventThread(void *arg)
gestureEvent.pointCount = 0;
gestureEvent.touchAction = touchAction;
- if (touchPosition[0].x >= 0) gestureEvent.pointCount++;
- if (touchPosition[1].x >= 0) gestureEvent.pointCount++;
- if (touchPosition[2].x >= 0) gestureEvent.pointCount++;
- if (touchPosition[3].x >= 0) gestureEvent.pointCount++;
+ if (CORE.Input.Touch.position[0].x >= 0) gestureEvent.pointCount++;
+ if (CORE.Input.Touch.position[1].x >= 0) gestureEvent.pointCount++;
+ if (CORE.Input.Touch.position[2].x >= 0) gestureEvent.pointCount++;
+ if (CORE.Input.Touch.position[3].x >= 0) gestureEvent.pointCount++;
gestureEvent.pointerId[0] = 0;
gestureEvent.pointerId[1] = 1;
gestureEvent.pointerId[2] = 2;
gestureEvent.pointerId[3] = 3;
- gestureEvent.position[0] = touchPosition[0];
- gestureEvent.position[1] = touchPosition[1];
- gestureEvent.position[2] = touchPosition[2];
- gestureEvent.position[3] = touchPosition[3];
+ gestureEvent.position[0] = CORE.Input.Touch.position[0];
+ gestureEvent.position[1] = CORE.Input.Touch.position[1];
+ gestureEvent.position[2] = CORE.Input.Touch.position[2];
+ gestureEvent.position[3] = CORE.Input.Touch.position[3];
ProcessGestureEvent(gestureEvent);
#endif
@@ -5113,22 +5153,22 @@ static void InitGamepad(void)
{
sprintf(gamepadDev, "%s%i", DEFAULT_GAMEPAD_DEV, i);
- if ((gamepadStream[i] = open(gamepadDev, O_RDONLY|O_NONBLOCK)) < 0)
+ if ((CORE.Input.Gamepad.streamId[i] = open(gamepadDev, O_RDONLY|O_NONBLOCK)) < 0)
{
// NOTE: Only show message for first gamepad
- if (i == 0) TraceLog(LOG_WARNING, "Gamepad device could not be opened, no gamepad available");
+ if (i == 0) TRACELOG(LOG_WARNING, "RPI: Failed to open Gamepad device, no gamepad available");
}
else
{
- gamepadReady[i] = true;
+ CORE.Input.Gamepad.ready[i] = true;
// NOTE: Only create one thread
if (i == 0)
{
- int error = pthread_create(&gamepadThreadId, NULL, &GamepadThread, NULL);
+ int error = pthread_create(&CORE.Input.Gamepad.threadId, NULL, &GamepadThread, NULL);
- if (error != 0) TraceLog(LOG_WARNING, "Error creating gamepad input event thread");
- else TraceLog(LOG_INFO, "Gamepad device initialized successfully");
+ if (error != 0) TRACELOG(LOG_WARNING, "RPI: Failed to create gamepad input event thread");
+ else TRACELOG(LOG_INFO, "RPI: Gamepad device initialized successfully");
}
}
}
@@ -5151,36 +5191,36 @@ static void *GamepadThread(void *arg)
// Read gamepad event
struct js_event gamepadEvent;
- while (!windowShouldClose)
+ while (!CORE.Window.shouldClose)
{
for (int i = 0; i < MAX_GAMEPADS; i++)
{
- if (read(gamepadStream[i], &gamepadEvent, sizeof(struct js_event)) == (int)sizeof(struct js_event))
+ if (read(CORE.Input.Gamepad.streamId[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)
{
- TraceLog(LOG_DEBUG, "Gamepad button: %i, value: %i", gamepadEvent.number, gamepadEvent.value);
+ TRACELOGD("RPI: Gamepad button: %i, value: %i", gamepadEvent.number, gamepadEvent.value);
if (gamepadEvent.number < MAX_GAMEPAD_BUTTONS)
{
// 1 - button pressed, 0 - button released
- currentGamepadState[i][gamepadEvent.number] = (int)gamepadEvent.value;
+ CORE.Input.Gamepad.currentState[i][gamepadEvent.number] = (int)gamepadEvent.value;
- if ((int)gamepadEvent.value == 1) lastGamepadButtonPressed = gamepadEvent.number;
- else lastGamepadButtonPressed = -1;
+ if ((int)gamepadEvent.value == 1) CORE.Input.Gamepad.lastButtonPressed = gamepadEvent.number;
+ else CORE.Input.Gamepad.lastButtonPressed = -1;
}
}
else if (gamepadEvent.type == JS_EVENT_AXIS)
{
- TraceLog(LOG_DEBUG, "Gamepad axis: %i, value: %i", gamepadEvent.number, gamepadEvent.value);
+ TRACELOGD("RPI: 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
- gamepadAxisState[i][gamepadEvent.number] = (float)gamepadEvent.value/32768;
+ CORE.Input.Gamepad.axisState[i][gamepadEvent.number] = (float)gamepadEvent.value/32768;
}
}
}