WARNING: REDESIGN: Move platform specific data to platform submodules #3313
REVIEWED: Defines, macros, types and tweaks
This commit is contained in:
parent
bbbaae5562
commit
d445fdaa19
7 changed files with 519 additions and 520 deletions
58
src/rcore.c
58
src/rcore.c
|
@ -1,33 +1,18 @@
|
|||
/**********************************************************************************************
|
||||
*
|
||||
* rcore - Basic functions to manage windows, OpenGL context and input on multiple platforms
|
||||
* rcore - Window/display management, Graphic device/context management and input management
|
||||
*
|
||||
* PLATFORMS SUPPORTED:
|
||||
* - PLATFORM_DESKTOP: Windows (Win32, Win64)
|
||||
* - PLATFORM_DESKTOP: Linux (X11 desktop mode)
|
||||
* - PLATFORM_DESKTOP: FreeBSD, OpenBSD, NetBSD, DragonFly (X11 desktop)
|
||||
* - PLATFORM_DESKTOP: OSX/macOS
|
||||
* - PLATFORM_WEB: HTML5 (WebAssembly)
|
||||
* - PLATFORM_DRM: Raspberry Pi 0-5
|
||||
* - PLATFORM_DRM: Linux native mode (KMS driver)
|
||||
* - PLATFORM_ANDROID: Android (ARM, ARM64)
|
||||
* - PLATFORM_DRM: Linux native mode, including Raspberry Pi 4 with V3D fkms driver
|
||||
* - PLATFORM_WEB: HTML5 with WebAssembly
|
||||
*
|
||||
* CONFIGURATION:
|
||||
* #define PLATFORM_DESKTOP
|
||||
* Windowing and input system configured for desktop platforms:
|
||||
* Windows, Linux, OSX, FreeBSD, OpenBSD, NetBSD, DragonFly
|
||||
*
|
||||
* #define PLATFORM_ANDROID
|
||||
* Windowing and input system configured for Android device, app activity managed internally in this module.
|
||||
* NOTE: OpenGL ES 2.0 is required and graphic device is managed by EGL
|
||||
*
|
||||
* #define PLATFORM_DRM
|
||||
* Windowing and input system configured for DRM native mode (RPI4 and other devices)
|
||||
* graphic device is managed by EGL and inputs are processed is raw mode, reading from /dev/input/
|
||||
*
|
||||
* #define PLATFORM_WEB
|
||||
* Windowing and input system configured for HTML5 (run on browser), code converted from C to asm.js
|
||||
* using emscripten compiler. OpenGL ES 2.0 required for direct translation to WebGL equivalent code.
|
||||
*
|
||||
* #define SUPPORT_DEFAULT_FONT (default)
|
||||
* Default font is loaded on window initialization to be available for the user to render simple text.
|
||||
* NOTE: If enabled, uses external module functions to load default raylib font (module: text)
|
||||
|
@ -42,11 +27,6 @@
|
|||
* #define SUPPORT_MOUSE_GESTURES
|
||||
* Mouse gestures are directly mapped like touches and processed by gestures system.
|
||||
*
|
||||
* #define SUPPORT_SSH_KEYBOARD_RPI (Raspberry Pi only)
|
||||
* Reconfigure standard input to receive key inputs, works with SSH connection.
|
||||
* WARNING: Reconfiguring standard input could lead to undesired effects, like breaking other
|
||||
* running processes orblocking the device if not restored properly. Use with care.
|
||||
*
|
||||
* #define SUPPORT_BUSY_WAIT_LOOP
|
||||
* Use busy wait loop for timing sync, if not defined, a high-resolution timer is setup and used
|
||||
*
|
||||
|
@ -68,7 +48,6 @@
|
|||
* Support automatic generated events, loading and recording of those events when required
|
||||
*
|
||||
* DEPENDENCIES:
|
||||
* rglfw - Manage graphic device, OpenGL context and inputs on PLATFORM_DESKTOP (Windows, Linux, OSX, FreeBSD...)
|
||||
* raymath - 3D math functionality (Vector2, Vector3, Matrix, Quaternion)
|
||||
* camera - Multiple 3D camera modes (free, orbital, 1st person, 3rd person)
|
||||
* gestures - Gestures system for touch-ready devices (or simulated from mouse inputs)
|
||||
|
@ -76,7 +55,7 @@
|
|||
*
|
||||
* LICENSE: zlib/libpng
|
||||
*
|
||||
* Copyright (c) 2013-2023 Ramon Santamaria (@raysan5)
|
||||
* Copyright (c) 2013-2023 Ramon Santamaria (@raysan5) and contributors
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
|
@ -102,7 +81,7 @@
|
|||
#include "config.h" // Defines module configuration flags
|
||||
#endif
|
||||
|
||||
#include "rcore.h"
|
||||
#include "rcore.h" // Defines types and globals
|
||||
|
||||
#define RLGL_IMPLEMENTATION
|
||||
#include "rlgl.h" // OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2
|
||||
|
@ -142,21 +121,19 @@
|
|||
#endif
|
||||
|
||||
// Platform specific defines to handle GetApplicationDirectory()
|
||||
#if defined (PLATFORM_DESKTOP)
|
||||
#if defined(_WIN32)
|
||||
#if defined(_WIN32)
|
||||
#ifndef MAX_PATH
|
||||
#define MAX_PATH 1025
|
||||
#endif
|
||||
__declspec(dllimport) unsigned long __stdcall GetModuleFileNameA(void *hModule, void *lpFilename, unsigned long nSize);
|
||||
__declspec(dllimport) unsigned long __stdcall GetModuleFileNameW(void *hModule, void *lpFilename, unsigned long nSize);
|
||||
__declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, void *widestr, int cchwide, void *str, int cbmb, void *defchar, int *used_default);
|
||||
#elif defined(__linux__)
|
||||
__declspec(dllimport) unsigned long __stdcall GetModuleFileNameA(void *hModule, void *lpFilename, unsigned long nSize);
|
||||
__declspec(dllimport) unsigned long __stdcall GetModuleFileNameW(void *hModule, void *lpFilename, unsigned long nSize);
|
||||
__declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, void *widestr, int cchwide, void *str, int cbmb, void *defchar, int *used_default);
|
||||
#elif defined(__linux__)
|
||||
#include <unistd.h>
|
||||
#elif defined(__APPLE__)
|
||||
#elif defined(__APPLE__)
|
||||
#include <sys/syslimits.h>
|
||||
#include <mach-o/dyld.h>
|
||||
#endif // OSs
|
||||
#endif // PLATFORM_DESKTOP
|
||||
#endif // OSs
|
||||
|
||||
#define _CRT_INTERNAL_NONSTDC_NAMES 1
|
||||
#include <sys/stat.h> // Required for: stat(), S_ISREG [Used in GetFileModTime(), IsFilePath()]
|
||||
|
@ -165,7 +142,7 @@
|
|||
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_DESKTOP) && defined(_WIN32) && (defined(_MSC_VER) || defined(__TINYC__))
|
||||
#if defined(_WIN32) && (defined(_MSC_VER) || defined(__TINYC__))
|
||||
#define DIRENT_MALLOC RL_MALLOC
|
||||
#define DIRENT_FREE RL_FREE
|
||||
|
||||
|
@ -333,7 +310,8 @@ const char *TextFormat(const char *text, ...); // Formatting of text with
|
|||
#elif defined(PLATFORM_ANDROID)
|
||||
#include "rcore_android.c"
|
||||
#else
|
||||
// Software rendering backend, user needs to provide buffer ;)
|
||||
// TODO: Include your custom platform backend!
|
||||
// i.e software rendering backend or console backend!
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
@ -1897,7 +1875,7 @@ bool IsKeyPressed(int key)
|
|||
return pressed;
|
||||
}
|
||||
|
||||
// Check if a key has been pressed again (only PLATFORM_DESKTOP)
|
||||
// Check if a key has been pressed again
|
||||
bool IsKeyPressedRepeat(int key)
|
||||
{
|
||||
bool repeat = false;
|
||||
|
@ -2291,7 +2269,7 @@ void InitTimer(void)
|
|||
timeBeginPeriod(1); // Setup high-resolution timer to 1ms (granularity of 1-2 ms)
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_DRM)
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__EMSCRIPTEN__)
|
||||
struct timespec now = { 0 };
|
||||
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &now) == 0) // Success
|
||||
|
|
137
src/rcore.h
137
src/rcore.h
|
@ -35,64 +35,6 @@
|
|||
#ifndef RCORE_H
|
||||
#define RCORE_H
|
||||
|
||||
#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(), memset()
|
||||
#include <time.h> // Required for: time() [Used in InitTimer()]
|
||||
#include <math.h> // Required for: tan() [Used in BeginMode3D()], atan2f() [Used in LoadVrStereoConfig()]
|
||||
|
||||
#include "utils.h" // Required for: TRACELOG() macros
|
||||
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
#define GLFW_INCLUDE_NONE // Disable the standard OpenGL header inclusion on GLFW3
|
||||
// NOTE: Already provided by rlgl implementation (on glad.h)
|
||||
#include "GLFW/glfw3.h" // GLFW3 library: Windows, OpenGL context and Input management
|
||||
// NOTE: GLFW3 already includes gl.h (OpenGL) headers
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
#include <EGL/egl.h> // Native platform windowing system interface
|
||||
//#include <GLES2/gl2.h> // OpenGL ES 2.0 library (not required in this module, only in rlgl)
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_DRM)
|
||||
|
||||
#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> // Required for: ioctl() - UNIX System call for device-specific input/output operations
|
||||
#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 <gbm.h> // Generic Buffer Management (native platform for EGL on DRM)
|
||||
#include <xf86drm.h> // Direct Rendering Manager user-level library interface
|
||||
#include <xf86drmMode.h> // Direct Rendering Manager mode setting (KMS) interface
|
||||
|
||||
#include "EGL/egl.h" // Native platform windowing system interface
|
||||
#include "EGL/eglext.h" // EGL extensions
|
||||
|
||||
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
|
||||
} InputEventWorker;
|
||||
|
||||
#endif
|
||||
|
||||
// TODO: PROVIDE A HEADER TO BE USED BY ALL THE rcore_* IMPLEMENTATIONS
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include "rlgl.h"
|
||||
|
@ -100,16 +42,17 @@
|
|||
#define RAYMATH_IMPLEMENTATION
|
||||
#include "raymath.h"
|
||||
|
||||
#include "utils.h" // Required for: TRACELOG() macros
|
||||
|
||||
#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(), memset()
|
||||
#include <time.h> // Required for: time() [Used in InitTimer()]
|
||||
#include <math.h> // Required for: tan() [Used in BeginMode3D()], atan2f() [Used in LoadVrStereoConfig()]
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
#if defined(PLATFORM_DRM)
|
||||
#define USE_LAST_TOUCH_DEVICE // When multiple touchscreens are connected, only use the one with the highest event<N> number
|
||||
|
||||
#define DEFAULT_GAMEPAD_DEV "/dev/input/js" // Gamepad input (base dev for all gamepads: js0, js1, ...)
|
||||
#define DEFAULT_EVDEV_PATH "/dev/input/" // Path to the linux input events
|
||||
#endif
|
||||
|
||||
#ifndef MAX_FILEPATH_CAPACITY
|
||||
#define MAX_FILEPATH_CAPACITY 8192 // Maximum capacity for filepath
|
||||
#endif
|
||||
|
@ -152,12 +95,6 @@
|
|||
#define FLAG_TOGGLE(n, f) ((n) ^= (f))
|
||||
#define FLAG_CHECK(n, f) ((n) & (f))
|
||||
|
||||
// TODO: HACK: Added flag if not provided by GLFW when using external library
|
||||
// Latest GLFW release (GLFW 3.3.8) does not implement this flag, it was added for 3.4.0-dev
|
||||
#if !defined(GLFW_MOUSE_PASSTHROUGH)
|
||||
#define GLFW_MOUSE_PASSTHROUGH 0x0002000D
|
||||
#endif
|
||||
|
||||
#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.
|
||||
|
@ -172,25 +109,6 @@ typedef struct { unsigned int width; unsigned int height; } Size;
|
|||
// Core global state context data
|
||||
typedef struct CoreData {
|
||||
struct {
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
GLFWwindow *handle; // GLFW window handle (graphic device)
|
||||
#endif
|
||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_DRM)
|
||||
#if defined(PLATFORM_DRM)
|
||||
int fd; // File descriptor for /dev/dri/...
|
||||
drmModeConnector *connector; // Direct Rendering Manager (DRM) mode connector
|
||||
drmModeCrtc *crtc; // CRT Controller
|
||||
int modeIndex; // Index of the used mode of connector->modes
|
||||
struct gbm_device *gbmDevice; // GBM device
|
||||
struct gbm_surface *gbmSurface; // GBM surface
|
||||
struct gbm_bo *prevBO; // Previous GBM buffer object (during frame swapping)
|
||||
uint32_t prevFB; // Previous GBM framebufer (during frame swapping)
|
||||
#endif // PLATFORM_DRM
|
||||
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
|
||||
const char *title; // Window text title const pointer
|
||||
unsigned int flags; // Configuration flags (bit based), keeps window state
|
||||
bool ready; // Check if window has been initialized successfully
|
||||
|
@ -217,25 +135,16 @@ typedef struct CoreData {
|
|||
unsigned int dropFileCount; // Count dropped files strings
|
||||
|
||||
} Window;
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
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
|
||||
bool contextRebindRequired; // Used to know context rebind required
|
||||
} Android;
|
||||
#endif
|
||||
struct {
|
||||
const char *basePath; // Base path for data storage
|
||||
|
||||
} Storage;
|
||||
struct {
|
||||
#if defined(PLATFORM_DRM)
|
||||
InputEventWorker eventWorker[10]; // List of worker threads for every monitored "/dev/input/event<N>"
|
||||
#endif
|
||||
struct {
|
||||
int exitKey; // Default exit key
|
||||
char currentKeyState[MAX_KEYBOARD_KEYS]; // Registers current frame key state
|
||||
char previousKeyState[MAX_KEYBOARD_KEYS]; // Registers previous frame key state
|
||||
|
||||
// NOTE: Since key press logic involves comparing prev vs cur key state, we need to handle key repeats specially
|
||||
char keyRepeatInFrame[MAX_KEYBOARD_KEYS]; // Registers key repeats for current frame.
|
||||
|
||||
|
@ -245,15 +154,6 @@ typedef struct CoreData {
|
|||
int charPressedQueue[MAX_CHAR_PRESSED_QUEUE]; // Input characters queue (unicode)
|
||||
int charPressedQueueCount; // Input characters queue count
|
||||
|
||||
#if defined(PLATFORM_DRM)
|
||||
int defaultMode; // Default keyboard mode
|
||||
#if defined(SUPPORT_SSH_KEYBOARD_RPI)
|
||||
bool evtMode; // Keyboard in event mode
|
||||
#endif
|
||||
int defaultFileFlags; // Default IO file flags
|
||||
struct termios defaultSettings; // Default keyboard settings
|
||||
int fd; // File descriptor for the evdev keyboard
|
||||
#endif
|
||||
} Keyboard;
|
||||
struct {
|
||||
Vector2 offset; // Mouse offset
|
||||
|
@ -269,11 +169,7 @@ typedef struct CoreData {
|
|||
char previousButtonState[MAX_MOUSE_BUTTONS]; // Registers previous mouse button state
|
||||
Vector2 currentWheelMove; // Registers current mouse wheel variation
|
||||
Vector2 previousWheelMove; // Registers previous mouse wheel variation
|
||||
#if defined(PLATFORM_DRM)
|
||||
Vector2 eventWheelMove; // Registers the event mouse wheel variation
|
||||
// NOTE: currentButtonState[] can't be written directly due to multithreading, app could miss the update
|
||||
char currentButtonStateEvdev[MAX_MOUSE_BUTTONS]; // Holds the new mouse state for the next polling event to grab
|
||||
#endif
|
||||
|
||||
} Mouse;
|
||||
struct {
|
||||
int pointCount; // Number of touch points active
|
||||
|
@ -281,6 +177,7 @@ typedef struct CoreData {
|
|||
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
|
||||
|
@ -290,10 +187,7 @@ typedef struct CoreData {
|
|||
char currentButtonState[MAX_GAMEPADS][MAX_GAMEPAD_BUTTONS]; // Current gamepad buttons state
|
||||
char previousButtonState[MAX_GAMEPADS][MAX_GAMEPAD_BUTTONS]; // Previous gamepad buttons state
|
||||
float axisState[MAX_GAMEPADS][MAX_GAMEPAD_AXIS]; // Gamepad axis state
|
||||
#if defined(PLATFORM_DRM)
|
||||
pthread_t threadId; // Gamepad reading thread id
|
||||
int streamId[MAX_GAMEPADS]; // Gamepad device file descriptor
|
||||
#endif
|
||||
|
||||
} Gamepad;
|
||||
} Input;
|
||||
struct {
|
||||
|
@ -303,10 +197,9 @@ typedef struct CoreData {
|
|||
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_DRM)
|
||||
unsigned long long int base; // Base time measure for hi-res timer
|
||||
#endif
|
||||
unsigned long long int base; // Base time measure for hi-res timer (PLATFORM_ANDROID, PLATFORM_DRM)
|
||||
unsigned int frameCounter; // Frame counter
|
||||
|
||||
} Time;
|
||||
} CoreData;
|
||||
|
||||
|
|
|
@ -53,16 +53,32 @@
|
|||
#include <android_native_app_glue.h> // Required for: android_app struct and activity management
|
||||
#include <jni.h> // Required for: JNIEnv and JavaVM [Used in OpenURL()]
|
||||
|
||||
#include <EGL/egl.h> // Native platform windowing system interface
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
//...
|
||||
typedef struct {
|
||||
// Application data
|
||||
struct android_app *app; // Android activity
|
||||
struct android_poll_source *source; // Android events polling source
|
||||
bool appEnabled; // Flag to detect if app is active ** = true
|
||||
bool contextRebindRequired; // Used to know context rebind required
|
||||
|
||||
// Display data
|
||||
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
|
||||
} PlatformData;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
extern CoreData CORE; // Global CORE state context
|
||||
|
||||
static PlatformData platform = { 0 }; // Platform specific data
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Internal Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
|
@ -89,7 +105,7 @@ extern int main(int argc, char *argv[]);
|
|||
void android_main(struct android_app *app)
|
||||
{
|
||||
char arg0[] = "raylib"; // NOTE: argv[] are mutable
|
||||
CORE.Android.app = app;
|
||||
platform.app = app;
|
||||
|
||||
// NOTE: Return from main is ignored
|
||||
(void)main(1, (char *[]) { arg0, NULL });
|
||||
|
@ -104,9 +120,9 @@ void android_main(struct android_app *app)
|
|||
// Waiting for application events before complete finishing
|
||||
while (!app->destroyRequested)
|
||||
{
|
||||
while ((pollResult = ALooper_pollAll(0, NULL, &pollEvents, (void **)&CORE.Android.source)) >= 0)
|
||||
while ((pollResult = ALooper_pollAll(0, NULL, &pollEvents, (void **)&platform.source)) >= 0)
|
||||
{
|
||||
if (CORE.Android.source != NULL) CORE.Android.source->process(app, CORE.Android.source);
|
||||
if (platform.source != NULL) platform.source->process(app, platform.source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -114,7 +130,7 @@ void android_main(struct android_app *app)
|
|||
// NOTE: Add this to header (if apps really need it)
|
||||
struct android_app *GetAndroidApp(void)
|
||||
{
|
||||
return CORE.Android.app;
|
||||
return platform.app;
|
||||
}
|
||||
|
||||
// Initialize window and OpenGL context
|
||||
|
@ -169,9 +185,9 @@ void InitWindow(int width, int height, const char *title)
|
|||
CORE.Window.currentFbo.height = height;
|
||||
|
||||
// Set desired windows flags before initializing anything
|
||||
ANativeActivity_setWindowFlags(CORE.Android.app->activity, AWINDOW_FLAG_FULLSCREEN, 0); //AWINDOW_FLAG_SCALED, AWINDOW_FLAG_DITHER
|
||||
ANativeActivity_setWindowFlags(platform.app->activity, AWINDOW_FLAG_FULLSCREEN, 0); //AWINDOW_FLAG_SCALED, AWINDOW_FLAG_DITHER
|
||||
|
||||
int orientation = AConfiguration_getOrientation(CORE.Android.app->config);
|
||||
int orientation = AConfiguration_getOrientation(platform.app->config);
|
||||
|
||||
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");
|
||||
|
@ -179,32 +195,32 @@ void InitWindow(int width, int height, const char *title)
|
|||
// TODO: Automatic orientation doesn't seem to work
|
||||
if (width <= height)
|
||||
{
|
||||
AConfiguration_setOrientation(CORE.Android.app->config, ACONFIGURATION_ORIENTATION_PORT);
|
||||
AConfiguration_setOrientation(platform.app->config, ACONFIGURATION_ORIENTATION_PORT);
|
||||
TRACELOG(LOG_WARNING, "ANDROID: Window orientation changed to portrait");
|
||||
}
|
||||
else
|
||||
{
|
||||
AConfiguration_setOrientation(CORE.Android.app->config, ACONFIGURATION_ORIENTATION_LAND);
|
||||
AConfiguration_setOrientation(platform.app->config, ACONFIGURATION_ORIENTATION_LAND);
|
||||
TRACELOG(LOG_WARNING, "ANDROID: Window orientation changed to landscape");
|
||||
}
|
||||
|
||||
//AConfiguration_getDensity(CORE.Android.app->config);
|
||||
//AConfiguration_getKeyboard(CORE.Android.app->config);
|
||||
//AConfiguration_getScreenSize(CORE.Android.app->config);
|
||||
//AConfiguration_getScreenLong(CORE.Android.app->config);
|
||||
//AConfiguration_getDensity(platform.app->config);
|
||||
//AConfiguration_getKeyboard(platform.app->config);
|
||||
//AConfiguration_getScreenSize(platform.app->config);
|
||||
//AConfiguration_getScreenLong(platform.app->config);
|
||||
|
||||
// Initialize App command system
|
||||
// NOTE: On APP_CMD_INIT_WINDOW -> InitGraphicsDevice(), InitTimer(), LoadFontDefault()...
|
||||
CORE.Android.app->onAppCmd = AndroidCommandCallback;
|
||||
platform.app->onAppCmd = AndroidCommandCallback;
|
||||
|
||||
// Initialize input events system
|
||||
CORE.Android.app->onInputEvent = AndroidInputCallback;
|
||||
platform.app->onInputEvent = AndroidInputCallback;
|
||||
|
||||
// Initialize assets manager
|
||||
InitAssetManager(CORE.Android.app->activity->assetManager, CORE.Android.app->activity->internalDataPath);
|
||||
InitAssetManager(platform.app->activity->assetManager, platform.app->activity->internalDataPath);
|
||||
|
||||
// Initialize base path for storage
|
||||
CORE.Storage.basePath = CORE.Android.app->activity->internalDataPath;
|
||||
CORE.Storage.basePath = platform.app->activity->internalDataPath;
|
||||
|
||||
TRACELOG(LOG_INFO, "ANDROID: App initialized successfully");
|
||||
|
||||
|
@ -216,13 +232,13 @@ void InitWindow(int width, int height, const char *title)
|
|||
while (!CORE.Window.ready)
|
||||
{
|
||||
// Process events loop
|
||||
while ((pollResult = ALooper_pollAll(0, NULL, &pollEvents, (void**)&CORE.Android.source)) >= 0)
|
||||
while ((pollResult = ALooper_pollAll(0, NULL, &pollEvents, (void**)&platform.source)) >= 0)
|
||||
{
|
||||
// Process this event
|
||||
if (CORE.Android.source != NULL) CORE.Android.source->process(CORE.Android.app, CORE.Android.source);
|
||||
if (platform.source != NULL) platform.source->process(platform.app, platform.source);
|
||||
|
||||
// NOTE: Never close window, native activity is controlled by the system!
|
||||
//if (CORE.Android.app->destroyRequested != 0) CORE.Window.shouldClose = true;
|
||||
//if (platform.app->destroyRequested != 0) CORE.Window.shouldClose = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -250,24 +266,24 @@ void CloseWindow(void)
|
|||
#endif
|
||||
|
||||
// Close surface, context and display
|
||||
if (CORE.Window.device != EGL_NO_DISPLAY)
|
||||
if (platform.device != EGL_NO_DISPLAY)
|
||||
{
|
||||
eglMakeCurrent(CORE.Window.device, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
eglMakeCurrent(platform.device, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
|
||||
if (CORE.Window.surface != EGL_NO_SURFACE)
|
||||
if (platform.surface != EGL_NO_SURFACE)
|
||||
{
|
||||
eglDestroySurface(CORE.Window.device, CORE.Window.surface);
|
||||
CORE.Window.surface = EGL_NO_SURFACE;
|
||||
eglDestroySurface(platform.device, platform.surface);
|
||||
platform.surface = EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
if (CORE.Window.context != EGL_NO_CONTEXT)
|
||||
if (platform.context != EGL_NO_CONTEXT)
|
||||
{
|
||||
eglDestroyContext(CORE.Window.device, CORE.Window.context);
|
||||
CORE.Window.context = EGL_NO_CONTEXT;
|
||||
eglDestroyContext(platform.device, platform.context);
|
||||
platform.context = EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
eglTerminate(CORE.Window.device);
|
||||
CORE.Window.device = EGL_NO_DISPLAY;
|
||||
eglTerminate(platform.device);
|
||||
platform.device = EGL_NO_DISPLAY;
|
||||
}
|
||||
|
||||
#if defined(SUPPORT_EVENTS_AUTOMATION)
|
||||
|
@ -306,7 +322,7 @@ bool IsWindowMaximized(void)
|
|||
// Check if window has the focus
|
||||
bool IsWindowFocused(void)
|
||||
{
|
||||
return CORE.Android.appEnabled;
|
||||
return platform.appEnabled;
|
||||
}
|
||||
|
||||
// Check if window has been resizedLastFrame
|
||||
|
@ -595,7 +611,7 @@ void OpenURL(const char *url)
|
|||
else
|
||||
{
|
||||
JNIEnv *env = NULL;
|
||||
JavaVM *vm = CORE.Android.app->activity->vm;
|
||||
JavaVM *vm = platform.app->activity->vm;
|
||||
(*vm)->AttachCurrentThread(vm, &env, NULL);
|
||||
|
||||
jstring urlString = (*env)->NewStringUTF(env, url);
|
||||
|
@ -612,7 +628,7 @@ void OpenURL(const char *url)
|
|||
(*env)->CallVoidMethod(env, intent, newIntent, actionView, uri);
|
||||
jclass activityClass = (*env)->FindClass(env, "android/app/Activity");
|
||||
jmethodID startActivity = (*env)->GetMethodID(env, activityClass, "startActivity", "(Landroid/content/Intent;)V");
|
||||
(*env)->CallVoidMethod(env, CORE.Android.app->activity->clazz, startActivity, intent);
|
||||
(*env)->CallVoidMethod(env, platform.app->activity->clazz, startActivity, intent);
|
||||
|
||||
(*vm)->DetachCurrentThread(vm);
|
||||
}
|
||||
|
@ -713,7 +729,7 @@ Vector2 GetTouchPosition(int index)
|
|||
// Swap back buffer with front buffer (screen drawing)
|
||||
void SwapScreenBuffer(void)
|
||||
{
|
||||
eglSwapBuffers(CORE.Window.device, CORE.Window.surface);
|
||||
eglSwapBuffers(platform.device, platform.surface);
|
||||
}
|
||||
|
||||
// Register all input events
|
||||
|
@ -756,17 +772,17 @@ void PollInputEvents(void)
|
|||
int pollEvents = 0;
|
||||
|
||||
// Poll Events (registered events)
|
||||
// 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)
|
||||
// NOTE: Activity is paused if not enabled (platform.appEnabled)
|
||||
while ((pollResult = ALooper_pollAll(platform.appEnabled? 0 : -1, NULL, &pollEvents, (void**)&platform.source)) >= 0)
|
||||
{
|
||||
// Process this event
|
||||
if (CORE.Android.source != NULL) CORE.Android.source->process(CORE.Android.app, CORE.Android.source);
|
||||
if (platform.source != NULL) platform.source->process(platform.app, platform.source);
|
||||
|
||||
// NOTE: Never close window, native activity is controlled by the system!
|
||||
if (CORE.Android.app->destroyRequested != 0)
|
||||
if (platform.app->destroyRequested != 0)
|
||||
{
|
||||
//CORE.Window.shouldClose = true;
|
||||
//ANativeActivity_finish(CORE.Android.app->activity);
|
||||
//ANativeActivity_finish(platform.app->activity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -829,15 +845,15 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
EGLint numConfigs = 0;
|
||||
|
||||
// Get an EGL device connection
|
||||
CORE.Window.device = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
if (CORE.Window.device == EGL_NO_DISPLAY)
|
||||
platform.device = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
if (platform.device == EGL_NO_DISPLAY)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Initialize the EGL device connection
|
||||
if (eglInitialize(CORE.Window.device, NULL, NULL) == EGL_FALSE)
|
||||
if (eglInitialize(platform.device, NULL, NULL) == EGL_FALSE)
|
||||
{
|
||||
// If all of the calls to eglInitialize returned EGL_FALSE then an error has occurred.
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
|
||||
|
@ -845,14 +861,14 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
}
|
||||
|
||||
// Get an appropriate EGL framebuffer configuration
|
||||
eglChooseConfig(CORE.Window.device, framebufferAttribs, &CORE.Window.config, 1, &numConfigs);
|
||||
eglChooseConfig(platform.device, framebufferAttribs, &platform.config, 1, &numConfigs);
|
||||
|
||||
// Set rendering API
|
||||
eglBindAPI(EGL_OPENGL_ES_API);
|
||||
|
||||
// Create an EGL rendering context
|
||||
CORE.Window.context = eglCreateContext(CORE.Window.device, CORE.Window.config, EGL_NO_CONTEXT, contextAttribs);
|
||||
if (CORE.Window.context == EGL_NO_CONTEXT)
|
||||
platform.context = eglCreateContext(platform.device, platform.config, EGL_NO_CONTEXT, contextAttribs);
|
||||
if (platform.context == EGL_NO_CONTEXT)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL context");
|
||||
return false;
|
||||
|
@ -864,7 +880,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
|
||||
// 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(CORE.Window.device, CORE.Window.config, EGL_NATIVE_VISUAL_ID, &displayFormat);
|
||||
eglGetConfigAttrib(platform.device, platform.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:
|
||||
|
@ -873,15 +889,15 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
// -> CORE.Window.screenScale
|
||||
SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);
|
||||
|
||||
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
|
||||
ANativeWindow_setBuffersGeometry(platform.app->window, CORE.Window.render.width, CORE.Window.render.height, displayFormat);
|
||||
//ANativeWindow_setBuffersGeometry(platform.app->window, 0, 0, displayFormat); // Force use of native display size
|
||||
|
||||
CORE.Window.surface = eglCreateWindowSurface(CORE.Window.device, CORE.Window.config, CORE.Android.app->window, NULL);
|
||||
platform.surface = eglCreateWindowSurface(platform.device, platform.config, platform.app->window, NULL);
|
||||
|
||||
// There must be at least one frame displayed before the buffers are swapped
|
||||
//eglSwapInterval(CORE.Window.device, 1);
|
||||
//eglSwapInterval(platform.device, 1);
|
||||
|
||||
if (eglMakeCurrent(CORE.Window.device, CORE.Window.surface, CORE.Window.surface, CORE.Window.context) == EGL_FALSE)
|
||||
if (eglMakeCurrent(platform.device, platform.surface, platform.surface, platform.context) == EGL_FALSE)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to attach EGL rendering context to EGL surface");
|
||||
return false;
|
||||
|
@ -933,11 +949,11 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
|
|||
{
|
||||
if (app->window != NULL)
|
||||
{
|
||||
if (CORE.Android.contextRebindRequired)
|
||||
if (platform.contextRebindRequired)
|
||||
{
|
||||
// Reset screen scaling to full display size
|
||||
EGLint displayFormat = 0;
|
||||
eglGetConfigAttrib(CORE.Window.device, CORE.Window.config, EGL_NATIVE_VISUAL_ID, &displayFormat);
|
||||
eglGetConfigAttrib(platform.device, platform.config, EGL_NATIVE_VISUAL_ID, &displayFormat);
|
||||
|
||||
// Adding renderOffset here feels rather hackish, but the viewport scaling is wrong after the
|
||||
// context rebinding if the screen is scaled unless offsets are added. There's probably a more
|
||||
|
@ -948,15 +964,15 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
|
|||
displayFormat);
|
||||
|
||||
// Recreate display surface and re-attach OpenGL 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);
|
||||
platform.surface = eglCreateWindowSurface(platform.device, platform.config, app->window, NULL);
|
||||
eglMakeCurrent(platform.device, platform.surface, platform.surface, platform.context);
|
||||
|
||||
CORE.Android.contextRebindRequired = false;
|
||||
platform.contextRebindRequired = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
CORE.Window.display.width = ANativeWindow_getWidth(CORE.Android.app->window);
|
||||
CORE.Window.display.height = ANativeWindow_getHeight(CORE.Android.app->window);
|
||||
CORE.Window.display.width = ANativeWindow_getWidth(platform.app->window);
|
||||
CORE.Window.display.height = ANativeWindow_getHeight(platform.app->window);
|
||||
|
||||
// Initialize graphics device (display device and OpenGL context)
|
||||
InitGraphicsDevice(CORE.Window.screen.width, CORE.Window.screen.height);
|
||||
|
@ -997,13 +1013,13 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
|
|||
} break;
|
||||
case APP_CMD_GAINED_FOCUS:
|
||||
{
|
||||
CORE.Android.appEnabled = true;
|
||||
platform.appEnabled = true;
|
||||
//ResumeMusicStream();
|
||||
} break;
|
||||
case APP_CMD_PAUSE: break;
|
||||
case APP_CMD_LOST_FOCUS:
|
||||
{
|
||||
CORE.Android.appEnabled = false;
|
||||
platform.appEnabled = false;
|
||||
//PauseMusicStream();
|
||||
} break;
|
||||
case APP_CMD_TERM_WINDOW:
|
||||
|
@ -1012,19 +1028,19 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
|
|||
// NOTE 1: This case is used when the user exits the app without closing it. We detach the context to ensure everything is recoverable upon resuming.
|
||||
// NOTE 2: Detaching context before destroying display surface avoids losing our resources (textures, shaders, VBOs...)
|
||||
// NOTE 3: In some cases (too many context loaded), OS could unload context automatically... :(
|
||||
if (CORE.Window.device != EGL_NO_DISPLAY)
|
||||
if (platform.device != EGL_NO_DISPLAY)
|
||||
{
|
||||
eglMakeCurrent(CORE.Window.device, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
eglMakeCurrent(platform.device, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
|
||||
if (CORE.Window.surface != EGL_NO_SURFACE)
|
||||
if (platform.surface != EGL_NO_SURFACE)
|
||||
{
|
||||
eglDestroySurface(CORE.Window.device, CORE.Window.surface);
|
||||
CORE.Window.surface = EGL_NO_SURFACE;
|
||||
eglDestroySurface(platform.device, platform.surface);
|
||||
platform.surface = EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
CORE.Android.contextRebindRequired = true;
|
||||
platform.contextRebindRequired = true;
|
||||
}
|
||||
// If 'CORE.Window.device' is already set to 'EGL_NO_DISPLAY'
|
||||
// If 'platform.device' is already set to 'EGL_NO_DISPLAY'
|
||||
// this means that the user has already called 'CloseWindow()'
|
||||
|
||||
} break;
|
||||
|
@ -1033,8 +1049,8 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
|
|||
case APP_CMD_DESTROY: break;
|
||||
case APP_CMD_CONFIG_CHANGED:
|
||||
{
|
||||
//AConfiguration_fromAssetManager(CORE.Android.app->config, CORE.Android.app->activity->assetManager);
|
||||
//print_cur_config(CORE.Android.app);
|
||||
//AConfiguration_fromAssetManager(platform.app->config, platform.app->activity->assetManager);
|
||||
//print_cur_config(platform.app);
|
||||
|
||||
// Check screen orientation here!
|
||||
} break;
|
||||
|
|
|
@ -85,16 +85,29 @@
|
|||
#include "GLFW/glfw3native.h" // Required for: glfwGetCocoaWindow()
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
// TODO: HACK: Added flag if not provided by GLFW when using external library
|
||||
// Latest GLFW release (GLFW 3.3.8) does not implement this flag, it was added for 3.4.0-dev
|
||||
#if !defined(GLFW_MOUSE_PASSTHROUGH)
|
||||
#define GLFW_MOUSE_PASSTHROUGH 0x0002000D
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
//...
|
||||
typedef struct {
|
||||
GLFWwindow *handle; // GLFW window handle (graphic device)
|
||||
} PlatformData;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
extern CoreData CORE; // Global CORE state context
|
||||
|
||||
static PlatformData platform = { 0 }; // Platform specific data
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Internal Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
|
@ -255,7 +268,7 @@ void CloseWindow(void)
|
|||
|
||||
rlglClose(); // De-init rlgl
|
||||
|
||||
glfwDestroyWindow(CORE.Window.handle);
|
||||
glfwDestroyWindow(platform.handle);
|
||||
glfwTerminate();
|
||||
|
||||
#if defined(_WIN32) && defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP)
|
||||
|
@ -279,10 +292,10 @@ bool WindowShouldClose(void)
|
|||
// While window minimized, stop loop execution
|
||||
while (IsWindowState(FLAG_WINDOW_MINIMIZED) && !IsWindowState(FLAG_WINDOW_ALWAYS_RUN)) glfwWaitEvents();
|
||||
|
||||
CORE.Window.shouldClose = glfwWindowShouldClose(CORE.Window.handle);
|
||||
CORE.Window.shouldClose = glfwWindowShouldClose(platform.handle);
|
||||
|
||||
// Reset close status for next frame
|
||||
glfwSetWindowShouldClose(CORE.Window.handle, GLFW_FALSE);
|
||||
glfwSetWindowShouldClose(platform.handle, GLFW_FALSE);
|
||||
|
||||
return CORE.Window.shouldClose;
|
||||
}
|
||||
|
@ -325,7 +338,7 @@ void ToggleFullscreen(void)
|
|||
if (!CORE.Window.fullscreen)
|
||||
{
|
||||
// Store previous window position (in case we exit fullscreen)
|
||||
glfwGetWindowPos(CORE.Window.handle, &CORE.Window.position.x, &CORE.Window.position.y);
|
||||
glfwGetWindowPos(platform.handle, &CORE.Window.position.x, &CORE.Window.position.y);
|
||||
|
||||
int monitorCount = 0;
|
||||
int monitorIndex = GetCurrentMonitor();
|
||||
|
@ -341,14 +354,14 @@ void ToggleFullscreen(void)
|
|||
CORE.Window.fullscreen = false;
|
||||
CORE.Window.flags &= ~FLAG_FULLSCREEN_MODE;
|
||||
|
||||
glfwSetWindowMonitor(CORE.Window.handle, NULL, 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
|
||||
glfwSetWindowMonitor(platform.handle, NULL, 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
|
||||
}
|
||||
else
|
||||
{
|
||||
CORE.Window.fullscreen = true;
|
||||
CORE.Window.flags |= FLAG_FULLSCREEN_MODE;
|
||||
|
||||
glfwSetWindowMonitor(CORE.Window.handle, monitor, 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
|
||||
glfwSetWindowMonitor(platform.handle, monitor, 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -357,7 +370,7 @@ void ToggleFullscreen(void)
|
|||
CORE.Window.fullscreen = false;
|
||||
CORE.Window.flags &= ~FLAG_FULLSCREEN_MODE;
|
||||
|
||||
glfwSetWindowMonitor(CORE.Window.handle, NULL, CORE.Window.position.x, CORE.Window.position.y, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
|
||||
glfwSetWindowMonitor(platform.handle, NULL, CORE.Window.position.x, CORE.Window.position.y, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
|
||||
}
|
||||
|
||||
// Try to enable GPU V-Sync, so frames are limited to screen refresh rate (60Hz -> 60 FPS)
|
||||
|
@ -368,9 +381,9 @@ void ToggleFullscreen(void)
|
|||
// Set window state: maximized, if resizable
|
||||
void MaximizeWindow(void)
|
||||
{
|
||||
if (glfwGetWindowAttrib(CORE.Window.handle, GLFW_RESIZABLE) == GLFW_TRUE)
|
||||
if (glfwGetWindowAttrib(platform.handle, GLFW_RESIZABLE) == GLFW_TRUE)
|
||||
{
|
||||
glfwMaximizeWindow(CORE.Window.handle);
|
||||
glfwMaximizeWindow(platform.handle);
|
||||
CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED;
|
||||
}
|
||||
}
|
||||
|
@ -379,16 +392,16 @@ void MaximizeWindow(void)
|
|||
void MinimizeWindow(void)
|
||||
{
|
||||
// NOTE: Following function launches callback that sets appropriate flag!
|
||||
glfwIconifyWindow(CORE.Window.handle);
|
||||
glfwIconifyWindow(platform.handle);
|
||||
}
|
||||
|
||||
// Set window state: not minimized/maximized
|
||||
void RestoreWindow(void)
|
||||
{
|
||||
if (glfwGetWindowAttrib(CORE.Window.handle, GLFW_RESIZABLE) == GLFW_TRUE)
|
||||
if (glfwGetWindowAttrib(platform.handle, GLFW_RESIZABLE) == GLFW_TRUE)
|
||||
{
|
||||
// Restores the specified window if it was previously iconified (minimized) or maximized
|
||||
glfwRestoreWindow(CORE.Window.handle);
|
||||
glfwRestoreWindow(platform.handle);
|
||||
CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED;
|
||||
CORE.Window.flags &= ~FLAG_WINDOW_MAXIMIZED;
|
||||
}
|
||||
|
@ -420,13 +433,13 @@ void ToggleBorderlessWindowed(void)
|
|||
{
|
||||
// Store screen position and size
|
||||
// NOTE: If it was on fullscreen, screen position was already stored, so skip setting it here
|
||||
if (!wasOnFullscreen) glfwGetWindowPos(CORE.Window.handle, &CORE.Window.previousPosition.x, &CORE.Window.previousPosition.y);
|
||||
if (!wasOnFullscreen) glfwGetWindowPos(platform.handle, &CORE.Window.previousPosition.x, &CORE.Window.previousPosition.y);
|
||||
CORE.Window.previousScreen = CORE.Window.screen;
|
||||
|
||||
// Set undecorated and topmost modes and flags
|
||||
glfwSetWindowAttrib(CORE.Window.handle, GLFW_DECORATED, GLFW_FALSE);
|
||||
glfwSetWindowAttrib(platform.handle, GLFW_DECORATED, GLFW_FALSE);
|
||||
CORE.Window.flags |= FLAG_WINDOW_UNDECORATED;
|
||||
glfwSetWindowAttrib(CORE.Window.handle, GLFW_FLOATING, GLFW_TRUE);
|
||||
glfwSetWindowAttrib(platform.handle, GLFW_FLOATING, GLFW_TRUE);
|
||||
CORE.Window.flags |= FLAG_WINDOW_TOPMOST;
|
||||
|
||||
// Get monitor position and size
|
||||
|
@ -437,29 +450,29 @@ void ToggleBorderlessWindowed(void)
|
|||
const int monitorHeight = mode->height;
|
||||
|
||||
// Set screen position and size
|
||||
glfwSetWindowPos(CORE.Window.handle, monitorPosX, monitorPosY);
|
||||
glfwSetWindowSize(CORE.Window.handle, monitorWidth, monitorHeight);
|
||||
glfwSetWindowPos(platform.handle, monitorPosX, monitorPosY);
|
||||
glfwSetWindowSize(platform.handle, monitorWidth, monitorHeight);
|
||||
|
||||
// Refocus window
|
||||
glfwFocusWindow(CORE.Window.handle);
|
||||
glfwFocusWindow(platform.handle);
|
||||
|
||||
CORE.Window.flags |= FLAG_BORDERLESS_WINDOWED_MODE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Remove topmost and undecorated modes and flags
|
||||
glfwSetWindowAttrib(CORE.Window.handle, GLFW_FLOATING, GLFW_FALSE);
|
||||
glfwSetWindowAttrib(platform.handle, GLFW_FLOATING, GLFW_FALSE);
|
||||
CORE.Window.flags &= ~FLAG_WINDOW_TOPMOST;
|
||||
glfwSetWindowAttrib(CORE.Window.handle, GLFW_DECORATED, GLFW_TRUE);
|
||||
glfwSetWindowAttrib(platform.handle, GLFW_DECORATED, GLFW_TRUE);
|
||||
CORE.Window.flags &= ~FLAG_WINDOW_UNDECORATED;
|
||||
|
||||
// Return previous screen size and position
|
||||
// NOTE: The order matters here, it must set size first, then set position, otherwise the screen will be positioned incorrectly
|
||||
glfwSetWindowSize(CORE.Window.handle, CORE.Window.previousScreen.width, CORE.Window.previousScreen.height);
|
||||
glfwSetWindowPos(CORE.Window.handle, CORE.Window.previousPosition.x, CORE.Window.previousPosition.y);
|
||||
glfwSetWindowSize(platform.handle, CORE.Window.previousScreen.width, CORE.Window.previousScreen.height);
|
||||
glfwSetWindowPos(platform.handle, CORE.Window.previousPosition.x, CORE.Window.previousPosition.y);
|
||||
|
||||
// Refocus window
|
||||
glfwFocusWindow(CORE.Window.handle);
|
||||
glfwFocusWindow(platform.handle);
|
||||
|
||||
CORE.Window.flags &= ~FLAG_BORDERLESS_WINDOWED_MODE;
|
||||
}
|
||||
|
@ -498,21 +511,21 @@ void SetWindowState(unsigned int flags)
|
|||
// State change: FLAG_WINDOW_RESIZABLE
|
||||
if (((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) != (flags & FLAG_WINDOW_RESIZABLE)) && ((flags & FLAG_WINDOW_RESIZABLE) > 0))
|
||||
{
|
||||
glfwSetWindowAttrib(CORE.Window.handle, GLFW_RESIZABLE, GLFW_TRUE);
|
||||
glfwSetWindowAttrib(platform.handle, GLFW_RESIZABLE, GLFW_TRUE);
|
||||
CORE.Window.flags |= FLAG_WINDOW_RESIZABLE;
|
||||
}
|
||||
|
||||
// State change: FLAG_WINDOW_UNDECORATED
|
||||
if (((CORE.Window.flags & FLAG_WINDOW_UNDECORATED) != (flags & FLAG_WINDOW_UNDECORATED)) && (flags & FLAG_WINDOW_UNDECORATED))
|
||||
{
|
||||
glfwSetWindowAttrib(CORE.Window.handle, GLFW_DECORATED, GLFW_FALSE);
|
||||
glfwSetWindowAttrib(platform.handle, GLFW_DECORATED, GLFW_FALSE);
|
||||
CORE.Window.flags |= FLAG_WINDOW_UNDECORATED;
|
||||
}
|
||||
|
||||
// State change: FLAG_WINDOW_HIDDEN
|
||||
if (((CORE.Window.flags & FLAG_WINDOW_HIDDEN) != (flags & FLAG_WINDOW_HIDDEN)) && ((flags & FLAG_WINDOW_HIDDEN) > 0))
|
||||
{
|
||||
glfwHideWindow(CORE.Window.handle);
|
||||
glfwHideWindow(platform.handle);
|
||||
CORE.Window.flags |= FLAG_WINDOW_HIDDEN;
|
||||
}
|
||||
|
||||
|
@ -533,14 +546,14 @@ void SetWindowState(unsigned int flags)
|
|||
// State change: FLAG_WINDOW_UNFOCUSED
|
||||
if (((CORE.Window.flags & FLAG_WINDOW_UNFOCUSED) != (flags & FLAG_WINDOW_UNFOCUSED)) && ((flags & FLAG_WINDOW_UNFOCUSED) > 0))
|
||||
{
|
||||
glfwSetWindowAttrib(CORE.Window.handle, GLFW_FOCUS_ON_SHOW, GLFW_FALSE);
|
||||
glfwSetWindowAttrib(platform.handle, GLFW_FOCUS_ON_SHOW, GLFW_FALSE);
|
||||
CORE.Window.flags |= FLAG_WINDOW_UNFOCUSED;
|
||||
}
|
||||
|
||||
// State change: FLAG_WINDOW_TOPMOST
|
||||
if (((CORE.Window.flags & FLAG_WINDOW_TOPMOST) != (flags & FLAG_WINDOW_TOPMOST)) && ((flags & FLAG_WINDOW_TOPMOST) > 0))
|
||||
{
|
||||
glfwSetWindowAttrib(CORE.Window.handle, GLFW_FLOATING, GLFW_TRUE);
|
||||
glfwSetWindowAttrib(platform.handle, GLFW_FLOATING, GLFW_TRUE);
|
||||
CORE.Window.flags |= FLAG_WINDOW_TOPMOST;
|
||||
}
|
||||
|
||||
|
@ -567,7 +580,7 @@ void SetWindowState(unsigned int flags)
|
|||
// State change: FLAG_WINDOW_MOUSE_PASSTHROUGH
|
||||
if (((CORE.Window.flags & FLAG_WINDOW_MOUSE_PASSTHROUGH) != (flags & FLAG_WINDOW_MOUSE_PASSTHROUGH)) && ((flags & FLAG_WINDOW_MOUSE_PASSTHROUGH) > 0))
|
||||
{
|
||||
glfwSetWindowAttrib(CORE.Window.handle, GLFW_MOUSE_PASSTHROUGH, GLFW_TRUE);
|
||||
glfwSetWindowAttrib(platform.handle, GLFW_MOUSE_PASSTHROUGH, GLFW_TRUE);
|
||||
CORE.Window.flags |= FLAG_WINDOW_MOUSE_PASSTHROUGH;
|
||||
}
|
||||
|
||||
|
@ -613,14 +626,14 @@ void ClearWindowState(unsigned int flags)
|
|||
// State change: FLAG_WINDOW_RESIZABLE
|
||||
if (((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) > 0) && ((flags & FLAG_WINDOW_RESIZABLE) > 0))
|
||||
{
|
||||
glfwSetWindowAttrib(CORE.Window.handle, GLFW_RESIZABLE, GLFW_FALSE);
|
||||
glfwSetWindowAttrib(platform.handle, GLFW_RESIZABLE, GLFW_FALSE);
|
||||
CORE.Window.flags &= ~FLAG_WINDOW_RESIZABLE;
|
||||
}
|
||||
|
||||
// State change: FLAG_WINDOW_HIDDEN
|
||||
if (((CORE.Window.flags & FLAG_WINDOW_HIDDEN) > 0) && ((flags & FLAG_WINDOW_HIDDEN) > 0))
|
||||
{
|
||||
glfwShowWindow(CORE.Window.handle);
|
||||
glfwShowWindow(platform.handle);
|
||||
CORE.Window.flags &= ~FLAG_WINDOW_HIDDEN;
|
||||
}
|
||||
|
||||
|
@ -639,21 +652,21 @@ void ClearWindowState(unsigned int flags)
|
|||
// State change: FLAG_WINDOW_UNDECORATED
|
||||
if (((CORE.Window.flags & FLAG_WINDOW_UNDECORATED) > 0) && ((flags & FLAG_WINDOW_UNDECORATED) > 0))
|
||||
{
|
||||
glfwSetWindowAttrib(CORE.Window.handle, GLFW_DECORATED, GLFW_TRUE);
|
||||
glfwSetWindowAttrib(platform.handle, GLFW_DECORATED, GLFW_TRUE);
|
||||
CORE.Window.flags &= ~FLAG_WINDOW_UNDECORATED;
|
||||
}
|
||||
|
||||
// State change: FLAG_WINDOW_UNFOCUSED
|
||||
if (((CORE.Window.flags & FLAG_WINDOW_UNFOCUSED) > 0) && ((flags & FLAG_WINDOW_UNFOCUSED) > 0))
|
||||
{
|
||||
glfwSetWindowAttrib(CORE.Window.handle, GLFW_FOCUS_ON_SHOW, GLFW_TRUE);
|
||||
glfwSetWindowAttrib(platform.handle, GLFW_FOCUS_ON_SHOW, GLFW_TRUE);
|
||||
CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED;
|
||||
}
|
||||
|
||||
// State change: FLAG_WINDOW_TOPMOST
|
||||
if (((CORE.Window.flags & FLAG_WINDOW_TOPMOST) > 0) && ((flags & FLAG_WINDOW_TOPMOST) > 0))
|
||||
{
|
||||
glfwSetWindowAttrib(CORE.Window.handle, GLFW_FLOATING, GLFW_FALSE);
|
||||
glfwSetWindowAttrib(platform.handle, GLFW_FLOATING, GLFW_FALSE);
|
||||
CORE.Window.flags &= ~FLAG_WINDOW_TOPMOST;
|
||||
}
|
||||
|
||||
|
@ -680,7 +693,7 @@ void ClearWindowState(unsigned int flags)
|
|||
// State change: FLAG_WINDOW_MOUSE_PASSTHROUGH
|
||||
if (((CORE.Window.flags & FLAG_WINDOW_MOUSE_PASSTHROUGH) > 0) && ((flags & FLAG_WINDOW_MOUSE_PASSTHROUGH) > 0))
|
||||
{
|
||||
glfwSetWindowAttrib(CORE.Window.handle, GLFW_MOUSE_PASSTHROUGH, GLFW_FALSE);
|
||||
glfwSetWindowAttrib(platform.handle, GLFW_MOUSE_PASSTHROUGH, GLFW_FALSE);
|
||||
CORE.Window.flags &= ~FLAG_WINDOW_MOUSE_PASSTHROUGH;
|
||||
}
|
||||
|
||||
|
@ -705,7 +718,7 @@ void SetWindowIcon(Image image)
|
|||
if (image.data == NULL)
|
||||
{
|
||||
// Revert to the default window icon, pass in an empty image array
|
||||
glfwSetWindowIcon(CORE.Window.handle, 0, NULL);
|
||||
glfwSetWindowIcon(platform.handle, 0, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -719,7 +732,7 @@ 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(CORE.Window.handle, 1, icon);
|
||||
glfwSetWindowIcon(platform.handle, 1, icon);
|
||||
}
|
||||
else TRACELOG(LOG_WARNING, "GLFW: Window icon image must be in R8G8B8A8 pixel format");
|
||||
}
|
||||
|
@ -734,7 +747,7 @@ void SetWindowIcons(Image *images, int count)
|
|||
if ((images == NULL) || (count <= 0))
|
||||
{
|
||||
// Revert to the default window icon, pass in an empty image array
|
||||
glfwSetWindowIcon(CORE.Window.handle, 0, NULL);
|
||||
glfwSetWindowIcon(platform.handle, 0, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -754,7 +767,7 @@ void SetWindowIcons(Image *images, int count)
|
|||
else TRACELOG(LOG_WARNING, "GLFW: Window icon image must be in R8G8B8A8 pixel format");
|
||||
}
|
||||
// NOTE: Images data is copied internally before this function returns
|
||||
glfwSetWindowIcon(CORE.Window.handle, valid, icons);
|
||||
glfwSetWindowIcon(platform.handle, valid, icons);
|
||||
|
||||
RL_FREE(icons);
|
||||
}
|
||||
|
@ -764,13 +777,13 @@ void SetWindowIcons(Image *images, int count)
|
|||
void SetWindowTitle(const char *title)
|
||||
{
|
||||
CORE.Window.title = title;
|
||||
glfwSetWindowTitle(CORE.Window.handle, title);
|
||||
glfwSetWindowTitle(platform.handle, title);
|
||||
}
|
||||
|
||||
// Set window position on screen (windowed mode)
|
||||
void SetWindowPosition(int x, int y)
|
||||
{
|
||||
glfwSetWindowPos(CORE.Window.handle, x, y);
|
||||
glfwSetWindowPos(platform.handle, x, y);
|
||||
}
|
||||
|
||||
// Set monitor for the current window
|
||||
|
@ -786,7 +799,7 @@ void SetWindowMonitor(int monitor)
|
|||
TRACELOG(LOG_INFO, "GLFW: Selected fullscreen monitor: [%i] %s", monitor, glfwGetMonitorName(monitors[monitor]));
|
||||
|
||||
const GLFWvidmode *mode = glfwGetVideoMode(monitors[monitor]);
|
||||
glfwSetWindowMonitor(CORE.Window.handle, monitors[monitor], 0, 0, mode->width, mode->height, mode->refreshRate);
|
||||
glfwSetWindowMonitor(platform.handle, monitors[monitor], 0, 0, mode->width, mode->height, mode->refreshRate);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -801,12 +814,12 @@ void SetWindowMonitor(int monitor)
|
|||
glfwGetMonitorWorkarea(monitors[monitor], &monitorWorkareaX, &monitorWorkareaY, &monitorWorkareaWidth, &monitorWorkareaHeight);
|
||||
|
||||
// If the screen size is larger than the monitor workarea, anchor it on the top left corner, otherwise, center it
|
||||
if ((screenWidth >= monitorWorkareaWidth) || (screenHeight >= monitorWorkareaHeight)) glfwSetWindowPos(CORE.Window.handle, monitorWorkareaX, monitorWorkareaY);
|
||||
if ((screenWidth >= monitorWorkareaWidth) || (screenHeight >= monitorWorkareaHeight)) glfwSetWindowPos(platform.handle, monitorWorkareaX, monitorWorkareaY);
|
||||
else
|
||||
{
|
||||
const int x = monitorWorkareaX + (monitorWorkareaWidth/2) - (screenWidth/2);
|
||||
const int y = monitorWorkareaY + (monitorWorkareaHeight/2) - (screenHeight/2);
|
||||
glfwSetWindowPos(CORE.Window.handle, x, y);
|
||||
glfwSetWindowPos(platform.handle, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -822,7 +835,7 @@ void SetWindowMinSize(int width, int height)
|
|||
int minHeight = (CORE.Window.screenMin.height == 0)? GLFW_DONT_CARE : CORE.Window.screenMin.height;
|
||||
int maxWidth = (CORE.Window.screenMax.width == 0)? GLFW_DONT_CARE : CORE.Window.screenMax.width;
|
||||
int maxHeight = (CORE.Window.screenMax.height == 0)? GLFW_DONT_CARE : CORE.Window.screenMax.height;
|
||||
glfwSetWindowSizeLimits(CORE.Window.handle, minWidth, minHeight, maxWidth, maxHeight);
|
||||
glfwSetWindowSizeLimits(platform.handle, minWidth, minHeight, maxWidth, maxHeight);
|
||||
}
|
||||
|
||||
// Set window maximum dimensions (FLAG_WINDOW_RESIZABLE)
|
||||
|
@ -834,13 +847,13 @@ void SetWindowMaxSize(int width, int height)
|
|||
int minHeight = (CORE.Window.screenMin.height == 0)? GLFW_DONT_CARE : CORE.Window.screenMin.height;
|
||||
int maxWidth = (CORE.Window.screenMax.width == 0)? GLFW_DONT_CARE : CORE.Window.screenMax.width;
|
||||
int maxHeight = (CORE.Window.screenMax.height == 0)? GLFW_DONT_CARE : CORE.Window.screenMax.height;
|
||||
glfwSetWindowSizeLimits(CORE.Window.handle, minWidth, minHeight, maxWidth, maxHeight);
|
||||
glfwSetWindowSizeLimits(platform.handle, minWidth, minHeight, maxWidth, maxHeight);
|
||||
}
|
||||
|
||||
// Set window dimensions
|
||||
void SetWindowSize(int width, int height)
|
||||
{
|
||||
glfwSetWindowSize(CORE.Window.handle, width, height);
|
||||
glfwSetWindowSize(platform.handle, width, height);
|
||||
}
|
||||
|
||||
// Set window opacity, value opacity is between 0.0 and 1.0
|
||||
|
@ -848,13 +861,13 @@ void SetWindowOpacity(float opacity)
|
|||
{
|
||||
if (opacity >= 1.0f) opacity = 1.0f;
|
||||
else if (opacity <= 0.0f) opacity = 0.0f;
|
||||
glfwSetWindowOpacity(CORE.Window.handle, opacity);
|
||||
glfwSetWindowOpacity(platform.handle, opacity);
|
||||
}
|
||||
|
||||
// Set window focused
|
||||
void SetWindowFocused(void)
|
||||
{
|
||||
glfwFocusWindow(CORE.Window.handle);
|
||||
glfwFocusWindow(platform.handle);
|
||||
}
|
||||
|
||||
// Get native window handle
|
||||
|
@ -862,19 +875,19 @@ void *GetWindowHandle(void)
|
|||
{
|
||||
#if defined(_WIN32)
|
||||
// NOTE: Returned handle is: void *HWND (windows.h)
|
||||
return glfwGetWin32Window(CORE.Window.handle);
|
||||
return glfwGetWin32Window(platform.handle);
|
||||
#endif
|
||||
#if defined(__linux__)
|
||||
// NOTE: Returned handle is: unsigned long Window (X.h)
|
||||
// typedef unsigned long XID;
|
||||
// typedef XID Window;
|
||||
//unsigned long id = (unsigned long)glfwGetX11Window(CORE.Window.handle);
|
||||
//unsigned long id = (unsigned long)glfwGetX11Window(platform.handle);
|
||||
//return NULL; // TODO: Find a way to return value... cast to void *?
|
||||
return (void *)CORE.Window.handle;
|
||||
return (void *)platform.handle;
|
||||
#endif
|
||||
#if defined(__APPLE__)
|
||||
// NOTE: Returned handle is: (objc_object *)
|
||||
return (void *)glfwGetCocoaWindow(CORE.Window.handle);
|
||||
return (void *)glfwGetCocoaWindow(platform.handle);
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
|
@ -903,7 +916,7 @@ int GetCurrentMonitor(void)
|
|||
if (IsWindowFullscreen())
|
||||
{
|
||||
// Get the handle of the monitor that the specified window is in full screen on
|
||||
monitor = glfwGetWindowMonitor(CORE.Window.handle);
|
||||
monitor = glfwGetWindowMonitor(platform.handle);
|
||||
|
||||
for (int i = 0; i < monitorCount; i++)
|
||||
{
|
||||
|
@ -919,7 +932,7 @@ int GetCurrentMonitor(void)
|
|||
int x = 0;
|
||||
int y = 0;
|
||||
|
||||
glfwGetWindowPos(CORE.Window.handle, &x, &y);
|
||||
glfwGetWindowPos(platform.handle, &x, &y);
|
||||
|
||||
for (int i = 0; i < monitorCount; i++)
|
||||
{
|
||||
|
@ -1070,7 +1083,7 @@ Vector2 GetWindowPosition(void)
|
|||
int x = 0;
|
||||
int y = 0;
|
||||
|
||||
glfwGetWindowPos(CORE.Window.handle, &x, &y);
|
||||
glfwGetWindowPos(platform.handle, &x, &y);
|
||||
|
||||
return (Vector2){ (float)x, (float)y };
|
||||
}
|
||||
|
@ -1109,34 +1122,34 @@ Vector2 GetWindowScaleDPI(void)
|
|||
// Set clipboard text content
|
||||
void SetClipboardText(const char *text)
|
||||
{
|
||||
glfwSetClipboardString(CORE.Window.handle, text);
|
||||
glfwSetClipboardString(platform.handle, text);
|
||||
}
|
||||
|
||||
// Get clipboard text content
|
||||
// NOTE: returned string is allocated and freed by GLFW
|
||||
const char *GetClipboardText(void)
|
||||
{
|
||||
return glfwGetClipboardString(CORE.Window.handle);
|
||||
return glfwGetClipboardString(platform.handle);
|
||||
}
|
||||
|
||||
// Show mouse cursor
|
||||
void ShowCursor(void)
|
||||
{
|
||||
glfwSetInputMode(CORE.Window.handle, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||
glfwSetInputMode(platform.handle, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||
CORE.Input.Mouse.cursorHidden = false;
|
||||
}
|
||||
|
||||
// Hides mouse cursor
|
||||
void HideCursor(void)
|
||||
{
|
||||
glfwSetInputMode(CORE.Window.handle, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
|
||||
glfwSetInputMode(platform.handle, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
|
||||
CORE.Input.Mouse.cursorHidden = true;
|
||||
}
|
||||
|
||||
// Enables cursor (unlock cursor)
|
||||
void EnableCursor(void)
|
||||
{
|
||||
glfwSetInputMode(CORE.Window.handle, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||
glfwSetInputMode(platform.handle, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||
|
||||
// Set cursor position in the middle
|
||||
SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2);
|
||||
|
@ -1147,7 +1160,7 @@ void EnableCursor(void)
|
|||
// Disables cursor (lock cursor)
|
||||
void DisableCursor(void)
|
||||
{
|
||||
glfwSetInputMode(CORE.Window.handle, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
glfwSetInputMode(platform.handle, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
|
||||
// Set cursor position in the middle
|
||||
SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2);
|
||||
|
@ -1276,7 +1289,7 @@ void SetMousePosition(int x, int y)
|
|||
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
|
||||
|
||||
// NOTE: emscripten not implemented
|
||||
glfwSetCursorPos(CORE.Window.handle, CORE.Input.Mouse.currentPosition.x, CORE.Input.Mouse.currentPosition.y);
|
||||
glfwSetCursorPos(platform.handle, CORE.Input.Mouse.currentPosition.x, CORE.Input.Mouse.currentPosition.y);
|
||||
}
|
||||
|
||||
// Get mouse wheel movement Y
|
||||
|
@ -1294,11 +1307,11 @@ float GetMouseWheelMove(void)
|
|||
void SetMouseCursor(int cursor)
|
||||
{
|
||||
CORE.Input.Mouse.cursor = cursor;
|
||||
if (cursor == MOUSE_CURSOR_DEFAULT) glfwSetCursor(CORE.Window.handle, NULL);
|
||||
if (cursor == MOUSE_CURSOR_DEFAULT) glfwSetCursor(platform.handle, NULL);
|
||||
else
|
||||
{
|
||||
// NOTE: We are relating internal GLFW enum values to our MouseCursor enum values
|
||||
glfwSetCursor(CORE.Window.handle, glfwCreateStandardCursor(0x00036000 + cursor));
|
||||
glfwSetCursor(platform.handle, glfwCreateStandardCursor(0x00036000 + cursor));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1331,7 +1344,7 @@ Vector2 GetTouchPosition(int index)
|
|||
// Swap back buffer with front buffer (screen drawing)
|
||||
void SwapScreenBuffer(void)
|
||||
{
|
||||
glfwSwapBuffers(CORE.Window.handle);
|
||||
glfwSwapBuffers(platform.handle);
|
||||
}
|
||||
|
||||
// Register all input events
|
||||
|
@ -1691,10 +1704,10 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
// HighDPI monitors are properly considered in a following similar function: SetupViewport()
|
||||
SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);
|
||||
|
||||
CORE.Window.handle = glfwCreateWindow(CORE.Window.display.width, CORE.Window.display.height, (CORE.Window.title != 0)? CORE.Window.title : " ", glfwGetPrimaryMonitor(), NULL);
|
||||
platform.handle = glfwCreateWindow(CORE.Window.display.width, CORE.Window.display.height, (CORE.Window.title != 0)? CORE.Window.title : " ", glfwGetPrimaryMonitor(), NULL);
|
||||
|
||||
// NOTE: Full-screen change, not working properly...
|
||||
//glfwSetWindowMonitor(CORE.Window.handle, glfwGetPrimaryMonitor(), 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
|
||||
//glfwSetWindowMonitor(platform.handle, glfwGetPrimaryMonitor(), 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1705,16 +1718,16 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
}
|
||||
|
||||
// No-fullscreen window creation
|
||||
CORE.Window.handle = glfwCreateWindow(CORE.Window.screen.width, CORE.Window.screen.height, (CORE.Window.title != 0)? CORE.Window.title : " ", NULL, NULL);
|
||||
platform.handle = glfwCreateWindow(CORE.Window.screen.width, CORE.Window.screen.height, (CORE.Window.title != 0)? CORE.Window.title : " ", NULL, NULL);
|
||||
|
||||
if (CORE.Window.handle)
|
||||
if (platform.handle)
|
||||
{
|
||||
CORE.Window.render.width = CORE.Window.screen.width;
|
||||
CORE.Window.render.height = CORE.Window.screen.height;
|
||||
}
|
||||
}
|
||||
|
||||
if (!CORE.Window.handle)
|
||||
if (!platform.handle)
|
||||
{
|
||||
glfwTerminate();
|
||||
TRACELOG(LOG_WARNING, "GLFW: Failed to initialize Window");
|
||||
|
@ -1722,23 +1735,23 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
}
|
||||
|
||||
// Set window callback events
|
||||
glfwSetWindowSizeCallback(CORE.Window.handle, WindowSizeCallback); // NOTE: Resizing not allowed by default!
|
||||
glfwSetWindowMaximizeCallback(CORE.Window.handle, WindowMaximizeCallback);
|
||||
glfwSetWindowIconifyCallback(CORE.Window.handle, WindowIconifyCallback);
|
||||
glfwSetWindowFocusCallback(CORE.Window.handle, WindowFocusCallback);
|
||||
glfwSetDropCallback(CORE.Window.handle, WindowDropCallback);
|
||||
glfwSetWindowSizeCallback(platform.handle, WindowSizeCallback); // NOTE: Resizing not allowed by default!
|
||||
glfwSetWindowMaximizeCallback(platform.handle, WindowMaximizeCallback);
|
||||
glfwSetWindowIconifyCallback(platform.handle, WindowIconifyCallback);
|
||||
glfwSetWindowFocusCallback(platform.handle, WindowFocusCallback);
|
||||
glfwSetDropCallback(platform.handle, WindowDropCallback);
|
||||
|
||||
// Set input callback events
|
||||
glfwSetKeyCallback(CORE.Window.handle, KeyCallback);
|
||||
glfwSetCharCallback(CORE.Window.handle, CharCallback);
|
||||
glfwSetMouseButtonCallback(CORE.Window.handle, MouseButtonCallback);
|
||||
glfwSetCursorPosCallback(CORE.Window.handle, MouseCursorPosCallback); // Track mouse position changes
|
||||
glfwSetScrollCallback(CORE.Window.handle, MouseScrollCallback);
|
||||
glfwSetCursorEnterCallback(CORE.Window.handle, CursorEnterCallback);
|
||||
glfwSetKeyCallback(platform.handle, KeyCallback);
|
||||
glfwSetCharCallback(platform.handle, CharCallback);
|
||||
glfwSetMouseButtonCallback(platform.handle, MouseButtonCallback);
|
||||
glfwSetCursorPosCallback(platform.handle, MouseCursorPosCallback); // Track mouse position changes
|
||||
glfwSetScrollCallback(platform.handle, MouseScrollCallback);
|
||||
glfwSetCursorEnterCallback(platform.handle, CursorEnterCallback);
|
||||
|
||||
glfwMakeContextCurrent(CORE.Window.handle);
|
||||
glfwMakeContextCurrent(platform.handle);
|
||||
|
||||
glfwSetInputMode(CORE.Window.handle, GLFW_LOCK_KEY_MODS, GLFW_TRUE); // Enable lock keys modifiers (CAPS, NUM)
|
||||
glfwSetInputMode(platform.handle, GLFW_LOCK_KEY_MODS, GLFW_TRUE); // Enable lock keys modifiers (CAPS, NUM)
|
||||
|
||||
glfwSwapInterval(0); // No V-Sync by default
|
||||
|
||||
|
@ -1760,7 +1773,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
// NOTE: On APPLE platforms system should manage window/input scaling and also framebuffer scaling.
|
||||
// Framebuffer scaling should be activated with: glfwWindowHint(GLFW_COCOA_RETINA_FRAMEBUFFER, GLFW_TRUE);
|
||||
#if !defined(__APPLE__)
|
||||
glfwGetFramebufferSize(CORE.Window.handle, &fbWidth, &fbHeight);
|
||||
glfwGetFramebufferSize(platform.handle, &fbWidth, &fbHeight);
|
||||
|
||||
// Screen scaling matrix is required in case desired screen area is different from display area
|
||||
CORE.Window.screenScale = MatrixScale((float)fbWidth/CORE.Window.screen.width, (float)fbHeight/CORE.Window.screen.height, 1.0f);
|
||||
|
@ -1913,7 +1926,7 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
|
|||
}
|
||||
|
||||
// Check the exit key to set close window
|
||||
if ((key == CORE.Input.Keyboard.exitKey) && (action == GLFW_PRESS)) glfwSetWindowShouldClose(CORE.Window.handle, GLFW_TRUE);
|
||||
if ((key == CORE.Input.Keyboard.exitKey) && (action == GLFW_PRESS)) glfwSetWindowShouldClose(platform.handle, GLFW_TRUE);
|
||||
|
||||
#if defined(SUPPORT_SCREEN_CAPTURE)
|
||||
if ((key == GLFW_KEY_F12) && (action == GLFW_PRESS))
|
||||
|
|
396
src/rcore_drm.c
396
src/rcore_drm.c
|
@ -17,8 +17,10 @@
|
|||
* - TRACELOG() function is located in raylib [utils] module
|
||||
*
|
||||
* CONFIGURATION:
|
||||
* #define RCORE_DRM_CUSTOM_FLAG
|
||||
* Custom flag for rcore on PLATFORM_DRM -not used-
|
||||
* #define SUPPORT_SSH_KEYBOARD_RPI (Raspberry Pi only)
|
||||
* Reconfigure standard input to receive key inputs, works with SSH connection.
|
||||
* WARNING: Reconfiguring standard input could lead to undesired effects, like breaking other
|
||||
* running processes orblocking the device if not restored properly. Use with care.
|
||||
*
|
||||
* DEPENDENCIES:
|
||||
* gestures - Gestures system for touch-ready devices (or simulated from mouse inputs)
|
||||
|
@ -47,16 +49,94 @@
|
|||
|
||||
#include "rcore.h"
|
||||
|
||||
#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> // Required for: ioctl() - UNIX System call for device-specific input/output operations
|
||||
#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 <gbm.h> // Generic Buffer Management (native platform for EGL on DRM)
|
||||
#include <xf86drm.h> // Direct Rendering Manager user-level library interface
|
||||
#include <xf86drmMode.h> // Direct Rendering Manager mode setting (KMS) interface
|
||||
|
||||
#include "EGL/egl.h" // Native platform windowing system interface
|
||||
#include "EGL/eglext.h" // EGL extensions
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
#define USE_LAST_TOUCH_DEVICE // When multiple touchscreens are connected, only use the one with the highest event<N> number
|
||||
|
||||
#define DEFAULT_GAMEPAD_DEV "/dev/input/js" // Gamepad input (base dev for all gamepads: js0, js1, ...)
|
||||
#define DEFAULT_EVDEV_PATH "/dev/input/" // Path to the linux input events
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
//...
|
||||
|
||||
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
|
||||
} InputEventWorker;
|
||||
|
||||
typedef struct {
|
||||
// Display data
|
||||
int fd; // File descriptor for /dev/dri/...
|
||||
drmModeConnector *connector; // Direct Rendering Manager (DRM) mode connector
|
||||
drmModeCrtc *crtc; // CRT Controller
|
||||
int modeIndex; // Index of the used mode of connector->modes
|
||||
struct gbm_device *gbmDevice; // GBM device
|
||||
struct gbm_surface *gbmSurface; // GBM surface
|
||||
struct gbm_bo *prevBO; // Previous GBM buffer object (during frame swapping)
|
||||
uint32_t prevFB; // Previous GBM framebufer (during frame swapping)
|
||||
|
||||
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
|
||||
|
||||
// Input data
|
||||
InputEventWorker eventWorker[10]; // List of worker threads for every monitored "/dev/input/event<N>"
|
||||
|
||||
// Keyboard data
|
||||
int defaultKeyboardMode; // Default keyboard mode
|
||||
bool eventKeyboardMode; // Keyboard in event mode
|
||||
int defaultFileFlags; // Default IO file flags
|
||||
struct termios defaultSettings; // Default keyboard settings
|
||||
int keyboardFd; // File descriptor for the evdev keyboard
|
||||
|
||||
// Mouse data
|
||||
Vector2 eventWheelMove; // Registers the event mouse wheel variation
|
||||
// NOTE: currentButtonState[] can't be written directly due to multithreading, app could miss the update
|
||||
char currentButtonStateEvdev[MAX_MOUSE_BUTTONS]; // Holds the new mouse state for the next polling event to grab
|
||||
|
||||
// Gamepad data
|
||||
pthread_t gamepadThreadId; // Gamepad reading thread id
|
||||
int gamepadStreamFd[MAX_GAMEPADS]; // Gamepad device file descriptor
|
||||
|
||||
} PlatformData;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
extern CoreData CORE; // Global CORE state context
|
||||
|
||||
static PlatformData platform = { 0 }; // Platform specific data
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Internal Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
|
@ -227,67 +307,67 @@ void CloseWindow(void)
|
|||
timeEndPeriod(1); // Restore time period
|
||||
#endif
|
||||
|
||||
if (CORE.Window.prevFB)
|
||||
if (platform.prevFB)
|
||||
{
|
||||
drmModeRmFB(CORE.Window.fd, CORE.Window.prevFB);
|
||||
CORE.Window.prevFB = 0;
|
||||
drmModeRmFB(platform.fd, platform.prevFB);
|
||||
platform.prevFB = 0;
|
||||
}
|
||||
|
||||
if (CORE.Window.prevBO)
|
||||
if (platform.prevBO)
|
||||
{
|
||||
gbm_surface_release_buffer(CORE.Window.gbmSurface, CORE.Window.prevBO);
|
||||
CORE.Window.prevBO = NULL;
|
||||
gbm_surface_release_buffer(platform.gbmSurface, platform.prevBO);
|
||||
platform.prevBO = NULL;
|
||||
}
|
||||
|
||||
if (CORE.Window.gbmSurface)
|
||||
if (platform.gbmSurface)
|
||||
{
|
||||
gbm_surface_destroy(CORE.Window.gbmSurface);
|
||||
CORE.Window.gbmSurface = NULL;
|
||||
gbm_surface_destroy(platform.gbmSurface);
|
||||
platform.gbmSurface = NULL;
|
||||
}
|
||||
|
||||
if (CORE.Window.gbmDevice)
|
||||
if (platform.gbmDevice)
|
||||
{
|
||||
gbm_device_destroy(CORE.Window.gbmDevice);
|
||||
CORE.Window.gbmDevice = NULL;
|
||||
gbm_device_destroy(platform.gbmDevice);
|
||||
platform.gbmDevice = NULL;
|
||||
}
|
||||
|
||||
if (CORE.Window.crtc)
|
||||
if (platform.crtc)
|
||||
{
|
||||
if (CORE.Window.connector)
|
||||
if (platform.connector)
|
||||
{
|
||||
drmModeSetCrtc(CORE.Window.fd, CORE.Window.crtc->crtc_id, CORE.Window.crtc->buffer_id,
|
||||
CORE.Window.crtc->x, CORE.Window.crtc->y, &CORE.Window.connector->connector_id, 1, &CORE.Window.crtc->mode);
|
||||
drmModeFreeConnector(CORE.Window.connector);
|
||||
CORE.Window.connector = NULL;
|
||||
drmModeSetCrtc(platform.fd, platform.crtc->crtc_id, platform.crtc->buffer_id,
|
||||
platform.crtc->x, platform.crtc->y, &platform.connector->connector_id, 1, &platform.crtc->mode);
|
||||
drmModeFreeConnector(platform.connector);
|
||||
platform.connector = NULL;
|
||||
}
|
||||
|
||||
drmModeFreeCrtc(CORE.Window.crtc);
|
||||
CORE.Window.crtc = NULL;
|
||||
drmModeFreeCrtc(platform.crtc);
|
||||
platform.crtc = NULL;
|
||||
}
|
||||
|
||||
if (CORE.Window.fd != -1)
|
||||
if (platform.fd != -1)
|
||||
{
|
||||
close(CORE.Window.fd);
|
||||
CORE.Window.fd = -1;
|
||||
close(platform.fd);
|
||||
platform.fd = -1;
|
||||
}
|
||||
|
||||
// Close surface, context and display
|
||||
if (CORE.Window.device != EGL_NO_DISPLAY)
|
||||
if (platform.device != EGL_NO_DISPLAY)
|
||||
{
|
||||
if (CORE.Window.surface != EGL_NO_SURFACE)
|
||||
if (platform.surface != EGL_NO_SURFACE)
|
||||
{
|
||||
eglDestroySurface(CORE.Window.device, CORE.Window.surface);
|
||||
CORE.Window.surface = EGL_NO_SURFACE;
|
||||
eglDestroySurface(platform.device, platform.surface);
|
||||
platform.surface = EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
if (CORE.Window.context != EGL_NO_CONTEXT)
|
||||
if (platform.context != EGL_NO_CONTEXT)
|
||||
{
|
||||
eglDestroyContext(CORE.Window.device, CORE.Window.context);
|
||||
CORE.Window.context = EGL_NO_CONTEXT;
|
||||
eglDestroyContext(platform.device, platform.context);
|
||||
platform.context = EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
eglTerminate(CORE.Window.device);
|
||||
CORE.Window.device = EGL_NO_DISPLAY;
|
||||
eglTerminate(platform.device);
|
||||
platform.device = EGL_NO_DISPLAY;
|
||||
}
|
||||
|
||||
// Wait for mouse and gamepad threads to finish before closing
|
||||
|
@ -297,21 +377,21 @@ void CloseWindow(void)
|
|||
CORE.Window.shouldClose = true; // Added to force threads to exit when the close window is called
|
||||
|
||||
// Close the evdev keyboard
|
||||
if (CORE.Input.Keyboard.fd != -1)
|
||||
if (platform.keyboardFd != -1)
|
||||
{
|
||||
close(CORE.Input.Keyboard.fd);
|
||||
CORE.Input.Keyboard.fd = -1;
|
||||
close(platform.keyboardFd);
|
||||
platform.keyboardFd = -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i)
|
||||
for (int i = 0; i < sizeof(platform.eventWorker)/sizeof(InputEventWorker); ++i)
|
||||
{
|
||||
if (CORE.Input.eventWorker[i].threadId)
|
||||
if (platform.eventWorker[i].threadId)
|
||||
{
|
||||
pthread_join(CORE.Input.eventWorker[i].threadId, NULL);
|
||||
pthread_join(platform.eventWorker[i].threadId, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (CORE.Input.Gamepad.threadId) pthread_join(CORE.Input.Gamepad.threadId, NULL);
|
||||
if (platform.gamepadThreadId) pthread_join(platform.gamepadThreadId, NULL);
|
||||
|
||||
#if defined(SUPPORT_EVENTS_AUTOMATION)
|
||||
RL_FREE(events);
|
||||
|
@ -524,9 +604,9 @@ int GetMonitorRefreshRate(int monitor)
|
|||
{
|
||||
int refresh = 0;
|
||||
|
||||
if ((CORE.Window.connector) && (CORE.Window.modeIndex >= 0))
|
||||
if ((platform.connector) && (platform.modeIndex >= 0))
|
||||
{
|
||||
refresh = CORE.Window.connector->modes[CORE.Window.modeIndex].vrefresh;
|
||||
refresh = platform.connector->modes[platform.modeIndex].vrefresh;
|
||||
}
|
||||
|
||||
return refresh;
|
||||
|
@ -659,7 +739,7 @@ const char *GetGamepadName(int gamepad)
|
|||
|
||||
if (CORE.Input.Gamepad.ready[gamepad])
|
||||
{
|
||||
ioctl(CORE.Input.Gamepad.streamId[gamepad], JSIOCGNAME(64), &CORE.Input.Gamepad.name[gamepad]);
|
||||
ioctl(platform.gamepadStreamFd[gamepad], JSIOCGNAME(64), &CORE.Input.Gamepad.name[gamepad]);
|
||||
name = CORE.Input.Gamepad.name[gamepad];
|
||||
}
|
||||
|
||||
|
@ -670,7 +750,7 @@ const char *GetGamepadName(int gamepad)
|
|||
int GetGamepadAxisCount(int gamepad)
|
||||
{
|
||||
int axisCount = 0;
|
||||
if (CORE.Input.Gamepad.ready[gamepad]) ioctl(CORE.Input.Gamepad.streamId[gamepad], JSIOCGAXES, &axisCount);
|
||||
if (CORE.Input.Gamepad.ready[gamepad]) ioctl(platform.gamepadStreamFd[gamepad], JSIOCGAXES, &axisCount);
|
||||
CORE.Input.Gamepad.axisCount = axisCount;
|
||||
|
||||
return CORE.Input.Gamepad.axisCount;
|
||||
|
@ -756,31 +836,31 @@ Vector2 GetTouchPosition(int index)
|
|||
// Swap back buffer with front buffer (screen drawing)
|
||||
void SwapScreenBuffer(void)
|
||||
{
|
||||
eglSwapBuffers(CORE.Window.device, CORE.Window.surface);
|
||||
eglSwapBuffers(platform.device, platform.surface);
|
||||
|
||||
if (!CORE.Window.gbmSurface || (-1 == CORE.Window.fd) || !CORE.Window.connector || !CORE.Window.crtc) TRACELOG(LOG_ERROR, "DISPLAY: DRM initialization failed to swap");
|
||||
if (!platform.gbmSurface || (-1 == platform.fd) || !platform.connector || !platform.crtc) TRACELOG(LOG_ERROR, "DISPLAY: DRM initialization failed to swap");
|
||||
|
||||
struct gbm_bo *bo = gbm_surface_lock_front_buffer(CORE.Window.gbmSurface);
|
||||
struct gbm_bo *bo = gbm_surface_lock_front_buffer(platform.gbmSurface);
|
||||
if (!bo) TRACELOG(LOG_ERROR, "DISPLAY: Failed GBM to lock front buffer");
|
||||
|
||||
uint32_t fb = 0;
|
||||
int result = drmModeAddFB(CORE.Window.fd, CORE.Window.connector->modes[CORE.Window.modeIndex].hdisplay, CORE.Window.connector->modes[CORE.Window.modeIndex].vdisplay, 24, 32, gbm_bo_get_stride(bo), gbm_bo_get_handle(bo).u32, &fb);
|
||||
int result = drmModeAddFB(platform.fd, platform.connector->modes[platform.modeIndex].hdisplay, platform.connector->modes[platform.modeIndex].vdisplay, 24, 32, gbm_bo_get_stride(bo), gbm_bo_get_handle(bo).u32, &fb);
|
||||
if (result != 0) TRACELOG(LOG_ERROR, "DISPLAY: drmModeAddFB() failed with result: %d", result);
|
||||
|
||||
result = drmModeSetCrtc(CORE.Window.fd, CORE.Window.crtc->crtc_id, fb, 0, 0, &CORE.Window.connector->connector_id, 1, &CORE.Window.connector->modes[CORE.Window.modeIndex]);
|
||||
result = drmModeSetCrtc(platform.fd, platform.crtc->crtc_id, fb, 0, 0, &platform.connector->connector_id, 1, &platform.connector->modes[platform.modeIndex]);
|
||||
if (result != 0) TRACELOG(LOG_ERROR, "DISPLAY: drmModeSetCrtc() failed with result: %d", result);
|
||||
|
||||
if (CORE.Window.prevFB)
|
||||
if (platform.prevFB)
|
||||
{
|
||||
result = drmModeRmFB(CORE.Window.fd, CORE.Window.prevFB);
|
||||
result = drmModeRmFB(platform.fd, platform.prevFB);
|
||||
if (result != 0) TRACELOG(LOG_ERROR, "DISPLAY: drmModeRmFB() failed with result: %d", result);
|
||||
}
|
||||
|
||||
CORE.Window.prevFB = fb;
|
||||
platform.prevFB = fb;
|
||||
|
||||
if (CORE.Window.prevBO) gbm_surface_release_buffer(CORE.Window.gbmSurface, CORE.Window.prevBO);
|
||||
if (platform.prevBO) gbm_surface_release_buffer(platform.gbmSurface, platform.prevBO);
|
||||
|
||||
CORE.Window.prevBO = bo;
|
||||
platform.prevBO = bo;
|
||||
}
|
||||
|
||||
// Register all input events
|
||||
|
@ -814,12 +894,12 @@ void PollInputEvents(void)
|
|||
|
||||
// Register previous mouse states
|
||||
CORE.Input.Mouse.previousWheelMove = CORE.Input.Mouse.currentWheelMove;
|
||||
CORE.Input.Mouse.currentWheelMove = CORE.Input.Mouse.eventWheelMove;
|
||||
CORE.Input.Mouse.eventWheelMove = (Vector2){ 0.0f, 0.0f };
|
||||
CORE.Input.Mouse.currentWheelMove = platform.eventWheelMove;
|
||||
platform.eventWheelMove = (Vector2){ 0.0f, 0.0f };
|
||||
for (int i = 0; i < MAX_MOUSE_BUTTONS; i++)
|
||||
{
|
||||
CORE.Input.Mouse.previousButtonState[i] = CORE.Input.Mouse.currentButtonState[i];
|
||||
CORE.Input.Mouse.currentButtonState[i] = CORE.Input.Mouse.currentButtonStateEvdev[i];
|
||||
CORE.Input.Mouse.currentButtonState[i] = platform.currentButtonStateEvdev[i];
|
||||
}
|
||||
|
||||
// Register gamepads buttons events
|
||||
|
@ -844,7 +924,7 @@ void PollInputEvents(void)
|
|||
// NOTE: Keyboard reading could be done using input_event(s) or just read from stdin, both methods are used here.
|
||||
// stdin reading is still used for legacy purposes, it allows keyboard input trough SSH console
|
||||
|
||||
if (!CORE.Input.Keyboard.evtMode) ProcessKeyboard();
|
||||
if (!platform.eventKeyboardMode) ProcessKeyboard();
|
||||
|
||||
// NOTE: Mouse input events polling is done asynchronously in another pthread - EventThread()
|
||||
// NOTE: Gamepad (Joystick) input events polling is done asynchonously in another pthread - GamepadThread()
|
||||
|
@ -877,41 +957,41 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
CORE.Window.fullscreen = true;
|
||||
CORE.Window.flags |= FLAG_FULLSCREEN_MODE;
|
||||
|
||||
CORE.Window.fd = -1;
|
||||
CORE.Window.connector = NULL;
|
||||
CORE.Window.modeIndex = -1;
|
||||
CORE.Window.crtc = NULL;
|
||||
CORE.Window.gbmDevice = NULL;
|
||||
CORE.Window.gbmSurface = NULL;
|
||||
CORE.Window.prevBO = NULL;
|
||||
CORE.Window.prevFB = 0;
|
||||
platform.fd = -1;
|
||||
platform.connector = NULL;
|
||||
platform.modeIndex = -1;
|
||||
platform.crtc = NULL;
|
||||
platform.gbmDevice = NULL;
|
||||
platform.gbmSurface = NULL;
|
||||
platform.prevBO = NULL;
|
||||
platform.prevFB = 0;
|
||||
|
||||
#if defined(DEFAULT_GRAPHIC_DEVICE_DRM)
|
||||
CORE.Window.fd = open(DEFAULT_GRAPHIC_DEVICE_DRM, O_RDWR);
|
||||
platform.fd = open(DEFAULT_GRAPHIC_DEVICE_DRM, O_RDWR);
|
||||
#else
|
||||
TRACELOG(LOG_INFO, "DISPLAY: No graphic card set, trying platform-gpu-card");
|
||||
CORE.Window.fd = open("/dev/dri/by-path/platform-gpu-card", O_RDWR); // VideoCore VI (Raspberry Pi 4)
|
||||
platform.fd = open("/dev/dri/by-path/platform-gpu-card", O_RDWR); // VideoCore VI (Raspberry Pi 4)
|
||||
|
||||
if ((CORE.Window.fd == -1) || (drmModeGetResources(CORE.Window.fd) == NULL))
|
||||
if ((platform.fd == -1) || (drmModeGetResources(platform.fd) == NULL))
|
||||
{
|
||||
TRACELOG(LOG_INFO, "DISPLAY: Failed to open platform-gpu-card, trying card1");
|
||||
CORE.Window.fd = open("/dev/dri/card1", O_RDWR); // Other Embedded
|
||||
platform.fd = open("/dev/dri/card1", O_RDWR); // Other Embedded
|
||||
}
|
||||
|
||||
if ((CORE.Window.fd == -1) || (drmModeGetResources(CORE.Window.fd) == NULL))
|
||||
if ((platform.fd == -1) || (drmModeGetResources(platform.fd) == NULL))
|
||||
{
|
||||
TRACELOG(LOG_INFO, "DISPLAY: Failed to open graphic card1, trying card0");
|
||||
CORE.Window.fd = open("/dev/dri/card0", O_RDWR); // VideoCore IV (Raspberry Pi 1-3)
|
||||
platform.fd = open("/dev/dri/card0", O_RDWR); // VideoCore IV (Raspberry Pi 1-3)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (CORE.Window.fd == -1)
|
||||
if (platform.fd == -1)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to open graphic card");
|
||||
return false;
|
||||
}
|
||||
|
||||
drmModeRes *res = drmModeGetResources(CORE.Window.fd);
|
||||
drmModeRes *res = drmModeGetResources(platform.fd);
|
||||
if (!res)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed get DRM resources");
|
||||
|
@ -924,13 +1004,13 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
{
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: Connector index %i", i);
|
||||
|
||||
drmModeConnector *con = drmModeGetConnector(CORE.Window.fd, res->connectors[i]);
|
||||
drmModeConnector *con = drmModeGetConnector(platform.fd, res->connectors[i]);
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: Connector modes detected: %i", con->count_modes);
|
||||
|
||||
if ((con->connection == DRM_MODE_CONNECTED) && (con->encoder_id))
|
||||
{
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: DRM mode connected");
|
||||
CORE.Window.connector = con;
|
||||
platform.connector = con;
|
||||
break;
|
||||
}
|
||||
else
|
||||
|
@ -940,14 +1020,14 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
}
|
||||
}
|
||||
|
||||
if (!CORE.Window.connector)
|
||||
if (!platform.connector)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: No suitable DRM connector found");
|
||||
drmModeFreeResources(res);
|
||||
return false;
|
||||
}
|
||||
|
||||
drmModeEncoder *enc = drmModeGetEncoder(CORE.Window.fd, CORE.Window.connector->encoder_id);
|
||||
drmModeEncoder *enc = drmModeGetEncoder(platform.fd, platform.connector->encoder_id);
|
||||
if (!enc)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get DRM mode encoder");
|
||||
|
@ -955,8 +1035,8 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
return false;
|
||||
}
|
||||
|
||||
CORE.Window.crtc = drmModeGetCrtc(CORE.Window.fd, enc->crtc_id);
|
||||
if (!CORE.Window.crtc)
|
||||
platform.crtc = drmModeGetCrtc(platform.fd, enc->crtc_id);
|
||||
if (!platform.crtc)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get DRM mode crtc");
|
||||
drmModeFreeEncoder(enc);
|
||||
|
@ -969,9 +1049,9 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
{
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: Selecting DRM connector mode for current used mode...");
|
||||
|
||||
CORE.Window.modeIndex = FindMatchingConnectorMode(CORE.Window.connector, &CORE.Window.crtc->mode);
|
||||
platform.modeIndex = FindMatchingConnectorMode(platform.connector, &platform.crtc->mode);
|
||||
|
||||
if (CORE.Window.modeIndex < 0)
|
||||
if (platform.modeIndex < 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: No matching DRM connector mode found");
|
||||
drmModeFreeEncoder(enc);
|
||||
|
@ -987,19 +1067,19 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
const int fps = (CORE.Time.target > 0)? (1.0/CORE.Time.target) : 60;
|
||||
|
||||
// Try to find an exact matching mode
|
||||
CORE.Window.modeIndex = FindExactConnectorMode(CORE.Window.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, allowInterlaced);
|
||||
platform.modeIndex = FindExactConnectorMode(platform.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, allowInterlaced);
|
||||
|
||||
// If nothing found, try to find a nearly matching mode
|
||||
if (CORE.Window.modeIndex < 0) CORE.Window.modeIndex = FindNearestConnectorMode(CORE.Window.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, allowInterlaced);
|
||||
if (platform.modeIndex < 0) platform.modeIndex = FindNearestConnectorMode(platform.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, allowInterlaced);
|
||||
|
||||
// If nothing found, try to find an exactly matching mode including interlaced
|
||||
if (CORE.Window.modeIndex < 0) CORE.Window.modeIndex = FindExactConnectorMode(CORE.Window.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, true);
|
||||
if (platform.modeIndex < 0) platform.modeIndex = FindExactConnectorMode(platform.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, true);
|
||||
|
||||
// If nothing found, try to find a nearly matching mode including interlaced
|
||||
if (CORE.Window.modeIndex < 0) CORE.Window.modeIndex = FindNearestConnectorMode(CORE.Window.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, true);
|
||||
if (platform.modeIndex < 0) platform.modeIndex = FindNearestConnectorMode(platform.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, true);
|
||||
|
||||
// If nothing found, there is no suitable mode
|
||||
if (CORE.Window.modeIndex < 0)
|
||||
if (platform.modeIndex < 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to find a suitable DRM connector mode");
|
||||
drmModeFreeEncoder(enc);
|
||||
|
@ -1007,13 +1087,13 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
return false;
|
||||
}
|
||||
|
||||
CORE.Window.display.width = CORE.Window.connector->modes[CORE.Window.modeIndex].hdisplay;
|
||||
CORE.Window.display.height = CORE.Window.connector->modes[CORE.Window.modeIndex].vdisplay;
|
||||
CORE.Window.display.width = platform.connector->modes[platform.modeIndex].hdisplay;
|
||||
CORE.Window.display.height = platform.connector->modes[platform.modeIndex].vdisplay;
|
||||
|
||||
TRACELOG(LOG_INFO, "DISPLAY: Selected DRM connector mode %s (%ux%u%c@%u)", CORE.Window.connector->modes[CORE.Window.modeIndex].name,
|
||||
CORE.Window.connector->modes[CORE.Window.modeIndex].hdisplay, CORE.Window.connector->modes[CORE.Window.modeIndex].vdisplay,
|
||||
(CORE.Window.connector->modes[CORE.Window.modeIndex].flags & DRM_MODE_FLAG_INTERLACE)? 'i' : 'p',
|
||||
CORE.Window.connector->modes[CORE.Window.modeIndex].vrefresh);
|
||||
TRACELOG(LOG_INFO, "DISPLAY: Selected DRM connector mode %s (%ux%u%c@%u)", platform.connector->modes[platform.modeIndex].name,
|
||||
platform.connector->modes[platform.modeIndex].hdisplay, platform.connector->modes[platform.modeIndex].vdisplay,
|
||||
(platform.connector->modes[platform.modeIndex].flags & DRM_MODE_FLAG_INTERLACE)? 'i' : 'p',
|
||||
platform.connector->modes[platform.modeIndex].vrefresh);
|
||||
|
||||
// Use the width and height of the surface for render
|
||||
CORE.Window.render.width = CORE.Window.screen.width;
|
||||
|
@ -1025,16 +1105,16 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
drmModeFreeResources(res);
|
||||
res = NULL;
|
||||
|
||||
CORE.Window.gbmDevice = gbm_create_device(CORE.Window.fd);
|
||||
if (!CORE.Window.gbmDevice)
|
||||
platform.gbmDevice = gbm_create_device(platform.fd);
|
||||
if (!platform.gbmDevice)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create GBM device");
|
||||
return false;
|
||||
}
|
||||
|
||||
CORE.Window.gbmSurface = gbm_surface_create(CORE.Window.gbmDevice, CORE.Window.connector->modes[CORE.Window.modeIndex].hdisplay,
|
||||
CORE.Window.connector->modes[CORE.Window.modeIndex].vdisplay, GBM_FORMAT_ARGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
|
||||
if (!CORE.Window.gbmSurface)
|
||||
platform.gbmSurface = gbm_surface_create(platform.gbmDevice, platform.connector->modes[platform.modeIndex].hdisplay,
|
||||
platform.connector->modes[platform.modeIndex].vdisplay, GBM_FORMAT_ARGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
|
||||
if (!platform.gbmSurface)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create GBM surface");
|
||||
return false;
|
||||
|
@ -1073,22 +1153,22 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
EGLint numConfigs = 0;
|
||||
|
||||
// Get an EGL device connection
|
||||
CORE.Window.device = eglGetDisplay((EGLNativeDisplayType)CORE.Window.gbmDevice);
|
||||
if (CORE.Window.device == EGL_NO_DISPLAY)
|
||||
platform.device = eglGetDisplay((EGLNativeDisplayType)platform.gbmDevice);
|
||||
if (platform.device == EGL_NO_DISPLAY)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Initialize the EGL device connection
|
||||
if (eglInitialize(CORE.Window.device, NULL, NULL) == EGL_FALSE)
|
||||
if (eglInitialize(platform.device, NULL, NULL) == EGL_FALSE)
|
||||
{
|
||||
// If all of the calls to eglInitialize returned EGL_FALSE then an error has occurred.
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!eglChooseConfig(CORE.Window.device, NULL, NULL, 0, &numConfigs))
|
||||
if (!eglChooseConfig(platform.device, NULL, NULL, 0, &numConfigs))
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get EGL config count: 0x%x", eglGetError());
|
||||
return false;
|
||||
|
@ -1104,7 +1184,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
}
|
||||
|
||||
EGLint matchingNumConfigs = 0;
|
||||
if (!eglChooseConfig(CORE.Window.device, framebufferAttribs, configs, numConfigs, &matchingNumConfigs))
|
||||
if (!eglChooseConfig(platform.device, framebufferAttribs, configs, numConfigs, &matchingNumConfigs))
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to choose EGL config: 0x%x", eglGetError());
|
||||
free(configs);
|
||||
|
@ -1118,7 +1198,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
for (EGLint i = 0; i < matchingNumConfigs; ++i)
|
||||
{
|
||||
EGLint id = 0;
|
||||
if (!eglGetConfigAttrib(CORE.Window.device, configs[i], EGL_NATIVE_VISUAL_ID, &id))
|
||||
if (!eglGetConfigAttrib(platform.device, configs[i], EGL_NATIVE_VISUAL_ID, &id))
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get EGL config attribute: 0x%x", eglGetError());
|
||||
continue;
|
||||
|
@ -1127,7 +1207,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
if (GBM_FORMAT_ARGB8888 == id)
|
||||
{
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: Using EGL config: %d", i);
|
||||
CORE.Window.config = configs[i];
|
||||
platform.config = configs[i];
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
@ -1145,8 +1225,8 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
eglBindAPI(EGL_OPENGL_ES_API);
|
||||
|
||||
// Create an EGL rendering context
|
||||
CORE.Window.context = eglCreateContext(CORE.Window.device, CORE.Window.config, EGL_NO_CONTEXT, contextAttribs);
|
||||
if (CORE.Window.context == EGL_NO_CONTEXT)
|
||||
platform.context = eglCreateContext(platform.device, platform.config, EGL_NO_CONTEXT, contextAttribs);
|
||||
if (platform.context == EGL_NO_CONTEXT)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL context");
|
||||
return false;
|
||||
|
@ -1154,8 +1234,8 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
|
||||
// Create an EGL window surface
|
||||
//---------------------------------------------------------------------------------
|
||||
CORE.Window.surface = eglCreateWindowSurface(CORE.Window.device, CORE.Window.config, (EGLNativeWindowType)CORE.Window.gbmSurface, NULL);
|
||||
if (EGL_NO_SURFACE == CORE.Window.surface)
|
||||
platform.surface = eglCreateWindowSurface(platform.device, platform.config, (EGLNativeWindowType)platform.gbmSurface, NULL);
|
||||
if (EGL_NO_SURFACE == platform.surface)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL window surface: 0x%04x", eglGetError());
|
||||
return false;
|
||||
|
@ -1169,9 +1249,9 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);
|
||||
|
||||
// There must be at least one frame displayed before the buffers are swapped
|
||||
//eglSwapInterval(CORE.Window.device, 1);
|
||||
//eglSwapInterval(platform.device, 1);
|
||||
|
||||
if (eglMakeCurrent(CORE.Window.device, CORE.Window.surface, CORE.Window.surface, CORE.Window.context) == EGL_FALSE)
|
||||
if (eglMakeCurrent(platform.device, platform.surface, platform.surface, platform.context) == EGL_FALSE)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to attach EGL rendering context to EGL surface");
|
||||
return false;
|
||||
|
@ -1214,11 +1294,11 @@ static void InitKeyboard(void)
|
|||
// Reading directly from stdin will give chars already key-mapped by kernel to ASCII or UNICODE
|
||||
|
||||
// Save terminal keyboard settings
|
||||
tcgetattr(STDIN_FILENO, &CORE.Input.Keyboard.defaultSettings);
|
||||
tcgetattr(STDIN_FILENO, &platform.defaultSettings);
|
||||
|
||||
// Reconfigure terminal with new settings
|
||||
struct termios keyboardNewSettings = { 0 };
|
||||
keyboardNewSettings = CORE.Input.Keyboard.defaultSettings;
|
||||
keyboardNewSettings = platform.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
|
||||
|
@ -1231,11 +1311,11 @@ static void InitKeyboard(void)
|
|||
tcsetattr(STDIN_FILENO, TCSANOW, &keyboardNewSettings);
|
||||
|
||||
// Save old keyboard mode to restore it at the end
|
||||
CORE.Input.Keyboard.defaultFileFlags = fcntl(STDIN_FILENO, F_GETFL, 0); // F_GETFL: Get the file access mode and the file status flags
|
||||
fcntl(STDIN_FILENO, F_SETFL, CORE.Input.Keyboard.defaultFileFlags | O_NONBLOCK); // F_SETFL: Set the file status flags to the value specified
|
||||
platform.defaultFileFlags = fcntl(STDIN_FILENO, F_GETFL, 0); // F_GETFL: Get the file access mode and the file status flags
|
||||
fcntl(STDIN_FILENO, F_SETFL, platform.defaultFileFlags | O_NONBLOCK); // F_SETFL: Set the file status flags to the value specified
|
||||
|
||||
// NOTE: If ioctl() returns -1, it means the call failed for some reason (error code set in errno)
|
||||
int result = ioctl(STDIN_FILENO, KDGKBMODE, &CORE.Input.Keyboard.defaultMode);
|
||||
int result = ioctl(STDIN_FILENO, KDGKBMODE, &platform.defaultKeyboardMode);
|
||||
|
||||
// In case of failure, it could mean a remote keyboard is used (SSH)
|
||||
if (result < 0) TRACELOG(LOG_WARNING, "RPI: Failed to change keyboard mode, an SSH keyboard is probably used");
|
||||
|
@ -1257,11 +1337,11 @@ static void InitKeyboard(void)
|
|||
static void RestoreKeyboard(void)
|
||||
{
|
||||
// Reset to default keyboard settings
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &CORE.Input.Keyboard.defaultSettings);
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &platform.defaultSettings);
|
||||
|
||||
// Reconfigure keyboard to default mode
|
||||
fcntl(STDIN_FILENO, F_SETFL, CORE.Input.Keyboard.defaultFileFlags);
|
||||
ioctl(STDIN_FILENO, KDSKBMODE, CORE.Input.Keyboard.defaultMode);
|
||||
fcntl(STDIN_FILENO, F_SETFL, platform.defaultFileFlags);
|
||||
ioctl(STDIN_FILENO, KDSKBMODE, platform.defaultKeyboardMode);
|
||||
}
|
||||
|
||||
#if defined(SUPPORT_SSH_KEYBOARD_RPI)
|
||||
|
@ -1389,7 +1469,7 @@ static void InitEvdevInput(void)
|
|||
struct dirent *entity = NULL;
|
||||
|
||||
// Initialise keyboard file descriptor
|
||||
CORE.Input.Keyboard.fd = -1;
|
||||
platform.keyboardFd = -1;
|
||||
|
||||
// Reset variables
|
||||
for (int i = 0; i < MAX_TOUCH_POINTS; ++i)
|
||||
|
@ -1451,9 +1531,9 @@ static void ConfigureEvdevDevice(char *device)
|
|||
// Open the device and allocate worker
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
// Find a free spot in the workers array
|
||||
for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i)
|
||||
for (int i = 0; i < sizeof(platform.eventWorker)/sizeof(InputEventWorker); ++i)
|
||||
{
|
||||
if (CORE.Input.eventWorker[i].threadId == 0)
|
||||
if (platform.eventWorker[i].threadId == 0)
|
||||
{
|
||||
freeWorkerId = i;
|
||||
break;
|
||||
|
@ -1463,7 +1543,7 @@ static void ConfigureEvdevDevice(char *device)
|
|||
// Select the free worker from array
|
||||
if (freeWorkerId >= 0)
|
||||
{
|
||||
worker = &(CORE.Input.eventWorker[freeWorkerId]); // Grab a pointer to the worker
|
||||
worker = &(platform.eventWorker[freeWorkerId]); // Grab a pointer to the worker
|
||||
memset(worker, 0, sizeof(InputEventWorker)); // Clear the worker
|
||||
}
|
||||
else
|
||||
|
@ -1574,13 +1654,13 @@ static void ConfigureEvdevDevice(char *device)
|
|||
|
||||
// Decide what to do with the device
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
if (worker->isKeyboard && (CORE.Input.Keyboard.fd == -1))
|
||||
if (worker->isKeyboard && (platform.keyboardFd == -1))
|
||||
{
|
||||
// Use the first keyboard encountered. This assumes that a device that says it's a keyboard is just a
|
||||
// keyboard. The keyboard is polled synchronously, whereas other input devices are polled in separate
|
||||
// threads so that they don't drop events when the frame rate is slow.
|
||||
TRACELOG(LOG_INFO, "RPI: Opening keyboard device: %s", device);
|
||||
CORE.Input.Keyboard.fd = worker->fd;
|
||||
platform.keyboardFd = worker->fd;
|
||||
}
|
||||
else if (worker->isTouch || worker->isMouse)
|
||||
{
|
||||
|
@ -1604,21 +1684,21 @@ static void ConfigureEvdevDevice(char *device)
|
|||
// Find touchscreen with the highest index
|
||||
int maxTouchNumber = -1;
|
||||
|
||||
for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i)
|
||||
for (int i = 0; i < sizeof(platform.eventWorker)/sizeof(InputEventWorker); ++i)
|
||||
{
|
||||
if (CORE.Input.eventWorker[i].isTouch && (CORE.Input.eventWorker[i].eventNum > maxTouchNumber)) maxTouchNumber = CORE.Input.eventWorker[i].eventNum;
|
||||
if (platform.eventWorker[i].isTouch && (platform.eventWorker[i].eventNum > maxTouchNumber)) maxTouchNumber = platform.eventWorker[i].eventNum;
|
||||
}
|
||||
|
||||
// Find touchscreens with lower indexes
|
||||
for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i)
|
||||
for (int i = 0; i < sizeof(platform.eventWorker)/sizeof(InputEventWorker); ++i)
|
||||
{
|
||||
if (CORE.Input.eventWorker[i].isTouch && (CORE.Input.eventWorker[i].eventNum < maxTouchNumber))
|
||||
if (platform.eventWorker[i].isTouch && (platform.eventWorker[i].eventNum < maxTouchNumber))
|
||||
{
|
||||
if (CORE.Input.eventWorker[i].threadId != 0)
|
||||
if (platform.eventWorker[i].threadId != 0)
|
||||
{
|
||||
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);
|
||||
pthread_cancel(platform.eventWorker[i].threadId);
|
||||
close(platform.eventWorker[i].fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1652,7 +1732,7 @@ static void PollKeyboardEvents(void)
|
|||
243, 244, 245, 246, 247, 248, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
int fd = CORE.Input.Keyboard.fd;
|
||||
int fd = platform.keyboardFd;
|
||||
if (fd == -1) return;
|
||||
|
||||
struct input_event event = { 0 };
|
||||
|
@ -1666,7 +1746,7 @@ static void PollKeyboardEvents(void)
|
|||
{
|
||||
#if defined(SUPPORT_SSH_KEYBOARD_RPI)
|
||||
// Change keyboard mode to events
|
||||
CORE.Input.Keyboard.evtMode = true;
|
||||
platform.eventKeyboardMode = true;
|
||||
#endif
|
||||
// Keyboard button parsing
|
||||
if ((event.code >= 1) && (event.code <= 255)) //Keyboard keys appear for codes 1 to 255
|
||||
|
@ -1739,7 +1819,7 @@ static void *EventThread(void *arg)
|
|||
gestureUpdate = true;
|
||||
}
|
||||
|
||||
if (event.code == REL_WHEEL) CORE.Input.Mouse.eventWheelMove.y += event.value;
|
||||
if (event.code == REL_WHEEL) platform.eventWheelMove.y += event.value;
|
||||
}
|
||||
|
||||
// Absolute movement parsing
|
||||
|
@ -1790,11 +1870,11 @@ static void *EventThread(void *arg)
|
|||
// Touchscreen tap
|
||||
if (event.code == ABS_PRESSURE)
|
||||
{
|
||||
int previousMouseLeftButtonState = CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_BUTTON_LEFT];
|
||||
int previousMouseLeftButtonState = platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT];
|
||||
|
||||
if (!event.value && previousMouseLeftButtonState)
|
||||
{
|
||||
CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 0;
|
||||
platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 0;
|
||||
|
||||
touchAction = 0; // TOUCH_ACTION_UP
|
||||
gestureUpdate = true;
|
||||
|
@ -1802,7 +1882,7 @@ static void *EventThread(void *arg)
|
|||
|
||||
if (event.value && !previousMouseLeftButtonState)
|
||||
{
|
||||
CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 1;
|
||||
platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 1;
|
||||
|
||||
touchAction = 1; // TOUCH_ACTION_DOWN
|
||||
gestureUpdate = true;
|
||||
|
@ -1817,19 +1897,19 @@ static void *EventThread(void *arg)
|
|||
// Mouse button parsing
|
||||
if ((event.code == BTN_TOUCH) || (event.code == BTN_LEFT))
|
||||
{
|
||||
CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = event.value;
|
||||
platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = event.value;
|
||||
|
||||
if (event.value > 0) touchAction = 1; // TOUCH_ACTION_DOWN
|
||||
else touchAction = 0; // TOUCH_ACTION_UP
|
||||
gestureUpdate = true;
|
||||
}
|
||||
|
||||
if (event.code == BTN_RIGHT) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_BUTTON_RIGHT] = event.value;
|
||||
if (event.code == BTN_MIDDLE) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_BUTTON_MIDDLE] = event.value;
|
||||
if (event.code == BTN_SIDE) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_BUTTON_SIDE] = event.value;
|
||||
if (event.code == BTN_EXTRA) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_BUTTON_EXTRA] = event.value;
|
||||
if (event.code == BTN_FORWARD) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_BUTTON_FORWARD] = event.value;
|
||||
if (event.code == BTN_BACK) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_BUTTON_BACK] = event.value;
|
||||
if (event.code == BTN_RIGHT) platform.currentButtonStateEvdev[MOUSE_BUTTON_RIGHT] = event.value;
|
||||
if (event.code == BTN_MIDDLE) platform.currentButtonStateEvdev[MOUSE_BUTTON_MIDDLE] = event.value;
|
||||
if (event.code == BTN_SIDE) platform.currentButtonStateEvdev[MOUSE_BUTTON_SIDE] = event.value;
|
||||
if (event.code == BTN_EXTRA) platform.currentButtonStateEvdev[MOUSE_BUTTON_EXTRA] = event.value;
|
||||
if (event.code == BTN_FORWARD) platform.currentButtonStateEvdev[MOUSE_BUTTON_FORWARD] = event.value;
|
||||
if (event.code == BTN_BACK) platform.currentButtonStateEvdev[MOUSE_BUTTON_BACK] = event.value;
|
||||
}
|
||||
|
||||
// Screen confinement
|
||||
|
@ -1885,7 +1965,7 @@ static void InitGamepad(void)
|
|||
{
|
||||
sprintf(gamepadDev, "%s%i", DEFAULT_GAMEPAD_DEV, i);
|
||||
|
||||
if ((CORE.Input.Gamepad.streamId[i] = open(gamepadDev, O_RDONLY | O_NONBLOCK)) < 0)
|
||||
if ((platform.gamepadStreamFd[i] = open(gamepadDev, O_RDONLY | O_NONBLOCK)) < 0)
|
||||
{
|
||||
// NOTE: Only show message for first gamepad
|
||||
if (i == 0) TRACELOG(LOG_WARNING, "RPI: Failed to open Gamepad device, no gamepad available");
|
||||
|
@ -1897,7 +1977,7 @@ static void InitGamepad(void)
|
|||
// NOTE: Only create one thread
|
||||
if (i == 0)
|
||||
{
|
||||
int error = pthread_create(&CORE.Input.Gamepad.threadId, NULL, &GamepadThread, NULL);
|
||||
int error = pthread_create(&platform.gamepadThreadId, NULL, &GamepadThread, NULL);
|
||||
|
||||
if (error != 0) TRACELOG(LOG_WARNING, "RPI: Failed to create gamepad input event thread");
|
||||
else TRACELOG(LOG_INFO, "RPI: Gamepad device initialized successfully");
|
||||
|
@ -1927,7 +2007,7 @@ static void *GamepadThread(void *arg)
|
|||
{
|
||||
for (int i = 0; i < MAX_GAMEPADS; i++)
|
||||
{
|
||||
if (read(CORE.Input.Gamepad.streamId[i], &gamepadEvent, sizeof(struct js_event)) == (int)sizeof(struct js_event))
|
||||
if (read(platform.gamepadStreamFd[i], &gamepadEvent, sizeof(struct js_event)) == (int)sizeof(struct js_event))
|
||||
{
|
||||
gamepadEvent.type &= ~JS_EVENT_INIT; // Ignore synthetic events
|
||||
|
||||
|
@ -1977,7 +2057,7 @@ static int FindMatchingConnectorMode(const drmModeConnector *connector, const dr
|
|||
TRACELOG(LOG_TRACE, "DISPLAY: DRM mode: %d %ux%u@%u %s", i, connector->modes[i].hdisplay, connector->modes[i].vdisplay,
|
||||
connector->modes[i].vrefresh, (connector->modes[i].flags & DRM_MODE_FLAG_INTERLACE)? "interlaced" : "progressive");
|
||||
|
||||
if (0 == BINCMP(&CORE.Window.crtc->mode, &CORE.Window.connector->modes[i])) return i;
|
||||
if (0 == BINCMP(&platform.crtc->mode, &platform.connector->modes[i])) return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
@ -1992,9 +2072,9 @@ static int FindExactConnectorMode(const drmModeConnector *connector, uint width,
|
|||
|
||||
if (NULL == connector) return -1;
|
||||
|
||||
for (int i = 0; i < CORE.Window.connector->count_modes; i++)
|
||||
for (int i = 0; i < platform.connector->count_modes; i++)
|
||||
{
|
||||
const drmModeModeInfo *const mode = &CORE.Window.connector->modes[i];
|
||||
const drmModeModeInfo *const mode = &platform.connector->modes[i];
|
||||
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: DRM Mode %d %ux%u@%u %s", i, mode->hdisplay, mode->vdisplay, mode->vrefresh, (mode->flags & DRM_MODE_FLAG_INTERLACE)? "interlaced" : "progressive");
|
||||
|
||||
|
@ -2015,9 +2095,9 @@ static int FindNearestConnectorMode(const drmModeConnector *connector, uint widt
|
|||
if (NULL == connector) return -1;
|
||||
|
||||
int nearestIndex = -1;
|
||||
for (int i = 0; i < CORE.Window.connector->count_modes; i++)
|
||||
for (int i = 0; i < platform.connector->count_modes; i++)
|
||||
{
|
||||
const drmModeModeInfo *const mode = &CORE.Window.connector->modes[i];
|
||||
const drmModeModeInfo *const mode = &platform.connector->modes[i];
|
||||
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: DRM mode: %d %ux%u@%u %s", i, mode->hdisplay, mode->vdisplay, mode->vrefresh,
|
||||
(mode->flags & DRM_MODE_FLAG_INTERLACE)? "interlaced" : "progressive");
|
||||
|
@ -2044,9 +2124,9 @@ static int FindNearestConnectorMode(const drmModeConnector *connector, uint widt
|
|||
const int heightDiff = abs(mode->vdisplay - height);
|
||||
const int fpsDiff = abs(mode->vrefresh - fps);
|
||||
|
||||
const int nearestWidthDiff = abs(CORE.Window.connector->modes[nearestIndex].hdisplay - width);
|
||||
const int nearestHeightDiff = abs(CORE.Window.connector->modes[nearestIndex].vdisplay - height);
|
||||
const int nearestFpsDiff = abs(CORE.Window.connector->modes[nearestIndex].vrefresh - fps);
|
||||
const int nearestWidthDiff = abs(platform.connector->modes[nearestIndex].hdisplay - width);
|
||||
const int nearestHeightDiff = abs(platform.connector->modes[nearestIndex].vdisplay - height);
|
||||
const int nearestFpsDiff = abs(platform.connector->modes[nearestIndex].vrefresh - fps);
|
||||
|
||||
if ((widthDiff < nearestWidthDiff) || (heightDiff < nearestHeightDiff) || (fpsDiff < nearestFpsDiff)) {
|
||||
nearestIndex = i;
|
||||
|
|
|
@ -50,21 +50,40 @@
|
|||
#define GLFW_INCLUDE_ES2 // GLFW3: Enable OpenGL ES 2.0 (translated to WebGL)
|
||||
// #define GLFW_INCLUDE_ES3 // GLFW3: Enable OpenGL ES 3.0 (transalted to WebGL2?)
|
||||
#include "GLFW/glfw3.h" // GLFW3: Windows, OpenGL context and Input management
|
||||
#include <sys/time.h> // Required for: timespec, nanosleep(), select() - POSIX
|
||||
|
||||
#include <emscripten/emscripten.h> // Emscripten functionality for C
|
||||
#include <emscripten/html5.h> // Emscripten HTML5 library
|
||||
|
||||
#include <sys/time.h> // Required for: timespec, nanosleep(), select() - POSIX
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
// TODO: HACK: Added flag if not provided by GLFW when using external library
|
||||
// Latest GLFW release (GLFW 3.3.8) does not implement this flag, it was added for 3.4.0-dev
|
||||
#if !defined(GLFW_MOUSE_PASSTHROUGH)
|
||||
#define GLFW_MOUSE_PASSTHROUGH 0x0002000D
|
||||
#endif
|
||||
|
||||
#if (_POSIX_C_SOURCE < 199309L)
|
||||
#undef _POSIX_C_SOURCE
|
||||
#define _POSIX_C_SOURCE 199309L // Required for: CLOCK_MONOTONIC if compiled with c99 without gnu ext.
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
//...
|
||||
typedef struct {
|
||||
GLFWwindow *handle; // GLFW window handle (graphic device)
|
||||
} PlatformData;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
extern CoreData CORE; // Global CORE state context
|
||||
|
||||
static PlatformData platform = { 0 }; // Platform specific data
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Internal Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
|
@ -263,7 +282,7 @@ void CloseWindow(void)
|
|||
|
||||
rlglClose(); // De-init rlgl
|
||||
|
||||
glfwDestroyWindow(CORE.Window.handle);
|
||||
glfwDestroyWindow(platform.handle);
|
||||
glfwTerminate();
|
||||
|
||||
#if defined(_WIN32) && defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP)
|
||||
|
@ -481,7 +500,7 @@ void SetWindowMaxSize(int width, int height)
|
|||
// Set window dimensions
|
||||
void SetWindowSize(int width, int height)
|
||||
{
|
||||
glfwSetWindowSize(CORE.Window.handle, width, height);
|
||||
glfwSetWindowSize(platform.handle, width, height);
|
||||
}
|
||||
|
||||
// Set window opacity, value opacity is between 0.0 and 1.0
|
||||
|
@ -759,7 +778,7 @@ void SetMousePosition(int x, int y)
|
|||
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
|
||||
|
||||
// NOTE: emscripten not implemented
|
||||
glfwSetCursorPos(CORE.Window.handle, CORE.Input.Mouse.currentPosition.x, CORE.Input.Mouse.currentPosition.y);
|
||||
glfwSetCursorPos(platform.handle, CORE.Input.Mouse.currentPosition.x, CORE.Input.Mouse.currentPosition.y);
|
||||
}
|
||||
|
||||
// Get mouse wheel movement Y
|
||||
|
@ -806,7 +825,7 @@ Vector2 GetTouchPosition(int index)
|
|||
// Swap back buffer with front buffer (screen drawing)
|
||||
void SwapScreenBuffer(void)
|
||||
{
|
||||
glfwSwapBuffers(CORE.Window.handle);
|
||||
glfwSwapBuffers(platform.handle);
|
||||
}
|
||||
|
||||
// Register all input events
|
||||
|
@ -1110,24 +1129,24 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
// HighDPI monitors are properly considered in a following similar function: SetupViewport()
|
||||
SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);
|
||||
|
||||
CORE.Window.handle = glfwCreateWindow(CORE.Window.display.width, CORE.Window.display.height, (CORE.Window.title != 0)? CORE.Window.title : " ", glfwGetPrimaryMonitor(), NULL);
|
||||
platform.handle = glfwCreateWindow(CORE.Window.display.width, CORE.Window.display.height, (CORE.Window.title != 0)? CORE.Window.title : " ", glfwGetPrimaryMonitor(), NULL);
|
||||
|
||||
// NOTE: Full-screen change, not working properly...
|
||||
// glfwSetWindowMonitor(CORE.Window.handle, glfwGetPrimaryMonitor(), 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
|
||||
// glfwSetWindowMonitor(platform.handle, glfwGetPrimaryMonitor(), 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No-fullscreen window creation
|
||||
CORE.Window.handle = glfwCreateWindow(CORE.Window.screen.width, CORE.Window.screen.height, (CORE.Window.title != 0)? CORE.Window.title : " ", NULL, NULL);
|
||||
platform.handle = glfwCreateWindow(CORE.Window.screen.width, CORE.Window.screen.height, (CORE.Window.title != 0)? CORE.Window.title : " ", NULL, NULL);
|
||||
|
||||
if (CORE.Window.handle)
|
||||
if (platform.handle)
|
||||
{
|
||||
CORE.Window.render.width = CORE.Window.screen.width;
|
||||
CORE.Window.render.height = CORE.Window.screen.height;
|
||||
}
|
||||
}
|
||||
|
||||
if (!CORE.Window.handle)
|
||||
if (!platform.handle)
|
||||
{
|
||||
glfwTerminate();
|
||||
TRACELOG(LOG_WARNING, "GLFW: Failed to initialize Window");
|
||||
|
@ -1138,20 +1157,20 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
emscripten_set_window_title((CORE.Window.title != 0)? CORE.Window.title : " ");
|
||||
|
||||
// Set window callback events
|
||||
glfwSetWindowSizeCallback(CORE.Window.handle, WindowSizeCallback); // NOTE: Resizing not allowed by default!
|
||||
glfwSetWindowIconifyCallback(CORE.Window.handle, WindowIconifyCallback);
|
||||
glfwSetWindowFocusCallback(CORE.Window.handle, WindowFocusCallback);
|
||||
glfwSetDropCallback(CORE.Window.handle, WindowDropCallback);
|
||||
glfwSetWindowSizeCallback(platform.handle, WindowSizeCallback); // NOTE: Resizing not allowed by default!
|
||||
glfwSetWindowIconifyCallback(platform.handle, WindowIconifyCallback);
|
||||
glfwSetWindowFocusCallback(platform.handle, WindowFocusCallback);
|
||||
glfwSetDropCallback(platform.handle, WindowDropCallback);
|
||||
|
||||
// Set input callback events
|
||||
glfwSetKeyCallback(CORE.Window.handle, KeyCallback);
|
||||
glfwSetCharCallback(CORE.Window.handle, CharCallback);
|
||||
glfwSetMouseButtonCallback(CORE.Window.handle, MouseButtonCallback);
|
||||
glfwSetCursorPosCallback(CORE.Window.handle, MouseCursorPosCallback); // Track mouse position changes
|
||||
glfwSetScrollCallback(CORE.Window.handle, MouseScrollCallback);
|
||||
glfwSetCursorEnterCallback(CORE.Window.handle, CursorEnterCallback);
|
||||
glfwSetKeyCallback(platform.handle, KeyCallback);
|
||||
glfwSetCharCallback(platform.handle, CharCallback);
|
||||
glfwSetMouseButtonCallback(platform.handle, MouseButtonCallback);
|
||||
glfwSetCursorPosCallback(platform.handle, MouseCursorPosCallback); // Track mouse position changes
|
||||
glfwSetScrollCallback(platform.handle, MouseScrollCallback);
|
||||
glfwSetCursorEnterCallback(platform.handle, CursorEnterCallback);
|
||||
|
||||
glfwMakeContextCurrent(CORE.Window.handle);
|
||||
glfwMakeContextCurrent(platform.handle);
|
||||
|
||||
// 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, it doesn't need
|
||||
|
@ -1293,7 +1312,7 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
|
|||
}
|
||||
|
||||
// Check the exit key to set close window
|
||||
if ((key == CORE.Input.Keyboard.exitKey) && (action == GLFW_PRESS)) glfwSetWindowShouldClose(CORE.Window.handle, GLFW_TRUE);
|
||||
if ((key == CORE.Input.Keyboard.exitKey) && (action == GLFW_PRESS)) glfwSetWindowShouldClose(platform.handle, GLFW_TRUE);
|
||||
|
||||
#if defined(SUPPORT_SCREEN_CAPTURE)
|
||||
if ((key == GLFW_KEY_F12) && (action == GLFW_PRESS))
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include <android/asset_manager.h> // Required for: AAssetManager
|
||||
#endif
|
||||
|
||||
#if defined(SUPPORT_TRACELOG)
|
||||
#if defined(SUPPORT_TRACELOG) && !defined(TRACELOG)
|
||||
#define TRACELOG(level, ...) TraceLog(level, __VA_ARGS__)
|
||||
|
||||
#if defined(SUPPORT_TRACELOG_DEBUG)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue