| @ -0,0 +1,591 @@ | |||||
| /********************************************************************************************** | |||||
| * | |||||
| * rcore_<platform> template - Functions to manage window, graphics device and inputs | |||||
| * | |||||
| * PLATFORM: <PLATFORM> | |||||
| * - TODO: Define the target platform for the core | |||||
| * | |||||
| * LIMITATIONS: | |||||
| * - Limitation 01 | |||||
| * - Limitation 02 | |||||
| * | |||||
| * POSSIBLE IMPROVEMENTS: | |||||
| * - Improvement 01 | |||||
| * - Improvement 02 | |||||
| * | |||||
| * ADDITIONAL NOTES: | |||||
| * - TRACELOG() function is located in raylib [utils] module | |||||
| * | |||||
| * CONFIGURATION: | |||||
| * #define RCORE_PLATFORM_CUSTOM_FLAG | |||||
| * Custom flag for rcore on target platform -not used- | |||||
| * | |||||
| * DEPENDENCIES: | |||||
| * - <platform-specific SDK dependency> | |||||
| * - gestures: Gestures system for touch-ready devices (or simulated from mouse inputs) | |||||
| * | |||||
| * | |||||
| * LICENSE: zlib/libpng | |||||
| * | |||||
| * Copyright (c) 2013-2024 Ramon Santamaria (@raysan5) and contributors | |||||
| * | |||||
| * This software is provided "as-is", without any express or implied warranty. In no event | |||||
| * will the authors be held liable for any damages arising from the use of this software. | |||||
| * | |||||
| * Permission is granted to anyone to use this software for any purpose, including commercial | |||||
| * applications, and to alter it and redistribute it freely, subject to the following restrictions: | |||||
| * | |||||
| * 1. The origin of this software must not be misrepresented; you must not claim that you | |||||
| * wrote the original software. If you use this software in a product, an acknowledgment | |||||
| * in the product documentation would be appreciated but is not required. | |||||
| * | |||||
| * 2. Altered source versions must be plainly marked as such, and must not be misrepresented | |||||
| * as being the original software. | |||||
| * | |||||
| * 3. This notice may not be removed or altered from any source distribution. | |||||
| * | |||||
| **********************************************************************************************/ | |||||
| // TODO: Include the platform specific libraries | |||||
| //---------------------------------------------------------------------------------- | |||||
| // Types and Structures Definition | |||||
| //---------------------------------------------------------------------------------- | |||||
| typedef struct { | |||||
| // TODO: Define the platform specific variables required | |||||
| // Display data | |||||
| EGLDisplay device; // Native display device (physical screen connection) | |||||
| EGLSurface surface; // Surface to draw on, framebuffers (connected to context) | |||||
| EGLContext context; // Graphic context, mode in which drawing can be done | |||||
| EGLConfig config; // Graphic config | |||||
| } PlatformData; | |||||
| //---------------------------------------------------------------------------------- | |||||
| // Global Variables Definition | |||||
| //---------------------------------------------------------------------------------- | |||||
| extern CoreData CORE; // Global CORE state context | |||||
| static PlatformData platform = { 0 }; // Platform specific data | |||||
| //---------------------------------------------------------------------------------- | |||||
| // Module Internal Functions Declaration | |||||
| //---------------------------------------------------------------------------------- | |||||
| int InitPlatform(void); // Initialize platform (graphics, inputs and more) | |||||
| bool InitGraphicsDevice(void); // Initialize graphics device | |||||
| //---------------------------------------------------------------------------------- | |||||
| // Module Functions Declaration | |||||
| //---------------------------------------------------------------------------------- | |||||
| // NOTE: Functions declaration is provided by raylib.h | |||||
| //---------------------------------------------------------------------------------- | |||||
| // Module Functions Definition: Window and Graphics Device | |||||
| //---------------------------------------------------------------------------------- | |||||
| // Check if application should close | |||||
| bool WindowShouldClose(void) | |||||
| { | |||||
| if (CORE.Window.ready) return CORE.Window.shouldClose; | |||||
| else return true; | |||||
| } | |||||
| // Toggle fullscreen mode | |||||
| void ToggleFullscreen(void) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "ToggleFullscreen() not available on target platform"); | |||||
| } | |||||
| // Toggle borderless windowed mode | |||||
| void ToggleBorderlessWindowed(void) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "ToggleBorderlessWindowed() not available on target platform"); | |||||
| } | |||||
| // Set window state: maximized, if resizable | |||||
| void MaximizeWindow(void) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "MaximizeWindow() not available on target platform"); | |||||
| } | |||||
| // Set window state: minimized | |||||
| void MinimizeWindow(void) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "MinimizeWindow() not available on target platform"); | |||||
| } | |||||
| // Set window state: not minimized/maximized | |||||
| void RestoreWindow(void) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "RestoreWindow() not available on target platform"); | |||||
| } | |||||
| // Set window configuration state using flags | |||||
| void SetWindowState(unsigned int flags) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "SetWindowState() not available on target platform"); | |||||
| } | |||||
| // Clear window configuration state flags | |||||
| void ClearWindowState(unsigned int flags) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "ClearWindowState() not available on target platform"); | |||||
| } | |||||
| // Set icon for window | |||||
| void SetWindowIcon(Image image) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "SetWindowIcon() not available on target platform"); | |||||
| } | |||||
| // Set icon for window | |||||
| void SetWindowIcons(Image *images, int count) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "SetWindowIcons() not available on target platform"); | |||||
| } | |||||
| // Set title for window | |||||
| void SetWindowTitle(const char *title) | |||||
| { | |||||
| CORE.Window.title = title; | |||||
| } | |||||
| // Set window position on screen (windowed mode) | |||||
| void SetWindowPosition(int x, int y) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "SetWindowPosition() not available on target platform"); | |||||
| } | |||||
| // Set monitor for the current window | |||||
| void SetWindowMonitor(int monitor) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "SetWindowMonitor() not available on target platform"); | |||||
| } | |||||
| // Set window minimum dimensions (FLAG_WINDOW_RESIZABLE) | |||||
| void SetWindowMinSize(int width, int height) | |||||
| { | |||||
| CORE.Window.screenMin.width = width; | |||||
| CORE.Window.screenMin.height = height; | |||||
| } | |||||
| // Set window maximum dimensions (FLAG_WINDOW_RESIZABLE) | |||||
| void SetWindowMaxSize(int width, int height) | |||||
| { | |||||
| CORE.Window.screenMax.width = width; | |||||
| CORE.Window.screenMax.height = height; | |||||
| } | |||||
| // Set window dimensions | |||||
| void SetWindowSize(int width, int height) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "SetWindowSize() not available on target platform"); | |||||
| } | |||||
| // Set window opacity, value opacity is between 0.0 and 1.0 | |||||
| void SetWindowOpacity(float opacity) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "SetWindowOpacity() not available on target platform"); | |||||
| } | |||||
| // Set window focused | |||||
| void SetWindowFocused(void) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "SetWindowFocused() not available on target platform"); | |||||
| } | |||||
| // Get native window handle | |||||
| void *GetWindowHandle(void) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "GetWindowHandle() not implemented on target platform"); | |||||
| return NULL; | |||||
| } | |||||
| // Get number of monitors | |||||
| int GetMonitorCount(void) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "GetMonitorCount() not implemented on target platform"); | |||||
| return 1; | |||||
| } | |||||
| // Get number of monitors | |||||
| int GetCurrentMonitor(void) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "GetCurrentMonitor() not implemented on target platform"); | |||||
| return 0; | |||||
| } | |||||
| // Get selected monitor position | |||||
| Vector2 GetMonitorPosition(int monitor) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "GetMonitorPosition() not implemented on target platform"); | |||||
| return (Vector2){ 0, 0 }; | |||||
| } | |||||
| // Get selected monitor width (currently used by monitor) | |||||
| int GetMonitorWidth(int monitor) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "GetMonitorWidth() not implemented on target platform"); | |||||
| return 0; | |||||
| } | |||||
| // Get selected monitor height (currently used by monitor) | |||||
| int GetMonitorHeight(int monitor) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "GetMonitorHeight() not implemented on target platform"); | |||||
| return 0; | |||||
| } | |||||
| // Get selected monitor physical width in millimetres | |||||
| int GetMonitorPhysicalWidth(int monitor) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "GetMonitorPhysicalWidth() not implemented on target platform"); | |||||
| return 0; | |||||
| } | |||||
| // Get selected monitor physical height in millimetres | |||||
| int GetMonitorPhysicalHeight(int monitor) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "GetMonitorPhysicalHeight() not implemented on target platform"); | |||||
| return 0; | |||||
| } | |||||
| // Get selected monitor refresh rate | |||||
| int GetMonitorRefreshRate(int monitor) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "GetMonitorRefreshRate() not implemented on target platform"); | |||||
| return 0; | |||||
| } | |||||
| // Get the human-readable, UTF-8 encoded name of the selected monitor | |||||
| const char *GetMonitorName(int monitor) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "GetMonitorName() not implemented on target platform"); | |||||
| return ""; | |||||
| } | |||||
| // Get window position XY on monitor | |||||
| Vector2 GetWindowPosition(void) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "GetWindowPosition() not implemented on target platform"); | |||||
| return (Vector2){ 0, 0 }; | |||||
| } | |||||
| // Get window scale DPI factor for current monitor | |||||
| Vector2 GetWindowScaleDPI(void) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "GetWindowScaleDPI() not implemented on target platform"); | |||||
| return (Vector2){ 1.0f, 1.0f }; | |||||
| } | |||||
| // Set clipboard text content | |||||
| void SetClipboardText(const char *text) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "SetClipboardText() not implemented on target platform"); | |||||
| } | |||||
| // Get clipboard text content | |||||
| // NOTE: returned string is allocated and freed by GLFW | |||||
| const char *GetClipboardText(void) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "GetClipboardText() not implemented on target platform"); | |||||
| return NULL; | |||||
| } | |||||
| // Show mouse cursor | |||||
| void ShowCursor(void) | |||||
| { | |||||
| CORE.Input.Mouse.cursorHidden = false; | |||||
| } | |||||
| // Hides mouse cursor | |||||
| void HideCursor(void) | |||||
| { | |||||
| CORE.Input.Mouse.cursorHidden = true; | |||||
| } | |||||
| // Enables cursor (unlock cursor) | |||||
| void EnableCursor(void) | |||||
| { | |||||
| // Set cursor position in the middle | |||||
| SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2); | |||||
| CORE.Input.Mouse.cursorHidden = false; | |||||
| } | |||||
| // Disables cursor (lock cursor) | |||||
| void DisableCursor(void) | |||||
| { | |||||
| // Set cursor position in the middle | |||||
| SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2); | |||||
| CORE.Input.Mouse.cursorHidden = true; | |||||
| } | |||||
| // Swap back buffer with front buffer (screen drawing) | |||||
| void SwapScreenBuffer(void) | |||||
| { | |||||
| eglSwapBuffers(platform.device, platform.surface); | |||||
| } | |||||
| //---------------------------------------------------------------------------------- | |||||
| // Module Functions Definition: Misc | |||||
| //---------------------------------------------------------------------------------- | |||||
| // Get elapsed time measure in seconds since InitTimer() | |||||
| double GetTime(void) | |||||
| { | |||||
| double time = 0.0; | |||||
| struct timespec ts = { 0 }; | |||||
| clock_gettime(CLOCK_MONOTONIC, &ts); | |||||
| unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec; | |||||
| time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer() | |||||
| return time; | |||||
| } | |||||
| // Open URL with default system browser (if available) | |||||
| // NOTE: This function is only safe to use if you control the URL given. | |||||
| // A user could craft a malicious string performing another action. | |||||
| // Only call this function yourself not with user input or make sure to check the string yourself. | |||||
| // Ref: https://github.com/raysan5/raylib/issues/686 | |||||
| void OpenURL(const char *url) | |||||
| { | |||||
| // Security check to (partially) avoid malicious code on target platform | |||||
| if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character"); | |||||
| else | |||||
| { | |||||
| // TODO: | |||||
| } | |||||
| } | |||||
| //---------------------------------------------------------------------------------- | |||||
| // Module Functions Definition: Inputs | |||||
| //---------------------------------------------------------------------------------- | |||||
| // Set internal gamepad mappings | |||||
| int SetGamepadMappings(const char *mappings) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "SetGamepadMappings() not implemented on target platform"); | |||||
| return 0; | |||||
| } | |||||
| // Set mouse position XY | |||||
| void SetMousePosition(int x, int y) | |||||
| { | |||||
| CORE.Input.Mouse.currentPosition = (Vector2){ (float)x, (float)y }; | |||||
| CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition; | |||||
| } | |||||
| // Set mouse cursor | |||||
| void SetMouseCursor(int cursor) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "SetMouseCursor() not implemented on target platform"); | |||||
| } | |||||
| // Register all input events | |||||
| void PollInputEvents(void) | |||||
| { | |||||
| #if defined(SUPPORT_GESTURES_SYSTEM) | |||||
| // NOTE: Gestures update must be called every frame to reset gestures correctly | |||||
| // because ProcessGestureEvent() is just called on an event, not every frame | |||||
| UpdateGestures(); | |||||
| #endif | |||||
| // Reset keys/chars pressed registered | |||||
| CORE.Input.Keyboard.keyPressedQueueCount = 0; | |||||
| CORE.Input.Keyboard.charPressedQueueCount = 0; | |||||
| // Reset key repeats | |||||
| for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) CORE.Input.Keyboard.keyRepeatInFrame[i] = 0; | |||||
| // Reset last gamepad button/axis registered state | |||||
| CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN | |||||
| //CORE.Input.Gamepad.axisCount = 0; | |||||
| // Register previous touch states | |||||
| for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.previousTouchState[i] = CORE.Input.Touch.currentTouchState[i]; | |||||
| // Reset touch positions | |||||
| // TODO: It resets on target platform the mouse position and not filled again until a move-event, | |||||
| // so, if mouse is not moved it returns a (0, 0) position... this behaviour should be reviewed! | |||||
| //for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.position[i] = (Vector2){ 0, 0 }; | |||||
| // Register previous keys states | |||||
| // NOTE: Android supports up to 260 keys | |||||
| for (int i = 0; i < 260; i++) | |||||
| { | |||||
| CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i]; | |||||
| CORE.Input.Keyboard.keyRepeatInFrame[i] = 0; | |||||
| } | |||||
| // TODO: Poll input events for current platform | |||||
| } | |||||
| //---------------------------------------------------------------------------------- | |||||
| // Module Internal Functions Definition | |||||
| //---------------------------------------------------------------------------------- | |||||
| // Initialize platform: graphics, inputs and more | |||||
| int InitPlatform(void) | |||||
| { | |||||
| // TODO: Initialize graphic device: display/window | |||||
| // It usually requires setting up the platform display system configuration | |||||
| // and connexion with the GPU through some system graphic API | |||||
| // raylib uses OpenGL so, platform should create that kind of connection | |||||
| // Below example illustrates that process using EGL library | |||||
| //---------------------------------------------------------------------------- | |||||
| CORE.Window.fullscreen = true; | |||||
| CORE.Window.flags |= FLAG_FULLSCREEN_MODE; | |||||
| EGLint samples = 0; | |||||
| EGLint sampleBuffer = 0; | |||||
| if (CORE.Window.flags & FLAG_MSAA_4X_HINT) | |||||
| { | |||||
| samples = 4; | |||||
| sampleBuffer = 1; | |||||
| TRACELOG(LOG_INFO, "DISPLAY: Trying to enable MSAA x4"); | |||||
| } | |||||
| const EGLint framebufferAttribs[] = | |||||
| { | |||||
| EGL_RENDERABLE_TYPE, (rlGetVersion() == RL_OPENGL_ES_30)? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT, // Type of context support | |||||
| EGL_RED_SIZE, 8, // RED color bit depth (alternative: 5) | |||||
| EGL_GREEN_SIZE, 8, // GREEN color bit depth (alternative: 6) | |||||
| EGL_BLUE_SIZE, 8, // BLUE color bit depth (alternative: 5) | |||||
| //EGL_TRANSPARENT_TYPE, EGL_NONE, // Request transparent framebuffer (EGL_TRANSPARENT_RGB does not work on RPI) | |||||
| EGL_DEPTH_SIZE, 16, // Depth buffer size (Required to use Depth testing!) | |||||
| //EGL_STENCIL_SIZE, 8, // Stencil buffer size | |||||
| EGL_SAMPLE_BUFFERS, sampleBuffer, // Activate MSAA | |||||
| EGL_SAMPLES, samples, // 4x Antialiasing if activated (Free on MALI GPUs) | |||||
| EGL_NONE | |||||
| }; | |||||
| const EGLint contextAttribs[] = | |||||
| { | |||||
| EGL_CONTEXT_CLIENT_VERSION, 2, | |||||
| EGL_NONE | |||||
| }; | |||||
| EGLint numConfigs = 0; | |||||
| // Get an EGL device connection | |||||
| platform.device = eglGetDisplay(EGL_DEFAULT_DISPLAY); | |||||
| if (platform.device == EGL_NO_DISPLAY) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device"); | |||||
| return false; | |||||
| } | |||||
| // Initialize the EGL device connection | |||||
| if (eglInitialize(platform.device, NULL, NULL) == EGL_FALSE) | |||||
| { | |||||
| // If all of the calls to eglInitialize returned EGL_FALSE then an error has occurred. | |||||
| TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device"); | |||||
| return false; | |||||
| } | |||||
| // Get an appropriate EGL framebuffer configuration | |||||
| eglChooseConfig(platform.device, framebufferAttribs, &platform.config, 1, &numConfigs); | |||||
| // Set rendering API | |||||
| eglBindAPI(EGL_OPENGL_ES_API); | |||||
| // Create an EGL rendering context | |||||
| platform.context = eglCreateContext(platform.device, platform.config, EGL_NO_CONTEXT, contextAttribs); | |||||
| if (platform.context == EGL_NO_CONTEXT) | |||||
| { | |||||
| TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL context"); | |||||
| return -1; | |||||
| } | |||||
| // Create an EGL window surface | |||||
| EGLint displayFormat = 0; | |||||
| // EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is guaranteed to be accepted by ANativeWindow_setBuffersGeometry() | |||||
| // As soon as we picked a EGLConfig, we can safely reconfigure the ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID | |||||
| eglGetConfigAttrib(platform.device, platform.config, EGL_NATIVE_VISUAL_ID, &displayFormat); | |||||
| // Android specific call | |||||
| ANativeWindow_setBuffersGeometry(platform.app->window, 0, 0, displayFormat); // Force use of native display size | |||||
| platform.surface = eglCreateWindowSurface(platform.device, platform.config, platform.app->window, NULL); | |||||
| // There must be at least one frame displayed before the buffers are swapped | |||||
| eglSwapInterval(platform.device, 1); | |||||
| EGLBoolean result = eglMakeCurrent(platform.device, platform.surface, platform.surface, platform.context); | |||||
| // Check surface and context activation | |||||
| if (result != EGL_FALSE) | |||||
| { | |||||
| CORE.Window.ready = true; | |||||
| CORE.Window.render.width = CORE.Window.screen.width; | |||||
| CORE.Window.render.height = CORE.Window.screen.height; | |||||
| CORE.Window.currentFbo.width = CORE.Window.render.width; | |||||
| CORE.Window.currentFbo.height = CORE.Window.render.height; | |||||
| TRACELOG(LOG_INFO, "DISPLAY: Device initialized successfully"); | |||||
| TRACELOG(LOG_INFO, " > Display size: %i x %i", CORE.Window.display.width, CORE.Window.display.height); | |||||
| TRACELOG(LOG_INFO, " > 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); | |||||
| } | |||||
| else | |||||
| { | |||||
| TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphics device"); | |||||
| return -1; | |||||
| } | |||||
| //---------------------------------------------------------------------------- | |||||
| // If everything work as expected, we can continue | |||||
| CORE.Window.render.width = CORE.Window.screen.width; | |||||
| CORE.Window.render.height = CORE.Window.screen.height; | |||||
| CORE.Window.currentFbo.width = CORE.Window.render.width; | |||||
| CORE.Window.currentFbo.height = CORE.Window.render.height; | |||||
| TRACELOG(LOG_INFO, "DISPLAY: Device initialized successfully"); | |||||
| TRACELOG(LOG_INFO, " > Display size: %i x %i", CORE.Window.display.width, CORE.Window.display.height); | |||||
| TRACELOG(LOG_INFO, " > 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); | |||||
| // TODO: Load OpenGL extensions | |||||
| // NOTE: GL procedures address loader is required to load extensions | |||||
| //---------------------------------------------------------------------------- | |||||
| rlLoadExtensions(eglGetProcAddress); | |||||
| //---------------------------------------------------------------------------- | |||||
| // TODO: Initialize input events system | |||||
| // It could imply keyboard, mouse, gamepad, touch... | |||||
| // Depending on the platform libraries/SDK it could use a callback mechanism | |||||
| // For system events and inputs evens polling on a per-frame basis, use PollInputEvents() | |||||
| //---------------------------------------------------------------------------- | |||||
| // ... | |||||
| //---------------------------------------------------------------------------- | |||||
| // TODO: Initialize timing system | |||||
| //---------------------------------------------------------------------------- | |||||
| InitTimer(); | |||||
| //---------------------------------------------------------------------------- | |||||
| // TODO: Initialize storage system | |||||
| //---------------------------------------------------------------------------- | |||||
| CORE.Storage.basePath = GetWorkingDirectory(); | |||||
| //---------------------------------------------------------------------------- | |||||
| TRACELOG(LOG_INFO, "PLATFORM: CUSTOM: Initialized successfully"); | |||||
| return 0; | |||||
| } | |||||
| // Close platform | |||||
| void ClosePlatform(void) | |||||
| { | |||||
| // TODO: De-initialize graphics, inputs and more | |||||
| } | |||||
| // EOF | |||||