summaryrefslogtreecommitdiffhomepage
path: root/src/platforms
diff options
context:
space:
mode:
authorColleague Riley <[email protected]>2024-05-07 14:30:52 -0400
committerGitHub <[email protected]>2024-05-07 20:30:52 +0200
commit9805fe0b1afe8a25a5c7be92468a58bc2fbf8e4a (patch)
tree9ffcdcf6389d9593a6ad00c47b0b96c558236916 /src/platforms
parentfa2b1c8f094db18466079fcd2f8e488bf89095c2 (diff)
downloadraylib-9805fe0b1afe8a25a5c7be92468a58bc2fbf8e4a.tar.gz
raylib-9805fe0b1afe8a25a5c7be92468a58bc2fbf8e4a.zip
make RGFW a custom platform (#3941)
* fix minor bugs and errors (x86) for the RGFW platform, update RGFW platform license, update makefile info for RGFW platform * revert * (RGFW) (winapi) fix mouse hide bug when cursor changes * ensure PLATFORM_SHELL is defined (PLATFORM_RGFW) --------- Co-authored-by: ColleagueRiley <[email protected]>
Diffstat (limited to 'src/platforms')
-rw-r--r--src/platforms/rcore_desktop_rgfw.c1519
1 files changed, 1519 insertions, 0 deletions
diff --git a/src/platforms/rcore_desktop_rgfw.c b/src/platforms/rcore_desktop_rgfw.c
new file mode 100644
index 00000000..e4f74938
--- /dev/null
+++ b/src/platforms/rcore_desktop_rgfw.c
@@ -0,0 +1,1519 @@
+/**********************************************************************************************
+*
+* rcore_desktop_rgfw template - Functions to manage window, graphics device and inputs
+*
+* PLATFORM: RGFW
+* - Windows (Win32, Win64)
+* - Linux (X11/Wayland desktop mode)
+* - MacOS (Cocoa)
+*
+* 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:
+* - RGFW.h (main library): Windowing and inputs management
+* - gestures: Gestures system for touch-ready devices (or simulated from mouse inputs)
+*
+*
+* LICENSE: zlib/libpng
+*
+* Copyright (c) 2013-2024 Ramon Santamaria (@raysan5), Colleague Riley 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.
+*
+**********************************************************************************************/
+
+#ifdef GRAPHICS_API_OPENGL_ES2
+#define RGFW_OPENGL_ES2
+#endif
+
+void ShowCursor(void);
+void CloseWindow(void);
+
+#define _INPUT_EVENT_CODES_H
+#define _APISETSTRING_
+#define RGFWDEF
+#define _XTYPEDEF_FONT
+#define RGFW_IMPLEMENTATION
+
+#define WIN32_LEAN_AND_MEAN
+#define Rectangle rectangle_win32
+#define CloseWindow CloseWindow_win32
+#define ShowCursor __imp_ShowCursor
+
+#define Point NSPOINT
+#define Size NSSIZE
+
+#ifdef _MSC_VER
+__declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int CodePage, unsigned long dwFlags, const char* lpMultiByteStr, int cbMultiByte, wchar_t* lpWideCharStr, int cchWideChar);
+#endif
+
+#include "../external/RGFW.h"
+#undef DrawText
+#undef ShowCursor
+#undef CloseWindow
+#undef Point
+#undef Size
+
+#define Rectangle struct Rectangle
+void CloseWindow(void);
+void ShowCursor(void);
+
+
+#include <stdbool.h>
+
+//----------------------------------------------------------------------------------
+// Types and Structures Definition
+//----------------------------------------------------------------------------------
+typedef struct {
+ // TODO: Define the platform specific variables required
+
+ RGFW_window* window; // Native display device (physical screen connection)
+} PlatformData;
+
+//----------------------------------------------------------------------------------
+// Global Variables Definition
+//----------------------------------------------------------------------------------
+extern CoreData CORE; // Global CORE state context
+
+static PlatformData platform = { NULL }; // Platform specific
+
+//----------------------------------------------------------------------------------
+// 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.shouldClose == false)
+ CORE.Window.shouldClose = RGFW_window_shouldClose(platform.window);
+ if (CORE.Window.ready) return CORE.Window.shouldClose;
+ else return true;
+}
+
+// Toggle fullscreen mode
+void ToggleFullscreen(void)
+{
+ RGFW_window_maximize(platform.window);
+ ToggleBorderlessWindowed();
+}
+
+// Toggle borderless windowed mode
+void ToggleBorderlessWindowed(void)
+{
+ CORE.Window.flags & FLAG_WINDOW_UNDECORATED;
+
+ if (platform.window != NULL)
+ TRACELOG(LOG_WARNING, "ToggleBorderlessWindowed() after window creation not available on target platform");
+}
+
+// Set window state: maximized, if resizable
+void MaximizeWindow(void)
+{
+ RGFW_window_maximize(platform.window);
+}
+
+// Set window state: minimized
+void MinimizeWindow(void)
+{
+ RGFW_window_minimize(platform.window);
+}
+
+// Set window state: not minimized/maximized
+void RestoreWindow(void)
+{
+ RGFW_window_restore(platform.window);
+}
+
+// Set window configuration state using flags
+void SetWindowState(unsigned int flags)
+{
+ CORE.Window.flags |= flags;
+
+ if (flags & FLAG_VSYNC_HINT)
+ {
+ RGFW_window_swapInterval(platform.window, 1);
+ }
+ if (flags & FLAG_FULLSCREEN_MODE)
+ {
+ RGFW_window_maximize(platform.window);
+ ToggleBorderlessWindowed();
+ }
+ if (flags & FLAG_WINDOW_RESIZABLE)
+ {
+ RGFW_window_setMaxSize(platform.window, RGFW_AREA(platform.window->r.w, platform.window->r.h));
+ RGFW_window_setMinSize(platform.window, RGFW_AREA(platform.window->r.w, platform.window->r.h));
+ }
+ if (flags & FLAG_WINDOW_UNDECORATED)
+ {
+ ToggleBorderlessWindowed();
+ }
+ if (flags & FLAG_WINDOW_HIDDEN)
+ {
+ RGFW_window_hide(platform.window);
+ }
+ if (flags & FLAG_WINDOW_MINIMIZED)
+ {
+ RGFW_window_minimize(platform.window);
+ }
+ if (flags & FLAG_WINDOW_MAXIMIZED)
+ {
+ RGFW_window_maximize(platform.window);
+ }
+ if (flags & FLAG_WINDOW_UNFOCUSED)
+ {
+ TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_UNFOCUSED is not supported on PLATFORM_DESKTOP_SDL");
+ }
+ if (flags & FLAG_WINDOW_TOPMOST)
+ {
+ TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_TOPMOST is not supported on PLATFORM_DESKTOP_RGFW");
+ }
+ if (flags & FLAG_WINDOW_ALWAYS_RUN)
+ {
+ TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_ALWAYS_RUN is not supported on PLATFORM_DESKTOP_RGFW");
+ }
+ if (flags & FLAG_WINDOW_TRANSPARENT)
+ {
+ TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_TRANSPARENT is not supported on PLATFORM_DESKTOP_RGFW");
+ }
+ if (flags & FLAG_WINDOW_HIGHDPI)
+ {
+ TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_HIGHDPI is not supported on PLATFORM_DESKTOP_RGFW");
+ }
+ if (flags & FLAG_WINDOW_MOUSE_PASSTHROUGH)
+ {
+ TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_MOUSE_PASSTHROUGH is not supported on PLATFORM_DESKTOP_RGFW");
+ }
+ if (flags & FLAG_BORDERLESS_WINDOWED_MODE)
+ {
+ ToggleBorderlessWindowed();
+ }
+ if (flags & FLAG_MSAA_4X_HINT)
+ {
+ RGFW_setGLSamples(4);
+ }
+ if (flags & FLAG_INTERLACED_HINT)
+ {
+ TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_INTERLACED_HINT is not supported on PLATFORM_DESKTOP_RGFW");
+ }
+}
+
+// Clear window configuration state flags
+void ClearWindowState(unsigned int flags)
+{
+ CORE.Window.flags &= ~flags;
+
+ if (flags & FLAG_VSYNC_HINT)
+ {
+ RGFW_window_swapInterval(platform.window, 0);
+ }
+ if (flags & FLAG_FULLSCREEN_MODE)
+ {
+ ToggleBorderlessWindowed();
+ RGFW_window_restore(platform.window);
+ CORE.Window.fullscreen = false;
+ }
+ if (flags & FLAG_WINDOW_RESIZABLE)
+ {
+ RGFW_window_setMaxSize(platform.window, RGFW_AREA(0, 0));
+ RGFW_window_setMinSize(platform.window, RGFW_AREA(0, 0));
+ }
+ if (flags & FLAG_WINDOW_UNDECORATED)
+ {
+ ToggleBorderlessWindowed();
+ }
+ if (flags & FLAG_WINDOW_HIDDEN)
+ {
+ RGFW_window_show(platform.window);
+ }
+ if (flags & FLAG_WINDOW_MINIMIZED)
+ {
+ RGFW_window_restore(platform.window);
+ }
+ if (flags & FLAG_WINDOW_MAXIMIZED)
+ {
+ RGFW_window_restore(platform.window);
+ }
+ if (flags & FLAG_WINDOW_UNFOCUSED)
+ {
+ TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_UNFOCUSED is not supported on PLATFORM_DESKTOP_RGFW");
+ }
+ if (flags & FLAG_WINDOW_TOPMOST)
+ {
+ TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_TOPMOST is not supported on PLATFORM_DESKTOP_RGFW");
+ }
+ if (flags & FLAG_WINDOW_ALWAYS_RUN)
+ {
+ TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_ALWAYS_RUN is not supported on PLATFORM_DESKTOP_RGFW");
+ }
+ if (flags & FLAG_WINDOW_TRANSPARENT)
+ {
+ TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_TRANSPARENT is not supported on PLATFORM_DESKTOP_RGFW");
+ }
+ if (flags & FLAG_WINDOW_HIGHDPI)
+ {
+ // NOTE: There also doesn't seem to be a feature to disable high DPI once enabled
+ TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_HIGHDPI is not supported on PLATFORM_DESKTOP_RGFW");
+ }
+ if (flags & FLAG_WINDOW_MOUSE_PASSTHROUGH)
+ {
+ //SDL_SetWindowGrab(platform.window, SDL_TRUE);
+ TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_MOUSE_PASSTHROUGH is not supported on PLATFORM_DESKTOP_RGFW");
+ }
+ if (flags & FLAG_BORDERLESS_WINDOWED_MODE)
+ {
+ ToggleFullscreen();
+ }
+ if (flags & FLAG_MSAA_4X_HINT)
+ {
+ RGFW_setGLSamples(0);
+ }
+ if (flags & FLAG_INTERLACED_HINT)
+ {
+ TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_INTERLACED_HINT is not supported on PLATFORM_DESKTOP_RGFW");
+ }
+}
+
+// Set icon for window
+void SetWindowIcon(Image image)
+{
+ i32 channels = 4;
+
+ switch (image.format) {
+ case PIXELFORMAT_UNCOMPRESSED_GRAYSCALE:
+ case PIXELFORMAT_UNCOMPRESSED_R16: // 16 bpp (1 channel - half float)
+ case PIXELFORMAT_UNCOMPRESSED_R32: // 32 bpp (1 channel - float)
+ channels = 1;
+ break;
+
+ case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: // 8*2 bpp (2 channels)
+ case PIXELFORMAT_UNCOMPRESSED_R5G6B5: // 16 bpp
+ case PIXELFORMAT_UNCOMPRESSED_R8G8B8: // 24 bpp
+ case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: // 16 bpp (1 bit alpha)
+ case PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: // 16 bpp (4 bit alpha)
+ case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: // 32 bpp
+ channels = 2;
+ break;
+
+ case PIXELFORMAT_UNCOMPRESSED_R32G32B32: // 32*3 bpp (3 channels - float)
+ case PIXELFORMAT_UNCOMPRESSED_R16G16B16: // 16*3 bpp (3 channels - half float)
+ case PIXELFORMAT_COMPRESSED_DXT1_RGB: // 4 bpp (no alpha)
+ case PIXELFORMAT_COMPRESSED_ETC1_RGB: // 4 bpp
+ case PIXELFORMAT_COMPRESSED_ETC2_RGB: // 4 bpp
+ case PIXELFORMAT_COMPRESSED_PVRT_RGB: // 4 bpp
+ channels = 3;
+ break;
+
+ case PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: // 32*4 bpp (4 channels - float)
+ case PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: // 16*4 bpp (4 channels - half float)
+ case PIXELFORMAT_COMPRESSED_DXT1_RGBA: // 4 bpp (1 bit alpha)
+ case PIXELFORMAT_COMPRESSED_DXT3_RGBA: // 8 bpp
+ case PIXELFORMAT_COMPRESSED_DXT5_RGBA: // 8 bpp
+ case PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA: // 8 bpp
+ case PIXELFORMAT_COMPRESSED_PVRT_RGBA: // 4 bpp
+ case PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: // 8 bpp
+ case PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: // 2 bpp
+ channels = 4;
+ break;
+
+ default: break;
+ }
+
+ RGFW_window_setIcon(platform.window, image.data, RGFW_AREA(image.width, image.height), channels);
+}
+
+// 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)
+{
+ RGFW_window_setName(platform.window, title);
+ CORE.Window.title = title;
+}
+
+// Set window position on screen (windowed mode)
+void SetWindowPosition(int x, int y)
+{
+ RGFW_window_move(platform.window, RGFW_VECTOR(x, y));
+}
+
+// Set monitor for the current window
+void SetWindowMonitor(int monitor)
+{
+ RGFW_window_moveToMonitor(platform.window, RGFW_getMonitors()[monitor]);
+}
+
+// Set window minimum dimensions (FLAG_WINDOW_RESIZABLE)
+void SetWindowMinSize(int width, int height)
+{
+ RGFW_window_setMinSize(platform.window, RGFW_AREA(width, height));
+ CORE.Window.screenMin.width = width;
+ CORE.Window.screenMin.height = height;
+}
+
+// Set window maximum dimensions (FLAG_WINDOW_RESIZABLE)
+void SetWindowMaxSize(int width, int height)
+{
+ RGFW_window_setMaxSize(platform.window, RGFW_AREA(width, height));
+ CORE.Window.screenMax.width = width;
+ CORE.Window.screenMax.height = height;
+}
+
+// Set window dimensions
+void SetWindowSize(int width, int height)
+{
+ RGFW_window_resize(platform.window, RGFW_AREA(width, height));
+}
+
+// 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)
+{
+ RGFW_window_show(platform.window);
+}
+
+// Get native window handle
+void *GetWindowHandle(void)
+{
+ return platform.window->src.window;
+}
+
+// Get number of monitors
+int GetMonitorCount(void)
+{
+ RGFW_monitor* mons = RGFW_getMonitors();
+ u32 i;
+ for (i = 0; i < 6; i++) {
+ if (!mons[i].rect.x && !mons[i].rect.y && !mons[i].rect.w && mons[i].rect.h)
+ return i;
+ }
+
+ return 6;
+}
+
+// Get number of monitors
+int GetCurrentMonitor(void)
+{
+ RGFW_monitor* mons = RGFW_getMonitors();
+ RGFW_monitor mon = RGFW_window_getMonitor(platform.window);
+
+ u32 i;
+ for (i = 0; i < 6; i++) {
+ if (mons[i].rect.x == mon.rect.x &&
+ mons[i].rect.y == mon.rect.y)
+ return i;
+ }
+
+ return 0;
+}
+
+// Get selected monitor position
+Vector2 GetMonitorPosition(int monitor)
+{
+ RGFW_monitor* mons = RGFW_getMonitors();
+
+ return (Vector2){mons[monitor].rect.x, mons[monitor].rect.y};
+}
+
+// Get selected monitor width (currently used by monitor)
+int GetMonitorWidth(int monitor)
+{
+ RGFW_monitor* mons = RGFW_getMonitors();
+
+ return mons[monitor].rect.w;
+}
+
+// Get selected monitor height (currently used by monitor)
+int GetMonitorHeight(int monitor)
+{
+ RGFW_monitor* mons = RGFW_getMonitors();
+
+ return mons[monitor].rect.h;
+ return 0;
+}
+
+// Get selected monitor physical width in millimetres
+int GetMonitorPhysicalWidth(int monitor)
+{
+ RGFW_monitor* mons = RGFW_getMonitors();
+
+ return mons[monitor].physW;
+}
+
+// Get selected monitor physical height in millimetres
+int GetMonitorPhysicalHeight(int monitor)
+{
+ RGFW_monitor* mons = RGFW_getMonitors();
+
+ return mons[monitor].physH;
+}
+
+// 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)
+{
+ RGFW_monitor* mons = RGFW_getMonitors();
+
+ return mons[monitor].name;
+}
+
+// Get window position XY on monitor
+Vector2 GetWindowPosition(void)
+{
+ return (Vector2){ platform.window->r.x, platform.window->r.y };
+}
+
+// Get window scale DPI factor for current monitor
+Vector2 GetWindowScaleDPI(void)
+{
+ RGFW_monitor monitor = RGFW_window_getMonitor(platform.window);
+
+ return (Vector2){((u32)monitor.scaleX) * platform.window->r.w, ((u32) monitor.scaleX) * platform.window->r.h};
+}
+
+// Set clipboard text content
+void SetClipboardText(const char *text)
+{
+ RGFW_writeClipboard(text, strlen(text));
+}
+
+// Get clipboard text content
+// NOTE: returned string is allocated and freed by GLFW
+const char *GetClipboardText(void)
+{
+ return RGFW_readClipboard(NULL);
+}
+
+// Show mouse cursor
+void ShowCursor(void)
+{
+ RGFW_window_showMouse(platform.window, true);
+ CORE.Input.Mouse.cursorHidden = false;
+}
+
+// Hides mouse cursor
+void HideCursor(void)
+{
+ RGFW_window_showMouse(platform.window, false);
+ CORE.Input.Mouse.cursorHidden = true;
+}
+
+// Enables cursor (unlock cursor)
+void EnableCursor(void)
+{
+ RGFW_window_mouseUnhold(platform.window);
+
+ // Set cursor position in the middle
+ SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2);
+ RGFW_window_showMouse(platform.window, true);
+ CORE.Input.Mouse.cursorHidden = false;
+}
+
+// Disables cursor (lock cursor)
+void DisableCursor(void)
+{
+ RGFW_window_mouseHold(platform.window);
+ // Set cursor position in the middle
+ SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2);
+
+ HideCursor();
+}
+
+// Swap back buffer with front buffer (screen drawing)
+void SwapScreenBuffer(void)
+{
+ RGFW_window_swapBuffers(platform.window);
+}
+
+//----------------------------------------------------------------------------------
+// Module Functions Definition: Misc
+//----------------------------------------------------------------------------------
+
+// Get elapsed time measure in seconds since InitTimer()
+double GetTime(void)
+{
+ double time = 0.0;
+ unsigned long long int nanoSeconds = RGFW_getTimeNS();
+ 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)
+{
+ RGFW_window_moveMouse(platform.window, RGFW_VECTOR(x, 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)
+{
+ switch (cursor) {
+ case MOUSE_CURSOR_DEFAULT:
+ return RGFW_window_setMouseDefault(platform.window);
+ case MOUSE_CURSOR_ARROW:
+ return RGFW_window_setMouseStandard(platform.window, RGFW_MOUSE_ARROW);
+ case MOUSE_CURSOR_IBEAM:
+ return RGFW_window_setMouseStandard(platform.window, RGFW_MOUSE_IBEAM);
+ case MOUSE_CURSOR_CROSSHAIR:
+ return RGFW_window_setMouseStandard(platform.window, RGFW_MOUSE_CROSSHAIR);
+ case MOUSE_CURSOR_POINTING_HAND:
+ return RGFW_window_setMouseStandard(platform.window, RGFW_MOUSE_POINTING_HAND);
+ case MOUSE_CURSOR_RESIZE_EW:
+ return RGFW_window_setMouseStandard(platform.window, RGFW_MOUSE_RESIZE_EW);
+ case MOUSE_CURSOR_RESIZE_NS:
+ return RGFW_window_setMouseStandard(platform.window, RGFW_MOUSE_RESIZE_NS);
+ #ifndef RGFW_MACOS
+ case MOUSE_CURSOR_RESIZE_NWSE:
+ return RGFW_window_setMouseStandard(platform.window, RGFW_MOUSE_RESIZE_NWSE);
+ case MOUSE_CURSOR_RESIZE_NESW:
+ return RGFW_window_setMouseStandard(platform.window, RGFW_MOUSE_RESIZE_NESW);
+ #endif
+ case MOUSE_CURSOR_RESIZE_ALL:
+ return RGFW_window_setMouseStandard(platform.window, RGFW_MOUSE_RESIZE_ALL);
+ case MOUSE_CURSOR_NOT_ALLOWED:
+ return RGFW_window_setMouseStandard(platform.window, RGFW_MOUSE_NOT_ALLOWED);
+ default:
+ break;
+ }
+}
+
+static KeyboardKey ConvertScancodeToKey(u32 keycode);
+
+// 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 mouse wheel
+ CORE.Input.Mouse.currentWheelMove.x = 0;
+ CORE.Input.Mouse.currentWheelMove.y = 0;
+
+ // Register previous mouse position
+
+ // Reset last gamepad button/axis registered state
+
+ for (int i = 0; (i < 4) && (i < MAX_GAMEPADS); i++)
+ {
+ // Check if gamepad is available
+ if (CORE.Input.Gamepad.ready[i])
+ {
+ // Register previous gamepad button states
+ for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++)
+ {
+ CORE.Input.Gamepad.previousButtonState[i][k] = CORE.Input.Gamepad.currentButtonState[i][k];
+ }
+ }
+ }
+
+ // Register previous touch states
+ for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.previousTouchState[i] = CORE.Input.Touch.currentTouchState[i];
+
+ // Map touch position to mouse position for convenience
+ CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition;
+
+ int touchAction = -1; // 0-TOUCH_ACTION_UP, 1-TOUCH_ACTION_DOWN, 2-TOUCH_ACTION_MOVE
+ bool realTouch = false; // Flag to differentiate real touch gestures from mouse ones
+
+ // Register previous keys states
+ // NOTE: Android supports up to 260 keys
+ for (int i = 0; i < MAX_KEYBOARD_KEYS; i++)
+ {
+ CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i];
+ CORE.Input.Keyboard.keyRepeatInFrame[i] = 0;
+ }
+
+ // Register previous mouse states
+ for (int i = 0; i < MAX_MOUSE_BUTTONS; i++)
+ CORE.Input.Mouse.previousButtonState[i] = CORE.Input.Mouse.currentButtonState[i];
+
+ // Poll input events for current platform
+ //-----------------------------------------------------------------------------
+ CORE.Window.resizedLastFrame = false;
+
+
+ #define RGFW_HOLD_MOUSE (1L<<2)
+ #if defined(RGFW_X11) //|| defined(RGFW_MACOS)
+ if (platform.window->src.winArgs & RGFW_HOLD_MOUSE)
+ {
+ CORE.Input.Mouse.previousPosition = (Vector2){ 0.0f, 0.0f };
+ CORE.Input.Mouse.currentPosition = (Vector2){ 0.0f, 0.0f };
+ }
+ else {
+ CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
+ }
+ #endif
+
+ while (RGFW_window_checkEvent(platform.window))
+ {
+
+ if (platform.window->event.type >= RGFW_jsButtonPressed && platform.window->event.type <= RGFW_jsAxisMove) {
+ if (!CORE.Input.Gamepad.ready[platform.window->event.joystick])
+ {
+ CORE.Input.Gamepad.ready[platform.window->event.joystick] = true;
+ CORE.Input.Gamepad.axisCount[platform.window->event.joystick] = platform.window->event.axisesCount;
+ CORE.Input.Gamepad.name[platform.window->event.joystick][0] = '\0';
+ CORE.Input.Gamepad.axisState[platform.window->event.joystick][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f;
+ CORE.Input.Gamepad.axisState[platform.window->event.joystick][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f;
+ }
+ }
+
+ RGFW_Event* event = &platform.window->event;
+
+ // All input events can be processed after polling
+ switch (event->type)
+ {
+ case RGFW_quit: CORE.Window.shouldClose = true; break;
+
+ case RGFW_dnd: // Dropped file
+ {
+ size_t i;
+ for (i = 0; i < event->droppedFilesCount; i++) {
+ if (CORE.Window.dropFileCount == 0)
+ {
+ // When a new file is dropped, we reserve a fixed number of slots for all possible dropped files
+ // at the moment we limit the number of drops at once to 1024 files but this behaviour should probably be reviewed
+ // TODO: Pointers should probably be reallocated for any new file added...
+ CORE.Window.dropFilepaths = (char **)RL_CALLOC(1024, sizeof(char *));
+
+ CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char));
+ strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event->droppedFiles[i]);
+
+ CORE.Window.dropFileCount++;
+ }
+ else if (CORE.Window.dropFileCount < 1024)
+ {
+ CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char));
+ strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event->droppedFiles[i]);
+
+ CORE.Window.dropFileCount++;
+ }
+ else TRACELOG(LOG_WARNING, "FILE: Maximum drag and drop files at once is limited to 1024 files!");
+ }
+ } break;
+
+ // Window events are also polled (Minimized, maximized, close...)
+ case RGFW_windowAttribsChange:
+ {
+ SetupViewport(platform.window->r.w, platform.window->r.h);
+ CORE.Window.position.x = platform.window->r.x;
+ CORE.Window.position.y = platform.window->r.x;
+ CORE.Window.screen.width = platform.window->r.w;
+ CORE.Window.screen.height = platform.window->r.h;
+ CORE.Window.currentFbo.width = platform.window->r.w;;
+ CORE.Window.currentFbo.height = platform.window->r.h;
+ CORE.Window.resizedLastFrame = true;
+ } break;
+
+ // Keyboard events
+ case RGFW_keyPressed:
+ {
+ KeyboardKey key = ConvertScancodeToKey(event->keyCode);
+
+ if (key != KEY_NULL) {
+ // If key was up, add it to the key pressed queue
+ if ((CORE.Input.Keyboard.currentKeyState[key] == 0) && (CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE))
+ {
+ CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = key;
+ CORE.Input.Keyboard.keyPressedQueueCount++;
+ }
+
+ CORE.Input.Keyboard.currentKeyState[key] = 1;
+ }
+
+ // TODO: Put exitKey verification outside the switch?
+ if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey])
+ {
+ CORE.Window.shouldClose = true;
+ }
+
+ // NOTE: event.text.text data comes an UTF-8 text sequence but we register codepoints (int)
+ // Check if there is space available in the queue
+ if (CORE.Input.Keyboard.charPressedQueueCount < MAX_CHAR_PRESSED_QUEUE)
+ {
+ // Add character (codepoint) to the queue
+ CORE.Input.Keyboard.charPressedQueue[CORE.Input.Keyboard.charPressedQueueCount] = RGFW_keystrToChar(event->keyName);
+ CORE.Input.Keyboard.charPressedQueueCount++;
+ }
+ } break;
+
+ case RGFW_keyReleased:
+ {
+ KeyboardKey key = ConvertScancodeToKey(event->keyCode);
+ if (key != KEY_NULL) CORE.Input.Keyboard.currentKeyState[key] = 0;
+ } break;
+
+ // Check mouse events
+ case RGFW_mouseButtonPressed:
+ {
+ if (event->button == RGFW_mouseScrollUp || event->button == RGFW_mouseScrollDown) {
+ CORE.Input.Mouse.currentWheelMove.y = event->scroll;
+ break;
+ }
+
+ int btn = event->button;
+ if (btn == RGFW_mouseLeft) btn = 1;
+ else if (btn == RGFW_mouseRight) btn = 2;
+ else if (btn == RGFW_mouseMiddle) btn = 3;
+
+ CORE.Input.Mouse.currentButtonState[btn - 1] = 1;
+ CORE.Input.Touch.currentTouchState[btn - 1] = 1;
+
+ touchAction = 1;
+ } break;
+ case RGFW_mouseButtonReleased:
+ {
+
+ if (event->button == RGFW_mouseScrollUp || event->button == RGFW_mouseScrollDown) {
+ CORE.Input.Mouse.currentWheelMove.y = event->scroll;
+ break;
+ }
+
+ int btn = event->button;
+ if (btn == RGFW_mouseLeft) btn = 1;
+ else if (btn == RGFW_mouseRight) btn = 2;
+ else if (btn == RGFW_mouseMiddle) btn = 3;
+
+ CORE.Input.Mouse.currentButtonState[btn - 1] = 0;
+ CORE.Input.Touch.currentTouchState[btn - 1] = 0;
+
+ touchAction = 0;
+ } break;
+ case RGFW_mousePosChanged:
+ {
+ if (platform.window->src.winArgs & RGFW_HOLD_MOUSE) {
+
+ CORE.Input.Mouse.previousPosition = (Vector2){ 0.0f, 0.0f };
+
+ if ((event->point.x - (platform.window->r.w / 2)) * 2)
+ CORE.Input.Mouse.previousPosition.x = CORE.Input.Mouse.currentPosition.x;
+ if ((event->point.y - (platform.window->r.h / 2)) * 2)
+ CORE.Input.Mouse.previousPosition.y = CORE.Input.Mouse.currentPosition.y;
+
+ CORE.Input.Mouse.currentPosition.x = (event->point.x - (platform.window->r.w / 2)) * 2;
+ CORE.Input.Mouse.currentPosition.y = (event->point.y - (platform.window->r.h / 2)) * 2;
+
+ RGFW_window_showMouse(platform.window, 1);
+ }
+ else {
+ CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
+ CORE.Input.Mouse.currentPosition.x = (float)event->point.x;
+ CORE.Input.Mouse.currentPosition.y = (float)event->point.y;
+ }
+
+ CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition;
+ touchAction = 2;
+ } break;
+
+ case RGFW_jsButtonPressed:
+ {
+ int button = -1;
+
+ switch (event->button)
+ {
+ case RGFW_JS_Y: button = GAMEPAD_BUTTON_RIGHT_FACE_UP; break;
+ case RGFW_JS_B: button = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT; break;
+ case RGFW_JS_A: button = GAMEPAD_BUTTON_RIGHT_FACE_DOWN; break;
+ case RGFW_JS_X: button = GAMEPAD_BUTTON_RIGHT_FACE_LEFT; break;
+
+ case RGFW_JS_L1: button = GAMEPAD_BUTTON_LEFT_TRIGGER_1; break;
+ case RGFW_JS_R1: button = GAMEPAD_BUTTON_RIGHT_TRIGGER_1; break;
+
+ case RGFW_JS_L2: button = GAMEPAD_BUTTON_LEFT_TRIGGER_2; break;
+ case RGFW_JS_R2: button = GAMEPAD_BUTTON_RIGHT_TRIGGER_2; break;
+
+ case RGFW_JS_SELECT: button = GAMEPAD_BUTTON_MIDDLE_LEFT; break;
+ case RGFW_JS_HOME: button = GAMEPAD_BUTTON_MIDDLE; break;
+ case RGFW_JS_START: button = GAMEPAD_BUTTON_MIDDLE_RIGHT; break;
+
+ case RGFW_JS_UP: button = GAMEPAD_BUTTON_LEFT_FACE_UP; break;
+ case RGFW_JS_RIGHT: button = GAMEPAD_BUTTON_LEFT_FACE_RIGHT; break;
+ case RGFW_JS_DOWN: button = GAMEPAD_BUTTON_LEFT_FACE_DOWN; break;
+ case RGFW_JS_LEFT: button = GAMEPAD_BUTTON_LEFT_FACE_LEFT; break;
+
+ default: break;
+ }
+
+ if (button >= 0)
+ {
+ CORE.Input.Gamepad.currentButtonState[event->joystick][button] = 1;
+ CORE.Input.Gamepad.lastButtonPressed = button;
+ }
+ } break;
+ case RGFW_jsButtonReleased:
+ {
+ int button = -1;
+ switch (event->button)
+ {
+ case RGFW_JS_Y: button = GAMEPAD_BUTTON_RIGHT_FACE_UP; break;
+ case RGFW_JS_B: button = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT; break;
+ case RGFW_JS_A: button = GAMEPAD_BUTTON_RIGHT_FACE_DOWN; break;
+ case RGFW_JS_X: button = GAMEPAD_BUTTON_RIGHT_FACE_LEFT; break;
+
+ case RGFW_JS_L1: button = GAMEPAD_BUTTON_LEFT_TRIGGER_1; break;
+ case RGFW_JS_R1: button = GAMEPAD_BUTTON_RIGHT_TRIGGER_1; break;
+
+ case RGFW_JS_L2: button = GAMEPAD_BUTTON_LEFT_TRIGGER_2; break;
+ case RGFW_JS_R2: button = GAMEPAD_BUTTON_RIGHT_TRIGGER_2; break;
+
+ case RGFW_JS_SELECT: button = GAMEPAD_BUTTON_MIDDLE_LEFT; break;
+ case RGFW_JS_HOME: button = GAMEPAD_BUTTON_MIDDLE; break;
+ case RGFW_JS_START: button = GAMEPAD_BUTTON_MIDDLE_RIGHT; break;
+
+ case RGFW_JS_UP: button = GAMEPAD_BUTTON_LEFT_FACE_UP; break;
+ case RGFW_JS_RIGHT: button = GAMEPAD_BUTTON_LEFT_FACE_RIGHT; break;
+ case RGFW_JS_DOWN: button = GAMEPAD_BUTTON_LEFT_FACE_DOWN; break;
+ case RGFW_JS_LEFT: button = GAMEPAD_BUTTON_LEFT_FACE_LEFT; break;
+ default: break;
+ }
+
+ if (button >= 0)
+ {
+ CORE.Input.Gamepad.currentButtonState[event->joystick][button] = 0;
+ if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0;
+ }
+ } break;
+ case RGFW_jsAxisMove:
+ {
+ int axis = -1;
+
+ size_t i;
+ for (i = 0; i < event->axisesCount; i++)
+ {
+ switch(i) {
+ case 0:
+ if (abs(event->axis[i].x) > abs(event->axis[i].y)) {
+ axis = GAMEPAD_AXIS_LEFT_X;
+ break;
+ }
+
+ axis = GAMEPAD_AXIS_LEFT_Y;
+ break;
+ case 1:
+ if (abs(event->axis[i].x) > abs(event->axis[i].y)) {
+ axis = GAMEPAD_AXIS_RIGHT_X; break;
+ }
+
+ axis = GAMEPAD_AXIS_RIGHT_Y; break;
+ case 2: axis = GAMEPAD_AXIS_LEFT_TRIGGER; break;
+ case 3: axis = GAMEPAD_AXIS_RIGHT_TRIGGER; break;
+ default: break;
+ }
+
+ #ifdef __linux__
+ float value = (event->axis[i].x + event->axis[i].y) / (float) 32767;
+ #else
+ float value = (event->axis[i].x + -event->axis[i].y) / (float) 32767;
+ #endif
+ CORE.Input.Gamepad.axisState[event->joystick][axis] = value;
+
+ // Register button state for triggers in addition to their axes
+ if ((axis == GAMEPAD_AXIS_LEFT_TRIGGER) || (axis == GAMEPAD_AXIS_RIGHT_TRIGGER))
+ {
+ int button = (axis == GAMEPAD_AXIS_LEFT_TRIGGER) ? GAMEPAD_BUTTON_LEFT_TRIGGER_2 : GAMEPAD_BUTTON_RIGHT_TRIGGER_2;
+ int pressed = (value > 0.1f);
+ CORE.Input.Gamepad.currentButtonState[event->joystick][button] = pressed;
+ if (pressed) CORE.Input.Gamepad.lastButtonPressed = button;
+ else if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0;
+ }
+ }
+ } break;
+ default: break;
+ }
+
+#if defined(SUPPORT_GESTURES_SYSTEM)
+ if (touchAction > -1)
+ {
+ // Process mouse events as touches to be able to use mouse-gestures
+ GestureEvent gestureEvent = { 0 };
+
+ // Register touch actions
+ gestureEvent.touchAction = touchAction;
+
+ // Assign a pointer ID
+ gestureEvent.pointId[0] = 0;
+
+ // Register touch points count
+ gestureEvent.pointCount = 1;
+
+ // Register touch points position, only one point registered
+ if (touchAction == 2 || realTouch) gestureEvent.position[0] = CORE.Input.Touch.position[0];
+ else gestureEvent.position[0] = GetMousePosition();
+
+ // Normalize gestureEvent.position[0] for CORE.Window.screen.width and CORE.Window.screen.height
+ gestureEvent.position[0].x /= (float)GetScreenWidth();
+ gestureEvent.position[0].y /= (float)GetScreenHeight();
+
+ // Gesture data is sent to gestures-system for processing
+ ProcessGestureEvent(gestureEvent);
+
+ touchAction = -1;
+ }
+#endif
+ }
+ //-----------------------------------------------------------------------------
+}
+
+
+//----------------------------------------------------------------------------------
+// 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
+ //----------------------------------------------------------------------------
+ // Initialize RGFW internal global state, only required systems
+ // Initialize graphic device: display/window and graphic context
+ //----------------------------------------------------------------------------
+ unsigned int flags = RGFW_CENTER | RGFW_ALLOW_DND;
+
+ // Check window creation flags
+ if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0)
+ {
+ CORE.Window.fullscreen = true;
+ flags |= RGFW_FULLSCREEN;
+ }
+
+ if ((CORE.Window.flags & FLAG_WINDOW_UNDECORATED) > 0) flags |= RGFW_NO_BORDER;
+ if ((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) == 0) flags |= RGFW_NO_RESIZE;
+
+ if ((CORE.Window.flags & FLAG_WINDOW_TRANSPARENT) > 0) flags |= RGFW_TRANSPARENT_WINDOW;
+
+ if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) flags |= RGFW_FULLSCREEN;
+
+ // NOTE: Some OpenGL context attributes must be set before window creation
+
+ // Check selection OpenGL version
+ if (rlGetVersion() == RL_OPENGL_21)
+ {
+ RGFW_setGLVersion(2, 1);
+ }
+ else if (rlGetVersion() == RL_OPENGL_33)
+ {
+ RGFW_setGLVersion(3, 3);
+ }
+ else if (rlGetVersion() == RL_OPENGL_43)
+ {
+ RGFW_setGLVersion(4, 1);
+ }
+
+ if (CORE.Window.flags & FLAG_MSAA_4X_HINT)
+ {
+ RGFW_setGLSamples(4);
+ }
+
+ platform.window = RGFW_createWindow(CORE.Window.title, RGFW_RECT(0, 0, CORE.Window.screen.width, CORE.Window.screen.height), flags);
+
+ if (CORE.Window.flags & FLAG_VSYNC_HINT)
+ RGFW_window_swapInterval(platform.window, 1);
+
+ RGFW_window_makeCurrent(platform.window);
+
+ // Check surface and context activation
+ if (platform.window != NULL)
+ {
+ 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.position.x = platform.window->r.x;
+ CORE.Window.position.y = platform.window->r.y;
+ 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((void*)RGFW_getProcAddress);
+ //----------------------------------------------------------------------------
+
+ // 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();
+ //----------------------------------------------------------------------------
+
+ #ifdef RGFW_X11
+ for (int i = 0; (i < 4) && (i < MAX_GAMEPADS); i++)
+ {
+ RGFW_registerJoystick(platform.window, i);
+ }
+ #endif
+
+ TRACELOG(LOG_INFO, "PLATFORM: CUSTOM: Initialized successfully");
+
+ return 0;
+}
+
+// Close platform
+void ClosePlatform(void)
+{
+ RGFW_window_close(platform.window);
+ // TODO: De-initialize graphics, inputs and more
+}
+
+
+static KeyboardKey ConvertScancodeToKey(u32 keycode) {
+ switch (keycode) {
+ case RGFW_Quote:
+ return KEY_APOSTROPHE;
+ case RGFW_Comma:
+ return KEY_COMMA;
+ case RGFW_Minus:
+ return KEY_MINUS;
+ case RGFW_Period:
+ return KEY_PERIOD;
+ case RGFW_Slash:
+ return KEY_SLASH;
+ case RGFW_Escape:
+ return KEY_ESCAPE;
+ case RGFW_F1:
+ return KEY_F1;
+ case RGFW_F2:
+ return KEY_F2;
+ case RGFW_F3:
+ return KEY_F3;
+ case RGFW_F4:
+ return KEY_F4;
+ case RGFW_F5:
+ return KEY_F5;
+ case RGFW_F6:
+ return KEY_F6;
+ case RGFW_F7:
+ return KEY_F7;
+ case RGFW_F8:
+ return KEY_F8;
+ case RGFW_F9:
+ return KEY_F9;
+ case RGFW_F10:
+ return KEY_F10;
+ case RGFW_F11:
+ return KEY_F11;
+ case RGFW_F12:
+ return KEY_F12;
+ case RGFW_Backtick:
+ return KEY_GRAVE;
+ case RGFW_0:
+ return KEY_ZERO;
+ case RGFW_1:
+ return KEY_ONE;
+ case RGFW_2:
+ return KEY_TWO;
+ case RGFW_3:
+ return KEY_THREE;
+ case RGFW_4:
+ return KEY_FOUR;
+ case RGFW_5:
+ return KEY_FIVE;
+ case RGFW_6:
+ return KEY_SIX;
+ case RGFW_7:
+ return KEY_SEVEN;
+ case RGFW_8:
+ return KEY_EIGHT;
+ case RGFW_9:
+ return KEY_NINE;
+ case RGFW_Equals:
+ return KEY_EQUAL;
+ case RGFW_BackSpace:
+ return KEY_BACKSPACE;
+ case RGFW_Tab:
+ return KEY_TAB;
+ case RGFW_CapsLock:
+ return KEY_CAPS_LOCK;
+ case RGFW_ShiftL:
+ return KEY_LEFT_SHIFT;
+ case RGFW_ControlL:
+ return KEY_LEFT_CONTROL;
+ case RGFW_AltL:
+ return KEY_LEFT_ALT;
+ case RGFW_SuperL:
+ return KEY_LEFT_SUPER;
+ #ifndef RGFW_MACOS
+ case RGFW_ShiftR:
+ return KEY_RIGHT_SHIFT;
+
+ case RGFW_AltR:
+ return KEY_RIGHT_ALT;
+ #endif
+ case RGFW_Space:
+ return KEY_SPACE;
+
+ #ifdef RGFW_X11
+ case RGFW_a:
+ #endif
+
+ case RGFW_A:
+ return KEY_A;
+
+ #ifdef RGFW_X11
+ case RGFW_b:
+ #endif
+
+ case RGFW_B:
+ return KEY_B;
+
+ #ifdef RGFW_X11
+ case RGFW_c:
+ #endif
+
+ case RGFW_C:
+ return KEY_C;
+
+ #ifdef RGFW_X11
+ case RGFW_d:
+ #endif
+
+ case RGFW_D:
+ return KEY_D;
+
+ #ifdef RGFW_X11
+ case RGFW_e:
+ #endif
+
+ case RGFW_E:
+ return KEY_E;
+
+ #ifdef RGFW_X11
+ case RGFW_f:
+ #endif
+
+ case RGFW_F:
+ return KEY_F;
+
+ #ifdef RGFW_X11
+ case RGFW_g:
+ #endif
+
+ case RGFW_G:
+ return KEY_G;
+
+ #ifdef RGFW_X11
+ case RGFW_h:
+ #endif
+
+ case RGFW_H:
+ return KEY_H;
+
+ #ifdef RGFW_X11
+ case RGFW_i:
+ #endif
+
+ case RGFW_I:
+ return KEY_I;
+
+ #ifdef RGFW_X11
+ case RGFW_j:
+ #endif
+
+ case RGFW_J:
+ return KEY_J;
+
+ #ifdef RGFW_X11
+ case RGFW_k:
+ #endif
+
+ case RGFW_K:
+ return KEY_K;
+
+ #ifdef RGFW_X11
+ case RGFW_l:
+ #endif
+
+ case RGFW_L:
+ return KEY_L;
+
+ #ifdef RGFW_X11
+ case RGFW_m:
+ #endif
+
+ case RGFW_M:
+ return KEY_M;
+
+ #ifdef RGFW_X11
+ case RGFW_n:
+ #endif
+
+ case RGFW_N:
+ return KEY_N;
+
+ #ifdef RGFW_X11
+ case RGFW_o:
+ #endif
+
+ case RGFW_O:
+ return KEY_O;
+
+ #ifdef RGFW_X11
+ case RGFW_p:
+ #endif
+
+ case RGFW_P:
+ return KEY_P;
+
+ #ifdef RGFW_X11
+ case RGFW_q:
+ #endif
+
+ case RGFW_Q:
+ return KEY_Q;
+
+ #ifdef RGFW_X11
+ case RGFW_r:
+ #endif
+
+ case RGFW_R:
+ return KEY_R;
+
+ #ifdef RGFW_X11
+ case RGFW_s:
+ #endif
+
+ case RGFW_S:
+ return KEY_S;
+
+ #ifdef RGFW_X11
+ case RGFW_t:
+ #endif
+
+ case RGFW_T:
+ return KEY_T;
+
+ #ifdef RGFW_X11
+ case RGFW_u:
+ #endif
+
+ case RGFW_U:
+ return KEY_U;
+
+ #ifdef RGFW_X11
+ case RGFW_v:
+ #endif
+
+ case RGFW_V:
+ return KEY_V;
+
+ #ifdef RGFW_X11
+ case RGFW_w:
+ #endif
+
+ case RGFW_W:
+ return KEY_W;
+
+ #ifdef RGFW_X11
+ case RGFW_x:
+ #endif
+
+ case RGFW_X:
+ return KEY_X;
+
+ #ifdef RGFW_X11
+ case RGFW_y:
+ #endif
+
+ case RGFW_Y:
+ return KEY_Y;
+
+ #ifdef RGFW_X11
+ case RGFW_z:
+ #endif
+
+ case RGFW_Z:
+ return KEY_Z;
+ case RGFW_Bracket:
+ return KEY_LEFT_BRACKET;
+ case RGFW_BackSlash:
+ return KEY_BACKSLASH;
+ case RGFW_CloseBracket:
+ return KEY_RIGHT_BRACKET;
+ case RGFW_Semicolon:
+ return KEY_SEMICOLON;
+ case RGFW_Insert:
+ return KEY_INSERT;
+ case RGFW_Home:
+ return KEY_HOME;
+ case RGFW_PageUp:
+ return KEY_PAGE_UP;
+ case RGFW_Delete:
+ return KEY_DELETE;
+ case RGFW_End:
+ return KEY_END;
+ case RGFW_PageDown:
+ return KEY_PAGE_DOWN;
+ case RGFW_Right:
+ return KEY_RIGHT;
+ case RGFW_Left:
+ return KEY_LEFT;
+ case RGFW_Down:
+ return KEY_DOWN;
+ case RGFW_Up:
+ return KEY_UP;
+ case RGFW_Numlock:
+ return KEY_NUM_LOCK;
+ case RGFW_KP_Slash:
+ return KEY_KP_DIVIDE;
+ case RGFW_Multiply:
+ return KEY_KP_MULTIPLY;
+ case RGFW_KP_Minus:
+ return KEY_KP_SUBTRACT;
+ case RGFW_KP_Return:
+ return KEY_KP_ENTER;
+ case RGFW_KP_1:
+ return KEY_KP_1;
+ case RGFW_KP_2:
+ return KEY_KP_2;
+ case RGFW_KP_3:
+ return KEY_KP_3;
+ case RGFW_KP_4:
+ return KEY_KP_4;
+ case RGFW_KP_5:
+ return KEY_KP_5;
+ case RGFW_KP_6:
+ return KEY_KP_6;
+ case RGFW_KP_7:
+ return KEY_KP_7;
+ case RGFW_KP_8:
+ return KEY_KP_8;
+ case RGFW_KP_9:
+ return KEY_KP_9;
+ case RGFW_KP_0:
+ return KEY_KP_0;
+ case RGFW_KP_Period:
+ return KEY_KP_DECIMAL;
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+// EOF \ No newline at end of file