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.
This commit is contained in:
parent
4521a142c3
commit
b34c2ecbcb
@ -2365,10 +2365,10 @@ int GetTouchPointCount(void)
|
|||||||
// Initialize hi-resolution timer
|
// Initialize hi-resolution timer
|
||||||
void InitTimer(void)
|
void InitTimer(void)
|
||||||
{
|
{
|
||||||
// Setting a higher resolution can improve the accuracy of time-out intervals in wait functions.
|
// 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.
|
// 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.
|
// 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 does not improve the accuracy of the high-resolution performance counter.
|
||||||
#if defined(_WIN32) && defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP)
|
#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)
|
timeBeginPeriod(1); // Setup high-resolution timer to 1ms (granularity of 1-2 ms)
|
||||||
#endif
|
#endif
|
||||||
|
@ -82,7 +82,8 @@ static PlatformData platform = { 0 }; // Platform specific data
|
|||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Internal Functions Declaration
|
// 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 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
|
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)");
|
TRACELOG(LOG_INFO, " > raudio:.... not loaded (optional)");
|
||||||
#endif
|
#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;
|
if ((title != NULL) && (title[0] != 0)) CORE.Window.title = title;
|
||||||
|
|
||||||
// Initialize global input state
|
// 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.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.Mouse.cursor = MOUSE_CURSOR_ARROW;
|
||||||
CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN
|
CORE.Input.Gamepad.lastButtonPressed = GAMEPAD_BUTTON_UNKNOWN;
|
||||||
CORE.Window.eventWaiting = false;
|
|
||||||
|
|
||||||
|
// Initialize platform
|
||||||
// Platform specific init window
|
//--------------------------------------------------------------
|
||||||
//--------------------------------------------------------------
|
InitPlatform();
|
||||||
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
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,28 +215,9 @@ void CloseWindow(void)
|
|||||||
timeEndPeriod(1); // Restore time period
|
timeEndPeriod(1); // Restore time period
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Platform specific close window
|
// De-initialize platform
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
// Close surface, context and display
|
ClosePlatform();
|
||||||
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;
|
|
||||||
}
|
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
|
|
||||||
#if defined(SUPPORT_EVENTS_AUTOMATION)
|
#if defined(SUPPORT_EVENTS_AUTOMATION)
|
||||||
@ -690,25 +607,108 @@ void PollInputEvents(void)
|
|||||||
// Module Internal Functions Definition
|
// 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
|
// Initialize display device and framebuffer
|
||||||
// NOTE: width and height represent the screen (framebuffer) desired size, not actual display size
|
// 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
|
// 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
|
// 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.fullscreen = true;
|
||||||
CORE.Window.flags |= FLAG_FULLSCREEN_MODE;
|
CORE.Window.flags |= FLAG_FULLSCREEN_MODE;
|
||||||
|
|
||||||
@ -748,7 +748,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||||||
if (platform.device == EGL_NO_DISPLAY)
|
if (platform.device == EGL_NO_DISPLAY)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the EGL device connection
|
// 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.
|
// If all of the calls to eglInitialize returned EGL_FALSE then an error has occurred.
|
||||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get an appropriate EGL framebuffer configuration
|
// Get an appropriate EGL framebuffer configuration
|
||||||
@ -770,7 +770,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||||||
if (platform.context == EGL_NO_CONTEXT)
|
if (platform.context == EGL_NO_CONTEXT)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL context");
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL context");
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create an EGL window surface
|
// 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)
|
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");
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to attach EGL rendering context to EGL surface");
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -819,19 +819,11 @@ static bool InitGraphicsDevice(int width, int height)
|
|||||||
// NOTE: GL procedures address loader is required to load extensions
|
// NOTE: GL procedures address loader is required to load extensions
|
||||||
rlLoadExtensions(eglGetProcAddress);
|
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;
|
CORE.Window.ready = true;
|
||||||
|
|
||||||
if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow();
|
if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow();
|
||||||
|
|
||||||
return true;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ANDROID: Process activity lifecycle commands
|
// 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);
|
CORE.Window.display.height = ANativeWindow_getHeight(platform.app->window);
|
||||||
|
|
||||||
// Initialize graphics device (display device and OpenGL context)
|
// 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
|
// Initialize hi-res timer
|
||||||
InitTimer();
|
InitTimer();
|
||||||
|
|
||||||
// Initialize random seed
|
|
||||||
srand((unsigned int)time(NULL));
|
|
||||||
|
|
||||||
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
|
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
|
||||||
// Load default font
|
// Load default font
|
||||||
// WARNING: External function: Module required: rtext
|
// WARNING: External function: Module required: rtext
|
||||||
LoadFontDefault();
|
LoadFontDefault();
|
||||||
Rectangle rec = GetFontDefault().recs[95];
|
|
||||||
// NOTE: We setup a 1px padding on char rectangle to avoid pixel bleeding on MSAA filtering
|
|
||||||
#if defined(SUPPORT_MODULE_RSHAPES)
|
#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 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];
|
||||||
|
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)
|
||||||
|
// 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
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Initialize random seed
|
||||||
|
SetRandomSeed((unsigned int)time(NULL));
|
||||||
|
|
||||||
// TODO: GPU assets reload in case of lost focus (lost context)
|
// TODO: GPU assets reload in case of lost focus (lost context)
|
||||||
// NOTE: This problem has been solved just unbinding and rebinding context from display
|
// NOTE: This problem has been solved just unbinding and rebinding context from display
|
||||||
|
@ -111,7 +111,8 @@ static PlatformData platform = { 0 }; // Platform specific data
|
|||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Internal Functions Declaration
|
// 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
|
// 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
|
||||||
@ -176,53 +177,31 @@ void InitWindow(int width, int height, const char *title)
|
|||||||
TRACELOG(LOG_INFO, " > raudio:.... not loaded (optional)");
|
TRACELOG(LOG_INFO, " > raudio:.... not loaded (optional)");
|
||||||
#endif
|
#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;
|
if ((title != NULL) && (title[0] != 0)) CORE.Window.title = title;
|
||||||
|
|
||||||
// Initialize global input state
|
// 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.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.Mouse.cursor = MOUSE_CURSOR_ARROW;
|
||||||
CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN
|
CORE.Input.Gamepad.lastButtonPressed = 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();
|
|
||||||
|
|
||||||
// Initialize base path for storage
|
// Initialize platform
|
||||||
CORE.Storage.basePath = GetWorkingDirectory();
|
//--------------------------------------------------------------
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Setup default viewport
|
||||||
// Initialize random seed
|
SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
|
||||||
SetRandomSeed((unsigned int)time(NULL));
|
|
||||||
|
|
||||||
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
|
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
|
||||||
// Load default font
|
// Load default font
|
||||||
@ -266,6 +245,9 @@ void InitWindow(int width, int height, const char *title)
|
|||||||
CORE.Time.frameCounter = 0;
|
CORE.Time.frameCounter = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Initialize random seed
|
||||||
|
SetRandomSeed((unsigned int)time(NULL));
|
||||||
|
|
||||||
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP: Application initialized successfully");
|
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP: Application initialized successfully");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,14 +269,9 @@ void CloseWindow(void)
|
|||||||
|
|
||||||
rlglClose(); // De-init rlgl
|
rlglClose(); // De-init rlgl
|
||||||
|
|
||||||
// Platform specific close window
|
// De-initialize platform
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
glfwDestroyWindow(platform.handle);
|
ClosePlatform();
|
||||||
glfwTerminate();
|
|
||||||
|
|
||||||
#if defined(_WIN32) && defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP)
|
|
||||||
timeEndPeriod(1); // Restore time period
|
|
||||||
#endif
|
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
|
|
||||||
#if defined(SUPPORT_EVENTS_AUTOMATION)
|
#if defined(SUPPORT_EVENTS_AUTOMATION)
|
||||||
@ -1379,34 +1356,28 @@ void PollInputEvents(void)
|
|||||||
// Module Internal Functions Definition
|
// Module Internal Functions Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Initialize display device and framebuffer
|
// Initialize platform: graphics, inputs and more
|
||||||
// NOTE: width and height represent the screen (framebuffer) desired size, not actual display size
|
static int InitPlatform(void)
|
||||||
// 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)
|
|
||||||
{
|
{
|
||||||
CORE.Window.screen.width = width; // User desired width
|
glfwSetErrorCallback(ErrorCallback);
|
||||||
CORE.Window.screen.height = height; // User desired height
|
/*
|
||||||
CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default
|
// TODO: Setup GLFW custom allocators to match raylib ones
|
||||||
|
const GLFWallocator allocator = {
|
||||||
|
.allocate = MemAlloc,
|
||||||
|
.deallocate = MemFree,
|
||||||
|
.reallocate = MemRealloc,
|
||||||
|
.user = NULL
|
||||||
|
};
|
||||||
|
|
||||||
// Set the screen minimum and maximum default values to 0
|
glfwInitAllocator(&allocator);
|
||||||
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)
|
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
glfwInitHint(GLFW_COCOA_CHDIR_RESOURCES, GLFW_FALSE);
|
glfwInitHint(GLFW_COCOA_CHDIR_RESOURCES, GLFW_FALSE);
|
||||||
#endif
|
#endif
|
||||||
|
// Initialize GLFW internal global state
|
||||||
if (!glfwInit())
|
int result = glfwInit();
|
||||||
{
|
if (result == GLFW_FALSE) { TRACELOG(LOG_WARNING, "GLFW: Failed to initialize GLFW"); return -1; }
|
||||||
TRACELOG(LOG_WARNING, "GLFW: Failed to initialize GLFW");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
glfwDefaultWindowHints(); // Set default windows hints
|
glfwDefaultWindowHints(); // Set default windows hints
|
||||||
//glfwWindowHint(GLFW_RED_BITS, 8); // Framebuffer red color component bits
|
//glfwWindowHint(GLFW_RED_BITS, 8); // Framebuffer red color component bits
|
||||||
@ -1528,7 +1499,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||||||
if (!monitor)
|
if (!monitor)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "GLFW: Failed to get primary monitor");
|
TRACELOG(LOG_WARNING, "GLFW: Failed to get primary monitor");
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
|
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
|
||||||
@ -1617,7 +1588,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||||||
{
|
{
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
TRACELOG(LOG_WARNING, "GLFW: Failed to initialize Window");
|
TRACELOG(LOG_WARNING, "GLFW: Failed to initialize Window");
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set window callback events
|
// Set window callback events
|
||||||
@ -1683,22 +1654,35 @@ static bool InitGraphicsDevice(int width, int height)
|
|||||||
|
|
||||||
// Load OpenGL extensions
|
// Load OpenGL extensions
|
||||||
// NOTE: GL procedures address loader is required to load extensions
|
// NOTE: GL procedures address loader is required to load extensions
|
||||||
|
|
||||||
rlLoadExtensions(glfwGetProcAddress);
|
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);
|
|
||||||
|
|
||||||
// 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 ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow();
|
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);
|
||||||
|
|
||||||
return true;
|
// Initialize hi-res timer
|
||||||
|
InitTimer();
|
||||||
|
|
||||||
|
// Initialize base path for storage
|
||||||
|
CORE.Storage.basePath = GetWorkingDirectory();
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close platform
|
||||||
|
static void ClosePlatform(void)
|
||||||
|
{
|
||||||
|
glfwDestroyWindow(platform.handle);
|
||||||
|
glfwTerminate();
|
||||||
|
|
||||||
|
#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
|
// GLFW3 Error Callback, runs on GLFW3 error
|
||||||
static void ErrorCallback(int error, const char *description)
|
static void ErrorCallback(int error, const char *description)
|
||||||
{
|
{
|
||||||
|
354
src/rcore_drm.c
354
src/rcore_drm.c
@ -140,21 +140,22 @@ static PlatformData platform = { 0 }; // Platform specific data
|
|||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Internal Functions Declaration
|
// 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 InitKeyboard(void); // Initialize raw keyboard system
|
||||||
static void RestoreKeyboard(void); // Restore keyboard system
|
static void RestoreKeyboard(void); // Restore keyboard system
|
||||||
#if defined(SUPPORT_SSH_KEYBOARD_RPI)
|
#if defined(SUPPORT_SSH_KEYBOARD_RPI)
|
||||||
static void ProcessKeyboard(void); // Process keyboard events
|
static void ProcessKeyboard(void); // Process keyboard events
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void InitEvdevInput(void); // Initialize evdev inputs
|
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 ConfigureEvdevDevice(char *device); // Identifies a input device and configures it for use if appropriate
|
||||||
static void PollKeyboardEvents(void); // Process evdev keyboard events
|
static void PollKeyboardEvents(void); // Process evdev keyboard events
|
||||||
static void *EventThread(void *arg); // Input device events reading thread
|
static void *EventThread(void *arg); // Input device events reading thread
|
||||||
|
|
||||||
static void InitGamepad(void); // Initialize raw gamepad input
|
static void InitGamepad(void); // Initialize raw gamepad input
|
||||||
static void *GamepadThread(void *arg); // Mouse reading thread
|
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 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
|
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)");
|
TRACELOG(LOG_INFO, " > raudio:.... not loaded (optional)");
|
||||||
#endif
|
#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;
|
if ((title != NULL) && (title[0] != 0)) CORE.Window.title = title;
|
||||||
|
|
||||||
// Initialize global input state
|
// 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.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.Mouse.cursor = MOUSE_CURSOR_ARROW;
|
||||||
CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN
|
CORE.Input.Gamepad.lastButtonPressed = GAMEPAD_BUTTON_UNKNOWN;
|
||||||
CORE.Window.eventWaiting = false;
|
|
||||||
|
// Initialize platform
|
||||||
|
//--------------------------------------------------------------
|
||||||
// Platform specific init window
|
InitPlatform();
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
// Initialize graphics device (display device and OpenGL context)
|
|
||||||
// NOTE: returns true if window and graphic device has been initialized successfully
|
// Initialize rlgl default data (buffers and shaders)
|
||||||
CORE.Window.ready = InitGraphicsDevice(width, height);
|
// 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 graphic device is no properly initialized, we end program
|
// Setup default viewport
|
||||||
if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return; }
|
SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
|
||||||
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)
|
|
||||||
//--------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
// Initialize random seed
|
|
||||||
SetRandomSeed((unsigned int)time(NULL));
|
|
||||||
|
|
||||||
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
|
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
|
||||||
// Load 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));
|
events = (AutomationEvent *)RL_CALLOC(MAX_CODE_AUTOMATION_EVENTS, sizeof(AutomationEvent));
|
||||||
CORE.Time.frameCounter = 0;
|
CORE.Time.frameCounter = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Initialize random seed
|
||||||
|
SetRandomSeed((unsigned int)time(NULL));
|
||||||
|
|
||||||
TRACELOG(LOG_INFO, "PLATFORM: DRM: Application initialized successfully");
|
TRACELOG(LOG_INFO, "PLATFORM: DRM: Application initialized successfully");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,93 +301,9 @@ void CloseWindow(void)
|
|||||||
timeEndPeriod(1); // Restore time period
|
timeEndPeriod(1); // Restore time period
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Platform specific close window
|
// De-initialize platform
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
if (platform.prevFB)
|
ClosePlatform();
|
||||||
{
|
|
||||||
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);
|
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
|
|
||||||
#if defined(SUPPORT_EVENTS_AUTOMATION)
|
#if defined(SUPPORT_EVENTS_AUTOMATION)
|
||||||
@ -808,28 +710,9 @@ void PollInputEvents(void)
|
|||||||
// Module Internal Functions Definition
|
// Module Internal Functions Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Initialize display device and framebuffer
|
// Initialize platform: graphics, inputs and more
|
||||||
// NOTE: width and height represent the screen (framebuffer) desired size, not actual display size
|
static int InitPlatform(void)
|
||||||
// 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)
|
|
||||||
{
|
{
|
||||||
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.fd = -1;
|
||||||
platform.connector = NULL;
|
platform.connector = NULL;
|
||||||
platform.modeIndex = -1;
|
platform.modeIndex = -1;
|
||||||
@ -838,6 +721,9 @@ static bool InitGraphicsDevice(int width, int height)
|
|||||||
platform.gbmSurface = NULL;
|
platform.gbmSurface = NULL;
|
||||||
platform.prevBO = NULL;
|
platform.prevBO = NULL;
|
||||||
platform.prevFB = 0;
|
platform.prevFB = 0;
|
||||||
|
|
||||||
|
CORE.Window.fullscreen = true;
|
||||||
|
CORE.Window.flags |= FLAG_FULLSCREEN_MODE;
|
||||||
|
|
||||||
#if defined(DEFAULT_GRAPHIC_DEVICE_DRM)
|
#if defined(DEFAULT_GRAPHIC_DEVICE_DRM)
|
||||||
platform.fd = open(DEFAULT_GRAPHIC_DEVICE_DRM, O_RDWR);
|
platform.fd = open(DEFAULT_GRAPHIC_DEVICE_DRM, O_RDWR);
|
||||||
@ -861,14 +747,14 @@ static bool InitGraphicsDevice(int width, int height)
|
|||||||
if (platform.fd == -1)
|
if (platform.fd == -1)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to open graphic card");
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to open graphic card");
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
drmModeRes *res = drmModeGetResources(platform.fd);
|
drmModeRes *res = drmModeGetResources(platform.fd);
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed get DRM resources");
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed get DRM resources");
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACELOG(LOG_TRACE, "DISPLAY: Connectors found: %i", res->count_connectors);
|
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");
|
TRACELOG(LOG_WARNING, "DISPLAY: No suitable DRM connector found");
|
||||||
drmModeFreeResources(res);
|
drmModeFreeResources(res);
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
drmModeEncoder *enc = drmModeGetEncoder(platform.fd, platform.connector->encoder_id);
|
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");
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get DRM mode encoder");
|
||||||
drmModeFreeResources(res);
|
drmModeFreeResources(res);
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
platform.crtc = drmModeGetCrtc(platform.fd, enc->crtc_id);
|
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");
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get DRM mode crtc");
|
||||||
drmModeFreeEncoder(enc);
|
drmModeFreeEncoder(enc);
|
||||||
drmModeFreeResources(res);
|
drmModeFreeResources(res);
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If InitWindow should use the current mode find it in the connector's mode list
|
// 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");
|
TRACELOG(LOG_WARNING, "DISPLAY: No matching DRM connector mode found");
|
||||||
drmModeFreeEncoder(enc);
|
drmModeFreeEncoder(enc);
|
||||||
drmModeFreeResources(res);
|
drmModeFreeResources(res);
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
CORE.Window.screen.width = CORE.Window.display.width;
|
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");
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to find a suitable DRM connector mode");
|
||||||
drmModeFreeEncoder(enc);
|
drmModeFreeEncoder(enc);
|
||||||
drmModeFreeResources(res);
|
drmModeFreeResources(res);
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
CORE.Window.display.width = platform.connector->modes[platform.modeIndex].hdisplay;
|
CORE.Window.display.width = platform.connector->modes[platform.modeIndex].hdisplay;
|
||||||
@ -982,7 +868,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||||||
if (!platform.gbmDevice)
|
if (!platform.gbmDevice)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create GBM device");
|
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,
|
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)
|
if (!platform.gbmSurface)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create GBM surface");
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create GBM surface");
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
EGLint samples = 0;
|
EGLint samples = 0;
|
||||||
@ -1030,7 +916,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||||||
if (platform.device == EGL_NO_DISPLAY)
|
if (platform.device == EGL_NO_DISPLAY)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the EGL device connection
|
// 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.
|
// If all of the calls to eglInitialize returned EGL_FALSE then an error has occurred.
|
||||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!eglChooseConfig(platform.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());
|
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);
|
TRACELOG(LOG_TRACE, "DISPLAY: EGL configs available: %d", numConfigs);
|
||||||
@ -1053,7 +939,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||||||
if (!configs)
|
if (!configs)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get memory for EGL configs");
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get memory for EGL configs");
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
EGLint matchingNumConfigs = 0;
|
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());
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to choose EGL config: 0x%x", eglGetError());
|
||||||
free(configs);
|
free(configs);
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACELOG(LOG_TRACE, "DISPLAY: EGL matching configs available: %d", matchingNumConfigs);
|
TRACELOG(LOG_TRACE, "DISPLAY: EGL matching configs available: %d", matchingNumConfigs);
|
||||||
@ -1091,7 +977,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to find a suitable EGL config");
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to find a suitable EGL config");
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set rendering API
|
// Set rendering API
|
||||||
@ -1102,7 +988,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||||||
if (platform.context == EGL_NO_CONTEXT)
|
if (platform.context == EGL_NO_CONTEXT)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL context");
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL context");
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create an EGL window surface
|
// Create an EGL window surface
|
||||||
@ -1111,7 +997,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||||||
if (EGL_NO_SURFACE == platform.surface)
|
if (EGL_NO_SURFACE == platform.surface)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL window surface: 0x%04x", eglGetError());
|
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
|
// 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)
|
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");
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to attach EGL rendering context to EGL surface");
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1147,19 +1033,123 @@ static bool InitGraphicsDevice(int width, int height)
|
|||||||
// NOTE: GL procedures address loader is required to load extensions
|
// NOTE: GL procedures address loader is required to load extensions
|
||||||
rlLoadExtensions(eglGetProcAddress);
|
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);
|
|
||||||
|
|
||||||
if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow();
|
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);
|
||||||
|
|
||||||
return true;
|
// 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)
|
||||||
|
|
||||||
|
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)
|
// Initialize Keyboard system (using standard input)
|
||||||
static void InitKeyboard(void)
|
static void InitKeyboard(void)
|
||||||
{
|
{
|
||||||
|
@ -73,7 +73,8 @@ static PlatformData platform = { 0 }; // Platform specific data
|
|||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Internal Functions Declaration
|
// 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
|
// 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
|
// NOTE: returns true if window and graphic device has been initialized successfully
|
||||||
CORE.Window.ready = InitGraphicsDevice(width, height);
|
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
|
// Initialize OpenGL context (states and resources)
|
||||||
CORE.Storage.basePath = GetWorkingDirectory();
|
// 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
|
||||||
// Initialize random seed
|
// NOTE: It updated CORE.Window.render.width and CORE.Window.render.height
|
||||||
SetRandomSeed((unsigned int)time(NULL));
|
SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
|
||||||
|
|
||||||
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
|
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
|
||||||
// Load default font
|
// Load default font
|
||||||
@ -198,6 +195,9 @@ void InitWindow(int width, int height, const char *title)
|
|||||||
CORE.Time.frameCounter = 0;
|
CORE.Time.frameCounter = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Initialize random seed
|
||||||
|
SetRandomSeed((unsigned int)time(NULL));
|
||||||
|
|
||||||
TRACELOG(LOG_INFO, "PLATFORM: CUSTOM: Application initialized successfully");
|
TRACELOG(LOG_INFO, "PLATFORM: CUSTOM: Application initialized successfully");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -597,25 +597,9 @@ void PollInputEvents(void)
|
|||||||
// Module Internal Functions Definition
|
// Module Internal Functions Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Initialize display device and framebuffer
|
// Initialize platform: graphics, inputs and more
|
||||||
// NOTE: width and height represent the screen (framebuffer) desired size, not actual display size
|
static int InitPlatform(void)
|
||||||
// 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)
|
|
||||||
{
|
{
|
||||||
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.fullscreen = true;
|
||||||
CORE.Window.flags |= FLAG_FULLSCREEN_MODE;
|
CORE.Window.flags |= FLAG_FULLSCREEN_MODE;
|
||||||
|
|
||||||
@ -677,7 +661,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||||||
if (platform.context == EGL_NO_CONTEXT)
|
if (platform.context == EGL_NO_CONTEXT)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL context");
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL context");
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create an EGL window surface
|
// 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)
|
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");
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to attach EGL rendering context to EGL surface");
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -726,19 +710,24 @@ static bool InitGraphicsDevice(int width, int height)
|
|||||||
// NOTE: GL procedures address loader is required to load extensions
|
// NOTE: GL procedures address loader is required to load extensions
|
||||||
rlLoadExtensions(eglGetProcAddress);
|
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;
|
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; }
|
||||||
|
|
||||||
if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow();
|
// Initialize hi-res timer
|
||||||
|
InitTimer();
|
||||||
|
|
||||||
|
// Initialize base path for storage
|
||||||
|
CORE.Storage.basePath = GetWorkingDirectory();
|
||||||
|
|
||||||
return true;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close platform
|
||||||
|
static void ClosePlatform(void)
|
||||||
|
{
|
||||||
|
// TODO: De-initialize graphics, inputs and more
|
||||||
}
|
}
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
|
198
src/rcore_web.c
198
src/rcore_web.c
@ -87,17 +87,18 @@ static PlatformData platform = { 0 }; // Platform specific data
|
|||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Internal Functions Declaration
|
// 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
|
// 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
|
// Window callbacks events
|
||||||
static void WindowSizeCallback(GLFWwindow *window, int width, int height); // GLFW3 WindowSize Callback, runs when window is resized
|
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 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 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 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 WindowDropCallback(GLFWwindow *window, int count, const char **paths); // GLFW3 Window Drop Callback, runs when drop files into window
|
||||||
|
|
||||||
// Input callbacks events
|
// Input callbacks events
|
||||||
static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods); // GLFW3 Keyboard Callback, runs on key pressed
|
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 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
|
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 EmscriptenFullscreenChangeCallback(int eventType, const EmscriptenFullscreenChangeEvent *event, void *userData);
|
||||||
static EM_BOOL EmscriptenWindowResizedCallback(int eventType, const EmscriptenUiEvent *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);
|
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 EmscriptenMouseCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData);
|
||||||
static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData);
|
static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData);
|
||||||
static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadEvent *gamepadEvent, 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)");
|
TRACELOG(LOG_INFO, " > raudio:.... not loaded (optional)");
|
||||||
#endif
|
#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;
|
if ((title != NULL) && (title[0] != 0)) CORE.Window.title = title;
|
||||||
|
|
||||||
// Initialize global input state
|
// 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.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.Mouse.cursor = MOUSE_CURSOR_ARROW;
|
||||||
CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN
|
CORE.Input.Gamepad.lastButtonPressed = GAMEPAD_BUTTON_UNKNOWN;
|
||||||
CORE.Window.eventWaiting = false;
|
|
||||||
|
|
||||||
|
// Initialize platform
|
||||||
// Platform specific init window
|
//--------------------------------------------------------------
|
||||||
//--------------------------------------------------------------
|
InitPlatform();
|
||||||
// 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 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
|
// Setup default viewport
|
||||||
SetRandomSeed((unsigned int)time(NULL));
|
// 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)
|
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
|
||||||
// Load default font
|
// Load default font
|
||||||
@ -264,6 +231,9 @@ void InitWindow(int width, int height, const char *title)
|
|||||||
CORE.Time.frameCounter = 0;
|
CORE.Time.frameCounter = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Initialize random seed
|
||||||
|
SetRandomSeed((unsigned int)time(NULL));
|
||||||
|
|
||||||
TRACELOG(LOG_INFO, "PLATFORM: WEB: Application initialized successfully");
|
TRACELOG(LOG_INFO, "PLATFORM: WEB: Application initialized successfully");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,10 +255,9 @@ void CloseWindow(void)
|
|||||||
|
|
||||||
rlglClose(); // De-init rlgl
|
rlglClose(); // De-init rlgl
|
||||||
|
|
||||||
// Platform specific close window
|
// De-initialize platform
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
glfwDestroyWindow(platform.handle);
|
ClosePlatform();
|
||||||
glfwTerminate();
|
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
|
|
||||||
#if defined(SUPPORT_EVENTS_AUTOMATION)
|
#if defined(SUPPORT_EVENTS_AUTOMATION)
|
||||||
@ -814,43 +783,14 @@ void PollInputEvents(void)
|
|||||||
// Module Internal Functions Definition
|
// Module Internal Functions Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Initialize display device and framebuffer
|
// Initialize platform: graphics, inputs and more
|
||||||
// NOTE: width and height represent the screen (framebuffer) desired size, not actual display size
|
static int InitPlatform(void)
|
||||||
// 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)
|
|
||||||
{
|
{
|
||||||
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);
|
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 GLFW internal global state
|
||||||
*/
|
int result = glfwInit();
|
||||||
|
if (result == GLFW_FALSE) { TRACELOG(LOG_WARNING, "GLFW: Failed to initialize GLFW"); return -1; }
|
||||||
if (!glfwInit())
|
|
||||||
{
|
|
||||||
TRACELOG(LOG_WARNING, "GLFW: Failed to initialize GLFW");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
glfwDefaultWindowHints(); // Set default windows hints
|
glfwDefaultWindowHints(); // Set default windows hints
|
||||||
// glfwWindowHint(GLFW_RED_BITS, 8); // Framebuffer red color component bits
|
// glfwWindowHint(GLFW_RED_BITS, 8); // Framebuffer red color component bits
|
||||||
@ -1016,7 +956,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||||||
{
|
{
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
TRACELOG(LOG_WARNING, "GLFW: Failed to initialize Window");
|
TRACELOG(LOG_WARNING, "GLFW: Failed to initialize Window");
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// WARNING: glfwCreateWindow() title doesn't work with emscripten
|
// WARNING: glfwCreateWindow() title doesn't work with emscripten
|
||||||
@ -1037,6 +977,12 @@ static bool InitGraphicsDevice(int width, int height)
|
|||||||
glfwSetCursorEnterCallback(platform.handle, CursorEnterCallback);
|
glfwSetCursorEnterCallback(platform.handle, CursorEnterCallback);
|
||||||
|
|
||||||
glfwMakeContextCurrent(platform.handle);
|
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)
|
// 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
|
// 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, " > 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, " > 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);
|
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
|
// Initialize hi-res timer
|
||||||
// NOTE: GL procedures address loader is required to load extensions
|
InitTimer();
|
||||||
rlLoadExtensions(glfwGetProcAddress);
|
|
||||||
|
// 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)
|
// WARNING: Below resize code was breaking fullscreen mode for sample games and examples, it needs review
|
||||||
// NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl
|
// Check fullscreen change events(note this is done on the window since most browsers don't support this on #canvas)
|
||||||
rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
|
// 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
|
// Trigger this once to get initial window sizing
|
||||||
// NOTE: It updated CORE.Window.render.width and CORE.Window.render.height
|
EmscriptenResizeCallback(EMSCRIPTEN_EVENT_RESIZE, NULL, NULL);
|
||||||
SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
|
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
return true;
|
// 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);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close platform
|
||||||
|
static void ClosePlatform(void)
|
||||||
|
{
|
||||||
|
glfwDestroyWindow(platform.handle);
|
||||||
|
glfwTerminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
// GLFW3 Error Callback, runs on GLFW3 error
|
// GLFW3 Error Callback, runs on GLFW3 error
|
||||||
|
Loading…
Reference in New Issue
Block a user