summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorRay <[email protected]>2023-10-14 12:49:54 +0200
committerRay <[email protected]>2023-10-14 12:49:54 +0200
commitb34c2ecbcb9da1d438b70acf8125ef5424744d11 (patch)
tree09c56fbad54fa55c1686616b49d64116d6d61a38 /src
parent4521a142c35fe9fe1386d79ae783363c9c164827 (diff)
downloadraylib-b34c2ecbcb9da1d438b70acf8125ef5424744d11.tar.gz
raylib-b34c2ecbcb9da1d438b70acf8125ef5424744d11.zip
WARNING: REDESIGN: `InitPlatform()` to initialize all platform data #3313
`InitGraphicsDevice()` could be confusing because the function actually initialized many things: window, graphics, inputs, callbacks, timming, storage... restructured it.
Diffstat (limited to 'src')
-rw-r--r--src/rcore.c8
-rw-r--r--src/rcore_android.c279
-rw-r--r--src/rcore_desktop.c144
-rw-r--r--src/rcore_drm.c352
-rw-r--r--src/rcore_template.c71
-rw-r--r--src/rcore_web.c198
6 files changed, 505 insertions, 547 deletions
diff --git a/src/rcore.c b/src/rcore.c
index d7aaa30b..e6015b33 100644
--- a/src/rcore.c
+++ b/src/rcore.c
@@ -2365,10 +2365,10 @@ int GetTouchPointCount(void)
// Initialize hi-resolution timer
void InitTimer(void)
{
-// Setting a higher resolution can improve the accuracy of time-out intervals in wait functions.
-// However, it can also reduce overall system performance, because the thread scheduler switches tasks more often.
-// High resolutions can also prevent the CPU power management system from entering power-saving modes.
-// Setting a higher resolution does not improve the accuracy of the high-resolution performance counter.
+ // Setting a higher resolution can improve the accuracy of time-out intervals in wait functions.
+ // However, it can also reduce overall system performance, because the thread scheduler switches tasks more often.
+ // High resolutions can also prevent the CPU power management system from entering power-saving modes.
+ // Setting a higher resolution does not improve the accuracy of the high-resolution performance counter.
#if defined(_WIN32) && defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP)
timeBeginPeriod(1); // Setup high-resolution timer to 1ms (granularity of 1-2 ms)
#endif
diff --git a/src/rcore_android.c b/src/rcore_android.c
index 3d9fab06..3e3b8cd1 100644
--- a/src/rcore_android.c
+++ b/src/rcore_android.c
@@ -82,7 +82,8 @@ static PlatformData platform = { 0 }; // Platform specific data
//----------------------------------------------------------------------------------
// Module Internal Functions Declaration
//----------------------------------------------------------------------------------
-static bool InitGraphicsDevice(int width, int height); // Initialize graphics device
+static int InitPlatform(void); // Initialize platform (graphics, inputs and more)
+static void ClosePlatform(void); // Close platform
static void AndroidCommandCallback(struct android_app *app, int32_t cmd); // Process Android activity lifecycle commands
static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event); // Process Android inputs
@@ -172,88 +173,23 @@ void InitWindow(int width, int height, const char *title)
TRACELOG(LOG_INFO, " > raudio:.... not loaded (optional)");
#endif
- // NOTE: Keep internal pointer to input title string (no copy)
+ // Initialize window data
+ CORE.Window.screen.width = width;
+ CORE.Window.screen.height = height;
+ CORE.Window.eventWaiting = false;
+ CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default
if ((title != NULL) && (title[0] != 0)) CORE.Window.title = title;
// Initialize global input state
- memset(&CORE.Input, 0, sizeof(CORE.Input));
+ memset(&CORE.Input, 0, sizeof(CORE.Input)); // Reset CORE.Input structure to 0
CORE.Input.Keyboard.exitKey = KEY_ESCAPE;
CORE.Input.Mouse.scale = (Vector2){ 1.0f, 1.0f };
CORE.Input.Mouse.cursor = MOUSE_CURSOR_ARROW;
- CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN
- CORE.Window.eventWaiting = false;
-
-
- // Platform specific init window
- //--------------------------------------------------------------
- CORE.Window.screen.width = width;
- CORE.Window.screen.height = height;
- CORE.Window.currentFbo.width = width;
- CORE.Window.currentFbo.height = height;
-
- // Set desired windows flags before initializing anything
- ANativeActivity_setWindowFlags(platform.app->activity, AWINDOW_FLAG_FULLSCREEN, 0); //AWINDOW_FLAG_SCALED, AWINDOW_FLAG_DITHER
-
- 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");
-
- // TODO: Automatic orientation doesn't seem to work
- if (width <= height)
- {
- AConfiguration_setOrientation(platform.app->config, ACONFIGURATION_ORIENTATION_PORT);
- TRACELOG(LOG_WARNING, "ANDROID: Window orientation changed to portrait");
- }
- else
- {
- AConfiguration_setOrientation(platform.app->config, ACONFIGURATION_ORIENTATION_LAND);
- TRACELOG(LOG_WARNING, "ANDROID: Window orientation changed to landscape");
- }
-
- //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()...
- platform.app->onAppCmd = AndroidCommandCallback;
-
- // Initialize input events system
- platform.app->onInputEvent = AndroidInputCallback;
-
- // Initialize assets manager
- InitAssetManager(platform.app->activity->assetManager, platform.app->activity->internalDataPath);
-
- // Initialize base path for storage
- CORE.Storage.basePath = platform.app->activity->internalDataPath;
-
- // Set some default window flags
- CORE.Window.flags &= ~FLAG_WINDOW_HIDDEN; // false
- CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED; // false
- CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; // true
- CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; // false
+ CORE.Input.Gamepad.lastButtonPressed = GAMEPAD_BUTTON_UNKNOWN;
- TRACELOG(LOG_INFO, "PLATFORM: ANDROID: Application initialized successfully");
-
- // Android ALooper_pollAll() variables
- int pollResult = 0;
- int pollEvents = 0;
-
- // Wait for window to be initialized (display and context)
- while (!CORE.Window.ready)
- {
- // Process events loop
- while ((pollResult = ALooper_pollAll(0, NULL, &pollEvents, (void**)&platform.source)) >= 0)
- {
- // Process this event
- if (platform.source != NULL) platform.source->process(platform.app, platform.source);
-
- // NOTE: Never close window, native activity is controlled by the system!
- //if (platform.app->destroyRequested != 0) CORE.Window.shouldClose = true;
- }
- }
+ // Initialize platform
+ //--------------------------------------------------------------
+ InitPlatform();
//--------------------------------------------------------------
}
@@ -279,28 +215,9 @@ void CloseWindow(void)
timeEndPeriod(1); // Restore time period
#endif
- // Platform specific close window
- //--------------------------------------------------------------
- // Close surface, context and display
- if (platform.device != EGL_NO_DISPLAY)
- {
- eglMakeCurrent(platform.device, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-
- if (platform.surface != EGL_NO_SURFACE)
- {
- eglDestroySurface(platform.device, platform.surface);
- platform.surface = EGL_NO_SURFACE;
- }
-
- if (platform.context != EGL_NO_CONTEXT)
- {
- eglDestroyContext(platform.device, platform.context);
- platform.context = EGL_NO_CONTEXT;
- }
-
- eglTerminate(platform.device);
- platform.device = EGL_NO_DISPLAY;
- }
+ // De-initialize platform
+ //--------------------------------------------------------------
+ ClosePlatform();
//--------------------------------------------------------------
#if defined(SUPPORT_EVENTS_AUTOMATION)
@@ -690,25 +607,108 @@ void PollInputEvents(void)
// Module Internal Functions Definition
//----------------------------------------------------------------------------------
+// Initialize platform: graphics, inputs and more
+static int InitPlatform(void)
+{
+ CORE.Window.currentFbo.width = CORE.Window.screen.width;
+ CORE.Window.currentFbo.height = CORE.Window.screen.width;
+
+ // Set desired windows flags before initializing anything
+ ANativeActivity_setWindowFlags(platform.app->activity, AWINDOW_FLAG_FULLSCREEN, 0); //AWINDOW_FLAG_SCALED, AWINDOW_FLAG_DITHER
+
+ 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");
+
+ // TODO: Automatic orientation doesn't seem to work
+ if (width <= height)
+ {
+ AConfiguration_setOrientation(platform.app->config, ACONFIGURATION_ORIENTATION_PORT);
+ TRACELOG(LOG_WARNING, "ANDROID: Window orientation changed to portrait");
+ }
+ else
+ {
+ AConfiguration_setOrientation(platform.app->config, ACONFIGURATION_ORIENTATION_LAND);
+ TRACELOG(LOG_WARNING, "ANDROID: Window orientation changed to landscape");
+ }
+
+ //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()...
+ platform.app->onAppCmd = AndroidCommandCallback;
+
+ // Initialize input events system
+ platform.app->onInputEvent = AndroidInputCallback;
+
+ // Initialize assets manager
+ InitAssetManager(platform.app->activity->assetManager, platform.app->activity->internalDataPath);
+
+ // Initialize base path for storage
+ CORE.Storage.basePath = platform.app->activity->internalDataPath;
+
+ // Set some default window flags
+ CORE.Window.flags &= ~FLAG_WINDOW_HIDDEN; // false
+ CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED; // false
+ CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; // true
+ CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; // false
+
+ TRACELOG(LOG_INFO, "PLATFORM: ANDROID: Application initialized successfully");
+
+ // Android ALooper_pollAll() variables
+ int pollResult = 0;
+ int pollEvents = 0;
+
+ // Wait for window to be initialized (display and context)
+ while (!CORE.Window.ready)
+ {
+ // Process events loop
+ while ((pollResult = ALooper_pollAll(0, NULL, &pollEvents, (void**)&platform.source)) >= 0)
+ {
+ // Process this event
+ if (platform.source != NULL) platform.source->process(platform.app, platform.source);
+
+ // NOTE: Never close window, native activity is controlled by the system!
+ //if (platform.app->destroyRequested != 0) CORE.Window.shouldClose = true;
+ }
+ }
+}
+
+// Close platform
+static void ClosePlatform(void)
+{
+ // Close surface, context and display
+ if (platform.device != EGL_NO_DISPLAY)
+ {
+ eglMakeCurrent(platform.device, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+ if (platform.surface != EGL_NO_SURFACE)
+ {
+ eglDestroySurface(platform.device, platform.surface);
+ platform.surface = EGL_NO_SURFACE;
+ }
+
+ if (platform.context != EGL_NO_CONTEXT)
+ {
+ eglDestroyContext(platform.device, platform.context);
+ platform.context = EGL_NO_CONTEXT;
+ }
+
+ eglTerminate(platform.device);
+ platform.device = EGL_NO_DISPLAY;
+ }
+}
+
// Initialize display device and framebuffer
// NOTE: width and height represent the screen (framebuffer) desired size, not actual display size
// If width or height are 0, default display size will be used for framebuffer size
// NOTE: returns false in case graphic device could not be created
-static bool InitGraphicsDevice(int width, int height)
+static bool InitGraphicsDevice(void)
{
- CORE.Window.screen.width = width; // User desired width
- CORE.Window.screen.height = height; // User desired height
- CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default
-
- // Set the screen minimum and maximum default values to 0
- CORE.Window.screenMin.width = 0;
- CORE.Window.screenMin.height = 0;
- CORE.Window.screenMax.width = 0;
- CORE.Window.screenMax.height = 0;
-
- // NOTE: Framebuffer (render area - CORE.Window.render.width, CORE.Window.render.height) could include black bars...
- // ...in top-down or left-right to match display aspect ratio (no weird scaling)
-
CORE.Window.fullscreen = true;
CORE.Window.flags |= FLAG_FULLSCREEN_MODE;
@@ -748,7 +748,7 @@ static bool InitGraphicsDevice(int width, int height)
if (platform.device == EGL_NO_DISPLAY)
{
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
- return false;
+ return -1;
}
// Initialize the EGL device connection
@@ -756,7 +756,7 @@ static bool InitGraphicsDevice(int width, int height)
{
// 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;
+ return -1;
}
// Get an appropriate EGL framebuffer configuration
@@ -770,7 +770,7 @@ static bool InitGraphicsDevice(int width, int height)
if (platform.context == EGL_NO_CONTEXT)
{
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL context");
- return false;
+ return -1;
}
// Create an EGL window surface
@@ -799,7 +799,7 @@ static bool InitGraphicsDevice(int width, int height)
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;
+ return -1;
}
else
{
@@ -819,19 +819,11 @@ static bool InitGraphicsDevice(int width, int height)
// NOTE: GL procedures address loader is required to load extensions
rlLoadExtensions(eglGetProcAddress);
- // Initialize OpenGL context (states and resources)
- // NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl
- rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
-
- // Setup default viewport
- // NOTE: It updated CORE.Window.render.width and CORE.Window.render.height
- SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
-
CORE.Window.ready = true;
if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow();
- return true;
+ return 0;
}
// ANDROID: Process activity lifecycle commands
@@ -874,24 +866,49 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
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);
+ InitGraphicsDevice();
+
+ // Initialize OpenGL context (states and resources)
+ // NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl
+ rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
+
+ // Setup default viewport
+ // NOTE: It updated CORE.Window.render.width and CORE.Window.render.height
+ SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
// Initialize hi-res timer
InitTimer();
- // Initialize random seed
- srand((unsigned int)time(NULL));
-
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
// Load default font
// WARNING: External function: Module required: rtext
LoadFontDefault();
+ #if defined(SUPPORT_MODULE_RSHAPES)
+ // Set font white rectangle for shapes drawing, so shapes and text can be batched together
+ // WARNING: rshapes module is required, if not available, default internal white rectangle is used
Rectangle rec = GetFontDefault().recs[95];
- // NOTE: We setup a 1px padding on char rectangle to avoid pixel bleeding on MSAA filtering
+ if (CORE.Window.flags & FLAG_MSAA_4X_HINT)
+ {
+ // NOTE: We try to maxime rec padding to avoid pixel bleeding on MSAA filtering
+ SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 2, rec.y + 2, 1, 1 });
+ }
+ else
+ {
+ // NOTE: We set up a 1px padding on char rectangle to avoid pixel bleeding
+ SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2 });
+ }
+ #endif
+ #else
#if defined(SUPPORT_MODULE_RSHAPES)
- SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2 }); // WARNING: Module required: rshapes
+ // Set default texture and rectangle to be used for shapes drawing
+ // NOTE: rlgl default texture is a 1x1 pixel UNCOMPRESSED_R8G8B8A8
+ Texture2D texture = { rlGetTextureIdDefault(), 1, 1, 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 };
+ SetShapesTexture(texture, (Rectangle){ 0.0f, 0.0f, 1.0f, 1.0f }); // WARNING: Module required: rshapes
#endif
#endif
+
+ // Initialize random seed
+ SetRandomSeed((unsigned int)time(NULL));
// TODO: GPU assets reload in case of lost focus (lost context)
// NOTE: This problem has been solved just unbinding and rebinding context from display
diff --git a/src/rcore_desktop.c b/src/rcore_desktop.c
index 8fa1edd7..81da488e 100644
--- a/src/rcore_desktop.c
+++ b/src/rcore_desktop.c
@@ -111,7 +111,8 @@ static PlatformData platform = { 0 }; // Platform specific data
//----------------------------------------------------------------------------------
// Module Internal Functions Declaration
//----------------------------------------------------------------------------------
-static bool InitGraphicsDevice(int width, int height); // Initialize graphics device
+static int InitPlatform(void); // Initialize platform (graphics, inputs and more)
+static void ClosePlatform(void); // Close platform
// Error callback event
static void ErrorCallback(int error, const char *description); // GLFW3 Error Callback, runs on GLFW3 error
@@ -176,53 +177,31 @@ void InitWindow(int width, int height, const char *title)
TRACELOG(LOG_INFO, " > raudio:.... not loaded (optional)");
#endif
- // NOTE: Keep internal pointer to input title string (no copy)
+ // Initialize window data
+ CORE.Window.screen.width = width;
+ CORE.Window.screen.height = height;
+ CORE.Window.eventWaiting = false;
+ CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default
if ((title != NULL) && (title[0] != 0)) CORE.Window.title = title;
// Initialize global input state
- memset(&CORE.Input, 0, sizeof(CORE.Input)); // Reset CORE structure to 0
+ memset(&CORE.Input, 0, sizeof(CORE.Input)); // Reset CORE.Input structure to 0
CORE.Input.Keyboard.exitKey = KEY_ESCAPE;
CORE.Input.Mouse.scale = (Vector2){ 1.0f, 1.0f };
CORE.Input.Mouse.cursor = MOUSE_CURSOR_ARROW;
- CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN
- CORE.Window.eventWaiting = false;
-
-
- // Platform specific init window
- //--------------------------------------------------------------
- glfwSetErrorCallback(ErrorCallback);
-/*
- // TODO: Setup GLFW custom allocators to match raylib ones
- const GLFWallocator allocator = {
- .allocate = MemAlloc,
- .deallocate = MemFree,
- .reallocate = MemRealloc,
- .user = NULL
- };
-
- glfwInitAllocator(&allocator);
-*/
-
- // Initialize graphics device
- // NOTE: returns true if window and graphic device has been initialized successfully
- // WARNING: Actually, all window initialization and input callbacks initialization is
- // done inside InitGraphicsDevice(), this functionality should be changed!
- CORE.Window.ready = InitGraphicsDevice(width, height);
-
- // If graphic device is no properly initialized, we end program
- if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return; }
- else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor())/2 - CORE.Window.screen.width/2, GetMonitorHeight(GetCurrentMonitor())/2 - CORE.Window.screen.height/2);
-
- // Initialize hi-res timer
- InitTimer();
+ CORE.Input.Gamepad.lastButtonPressed = GAMEPAD_BUTTON_UNKNOWN;
- // Initialize base path for storage
- CORE.Storage.basePath = GetWorkingDirectory();
+ // Initialize platform
+ //--------------------------------------------------------------
+ InitPlatform();
//--------------------------------------------------------------
+
+ // Initialize rlgl default data (buffers and shaders)
+ // NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl
+ rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
-
- // Initialize random seed
- SetRandomSeed((unsigned int)time(NULL));
+ // Setup default viewport
+ SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
// Load default font
@@ -266,6 +245,9 @@ void InitWindow(int width, int height, const char *title)
CORE.Time.frameCounter = 0;
#endif
+ // Initialize random seed
+ SetRandomSeed((unsigned int)time(NULL));
+
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP: Application initialized successfully");
}
@@ -287,14 +269,9 @@ void CloseWindow(void)
rlglClose(); // De-init rlgl
- // Platform specific close window
- //--------------------------------------------------------------
- glfwDestroyWindow(platform.handle);
- glfwTerminate();
-
-#if defined(_WIN32) && defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP)
- timeEndPeriod(1); // Restore time period
-#endif
+ // De-initialize platform
+ //--------------------------------------------------------------
+ ClosePlatform();
//--------------------------------------------------------------
#if defined(SUPPORT_EVENTS_AUTOMATION)
@@ -1379,34 +1356,28 @@ void PollInputEvents(void)
// Module Internal Functions Definition
//----------------------------------------------------------------------------------
-// Initialize display device and framebuffer
-// NOTE: width and height represent the screen (framebuffer) desired size, not actual display size
-// If width or height are 0, default display size will be used for framebuffer size
-// NOTE: returns false in case graphic device could not be created
-static bool InitGraphicsDevice(int width, int height)
+// Initialize platform: graphics, inputs and more
+static int InitPlatform(void)
{
- CORE.Window.screen.width = width; // User desired width
- CORE.Window.screen.height = height; // User desired height
- CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default
-
- // Set the screen minimum and maximum default values to 0
- CORE.Window.screenMin.width = 0;
- CORE.Window.screenMin.height = 0;
- CORE.Window.screenMax.width = 0;
- CORE.Window.screenMax.height = 0;
+ glfwSetErrorCallback(ErrorCallback);
+/*
+ // TODO: Setup GLFW custom allocators to match raylib ones
+ const GLFWallocator allocator = {
+ .allocate = MemAlloc,
+ .deallocate = MemFree,
+ .reallocate = MemRealloc,
+ .user = NULL
+ };
- // NOTE: Framebuffer (render area - CORE.Window.render.width, CORE.Window.render.height) could include black bars...
- // ...in top-down or left-right to match display aspect ratio (no weird scaling)
+ glfwInitAllocator(&allocator);
+*/
#if defined(__APPLE__)
glfwInitHint(GLFW_COCOA_CHDIR_RESOURCES, GLFW_FALSE);
#endif
-
- if (!glfwInit())
- {
- TRACELOG(LOG_WARNING, "GLFW: Failed to initialize GLFW");
- return false;
- }
+ // Initialize GLFW internal global state
+ int result = glfwInit();
+ if (result == GLFW_FALSE) { TRACELOG(LOG_WARNING, "GLFW: Failed to initialize GLFW"); return -1; }
glfwDefaultWindowHints(); // Set default windows hints
//glfwWindowHint(GLFW_RED_BITS, 8); // Framebuffer red color component bits
@@ -1528,7 +1499,7 @@ static bool InitGraphicsDevice(int width, int height)
if (!monitor)
{
TRACELOG(LOG_WARNING, "GLFW: Failed to get primary monitor");
- return false;
+ return -1;
}
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
@@ -1617,7 +1588,7 @@ static bool InitGraphicsDevice(int width, int height)
{
glfwTerminate();
TRACELOG(LOG_WARNING, "GLFW: Failed to initialize Window");
- return false;
+ return -1;
}
// Set window callback events
@@ -1683,22 +1654,35 @@ static bool InitGraphicsDevice(int width, int height)
// Load OpenGL extensions
// NOTE: GL procedures address loader is required to load extensions
-
rlLoadExtensions(glfwGetProcAddress);
- // Initialize OpenGL context (states and resources)
- // NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl
- rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
+ if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow();
+
+ // If graphic device is no properly initialized, we end program
+ if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return -1; }
+ else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor())/2 - CORE.Window.screen.width/2, GetMonitorHeight(GetCurrentMonitor())/2 - CORE.Window.screen.height/2);
- // Setup default viewport
- // NOTE: It updated CORE.Window.render.width and CORE.Window.render.height
- SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
+ // Initialize hi-res timer
+ InitTimer();
+
+ // Initialize base path for storage
+ CORE.Storage.basePath = GetWorkingDirectory();
+
+ return 0;
+}
- if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow();
+// Close platform
+static void ClosePlatform(void)
+{
+ glfwDestroyWindow(platform.handle);
+ glfwTerminate();
- return true;
+#if defined(_WIN32) && defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP)
+ timeEndPeriod(1); // Restore time period
+#endif
}
+
// GLFW3 Error Callback, runs on GLFW3 error
static void ErrorCallback(int error, const char *description)
{
diff --git a/src/rcore_drm.c b/src/rcore_drm.c
index 2644c5e7..213f2c54 100644
--- a/src/rcore_drm.c
+++ b/src/rcore_drm.c
@@ -140,21 +140,22 @@ static PlatformData platform = { 0 }; // Platform specific data
//----------------------------------------------------------------------------------
// Module Internal Functions Declaration
//----------------------------------------------------------------------------------
-static bool InitGraphicsDevice(int width, int height); // Initialize graphics device
+static int InitPlatform(void); // Initialize platform (graphics, inputs and more)
+static void ClosePlatform(void); // Close platform
-static void InitKeyboard(void); // Initialize raw keyboard system
-static void RestoreKeyboard(void); // Restore keyboard system
+static void InitKeyboard(void); // Initialize raw keyboard system
+static void RestoreKeyboard(void); // Restore keyboard system
#if defined(SUPPORT_SSH_KEYBOARD_RPI)
-static void ProcessKeyboard(void); // Process keyboard events
+static void ProcessKeyboard(void); // Process keyboard events
#endif
-static void InitEvdevInput(void); // Initialize evdev inputs
-static void ConfigureEvdevDevice(char *device); // Identifies a input device and configures it for use if appropriate
-static void PollKeyboardEvents(void); // Process evdev keyboard events
-static void *EventThread(void *arg); // Input device events reading thread
+static void InitEvdevInput(void); // Initialize evdev inputs
+static void ConfigureEvdevDevice(char *device); // Identifies a input device and configures it for use if appropriate
+static void PollKeyboardEvents(void); // Process evdev keyboard events
+static void *EventThread(void *arg); // Input device events reading thread
-static void InitGamepad(void); // Initialize raw gamepad input
-static void *GamepadThread(void *arg); // Mouse reading thread
+static void InitGamepad(void); // Initialize raw gamepad input
+static void *GamepadThread(void *arg); // Mouse reading thread
static int FindMatchingConnectorMode(const drmModeConnector *connector, const drmModeModeInfo *mode); // Search matching DRM mode in connector's mode list
static int FindExactConnectorMode(const drmModeConnector *connector, uint width, uint height, uint fps, bool allowInterlaced); // Search exactly matching DRM connector mode in connector's list
@@ -204,49 +205,31 @@ void InitWindow(int width, int height, const char *title)
TRACELOG(LOG_INFO, " > raudio:.... not loaded (optional)");
#endif
- // NOTE: Keep internal pointer to input title string (no copy)
+ // Initialize window data
+ CORE.Window.screen.width = width;
+ CORE.Window.screen.height = height;
+ CORE.Window.eventWaiting = false;
+ CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default
if ((title != NULL) && (title[0] != 0)) CORE.Window.title = title;
// Initialize global input state
- memset(&CORE.Input, 0, sizeof(CORE.Input));
+ memset(&CORE.Input, 0, sizeof(CORE.Input)); // Reset CORE.Input structure to 0
CORE.Input.Keyboard.exitKey = KEY_ESCAPE;
- CORE.Input.Mouse.scale = (Vector2){1.0f, 1.0f};
+ CORE.Input.Mouse.scale = (Vector2){ 1.0f, 1.0f };
CORE.Input.Mouse.cursor = MOUSE_CURSOR_ARROW;
- CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN
- CORE.Window.eventWaiting = false;
-
-
- // Platform specific init window
- //--------------------------------------------------------------
- // Initialize graphics device (display device and OpenGL context)
- // NOTE: returns true if window and graphic device has been initialized successfully
- CORE.Window.ready = InitGraphicsDevice(width, height);
-
- // If graphic device is no properly initialized, we end program
- if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return; }
- else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor()) / 2 - CORE.Window.screen.width / 2, GetMonitorHeight(GetCurrentMonitor()) / 2 - CORE.Window.screen.height / 2);
-
- // Set some default window flags
- CORE.Window.flags &= ~FLAG_WINDOW_HIDDEN; // false
- CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED; // false
- CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; // true
- CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; // false
-
- // Initialize hi-res timer
- InitTimer();
-
- // Initialize base path for storage
- CORE.Storage.basePath = GetWorkingDirectory();
-
- // Initialize raw input system
- InitEvdevInput(); // Evdev inputs initialization
- InitGamepad(); // Gamepad init
- InitKeyboard(); // Keyboard init (stdin)
+ CORE.Input.Gamepad.lastButtonPressed = GAMEPAD_BUTTON_UNKNOWN;
+
+ // Initialize platform
+ //--------------------------------------------------------------
+ InitPlatform();
//--------------------------------------------------------------
+
+ // Initialize rlgl default data (buffers and shaders)
+ // NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl
+ rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
-
- // Initialize random seed
- SetRandomSeed((unsigned int)time(NULL));
+ // Setup default viewport
+ SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
// Load default font
@@ -289,7 +272,10 @@ void InitWindow(int width, int height, const char *title)
events = (AutomationEvent *)RL_CALLOC(MAX_CODE_AUTOMATION_EVENTS, sizeof(AutomationEvent));
CORE.Time.frameCounter = 0;
#endif
-
+
+ // Initialize random seed
+ SetRandomSeed((unsigned int)time(NULL));
+
TRACELOG(LOG_INFO, "PLATFORM: DRM: Application initialized successfully");
}
@@ -315,93 +301,9 @@ void CloseWindow(void)
timeEndPeriod(1); // Restore time period
#endif
- // Platform specific close window
- //--------------------------------------------------------------
- if (platform.prevFB)
- {
- drmModeRmFB(platform.fd, platform.prevFB);
- platform.prevFB = 0;
- }
-
- if (platform.prevBO)
- {
- gbm_surface_release_buffer(platform.gbmSurface, platform.prevBO);
- platform.prevBO = NULL;
- }
-
- if (platform.gbmSurface)
- {
- gbm_surface_destroy(platform.gbmSurface);
- platform.gbmSurface = NULL;
- }
-
- if (platform.gbmDevice)
- {
- gbm_device_destroy(platform.gbmDevice);
- platform.gbmDevice = NULL;
- }
-
- if (platform.crtc)
- {
- if (platform.connector)
- {
- 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(platform.crtc);
- platform.crtc = NULL;
- }
-
- if (platform.fd != -1)
- {
- close(platform.fd);
- platform.fd = -1;
- }
-
- // Close surface, context and display
- if (platform.device != EGL_NO_DISPLAY)
- {
- if (platform.surface != EGL_NO_SURFACE)
- {
- eglDestroySurface(platform.device, platform.surface);
- platform.surface = EGL_NO_SURFACE;
- }
-
- if (platform.context != EGL_NO_CONTEXT)
- {
- eglDestroyContext(platform.device, platform.context);
- platform.context = EGL_NO_CONTEXT;
- }
-
- eglTerminate(platform.device);
- platform.device = EGL_NO_DISPLAY;
- }
-
- // Wait for mouse and gamepad threads to finish before closing
- // NOTE: Those threads should already have finished at this point
- // because they are controlled by CORE.Window.shouldClose variable
-
- CORE.Window.shouldClose = true; // Added to force threads to exit when the close window is called
-
- // Close the evdev keyboard
- if (platform.keyboardFd != -1)
- {
- close(platform.keyboardFd);
- platform.keyboardFd = -1;
- }
-
- for (int i = 0; i < sizeof(platform.eventWorker)/sizeof(InputEventWorker); ++i)
- {
- if (platform.eventWorker[i].threadId)
- {
- pthread_join(platform.eventWorker[i].threadId, NULL);
- }
- }
-
- if (platform.gamepadThreadId) pthread_join(platform.gamepadThreadId, NULL);
+ // De-initialize platform
+ //--------------------------------------------------------------
+ ClosePlatform();
//--------------------------------------------------------------
#if defined(SUPPORT_EVENTS_AUTOMATION)
@@ -808,28 +710,9 @@ void PollInputEvents(void)
// Module Internal Functions Definition
//----------------------------------------------------------------------------------
-// Initialize display device and framebuffer
-// NOTE: width and height represent the screen (framebuffer) desired size, not actual display size
-// If width or height are 0, default display size will be used for framebuffer size
-// NOTE: returns false in case graphic device could not be created
-static bool InitGraphicsDevice(int width, int height)
+// Initialize platform: graphics, inputs and more
+static int InitPlatform(void)
{
- CORE.Window.screen.width = width; // User desired width
- CORE.Window.screen.height = height; // User desired height
- CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default
-
- // Set the window minimum and maximum default values to 0
- CORE.Window.screenMin.width = 0;
- CORE.Window.screenMin.height = 0;
- CORE.Window.screenMax.width = 0;
- CORE.Window.screenMax.height = 0;
-
- // NOTE: Framebuffer (render area - CORE.Window.render.width, CORE.Window.render.height) could include black bars...
- // ...in top-down or left-right to match display aspect ratio (no weird scaling)
-
- CORE.Window.fullscreen = true;
- CORE.Window.flags |= FLAG_FULLSCREEN_MODE;
-
platform.fd = -1;
platform.connector = NULL;
platform.modeIndex = -1;
@@ -838,6 +721,9 @@ static bool InitGraphicsDevice(int width, int height)
platform.gbmSurface = NULL;
platform.prevBO = NULL;
platform.prevFB = 0;
+
+ CORE.Window.fullscreen = true;
+ CORE.Window.flags |= FLAG_FULLSCREEN_MODE;
#if defined(DEFAULT_GRAPHIC_DEVICE_DRM)
platform.fd = open(DEFAULT_GRAPHIC_DEVICE_DRM, O_RDWR);
@@ -861,14 +747,14 @@ static bool InitGraphicsDevice(int width, int height)
if (platform.fd == -1)
{
TRACELOG(LOG_WARNING, "DISPLAY: Failed to open graphic card");
- return false;
+ return -1;
}
drmModeRes *res = drmModeGetResources(platform.fd);
if (!res)
{
TRACELOG(LOG_WARNING, "DISPLAY: Failed get DRM resources");
- return false;
+ return -1;
}
TRACELOG(LOG_TRACE, "DISPLAY: Connectors found: %i", res->count_connectors);
@@ -897,7 +783,7 @@ static bool InitGraphicsDevice(int width, int height)
{
TRACELOG(LOG_WARNING, "DISPLAY: No suitable DRM connector found");
drmModeFreeResources(res);
- return false;
+ return -1;
}
drmModeEncoder *enc = drmModeGetEncoder(platform.fd, platform.connector->encoder_id);
@@ -905,7 +791,7 @@ static bool InitGraphicsDevice(int width, int height)
{
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get DRM mode encoder");
drmModeFreeResources(res);
- return false;
+ return -1;
}
platform.crtc = drmModeGetCrtc(platform.fd, enc->crtc_id);
@@ -914,7 +800,7 @@ static bool InitGraphicsDevice(int width, int height)
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get DRM mode crtc");
drmModeFreeEncoder(enc);
drmModeFreeResources(res);
- return false;
+ return -1;
}
// If InitWindow should use the current mode find it in the connector's mode list
@@ -929,7 +815,7 @@ static bool InitGraphicsDevice(int width, int height)
TRACELOG(LOG_WARNING, "DISPLAY: No matching DRM connector mode found");
drmModeFreeEncoder(enc);
drmModeFreeResources(res);
- return false;
+ return -1;
}
CORE.Window.screen.width = CORE.Window.display.width;
@@ -957,7 +843,7 @@ static bool InitGraphicsDevice(int width, int height)
TRACELOG(LOG_WARNING, "DISPLAY: Failed to find a suitable DRM connector mode");
drmModeFreeEncoder(enc);
drmModeFreeResources(res);
- return false;
+ return -1;
}
CORE.Window.display.width = platform.connector->modes[platform.modeIndex].hdisplay;
@@ -982,7 +868,7 @@ static bool InitGraphicsDevice(int width, int height)
if (!platform.gbmDevice)
{
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create GBM device");
- return false;
+ return -1;
}
platform.gbmSurface = gbm_surface_create(platform.gbmDevice, platform.connector->modes[platform.modeIndex].hdisplay,
@@ -990,7 +876,7 @@ static bool InitGraphicsDevice(int width, int height)
if (!platform.gbmSurface)
{
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create GBM surface");
- return false;
+ return -1;
}
EGLint samples = 0;
@@ -1030,7 +916,7 @@ static bool InitGraphicsDevice(int width, int height)
if (platform.device == EGL_NO_DISPLAY)
{
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
- return false;
+ return -1;
}
// Initialize the EGL device connection
@@ -1038,13 +924,13 @@ static bool InitGraphicsDevice(int width, int height)
{
// 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;
+ return -1;
}
if (!eglChooseConfig(platform.device, NULL, NULL, 0, &numConfigs))
{
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get EGL config count: 0x%x", eglGetError());
- return false;
+ return -1;
}
TRACELOG(LOG_TRACE, "DISPLAY: EGL configs available: %d", numConfigs);
@@ -1053,7 +939,7 @@ static bool InitGraphicsDevice(int width, int height)
if (!configs)
{
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get memory for EGL configs");
- return false;
+ return -1;
}
EGLint matchingNumConfigs = 0;
@@ -1061,7 +947,7 @@ static bool InitGraphicsDevice(int width, int height)
{
TRACELOG(LOG_WARNING, "DISPLAY: Failed to choose EGL config: 0x%x", eglGetError());
free(configs);
- return false;
+ return -1;
}
TRACELOG(LOG_TRACE, "DISPLAY: EGL matching configs available: %d", matchingNumConfigs);
@@ -1091,7 +977,7 @@ static bool InitGraphicsDevice(int width, int height)
if (!found)
{
TRACELOG(LOG_WARNING, "DISPLAY: Failed to find a suitable EGL config");
- return false;
+ return -1;
}
// Set rendering API
@@ -1102,7 +988,7 @@ static bool InitGraphicsDevice(int width, int height)
if (platform.context == EGL_NO_CONTEXT)
{
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL context");
- return false;
+ return -1;
}
// Create an EGL window surface
@@ -1111,7 +997,7 @@ static bool InitGraphicsDevice(int width, int height)
if (EGL_NO_SURFACE == platform.surface)
{
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL window surface: 0x%04x", eglGetError());
- return false;
+ return -1;
}
// At this point we need to manage render size vs screen size
@@ -1127,7 +1013,7 @@ static bool InitGraphicsDevice(int width, int height)
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;
+ return -1;
}
else
{
@@ -1147,19 +1033,123 @@ static bool InitGraphicsDevice(int width, int height)
// NOTE: GL procedures address loader is required to load extensions
rlLoadExtensions(eglGetProcAddress);
- // Initialize OpenGL context (states and resources)
- // NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl
- rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
+ if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow();
+
+ // If graphic device is no properly initialized, we end program
+ if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return -1; }
+ else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor()) / 2 - CORE.Window.screen.width / 2, GetMonitorHeight(GetCurrentMonitor()) / 2 - CORE.Window.screen.height / 2);
- // Setup default viewport
- // NOTE: It updated CORE.Window.render.width and CORE.Window.render.height
- SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
+ // Set some default window flags
+ CORE.Window.flags &= ~FLAG_WINDOW_HIDDEN; // false
+ CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED; // false
+ CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; // true
+ CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; // false
- if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow();
+ // Initialize hi-res timer
+ InitTimer();
- return true;
+ // Initialize base path for storage
+ CORE.Storage.basePath = GetWorkingDirectory();
+
+ // Initialize raw input system
+ InitEvdevInput(); // Evdev inputs initialization
+ InitGamepad(); // Gamepad init
+ InitKeyboard(); // Keyboard init (stdin)
+
+ return 0;
}
+// Close platform
+static void ClosePlatform(void)
+{
+ if (platform.prevFB)
+ {
+ drmModeRmFB(platform.fd, platform.prevFB);
+ platform.prevFB = 0;
+ }
+
+ if (platform.prevBO)
+ {
+ gbm_surface_release_buffer(platform.gbmSurface, platform.prevBO);
+ platform.prevBO = NULL;
+ }
+
+ if (platform.gbmSurface)
+ {
+ gbm_surface_destroy(platform.gbmSurface);
+ platform.gbmSurface = NULL;
+ }
+
+ if (platform.gbmDevice)
+ {
+ gbm_device_destroy(platform.gbmDevice);
+ platform.gbmDevice = NULL;
+ }
+
+ if (platform.crtc)
+ {
+ if (platform.connector)
+ {
+ 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(platform.crtc);
+ platform.crtc = NULL;
+ }
+
+ if (platform.fd != -1)
+ {
+ close(platform.fd);
+ platform.fd = -1;
+ }
+
+ // Close surface, context and display
+ if (platform.device != EGL_NO_DISPLAY)
+ {
+ if (platform.surface != EGL_NO_SURFACE)
+ {
+ eglDestroySurface(platform.device, platform.surface);
+ platform.surface = EGL_NO_SURFACE;
+ }
+
+ if (platform.context != EGL_NO_CONTEXT)
+ {
+ eglDestroyContext(platform.device, platform.context);
+ platform.context = EGL_NO_CONTEXT;
+ }
+
+ eglTerminate(platform.device);
+ platform.device = EGL_NO_DISPLAY;
+ }
+
+ // Wait for mouse and gamepad threads to finish before closing
+ // NOTE: Those threads should already have finished at this point
+ // because they are controlled by CORE.Window.shouldClose variable
+
+ CORE.Window.shouldClose = true; // Added to force threads to exit when the close window is called
+
+ // Close the evdev keyboard
+ if (platform.keyboardFd != -1)
+ {
+ close(platform.keyboardFd);
+ platform.keyboardFd = -1;
+ }
+
+ for (int i = 0; i < sizeof(platform.eventWorker)/sizeof(InputEventWorker); ++i)
+ {
+ if (platform.eventWorker[i].threadId)
+ {
+ pthread_join(platform.eventWorker[i].threadId, NULL);
+ }
+ }
+
+ if (platform.gamepadThreadId) pthread_join(platform.gamepadThreadId, NULL);
+}
+
+
// Initialize Keyboard system (using standard input)
static void InitKeyboard(void)
{
diff --git a/src/rcore_template.c b/src/rcore_template.c
index 88b3c4a7..3929de4b 100644
--- a/src/rcore_template.c
+++ b/src/rcore_template.c
@@ -73,7 +73,8 @@ static PlatformData platform = { 0 }; // Platform specific data
//----------------------------------------------------------------------------------
// Module Internal Functions Declaration
//----------------------------------------------------------------------------------
-static bool InitGraphicsDevice(int width, int height); // Initialize graphics device
+static int InitPlatform(void); // Initialize platform (graphics, inputs and more)
+static bool InitGraphicsDevice(void); // Initialize graphics device
//----------------------------------------------------------------------------------
// Module Functions Declaration
@@ -142,19 +143,15 @@ void InitWindow(int width, int height, const char *title)
// NOTE: returns true if window and graphic device has been initialized successfully
CORE.Window.ready = InitGraphicsDevice(width, height);
- // If graphic device is no properly initialized, we end program
- if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return; }
- // Initialize hi-res timer
- InitTimer();
- // Initialize base path for storage
- CORE.Storage.basePath = GetWorkingDirectory();
- //--------------------------------------------------------------
-
+ // Initialize OpenGL context (states and resources)
+ // NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl
+ rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
- // Initialize random seed
- SetRandomSeed((unsigned int)time(NULL));
+ // Setup default viewport
+ // NOTE: It updated CORE.Window.render.width and CORE.Window.render.height
+ SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
// Load default font
@@ -198,6 +195,9 @@ void InitWindow(int width, int height, const char *title)
CORE.Time.frameCounter = 0;
#endif
+ // Initialize random seed
+ SetRandomSeed((unsigned int)time(NULL));
+
TRACELOG(LOG_INFO, "PLATFORM: CUSTOM: Application initialized successfully");
}
@@ -597,25 +597,9 @@ void PollInputEvents(void)
// Module Internal Functions Definition
//----------------------------------------------------------------------------------
-// Initialize display device and framebuffer
-// NOTE: width and height represent the screen (framebuffer) desired size, not actual display size
-// If width or height are 0, default display size will be used for framebuffer size
-// NOTE: returns false in case graphic device could not be created
-static bool InitGraphicsDevice(int width, int height)
+// Initialize platform: graphics, inputs and more
+static int InitPlatform(void)
{
- CORE.Window.screen.width = width; // User desired width
- CORE.Window.screen.height = height; // User desired height
- CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default
-
- // Set the screen minimum and maximum default values to 0
- CORE.Window.screenMin.width = 0;
- CORE.Window.screenMin.height = 0;
- CORE.Window.screenMax.width = 0;
- CORE.Window.screenMax.height = 0;
-
- // NOTE: Framebuffer (render area - CORE.Window.render.width, CORE.Window.render.height) could include black bars...
- // ...in top-down or left-right to match display aspect ratio (no weird scaling)
-
CORE.Window.fullscreen = true;
CORE.Window.flags |= FLAG_FULLSCREEN_MODE;
@@ -677,7 +661,7 @@ static bool InitGraphicsDevice(int width, int height)
if (platform.context == EGL_NO_CONTEXT)
{
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL context");
- return false;
+ return -1;
}
// Create an EGL window surface
@@ -706,7 +690,7 @@ static bool InitGraphicsDevice(int width, int height)
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;
+ return -1;
}
else
{
@@ -726,19 +710,24 @@ static bool InitGraphicsDevice(int width, int height)
// NOTE: GL procedures address loader is required to load extensions
rlLoadExtensions(eglGetProcAddress);
- // Initialize OpenGL context (states and resources)
- // NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl
- rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
-
- // Setup default viewport
- // NOTE: It updated CORE.Window.render.width and CORE.Window.render.height
- SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
-
CORE.Window.ready = true;
+
+ // If graphic device is no properly initialized, we end program
+ if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return -1; }
+
+ // Initialize hi-res timer
+ InitTimer();
+
+ // Initialize base path for storage
+ CORE.Storage.basePath = GetWorkingDirectory();
- if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow();
+ return 0;
+}
- return true;
+// Close platform
+static void ClosePlatform(void)
+{
+ // TODO: De-initialize graphics, inputs and more
}
// EOF
diff --git a/src/rcore_web.c b/src/rcore_web.c
index 277d1378..3b9373bb 100644
--- a/src/rcore_web.c
+++ b/src/rcore_web.c
@@ -87,17 +87,18 @@ static PlatformData platform = { 0 }; // Platform specific data
//----------------------------------------------------------------------------------
// Module Internal Functions Declaration
//----------------------------------------------------------------------------------
-static bool InitGraphicsDevice(int width, int height); // Initialize graphics device
+static int InitPlatform(void); // Initialize platform (graphics, inputs and more)
+static void ClosePlatform(void); // Close platform
// Error callback event
-static void ErrorCallback(int error, const char *description); // GLFW3 Error Callback, runs on GLFW3 error
+static void ErrorCallback(int error, const char *description); // GLFW3 Error Callback, runs on GLFW3 error
// Window callbacks events
-static void WindowSizeCallback(GLFWwindow *window, int width, int height); // GLFW3 WindowSize Callback, runs when window is resized
-static void WindowIconifyCallback(GLFWwindow *window, int iconified); // GLFW3 WindowIconify Callback, runs when window is minimized/restored
-static void WindowMaximizeCallback(GLFWwindow *window, int maximized); // GLFW3 Window Maximize Callback, runs when window is maximized
-static void WindowFocusCallback(GLFWwindow *window, int focused); // GLFW3 WindowFocus Callback, runs when window get/lose focus
-static void WindowDropCallback(GLFWwindow *window, int count, const char **paths); // GLFW3 Window Drop Callback, runs when drop files into window
+static void WindowSizeCallback(GLFWwindow *window, int width, int height); // GLFW3 WindowSize Callback, runs when window is resized
+static void WindowIconifyCallback(GLFWwindow *window, int iconified); // GLFW3 WindowIconify Callback, runs when window is minimized/restored
+static void WindowMaximizeCallback(GLFWwindow *window, int maximized); // GLFW3 Window Maximize Callback, runs when window is maximized
+static void WindowFocusCallback(GLFWwindow *window, int focused); // GLFW3 WindowFocus Callback, runs when window get/lose focus
+static void WindowDropCallback(GLFWwindow *window, int count, const char **paths); // GLFW3 Window Drop Callback, runs when drop files into window
// Input callbacks events
static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods); // GLFW3 Keyboard Callback, runs on key pressed
@@ -107,11 +108,12 @@ static void MouseCursorPosCallback(GLFWwindow *window, double x, double y);
static void MouseScrollCallback(GLFWwindow *window, double xoffset, double yoffset); // GLFW3 Srolling Callback, runs on mouse wheel
static void CursorEnterCallback(GLFWwindow *window, int enter); // GLFW3 Cursor Enter Callback, cursor enters client area
-// Emscripten callback events
+// Emscripten window callback events
static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const EmscriptenFullscreenChangeEvent *event, void *userData);
static EM_BOOL EmscriptenWindowResizedCallback(int eventType, const EmscriptenUiEvent *event, void *userData);
static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent *event, void *userData);
+// Emscripten input callback events
static EM_BOOL EmscriptenMouseCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData);
static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData);
static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData);
@@ -160,67 +162,32 @@ void InitWindow(int width, int height, const char *title)
TRACELOG(LOG_INFO, " > raudio:.... not loaded (optional)");
#endif
- // NOTE: Keep internal pointer to input title string (no copy)
+ // Initialize window data
+ CORE.Window.screen.width = width;
+ CORE.Window.screen.height = height;
+ CORE.Window.eventWaiting = false;
+ CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default
if ((title != NULL) && (title[0] != 0)) CORE.Window.title = title;
// Initialize global input state
- memset(&CORE.Input, 0, sizeof(CORE.Input));
+ memset(&CORE.Input, 0, sizeof(CORE.Input)); // Reset CORE.Input structure to 0
CORE.Input.Keyboard.exitKey = KEY_ESCAPE;
- CORE.Input.Mouse.scale = (Vector2){1.0f, 1.0f};
+ CORE.Input.Mouse.scale = (Vector2){ 1.0f, 1.0f };
CORE.Input.Mouse.cursor = MOUSE_CURSOR_ARROW;
- CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN
- CORE.Window.eventWaiting = false;
+ CORE.Input.Gamepad.lastButtonPressed = GAMEPAD_BUTTON_UNKNOWN;
-
- // Platform specific init window
- //--------------------------------------------------------------
- // Initialize graphics device (display device and OpenGL context)
- // NOTE: returns true if window and graphic device has been initialized successfully
- CORE.Window.ready = InitGraphicsDevice(width, height);
-
- // If graphic device is no properly initialized, we end program
- if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return; }
- else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor())/2 - CORE.Window.screen.width/2, GetMonitorHeight(GetCurrentMonitor())/2 - CORE.Window.screen.height/2);
-
- // Initialize hi-res timer
- InitTimer();
-
- // Initialize base path for storage
- CORE.Storage.basePath = GetWorkingDirectory();
-
- // Setup callback functions for the DOM events
- emscripten_set_fullscreenchange_callback("#canvas", NULL, 1, EmscriptenFullscreenChangeCallback);
-
- // WARNING: Below resize code was breaking fullscreen mode for sample games and examples, it needs review
- // Check fullscreen change events(note this is done on the window since most browsers don't support this on #canvas)
- // emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenResizeCallback);
- // Check Resize event (note this is done on the window since most browsers don't support this on #canvas)
- emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenResizeCallback);
-
- // Trigger this once to get initial window sizing
- EmscriptenResizeCallback(EMSCRIPTEN_EVENT_RESIZE, NULL, NULL);
-
- // Support keyboard events -> Not used, GLFW.JS takes care of that
- // emscripten_set_keypress_callback("#canvas", NULL, 1, EmscriptenKeyboardCallback);
- // emscripten_set_keydown_callback("#canvas", NULL, 1, EmscriptenKeyboardCallback);
-
- // Support mouse events
- emscripten_set_click_callback("#canvas", NULL, 1, EmscriptenMouseCallback);
-
- // Support touch events
- emscripten_set_touchstart_callback("#canvas", NULL, 1, EmscriptenTouchCallback);
- emscripten_set_touchend_callback("#canvas", NULL, 1, EmscriptenTouchCallback);
- emscripten_set_touchmove_callback("#canvas", NULL, 1, EmscriptenTouchCallback);
- emscripten_set_touchcancel_callback("#canvas", NULL, 1, EmscriptenTouchCallback);
-
- // Support gamepad events (not provided by GLFW3 on emscripten)
- emscripten_set_gamepadconnected_callback(NULL, 1, EmscriptenGamepadCallback);
- emscripten_set_gamepaddisconnected_callback(NULL, 1, EmscriptenGamepadCallback);
+ // Initialize platform
+ //--------------------------------------------------------------
+ InitPlatform();
//--------------------------------------------------------------
+ // Initialize OpenGL context (states and resources)
+ // NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl
+ rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
- // Initialize random seed
- SetRandomSeed((unsigned int)time(NULL));
+ // Setup default viewport
+ // NOTE: It updated CORE.Window.render.width and CORE.Window.render.height
+ SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
// Load default font
@@ -264,6 +231,9 @@ void InitWindow(int width, int height, const char *title)
CORE.Time.frameCounter = 0;
#endif
+ // Initialize random seed
+ SetRandomSeed((unsigned int)time(NULL));
+
TRACELOG(LOG_INFO, "PLATFORM: WEB: Application initialized successfully");
}
@@ -285,10 +255,9 @@ void CloseWindow(void)
rlglClose(); // De-init rlgl
- // Platform specific close window
- //--------------------------------------------------------------
- glfwDestroyWindow(platform.handle);
- glfwTerminate();
+ // De-initialize platform
+ //--------------------------------------------------------------
+ ClosePlatform();
//--------------------------------------------------------------
#if defined(SUPPORT_EVENTS_AUTOMATION)
@@ -814,43 +783,14 @@ void PollInputEvents(void)
// Module Internal Functions Definition
//----------------------------------------------------------------------------------
-// Initialize display device and framebuffer
-// NOTE: width and height represent the screen (framebuffer) desired size, not actual display size
-// If width or height are 0, default display size will be used for framebuffer size
-// NOTE: returns false in case graphic device could not be created
-static bool InitGraphicsDevice(int width, int height)
+// Initialize platform: graphics, inputs and more
+static int InitPlatform(void)
{
- CORE.Window.screen.width = width; // User desired width
- CORE.Window.screen.height = height; // User desired height
- CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default
-
- // Set the screen minimum and maximum default values to 0
- CORE.Window.screenMin.width = 0;
- CORE.Window.screenMin.height = 0;
- CORE.Window.screenMax.width = 0;
- CORE.Window.screenMax.height = 0;
-
- // NOTE: Framebuffer (render area - CORE.Window.render.width, CORE.Window.render.height) could include black bars...
- // ...in top-down or left-right to match display aspect ratio (no weird scaling)
-
glfwSetErrorCallback(ErrorCallback);
-/*
- // TODO: Setup GLFW custom allocators to match raylib ones
- const GLFWallocator allocator = {
- .allocate = MemAlloc,
- .deallocate = MemFree,
- .reallocate = MemRealloc,
- .user = NULL
- };
-
- glfwInitAllocator(&allocator);
-*/
- if (!glfwInit())
- {
- TRACELOG(LOG_WARNING, "GLFW: Failed to initialize GLFW");
- return false;
- }
+ // Initialize GLFW internal global state
+ int result = glfwInit();
+ if (result == GLFW_FALSE) { TRACELOG(LOG_WARNING, "GLFW: Failed to initialize GLFW"); return -1; }
glfwDefaultWindowHints(); // Set default windows hints
// glfwWindowHint(GLFW_RED_BITS, 8); // Framebuffer red color component bits
@@ -1016,7 +956,7 @@ static bool InitGraphicsDevice(int width, int height)
{
glfwTerminate();
TRACELOG(LOG_WARNING, "GLFW: Failed to initialize Window");
- return false;
+ return -1;
}
// WARNING: glfwCreateWindow() title doesn't work with emscripten
@@ -1037,6 +977,12 @@ static bool InitGraphicsDevice(int width, int height)
glfwSetCursorEnterCallback(platform.handle, CursorEnterCallback);
glfwMakeContextCurrent(platform.handle);
+
+ // Load OpenGL extensions
+ // NOTE: GL procedures address loader is required to load extensions
+ rlLoadExtensions(glfwGetProcAddress);
+
+ if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow();
// 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
@@ -1055,22 +1001,54 @@ static bool InitGraphicsDevice(int width, int height)
TRACELOG(LOG_INFO, " > Screen size: %i x %i", CORE.Window.screen.width, CORE.Window.screen.height);
TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height);
TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y);
+
+ // If graphic device is no properly initialized, we end program
+ if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return -1; }
+ else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor())/2 - CORE.Window.screen.width/2, GetMonitorHeight(GetCurrentMonitor())/2 - CORE.Window.screen.height/2);
- // Load OpenGL extensions
- // NOTE: GL procedures address loader is required to load extensions
- rlLoadExtensions(glfwGetProcAddress);
+ // Initialize hi-res timer
+ InitTimer();
+
+ // Initialize base path for storage
+ CORE.Storage.basePath = GetWorkingDirectory();
+
+ // Setup callback functions for the DOM events
+ emscripten_set_fullscreenchange_callback("#canvas", NULL, 1, EmscriptenFullscreenChangeCallback);
- // Initialize OpenGL context (states and resources)
- // NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl
- rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
+ // WARNING: Below resize code was breaking fullscreen mode for sample games and examples, it needs review
+ // Check fullscreen change events(note this is done on the window since most browsers don't support this on #canvas)
+ // emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenResizeCallback);
+ // Check Resize event (note this is done on the window since most browsers don't support this on #canvas)
+ emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenResizeCallback);
- // Setup default viewport
- // NOTE: It updated CORE.Window.render.width and CORE.Window.render.height
- SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
+ // Trigger this once to get initial window sizing
+ EmscriptenResizeCallback(EMSCRIPTEN_EVENT_RESIZE, NULL, NULL);
- if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow();
+ // Support keyboard events -> Not used, GLFW.JS takes care of that
+ // emscripten_set_keypress_callback("#canvas", NULL, 1, EmscriptenKeyboardCallback);
+ // emscripten_set_keydown_callback("#canvas", NULL, 1, EmscriptenKeyboardCallback);
+
+ // Support mouse events
+ emscripten_set_click_callback("#canvas", NULL, 1, EmscriptenMouseCallback);
+
+ // Support touch events
+ emscripten_set_touchstart_callback("#canvas", NULL, 1, EmscriptenTouchCallback);
+ emscripten_set_touchend_callback("#canvas", NULL, 1, EmscriptenTouchCallback);
+ emscripten_set_touchmove_callback("#canvas", NULL, 1, EmscriptenTouchCallback);
+ emscripten_set_touchcancel_callback("#canvas", NULL, 1, EmscriptenTouchCallback);
- return true;
+ // Support gamepad events (not provided by GLFW3 on emscripten)
+ emscripten_set_gamepadconnected_callback(NULL, 1, EmscriptenGamepadCallback);
+ emscripten_set_gamepaddisconnected_callback(NULL, 1, EmscriptenGamepadCallback);
+
+ return 0;
+}
+
+// Close platform
+static void ClosePlatform(void)
+{
+ glfwDestroyWindow(platform.handle);
+ glfwTerminate();
}
// GLFW3 Error Callback, runs on GLFW3 error