From 6b220f2798837687599d54c690d65dcc4a6a7161 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 12 Dec 2024 12:13:17 +0100 Subject: [PATCH 01/14] Review formating --- src/platforms/rcore_android.c | 6 +++--- src/platforms/rcore_desktop_rgfw.c | 14 +++++++------- src/platforms/rcore_desktop_sdl.c | 6 +++--- src/platforms/rcore_drm.c | 6 +++--- src/platforms/rcore_web.c | 10 +++++----- src/rcore.c | 2 +- src/rtextures.c | 5 +---- 7 files changed, 23 insertions(+), 26 deletions(-) diff --git a/src/platforms/rcore_android.c b/src/platforms/rcore_android.c index 47dc5cabc..4528c810d 100644 --- a/src/platforms/rcore_android.c +++ b/src/platforms/rcore_android.c @@ -699,7 +699,7 @@ void PollInputEvents(void) // Poll Events (registered events) until we reach TIMEOUT which indicates there are no events left to poll // NOTE: Activity is paused if not enabled (platform.appEnabled) - while ((pollResult = ALooper_pollOnce(platform.appEnabled? 0 : -1, NULL, &pollEvents, (void**)&platform.source)) > ALOOPER_POLL_TIMEOUT) + while ((pollResult = ALooper_pollOnce(platform.appEnabled? 0 : -1, NULL, &pollEvents, ((void **)&platform.source)) > ALOOPER_POLL_TIMEOUT)) { // Process this event if (platform.source != NULL) platform.source->process(platform.app, platform.source); @@ -786,7 +786,7 @@ int InitPlatform(void) while (!CORE.Window.ready) { // Process events until we reach TIMEOUT, which indicates no more events queued. - while ((pollResult = ALooper_pollOnce(0, NULL, &pollEvents, (void**)&platform.source)) > ALOOPER_POLL_TIMEOUT) + while ((pollResult = ALooper_pollOnce(0, NULL, &pollEvents, ((void **)&platform.source)) > ALOOPER_POLL_TIMEOUT)) { // Process this event if (platform.source != NULL) platform.source->process(platform.app, platform.source); @@ -1226,7 +1226,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) return 1; // Handled gamepad button } - KeyboardKey key = (keycode > 0 && keycode < KEYCODE_MAP_SIZE)? mapKeycode[keycode] : KEY_NULL; + KeyboardKey key = ((keycode > 0) && (keycode < KEYCODE_MAP_SIZE))? mapKeycode[keycode] : KEY_NULL; if (key != KEY_NULL) { // Save current key and its state diff --git a/src/platforms/rcore_desktop_rgfw.c b/src/platforms/rcore_desktop_rgfw.c index 913223511..a6ef60c9e 100644 --- a/src/platforms/rcore_desktop_rgfw.c +++ b/src/platforms/rcore_desktop_rgfw.c @@ -485,7 +485,7 @@ void SetWindowIcons(Image *images, int count) // Set title for window void SetWindowTitle(const char *title) { - RGFW_window_setName(platform.window, (char*)title); + RGFW_window_setName(platform.window, (char *)title); CORE.Window.title = title; } @@ -542,9 +542,9 @@ void SetWindowFocused(void) void *GetWindowHandle(void) { #ifdef RGFW_WEBASM - return (void*)platform.window->src.ctx; + return (void *)platform.window->src.ctx; #else - return (void*)platform.window->src.window; + return (void *)platform.window->src.window; #endif } @@ -587,7 +587,7 @@ Vector2 GetMonitorPosition(int monitor) { RGFW_monitor *mons = RGFW_getMonitors(); - return (Vector2){(float)mons[monitor].rect.x, (float)mons[monitor].rect.y}; + return (Vector2){ (float)mons[monitor].rect.x, (float)mons[monitor].rect.y }; } // Get selected monitor width (currently used by monitor) @@ -609,7 +609,7 @@ int GetMonitorHeight(int monitor) // Get selected monitor physical width in millimetres int GetMonitorPhysicalWidth(int monitor) { - RGFW_monitor* mons = RGFW_getMonitors(); + RGFW_monitor *mons = RGFW_getMonitors(); return (int)mons[monitor].physW; } @@ -654,7 +654,7 @@ Vector2 GetWindowScaleDPI(void) // Set clipboard text content void SetClipboardText(const char *text) { - RGFW_writeClipboard(text, (u32)strlen(text)); + RGFW_writeClipboard(text, strlen(text)); } // Get clipboard text content @@ -1336,7 +1336,7 @@ int InitPlatform(void) // Load OpenGL extensions // NOTE: GL procedures address loader is required to load extensions //---------------------------------------------------------------------------- - rlLoadExtensions((void*)RGFW_getProcAddress); + rlLoadExtensions((void *)RGFW_getProcAddress); //---------------------------------------------------------------------------- // TODO: Initialize input events system diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index 99de9af22..d051ae83f 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -68,7 +68,7 @@ #define MAX_CLIPBOARD_BUFFER_LENGTH 1024 // Size of the clipboard buffer used on GetClipboardText() #endif -#if ((defined(SDL_MAJOR_VERSION) && SDL_MAJOR_VERSION == 3) && (defined(SDL_MINOR_VERSION) && SDL_MINOR_VERSION >= 1)) +#if ((defined(SDL_MAJOR_VERSION) && (SDL_MAJOR_VERSION == 3)) && (defined(SDL_MINOR_VERSION) && (SDL_MINOR_VERSION >= 1))) #ifndef PLATFORM_DESKTOP_SDL3 #define PLATFORM_DESKTOP_SDL3 #endif @@ -405,7 +405,7 @@ int SDL_GetNumTouchFingers(SDL_TouchID touchID) // Since SDL2 doesn't have this function we leave a stub // SDL_GetClipboardData function is available since SDL 3.1.3. (e.g. SDL3) -void* SDL_GetClipboardData(const char *mime_type, size_t *size) +void *SDL_GetClipboardData(const char *mime_type, size_t *size) { TRACELOG(LOG_WARNING, "Getting clipboard data that is not text is only available in SDL3"); @@ -1971,7 +1971,7 @@ void ClosePlatform(void) // Scancode to keycode mapping static KeyboardKey ConvertScancodeToKey(SDL_Scancode sdlScancode) { - if (sdlScancode >= 0 && sdlScancode < SCANCODE_MAPPED_NUM) + if ((sdlScancode >= 0) && (sdlScancode < SCANCODE_MAPPED_NUM)) { return mapScancodeToKey[sdlScancode]; } diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index e9a236868..425b1d4a6 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -1529,7 +1529,7 @@ static void ConfigureEvdevDevice(char *device) platform.absRange.height = absinfo[ABS_Y].info.maximum - absinfo[ABS_Y].info.minimum; } } - else if (isGamepad && !isMouse && !isKeyboard && platform.gamepadCount < MAX_GAMEPADS) + else if (isGamepad && !isMouse && !isKeyboard && (platform.gamepadCount < MAX_GAMEPADS)) { deviceKindStr = "gamepad"; int index = platform.gamepadCount++; @@ -1893,7 +1893,7 @@ static int FindExactConnectorMode(const drmModeConnector *connector, uint width, TRACELOG(LOG_TRACE, "DISPLAY: DRM Mode %d %ux%u@%u %s", i, mode->hdisplay, mode->vdisplay, mode->vrefresh, (mode->flags & DRM_MODE_FLAG_INTERLACE)? "interlaced" : "progressive"); - if ((mode->flags & DRM_MODE_FLAG_INTERLACE) && (!allowInterlaced)) continue; + if ((mode->flags & DRM_MODE_FLAG_INTERLACE) && !allowInterlaced) continue; if ((mode->hdisplay == width) && (mode->vdisplay == height) && (mode->vrefresh == fps)) return i; } @@ -1923,7 +1923,7 @@ static int FindNearestConnectorMode(const drmModeConnector *connector, uint widt continue; } - if ((mode->flags & DRM_MODE_FLAG_INTERLACE) && (!allowInterlaced)) + if ((mode->flags & DRM_MODE_FLAG_INTERLACE) && !allowInterlaced) { TRACELOG(LOG_TRACE, "DISPLAY: DRM shouldn't choose an interlaced mode"); continue; diff --git a/src/platforms/rcore_web.c b/src/platforms/rcore_web.c index d0be02514..d28ed55c2 100644 --- a/src/platforms/rcore_web.c +++ b/src/platforms/rcore_web.c @@ -319,7 +319,7 @@ void ToggleBorderlessWindowed(void) // Set window state: maximized, if resizable void MaximizeWindow(void) { - if (glfwGetWindowAttrib(platform.handle, GLFW_RESIZABLE) == GLFW_TRUE && !(CORE.Window.flags & FLAG_WINDOW_MAXIMIZED)) + if ((glfwGetWindowAttrib(platform.handle, GLFW_RESIZABLE) == GLFW_TRUE) && !(CORE.Window.flags & FLAG_WINDOW_MAXIMIZED)) { platform.unmaximizedWidth = CORE.Window.screen.width; platform.unmaximizedHeight = CORE.Window.screen.height; @@ -342,7 +342,7 @@ void MinimizeWindow(void) // Set window state: not minimized/maximized void RestoreWindow(void) { - if (glfwGetWindowAttrib(platform.handle, GLFW_RESIZABLE) == GLFW_TRUE && (CORE.Window.flags & FLAG_WINDOW_MAXIMIZED)) + if ((glfwGetWindowAttrib(platform.handle, GLFW_RESIZABLE) == GLFW_TRUE) && (CORE.Window.flags & FLAG_WINDOW_MAXIMIZED)) { if (platform.unmaximizedWidth && platform.unmaximizedHeight) glfwSetWindowSize(platform.handle, platform.unmaximizedWidth, platform.unmaximizedHeight); @@ -1664,10 +1664,10 @@ static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent * int height = EM_ASM_INT( return window.innerHeight; ); if (width < (int)CORE.Window.screenMin.width) width = CORE.Window.screenMin.width; - else if (width > (int)CORE.Window.screenMax.width && CORE.Window.screenMax.width > 0) width = CORE.Window.screenMax.width; + else if ((width > (int)CORE.Window.screenMax.width) && (CORE.Window.screenMax.width > 0)) width = CORE.Window.screenMax.width; if (height < (int)CORE.Window.screenMin.height) height = CORE.Window.screenMin.height; - else if (height > (int)CORE.Window.screenMax.height && CORE.Window.screenMax.height > 0) height = CORE.Window.screenMax.height; + else if ((height > (int)CORE.Window.screenMax.height) && (CORE.Window.screenMax.height > 0)) height = CORE.Window.screenMax.height; emscripten_set_canvas_element_size("#canvas", width, height); @@ -1722,7 +1722,7 @@ static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadE for (int i = 0; i < gamepadEvent->numButtons; ++i) TRACELOGD("Button %d: Digital: %d, Analog: %g", i, gamepadEvent->digitalButton[i], gamepadEvent->analogButton[i]); */ - if ((gamepadEvent->connected) && (gamepadEvent->index < MAX_GAMEPADS)) + if (gamepadEvent->connected && (gamepadEvent->index < MAX_GAMEPADS)) { CORE.Input.Gamepad.ready[gamepadEvent->index] = true; sprintf(CORE.Input.Gamepad.name[gamepadEvent->index], "%s", gamepadEvent->id); diff --git a/src/rcore.c b/src/rcore.c index d69fa0f6c..571abf97c 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -2063,7 +2063,7 @@ const char *GetDirectoryPath(const char *filePath) // In case provided path does not contain a root drive letter (C:\, D:\) nor leading path separator (\, /), // we add the current directory path to dirPath - if (filePath[1] != ':' && filePath[0] != '\\' && filePath[0] != '/') + if ((filePath[1] != ':') && (filePath[0] != '\\') && (filePath[0] != '/')) { // For security, we set starting path to current directory, // obtained path will be concatenated to this diff --git a/src/rtextures.c b/src/rtextures.c index 57ee57604..06f81e577 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -833,10 +833,7 @@ Image GenImageGradientLinear(int width, int height, int direction, Color start, // bottom-right or vice-versa), pixel (0, 0) is the farthest point on the gradient // (i.e. the pixel which should become one of the gradient's ends color); while for // directions that lie in the second or fourth quadrant, that point is pixel (width, 0). - float maxPosValue = - ((signbit(sinDir) != 0) == (signbit(cosDir) != 0)) - ? fabsf(startingPos) - : fabsf(startingPos+width*cosDir); + float maxPosValue = ((signbit(sinDir) != 0) == (signbit(cosDir) != 0))? fabsf(startingPos) : fabsf(startingPos + width*cosDir); for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) From 1f704be4e4aba6b25e56bde3c30cc136b6e94049 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 12 Dec 2024 12:13:38 +0100 Subject: [PATCH 02/14] Review comments spacing for better alignment --- src/raylib.h | 125 +++++++++++++++++++++++++-------------------------- 1 file changed, 62 insertions(+), 63 deletions(-) diff --git a/src/raylib.h b/src/raylib.h index 7482d4392..dcaaa44c7 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1155,20 +1155,19 @@ RLAPI unsigned char *CompressData(const unsigned char *data, int dataSize, int * RLAPI unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize); // Decompress data (DEFLATE algorithm), memory must be MemFree() RLAPI char *EncodeDataBase64(const unsigned char *data, int dataSize, int *outputSize); // Encode data to Base64 string, memory must be MemFree() RLAPI unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize); // Decode Base64 string data, memory must be MemFree() -RLAPI unsigned int ComputeCRC32(unsigned char *data, int dataSize); // Compute CRC32 hash code -RLAPI unsigned int *ComputeMD5(unsigned char *data, int dataSize); // Compute MD5 hash code, returns static int[4] (16 bytes) -RLAPI unsigned int *ComputeSHA1(unsigned char *data, int dataSize); // Compute SHA1 hash code, returns static int[5] (20 bytes) - +RLAPI unsigned int ComputeCRC32(unsigned char *data, int dataSize); // Compute CRC32 hash code +RLAPI unsigned int *ComputeMD5(unsigned char *data, int dataSize); // Compute MD5 hash code, returns static int[4] (16 bytes) +RLAPI unsigned int *ComputeSHA1(unsigned char *data, int dataSize); // Compute SHA1 hash code, returns static int[5] (20 bytes) // Automation events functionality -RLAPI AutomationEventList LoadAutomationEventList(const char *fileName); // Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS -RLAPI void UnloadAutomationEventList(AutomationEventList list); // Unload automation events list from file -RLAPI bool ExportAutomationEventList(AutomationEventList list, const char *fileName); // Export automation events list as text file -RLAPI void SetAutomationEventList(AutomationEventList *list); // Set automation event list to record to -RLAPI void SetAutomationEventBaseFrame(int frame); // Set automation event internal base frame to start recording -RLAPI void StartAutomationEventRecording(void); // Start recording automation events (AutomationEventList must be set) -RLAPI void StopAutomationEventRecording(void); // Stop recording automation events -RLAPI void PlayAutomationEvent(AutomationEvent event); // Play a recorded automation event +RLAPI AutomationEventList LoadAutomationEventList(const char *fileName); // Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS +RLAPI void UnloadAutomationEventList(AutomationEventList list); // Unload automation events list from file +RLAPI bool ExportAutomationEventList(AutomationEventList list, const char *fileName); // Export automation events list as text file +RLAPI void SetAutomationEventList(AutomationEventList *list); // Set automation event list to record to +RLAPI void SetAutomationEventBaseFrame(int frame); // Set automation event internal base frame to start recording +RLAPI void StartAutomationEventRecording(void); // Start recording automation events (AutomationEventList must be set) +RLAPI void StopAutomationEventRecording(void); // Stop recording automation events +RLAPI void PlayAutomationEvent(AutomationEvent event); // Play a recorded automation event //------------------------------------------------------------------------------------ // Input Handling Functions (Module: core) @@ -1186,16 +1185,16 @@ RLAPI const char *GetKeyName(int key); // Get name of a Q RLAPI void SetExitKey(int key); // Set a custom key to exit program (default is ESC) // Input-related functions: gamepads -RLAPI bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available -RLAPI const char *GetGamepadName(int gamepad); // Get gamepad internal name id -RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Check if a gamepad button has been pressed once -RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Check if a gamepad button is being pressed -RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Check if a gamepad button has been released once -RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Check if a gamepad button is NOT being pressed -RLAPI int GetGamepadButtonPressed(void); // Get the last gamepad button pressed -RLAPI int GetGamepadAxisCount(int gamepad); // Get gamepad axis count for a gamepad -RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Get axis movement value for a gamepad axis -RLAPI int SetGamepadMappings(const char *mappings); // Set internal gamepad mappings (SDL_GameControllerDB) +RLAPI bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available +RLAPI const char *GetGamepadName(int gamepad); // Get gamepad internal name id +RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Check if a gamepad button has been pressed once +RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Check if a gamepad button is being pressed +RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Check if a gamepad button has been released once +RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Check if a gamepad button is NOT being pressed +RLAPI int GetGamepadButtonPressed(void); // Get the last gamepad button pressed +RLAPI int GetGamepadAxisCount(int gamepad); // Get gamepad axis count for a gamepad +RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Get axis movement value for a gamepad axis +RLAPI int SetGamepadMappings(const char *mappings); // Set internal gamepad mappings (SDL_GameControllerDB) RLAPI void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration); // Set gamepad vibration for both motors (duration in seconds) // Input-related functions: mouse @@ -1224,19 +1223,19 @@ RLAPI int GetTouchPointCount(void); // Get number of t //------------------------------------------------------------------------------------ // Gestures and Touch Handling Functions (Module: rgestures) //------------------------------------------------------------------------------------ -RLAPI void SetGesturesEnabled(unsigned int flags); // Enable a set of gestures using flags -RLAPI bool IsGestureDetected(unsigned int gesture); // Check if a gesture have been detected -RLAPI int GetGestureDetected(void); // Get latest detected gesture -RLAPI float GetGestureHoldDuration(void); // Get gesture hold time in seconds -RLAPI Vector2 GetGestureDragVector(void); // Get gesture drag vector -RLAPI float GetGestureDragAngle(void); // Get gesture drag angle -RLAPI Vector2 GetGesturePinchVector(void); // Get gesture pinch delta -RLAPI float GetGesturePinchAngle(void); // Get gesture pinch angle +RLAPI void SetGesturesEnabled(unsigned int flags); // Enable a set of gestures using flags +RLAPI bool IsGestureDetected(unsigned int gesture); // Check if a gesture have been detected +RLAPI int GetGestureDetected(void); // Get latest detected gesture +RLAPI float GetGestureHoldDuration(void); // Get gesture hold time in seconds +RLAPI Vector2 GetGestureDragVector(void); // Get gesture drag vector +RLAPI float GetGestureDragAngle(void); // Get gesture drag angle +RLAPI Vector2 GetGesturePinchVector(void); // Get gesture pinch delta +RLAPI float GetGesturePinchAngle(void); // Get gesture pinch angle //------------------------------------------------------------------------------------ // Camera System Functions (Module: rcamera) //------------------------------------------------------------------------------------ -RLAPI void UpdateCamera(Camera *camera, int mode); // Update camera position for selected mode +RLAPI void UpdateCamera(Camera *camera, int mode); // Update camera position for selected mode RLAPI void UpdateCameraPro(Camera *camera, Vector3 movement, Vector3 rotation, float zoom); // Update camera movement/rotation //------------------------------------------------------------------------------------ @@ -1245,9 +1244,9 @@ RLAPI void UpdateCameraPro(Camera *camera, Vector3 movement, Vector3 rotation, f // Set texture and rectangle to be used on shapes drawing // NOTE: It can be useful when using basic shapes and one single font, // defining a font char white rectangle would allow drawing everything in a single draw call -RLAPI void SetShapesTexture(Texture2D texture, Rectangle source); // Set texture and rectangle to be used on shapes drawing -RLAPI Texture2D GetShapesTexture(void); // Get texture that is used for shapes drawing -RLAPI Rectangle GetShapesTextureRectangle(void); // Get texture source rectangle that is used for shapes drawing +RLAPI void SetShapesTexture(Texture2D texture, Rectangle source); // Set texture and rectangle to be used on shapes drawing +RLAPI Texture2D GetShapesTexture(void); // Get texture that is used for shapes drawing +RLAPI Rectangle GetShapesTextureRectangle(void); // Get texture source rectangle that is used for shapes drawing // Basic shapes drawing functions RLAPI void DrawPixel(int posX, int posY, Color color); // Draw a pixel using geometry [Can be slow, use with care] @@ -1289,11 +1288,11 @@ RLAPI void DrawPolyLines(Vector2 center, int sides, float radius, float rotation RLAPI void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float lineThick, Color color); // Draw a polygon outline of n sides with extended parameters // Splines drawing functions -RLAPI void DrawSplineLinear(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Linear, minimum 2 points -RLAPI void DrawSplineBasis(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: B-Spline, minimum 4 points -RLAPI void DrawSplineCatmullRom(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Catmull-Rom, minimum 4 points -RLAPI void DrawSplineBezierQuadratic(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...] -RLAPI void DrawSplineBezierCubic(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...] +RLAPI void DrawSplineLinear(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Linear, minimum 2 points +RLAPI void DrawSplineBasis(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: B-Spline, minimum 4 points +RLAPI void DrawSplineCatmullRom(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Catmull-Rom, minimum 4 points +RLAPI void DrawSplineBezierQuadratic(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...] +RLAPI void DrawSplineBezierCubic(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...] RLAPI void DrawSplineSegmentLinear(Vector2 p1, Vector2 p2, float thick, Color color); // Draw spline segment: Linear, 2 points RLAPI void DrawSplineSegmentBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color); // Draw spline segment: B-Spline, 4 points RLAPI void DrawSplineSegmentCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color); // Draw spline segment: Catmull-Rom, 4 points @@ -1492,15 +1491,15 @@ RLAPI GlyphInfo GetGlyphInfo(Font font, int codepoint); RLAPI Rectangle GetGlyphAtlasRec(Font font, int codepoint); // Get glyph rectangle in font atlas for a codepoint (unicode character), fallback to '?' if not found // Text codepoints management functions (unicode characters) -RLAPI char *LoadUTF8(const int *codepoints, int length); // Load UTF-8 text encoded from codepoints array -RLAPI void UnloadUTF8(char *text); // Unload UTF-8 text encoded from codepoints array -RLAPI int *LoadCodepoints(const char *text, int *count); // Load all codepoints from a UTF-8 text string, codepoints count returned by parameter -RLAPI void UnloadCodepoints(int *codepoints); // Unload codepoints data from memory -RLAPI int GetCodepointCount(const char *text); // Get total number of codepoints in a UTF-8 encoded string -RLAPI int GetCodepoint(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure -RLAPI int GetCodepointNext(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure -RLAPI int GetCodepointPrevious(const char *text, int *codepointSize); // Get previous codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure -RLAPI const char *CodepointToUTF8(int codepoint, int *utf8Size); // Encode one codepoint into UTF-8 byte array (array length returned as parameter) +RLAPI char *LoadUTF8(const int *codepoints, int length); // Load UTF-8 text encoded from codepoints array +RLAPI void UnloadUTF8(char *text); // Unload UTF-8 text encoded from codepoints array +RLAPI int *LoadCodepoints(const char *text, int *count); // Load all codepoints from a UTF-8 text string, codepoints count returned by parameter +RLAPI void UnloadCodepoints(int *codepoints); // Unload codepoints data from memory +RLAPI int GetCodepointCount(const char *text); // Get total number of codepoints in a UTF-8 encoded string +RLAPI int GetCodepoint(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure +RLAPI int GetCodepointNext(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure +RLAPI int GetCodepointPrevious(const char *text, int *codepointSize); // Get previous codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure +RLAPI const char *CodepointToUTF8(int codepoint, int *utf8Size); // Encode one codepoint into UTF-8 byte array (array length returned as parameter) // Text strings management functions (no UTF-8 strings, only byte chars) // NOTE: Some strings allocate memory internally for returned strings, just be careful! @@ -1515,14 +1514,14 @@ RLAPI const char *TextJoin(const char **textList, int count, const char *delimit RLAPI const char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings RLAPI void TextAppend(char *text, const char *append, int *position); // Append text at specific position and move cursor! RLAPI int TextFindIndex(const char *text, const char *find); // Find first text occurrence within a string -RLAPI const char *TextToUpper(const char *text); // Get upper case version of provided string -RLAPI const char *TextToLower(const char *text); // Get lower case version of provided string -RLAPI const char *TextToPascal(const char *text); // Get Pascal case notation version of provided string -RLAPI const char *TextToSnake(const char *text); // Get Snake case notation version of provided string -RLAPI const char *TextToCamel(const char *text); // Get Camel case notation version of provided string +RLAPI const char *TextToUpper(const char *text); // Get upper case version of provided string +RLAPI const char *TextToLower(const char *text); // Get lower case version of provided string +RLAPI const char *TextToPascal(const char *text); // Get Pascal case notation version of provided string +RLAPI const char *TextToSnake(const char *text); // Get Snake case notation version of provided string +RLAPI const char *TextToCamel(const char *text); // Get Camel case notation version of provided string -RLAPI int TextToInteger(const char *text); // Get integer value from text (negative values not supported) -RLAPI float TextToFloat(const char *text); // Get float value from text (negative values not supported) +RLAPI int TextToInteger(const char *text); // Get integer value from text (negative values not supported) +RLAPI float TextToFloat(const char *text); // Get float value from text (negative values not supported) //------------------------------------------------------------------------------------ // Basic 3d Shapes Drawing Functions (Module: models) @@ -1615,14 +1614,14 @@ RLAPI void UnloadModelAnimations(ModelAnimation *animations, int animCount); RLAPI bool IsModelAnimationValid(Model model, ModelAnimation anim); // Check model animation skeleton match // Collision detection functions -RLAPI bool CheckCollisionSpheres(Vector3 center1, float radius1, Vector3 center2, float radius2); // Check collision between two spheres -RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Check collision between two bounding boxes -RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 center, float radius); // Check collision between box and sphere -RLAPI RayCollision GetRayCollisionSphere(Ray ray, Vector3 center, float radius); // Get collision info between ray and sphere -RLAPI RayCollision GetRayCollisionBox(Ray ray, BoundingBox box); // Get collision info between ray and box -RLAPI RayCollision GetRayCollisionMesh(Ray ray, Mesh mesh, Matrix transform); // Get collision info between ray and mesh -RLAPI RayCollision GetRayCollisionTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3); // Get collision info between ray and triangle -RLAPI RayCollision GetRayCollisionQuad(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4); // Get collision info between ray and quad +RLAPI bool CheckCollisionSpheres(Vector3 center1, float radius1, Vector3 center2, float radius2); // Check collision between two spheres +RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Check collision between two bounding boxes +RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 center, float radius); // Check collision between box and sphere +RLAPI RayCollision GetRayCollisionSphere(Ray ray, Vector3 center, float radius); // Get collision info between ray and sphere +RLAPI RayCollision GetRayCollisionBox(Ray ray, BoundingBox box); // Get collision info between ray and box +RLAPI RayCollision GetRayCollisionMesh(Ray ray, Mesh mesh, Matrix transform); // Get collision info between ray and mesh +RLAPI RayCollision GetRayCollisionTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3); // Get collision info between ray and triangle +RLAPI RayCollision GetRayCollisionQuad(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4); // Get collision info between ray and quad //------------------------------------------------------------------------------------ // Audio Loading and Playing Functions (Module: audio) From 8a5a95c13a899564b98483f356d51a3024586870 Mon Sep 17 00:00:00 2001 From: __hexmaster111 Date: Fri, 13 Dec 2024 02:21:13 -0600 Subject: [PATCH 03/14] Removed inaccurate comment about negitves not being supported with TextToFloat And TextToInt Methods (#4596) --- src/raylib.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/raylib.h b/src/raylib.h index dcaaa44c7..7e1a1f838 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1520,8 +1520,8 @@ RLAPI const char *TextToPascal(const char *text); RLAPI const char *TextToSnake(const char *text); // Get Snake case notation version of provided string RLAPI const char *TextToCamel(const char *text); // Get Camel case notation version of provided string -RLAPI int TextToInteger(const char *text); // Get integer value from text (negative values not supported) -RLAPI float TextToFloat(const char *text); // Get float value from text (negative values not supported) +RLAPI int TextToInteger(const char *text); // Get integer value from text +RLAPI float TextToFloat(const char *text); // Get float value from text //------------------------------------------------------------------------------------ // Basic 3d Shapes Drawing Functions (Module: models) From 0a26d9a26f1ddd734ee844bc6730dc91aad4c1c3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 13 Dec 2024 08:21:27 +0000 Subject: [PATCH 04/14] Update raylib_api.* by CI --- parser/output/raylib_api.json | 4 ++-- parser/output/raylib_api.lua | 4 ++-- parser/output/raylib_api.txt | 4 ++-- parser/output/raylib_api.xml | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/parser/output/raylib_api.json b/parser/output/raylib_api.json index e05d8a748..853f591d4 100644 --- a/parser/output/raylib_api.json +++ b/parser/output/raylib_api.json @@ -9801,7 +9801,7 @@ }, { "name": "TextToInteger", - "description": "Get integer value from text (negative values not supported)", + "description": "Get integer value from text", "returnType": "int", "params": [ { @@ -9812,7 +9812,7 @@ }, { "name": "TextToFloat", - "description": "Get float value from text (negative values not supported)", + "description": "Get float value from text", "returnType": "float", "params": [ { diff --git a/parser/output/raylib_api.lua b/parser/output/raylib_api.lua index d8a848b45..2983456f3 100644 --- a/parser/output/raylib_api.lua +++ b/parser/output/raylib_api.lua @@ -6969,7 +6969,7 @@ return { }, { name = "TextToInteger", - description = "Get integer value from text (negative values not supported)", + description = "Get integer value from text", returnType = "int", params = { {type = "const char *", name = "text"} @@ -6977,7 +6977,7 @@ return { }, { name = "TextToFloat", - description = "Get float value from text (negative values not supported)", + description = "Get float value from text", returnType = "float", params = { {type = "const char *", name = "text"} diff --git a/parser/output/raylib_api.txt b/parser/output/raylib_api.txt index 7c7b003c4..038b43e17 100644 --- a/parser/output/raylib_api.txt +++ b/parser/output/raylib_api.txt @@ -3757,12 +3757,12 @@ Function 438: TextToCamel() (1 input parameters) Function 439: TextToInteger() (1 input parameters) Name: TextToInteger Return type: int - Description: Get integer value from text (negative values not supported) + Description: Get integer value from text Param[1]: text (type: const char *) Function 440: TextToFloat() (1 input parameters) Name: TextToFloat Return type: float - Description: Get float value from text (negative values not supported) + Description: Get float value from text Param[1]: text (type: const char *) Function 441: DrawLine3D() (3 input parameters) Name: DrawLine3D diff --git a/parser/output/raylib_api.xml b/parser/output/raylib_api.xml index e1b1f35e2..734f96465 100644 --- a/parser/output/raylib_api.xml +++ b/parser/output/raylib_api.xml @@ -2487,10 +2487,10 @@ - + - + From 93a1e75741175b9a2136593064b3714e79a363e2 Mon Sep 17 00:00:00 2001 From: Jeffery Myers Date: Fri, 13 Dec 2024 00:21:45 -0800 Subject: [PATCH 05/14] Disable the threading example in MSVC for release and debug build (was disabled for dll builds already) (#4594) --- projects/VS2022/raylib.sln | 4 ---- 1 file changed, 4 deletions(-) diff --git a/projects/VS2022/raylib.sln b/projects/VS2022/raylib.sln index 5142c14a1..feb0f2c35 100644 --- a/projects/VS2022/raylib.sln +++ b/projects/VS2022/raylib.sln @@ -693,16 +693,12 @@ Global {F026020F-7B00-40C8-91C3-5DE85EC45A95}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 {F026020F-7B00-40C8-91C3-5DE85EC45A95}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 {F026020F-7B00-40C8-91C3-5DE85EC45A95}.Debug|x64.ActiveCfg = Debug|x64 - {F026020F-7B00-40C8-91C3-5DE85EC45A95}.Debug|x64.Build.0 = Debug|x64 {F026020F-7B00-40C8-91C3-5DE85EC45A95}.Debug|x86.ActiveCfg = Debug|Win32 - {F026020F-7B00-40C8-91C3-5DE85EC45A95}.Debug|x86.Build.0 = Debug|Win32 {F026020F-7B00-40C8-91C3-5DE85EC45A95}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {F026020F-7B00-40C8-91C3-5DE85EC45A95}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 {F026020F-7B00-40C8-91C3-5DE85EC45A95}.Release.DLL|x86.Build.0 = Release.DLL|Win32 {F026020F-7B00-40C8-91C3-5DE85EC45A95}.Release|x64.ActiveCfg = Release|x64 - {F026020F-7B00-40C8-91C3-5DE85EC45A95}.Release|x64.Build.0 = Release|x64 {F026020F-7B00-40C8-91C3-5DE85EC45A95}.Release|x86.ActiveCfg = Release|Win32 - {F026020F-7B00-40C8-91C3-5DE85EC45A95}.Release|x86.Build.0 = Release|Win32 {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 From d0504800d2c5a5e722a65a9023ddadca17f930bc Mon Sep 17 00:00:00 2001 From: Per Hallsmark Date: Sun, 15 Dec 2024 11:16:08 +0100 Subject: [PATCH 06/14] install rcamera.h (#4603) Signed-off-by: Per Hallsmark --- build.zig | 1 + src/CMakeLists.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/build.zig b/build.zig index 866e70034..66e8fab4f 100644 --- a/build.zig +++ b/build.zig @@ -401,6 +401,7 @@ pub fn build(b: *std.Build) !void { const lib = try compileRaylib(b, target, optimize, Options.getOptions(b)); lib.installHeader(b.path("src/raylib.h"), "raylib.h"); + lib.installHeader(b.path("src/rcamera.h"), "rcamera.h"); lib.installHeader(b.path("src/raymath.h"), "raymath.h"); lib.installHeader(b.path("src/rlgl.h"), "rlgl.h"); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9735e267f..a7313a0b4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -23,6 +23,7 @@ endif() # Used as public API to be included into other projects set(raylib_public_headers raylib.h + rcamera.h rlgl.h raymath.h ) From 79facde3535af1f35942eec38f02f2851de618ab Mon Sep 17 00:00:00 2001 From: Le Juez Victor <90587919+Bigfoot71@users.noreply.github.com> Date: Mon, 16 Dec 2024 00:51:42 +0100 Subject: [PATCH 07/14] fix `rlActiveDrawBuffers` for OpenGL ES 3 (#4605) --- src/rlgl.h | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/rlgl.h b/src/rlgl.h index b09b04b18..857e97511 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -1890,16 +1890,6 @@ void rlActiveDrawBuffers(int count) else { unsigned int buffers[8] = { -#if defined(GRAPHICS_API_OPENGL_ES3) - GL_COLOR_ATTACHMENT0_EXT, - GL_COLOR_ATTACHMENT1_EXT, - GL_COLOR_ATTACHMENT2_EXT, - GL_COLOR_ATTACHMENT3_EXT, - GL_COLOR_ATTACHMENT4_EXT, - GL_COLOR_ATTACHMENT5_EXT, - GL_COLOR_ATTACHMENT6_EXT, - GL_COLOR_ATTACHMENT7_EXT, -#else GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, @@ -1908,14 +1898,9 @@ void rlActiveDrawBuffers(int count) GL_COLOR_ATTACHMENT5, GL_COLOR_ATTACHMENT6, GL_COLOR_ATTACHMENT7, -#endif }; -#if defined(GRAPHICS_API_OPENGL_ES3) - glDrawBuffersEXT(count, buffers); -#else glDrawBuffers(count, buffers); -#endif } } else TRACELOG(LOG_WARNING, "GL: One color buffer active by default"); From bdfbd6e8cc77b755d6552f90028ba8262d79ab92 Mon Sep 17 00:00:00 2001 From: Asdqwe Date: Mon, 16 Dec 2024 18:19:00 -0300 Subject: [PATCH 08/14] Fix maximizing, minimizing and restoring windows for SDL2 (#4607) --- src/platforms/rcore_desktop_sdl.c | 48 +++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index d051ae83f..de93a1f5e 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -497,20 +497,21 @@ void ToggleBorderlessWindowed(void) void MaximizeWindow(void) { SDL_MaximizeWindow(platform.window); - CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; + if ((CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) == 0) CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; } // Set window state: minimized void MinimizeWindow(void) { SDL_MinimizeWindow(platform.window); - CORE.Window.flags |= FLAG_WINDOW_MINIMIZED; + if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) == 0) CORE.Window.flags |= FLAG_WINDOW_MINIMIZED; } // Set window state: not minimized/maximized void RestoreWindow(void) { - SDL_ShowWindow(platform.window); + SDL_RestoreWindow(platform.window); + // CORE.Window.flags will be removed on PollInputEvents() } // Set window configuration state using flags @@ -1448,6 +1449,22 @@ void PollInputEvents(void) CORE.Window.currentFbo.width = width; CORE.Window.currentFbo.height = height; CORE.Window.resizedLastFrame = true; + + #ifndef PLATFORM_DESKTOP_SDL3 + // Manually detect if the window was maximized (due to SDL2 restore being unreliable on some platforms) to remove the FLAG_WINDOW_MAXIMIZED accordingly + if ((CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) > 0) + { + int borderTop = 0; + int borderLeft = 0; + int borderBottom = 0; + int borderRight = 0; + SDL_GetWindowBordersSize(platform.window, &borderTop, &borderLeft, &borderBottom, &borderRight); + SDL_Rect usableBounds; + SDL_GetDisplayUsableBounds(SDL_GetWindowDisplayIndex(platform.window), &usableBounds); + + if ((width + borderLeft + borderRight != usableBounds.w) && (height + borderTop + borderBottom != usableBounds.h)) CORE.Window.flags &= ~FLAG_WINDOW_MAXIMIZED; + } + #endif } break; case SDL_WINDOWEVENT_ENTER: { @@ -1457,13 +1474,32 @@ void PollInputEvents(void) { CORE.Input.Mouse.cursorOnScreen = false; } break; - case SDL_WINDOWEVENT_HIDDEN: case SDL_WINDOWEVENT_MINIMIZED: + { + if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) == 0) CORE.Window.flags |= FLAG_WINDOW_MINIMIZED; + } break; + case SDL_WINDOWEVENT_MAXIMIZED: + { + if ((CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) == 0) CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; + } break; + case SDL_WINDOWEVENT_RESTORED: + { + if ((SDL_GetWindowFlags(platform.window) & SDL_WINDOW_MINIMIZED) == 0) + { + if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED; + } + + #ifdef PLATFORM_DESKTOP_SDL3 + if ((SDL_GetWindowFlags(platform.window) & SDL_WINDOW_MAXIMIZED) == 0) + { + if ((CORE.Window.flags & SDL_WINDOW_MAXIMIZED) > 0) CORE.Window.flags &= ~SDL_WINDOW_MAXIMIZED; + } + #endif + } break; + case SDL_WINDOWEVENT_HIDDEN: case SDL_WINDOWEVENT_FOCUS_LOST: case SDL_WINDOWEVENT_SHOWN: case SDL_WINDOWEVENT_FOCUS_GAINED: - case SDL_WINDOWEVENT_MAXIMIZED: - case SDL_WINDOWEVENT_RESTORED: #if defined(PLATFORM_DESKTOP_SDL3) break; #else From 714cd5ef5c88a878aaa77e835e0260ed0b1d6d0b Mon Sep 17 00:00:00 2001 From: JupiterRider <60042618+JupiterRider@users.noreply.github.com> Date: Wed, 18 Dec 2024 11:38:11 +0100 Subject: [PATCH 09/14] add SetGamepadVibration to rgfw and template (#4612) --- src/platforms/rcore_desktop_rgfw.c | 6 ++++++ src/platforms/rcore_template.c | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/platforms/rcore_desktop_rgfw.c b/src/platforms/rcore_desktop_rgfw.c index a6ef60c9e..3cf005f25 100644 --- a/src/platforms/rcore_desktop_rgfw.c +++ b/src/platforms/rcore_desktop_rgfw.c @@ -780,6 +780,12 @@ int SetGamepadMappings(const char *mappings) return 0; } +// Set gamepad vibration +void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration) +{ + TRACELOG(LOG_WARNING, "GamepadSetVibration() not available on target platform"); +} + // Set mouse position XY void SetMousePosition(int x, int y) { diff --git a/src/platforms/rcore_template.c b/src/platforms/rcore_template.c index 891c4ab34..9eca9726a 100644 --- a/src/platforms/rcore_template.c +++ b/src/platforms/rcore_template.c @@ -381,6 +381,12 @@ int SetGamepadMappings(const char *mappings) return 0; } +// Set gamepad vibration +void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration) +{ + TRACELOG(LOG_WARNING, "GamepadSetVibration() not implemented on target platform"); +} + // Set mouse position XY void SetMousePosition(int x, int y) { From cdaff163cb8f2d0bb23e993be51190f4c07fb1b8 Mon Sep 17 00:00:00 2001 From: Asdqwe Date: Wed, 18 Dec 2024 07:39:30 -0300 Subject: [PATCH 10/14] Fix show, hide, focus and unfocus window/flags states for SDL2 (#4610) --- src/platforms/rcore_desktop_sdl.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index de93a1f5e..b7f00bc76 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -1427,7 +1427,7 @@ void PollInputEvents(void) // Window events are also polled (Minimized, maximized, close...) - #ifndef PLATFORM_DESKTOP_SDL3 + #ifndef PLATFORM_DESKTOP_SDL3 // SDL3 states: // The SDL_WINDOWEVENT_* events have been moved to top level events, // and SDL_WINDOWEVENT has been removed. @@ -1437,7 +1437,7 @@ void PollInputEvents(void) { switch (event.window.event) { - #endif + #endif case SDL_WINDOWEVENT_RESIZED: case SDL_WINDOWEVENT_SIZE_CHANGED: { @@ -1466,6 +1466,7 @@ void PollInputEvents(void) } #endif } break; + case SDL_WINDOWEVENT_ENTER: { CORE.Input.Mouse.cursorOnScreen = true; @@ -1474,6 +1475,7 @@ void PollInputEvents(void) { CORE.Input.Mouse.cursorOnScreen = false; } break; + case SDL_WINDOWEVENT_MINIMIZED: { if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) == 0) CORE.Window.flags |= FLAG_WINDOW_MINIMIZED; @@ -1496,13 +1498,26 @@ void PollInputEvents(void) } #endif } break; + case SDL_WINDOWEVENT_HIDDEN: - case SDL_WINDOWEVENT_FOCUS_LOST: + { + if ((CORE.Window.flags & FLAG_WINDOW_HIDDEN) == 0) CORE.Window.flags |= FLAG_WINDOW_HIDDEN; + } break; case SDL_WINDOWEVENT_SHOWN: + { + if ((CORE.Window.flags & FLAG_WINDOW_HIDDEN) > 0) CORE.Window.flags &= ~FLAG_WINDOW_HIDDEN; + } break; + case SDL_WINDOWEVENT_FOCUS_GAINED: - #if defined(PLATFORM_DESKTOP_SDL3) - break; - #else + { + if ((CORE.Window.flags & FLAG_WINDOW_UNFOCUSED) > 0) CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; + } break; + case SDL_WINDOWEVENT_FOCUS_LOST: + { + if ((CORE.Window.flags & FLAG_WINDOW_UNFOCUSED) == 0) CORE.Window.flags |= FLAG_WINDOW_UNFOCUSED; + } break; + + #ifndef PLATFORM_DESKTOP_SDL3 default: break; } } break; From 35c24084130f14397ab252b91f115a8fedfd9b7b Mon Sep 17 00:00:00 2001 From: Kirandeep-Singh-Khehra <107160937+Kirandeep-Singh-Khehra@users.noreply.github.com> Date: Wed, 18 Dec 2024 16:09:50 +0530 Subject: [PATCH 11/14] [rmodels] Optimized `UpdateModelAnimationBones()` function (#4602) - Updating bones only once instead for each mesh. - Updating only one `model.meshes[].boneMatrices` and then using deep copy for other meshes instead of calculating for each bone in each mesh. **Other points:** - Makes it a clean base/template/reference for bone updation functions. Because if using this as template then some calculations done in one mesh can affect bones in other mesh in next iteration(doubles the effect in for next mesh). Signed-off-by: Kirandeep-Singh-Khehra --- src/rmodels.c | 74 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 25 deletions(-) diff --git a/src/rmodels.c b/src/rmodels.c index a159d5432..cf799aa58 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -2270,38 +2270,62 @@ void UpdateModelAnimationBones(Model model, ModelAnimation anim, int frame) { if (frame >= anim.frameCount) frame = frame%anim.frameCount; + // Get first mesh which have bones + int firstMeshWithBones = -1; + for (int i = 0; i < model.meshCount; i++) { if (model.meshes[i].boneMatrices) { assert(model.meshes[i].boneCount == anim.boneCount); + if (firstMeshWithBones == -1) + { + firstMeshWithBones = i; + } + } + } - for (int boneId = 0; boneId < model.meshes[i].boneCount; boneId++) + // Update all bones and boneMatrices of first mesh with bones. + for (int boneId = 0; boneId < anim.boneCount; boneId++) + { + Vector3 inTranslation = model.bindPose[boneId].translation; + Quaternion inRotation = model.bindPose[boneId].rotation; + Vector3 inScale = model.bindPose[boneId].scale; + + Vector3 outTranslation = anim.framePoses[frame][boneId].translation; + Quaternion outRotation = anim.framePoses[frame][boneId].rotation; + Vector3 outScale = anim.framePoses[frame][boneId].scale; + + Vector3 invTranslation = Vector3RotateByQuaternion(Vector3Negate(inTranslation), QuaternionInvert(inRotation)); + Quaternion invRotation = QuaternionInvert(inRotation); + Vector3 invScale = Vector3Divide((Vector3){ 1.0f, 1.0f, 1.0f }, inScale); + + Vector3 boneTranslation = Vector3Add( + Vector3RotateByQuaternion(Vector3Multiply(outScale, invTranslation), + outRotation), outTranslation); + Quaternion boneRotation = QuaternionMultiply(outRotation, invRotation); + Vector3 boneScale = Vector3Multiply(outScale, invScale); + + Matrix boneMatrix = MatrixMultiply(MatrixMultiply( + QuaternionToMatrix(boneRotation), + MatrixTranslate(boneTranslation.x, boneTranslation.y, boneTranslation.z)), + MatrixScale(boneScale.x, boneScale.y, boneScale.z)); + + model.meshes[firstMeshWithBones].boneMatrices[boneId] = boneMatrix; + } + + // Update remaining meshes with bones (Use Deep copy because shallow copy results in double free with 'UnloadModel()') + if (firstMeshWithBones != -1) + { + for (int i = firstMeshWithBones + 1; i < model.meshCount; i++) + { + if (model.meshes[i].boneMatrices) { - Vector3 inTranslation = model.bindPose[boneId].translation; - Quaternion inRotation = model.bindPose[boneId].rotation; - Vector3 inScale = model.bindPose[boneId].scale; - - Vector3 outTranslation = anim.framePoses[frame][boneId].translation; - Quaternion outRotation = anim.framePoses[frame][boneId].rotation; - Vector3 outScale = anim.framePoses[frame][boneId].scale; - - Vector3 invTranslation = Vector3RotateByQuaternion(Vector3Negate(inTranslation), QuaternionInvert(inRotation)); - Quaternion invRotation = QuaternionInvert(inRotation); - Vector3 invScale = Vector3Divide((Vector3){ 1.0f, 1.0f, 1.0f }, inScale); - - Vector3 boneTranslation = Vector3Add( - Vector3RotateByQuaternion(Vector3Multiply(outScale, invTranslation), - outRotation), outTranslation); - Quaternion boneRotation = QuaternionMultiply(outRotation, invRotation); - Vector3 boneScale = Vector3Multiply(outScale, invScale); - - Matrix boneMatrix = MatrixMultiply(MatrixMultiply( - QuaternionToMatrix(boneRotation), - MatrixTranslate(boneTranslation.x, boneTranslation.y, boneTranslation.z)), - MatrixScale(boneScale.x, boneScale.y, boneScale.z)); - - model.meshes[i].boneMatrices[boneId] = boneMatrix; + memcpy( + model.meshes[i].boneMatrices, + model.meshes[firstMeshWithBones].boneMatrices, + model.meshes[i].boneCount * sizeof(model.meshes[i].boneMatrices[0]) + ); } } } From f76734fc5059a58d6026d17ff0da985d8a228d5b Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 18 Dec 2024 11:43:43 +0100 Subject: [PATCH 12/14] REVIEWED: `UpdateModelAnimationBones()`, break on first mesh found and formating --- src/rmodels.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/rmodels.c b/src/rmodels.c index cf799aa58..43997c318 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -2281,6 +2281,7 @@ void UpdateModelAnimationBones(Model model, ModelAnimation anim, int frame) if (firstMeshWithBones == -1) { firstMeshWithBones = i; + break; } } } @@ -2314,18 +2315,17 @@ void UpdateModelAnimationBones(Model model, ModelAnimation anim, int frame) model.meshes[firstMeshWithBones].boneMatrices[boneId] = boneMatrix; } - // Update remaining meshes with bones (Use Deep copy because shallow copy results in double free with 'UnloadModel()') + // Update remaining meshes with bones + // NOTE: Using deep copy because shallow copy results in double free with 'UnloadModel()' if (firstMeshWithBones != -1) { for (int i = firstMeshWithBones + 1; i < model.meshCount; i++) { if (model.meshes[i].boneMatrices) { - memcpy( - model.meshes[i].boneMatrices, + memcpy(model.meshes[i].boneMatrices, model.meshes[firstMeshWithBones].boneMatrices, - model.meshes[i].boneCount * sizeof(model.meshes[i].boneMatrices[0]) - ); + model.meshes[i].boneCount * sizeof(model.meshes[i].boneMatrices[0])); } } } @@ -2338,6 +2338,7 @@ void UpdateModelAnimationBones(Model model, ModelAnimation anim, int frame) void UpdateModelAnimation(Model model, ModelAnimation anim, int frame) { UpdateModelAnimationBones(model,anim,frame); + for (int m = 0; m < model.meshCount; m++) { Mesh mesh = model.meshes[m]; @@ -2346,8 +2347,9 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, int frame) int boneId = 0; int boneCounter = 0; float boneWeight = 0.0; - bool updated = false; // Flag to check when anim vertex information is updated + bool updated = false; // Flag to check when anim vertex information is updated const int vValues = mesh.vertexCount*3; + for (int vCounter = 0; vCounter < vValues; vCounter += 3) { mesh.animVertices[vCounter] = 0; From de6c09ee7aab56adb625eb6d2611f7e974af7c47 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 18 Dec 2024 11:45:55 +0100 Subject: [PATCH 13/14] WARNING: REVIEWED: Use `libraylib.web.a` naming on PLATFORM_WEB This change allows to have in same directory (currently `raylib/src`) two raylib build versions: Desktop and Web --- examples/Makefile | 2 +- examples/Makefile.Web | 2 +- src/Makefile | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/Makefile b/examples/Makefile index 34cf36f04..57a772229 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -482,7 +482,7 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DRM) endif ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) # Libraries for web (HTML5) compiling - LDLIBS = $(RAYLIB_RELEASE_PATH)/libraylib.a + LDLIBS = $(RAYLIB_RELEASE_PATH)/libraylib.web.a endif # Define source code object files required diff --git a/examples/Makefile.Web b/examples/Makefile.Web index dd5dc6881..92bcfa229 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -365,7 +365,7 @@ ifeq ($(PLATFORM),PLATFORM_DRM) endif ifeq ($(PLATFORM),PLATFORM_WEB) # Libraries for web (HTML5) compiling - LDLIBS = $(RAYLIB_RELEASE_PATH)/libraylib.a + LDLIBS = $(RAYLIB_RELEASE_PATH)/libraylib.web.a endif # Define source code object files required diff --git a/src/Makefile b/src/Makefile index 7dde52fbd..1e3ddb791 100644 --- a/src/Makefile +++ b/src/Makefile @@ -662,8 +662,8 @@ raylib: $(OBJS) ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) # Compile raylib libray for web #$(CC) $(OBJS) -r -o $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).bc - $(AR) rcs $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).a $(OBJS) - @echo "raylib library generated (lib$(RAYLIB_LIB_NAME).a)!" + $(AR) rcs $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).web.a $(OBJS) + @echo "raylib library generated (lib$(RAYLIB_LIB_NAME).web.a)!" else ifeq ($(RAYLIB_LIBTYPE),SHARED) ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW PLATFORM_DESKTOP_SDL PLATFORM_DESKTOP_RGFW)) From 58004723d8c0b4fe211b3a20815a9a1f8f20b601 Mon Sep 17 00:00:00 2001 From: Colleague Riley Date: Wed, 18 Dec 2024 03:03:42 -0800 Subject: [PATCH 14/14] [rcore][RGFW] Add new backend option: `PLATFORM_WEB_RGFW` and update RGFW (#4480) * add PLATFORM_WEB_RGFW * fix some bugs * fix web_rgfw gamepad * send fake screensize * fix gamepad bugs (linux) | add L3 + R3 (gamepad) * fix? * update RGFW (again) * update raylib (merge) * fix xinput stuff * delete makefile added by mistake * update RGFW * update RGFW (rename joystick to gamepad to avoid misunderstandings * update RGFW (fix X11 bug) * update RGFW * use RL_MALLOC for RGFW * update RGFW (fixes xdnd bug) * fix some formating --- examples/Makefile | 37 +- examples/Makefile.Web | 25 +- src/Makefile | 20 +- src/external/RGFW.h | 1502 +++++++++++++++------------- src/platforms/rcore_desktop_rgfw.c | 279 +++--- src/rcore.c | 17 +- 6 files changed, 985 insertions(+), 895 deletions(-) diff --git a/examples/Makefile b/examples/Makefile index 57a772229..c02cad434 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -20,6 +20,8 @@ # - Linux (X11 desktop mode) # - macOS/OSX (x64, arm64 (not tested)) # - Others (not tested) +# > PLATFORM_WEB_RGFW: +# - HTML5 (WebAssembly) # > PLATFORM_WEB: # - HTML5 (WebAssembly) # > PLATFORM_DRM: @@ -51,7 +53,7 @@ # Define required environment variables #------------------------------------------------------------------------------------------------ -# Define target platform: PLATFORM_DESKTOP, PLATFORM_DESKTOP_SDL, PLATFORM_DRM, PLATFORM_ANDROID, PLATFORM_WEB +# Define target platform: PLATFORM_DESKTOP, PLATFORM_DESKTOP_SDL, PLATFORM_DRM, PLATFORM_ANDROID, PLATFORM_WEB, PLATFORM_WEB_RGFW PLATFORM ?= PLATFORM_DESKTOP ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_DESKTOP_GLFW PLATFORM_DESKTOP_SDL PLATFORM_DESKTOP_RGFW)) @@ -107,7 +109,7 @@ BUILD_WEB_RESOURCES ?= TRUE BUILD_WEB_RESOURCES_PATH ?= $(dir $<)resources@resources # Determine PLATFORM_OS when required -ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW PLATFORM_DESKTOP_SDL PLATFORM_DESKTOP_RGFW PLATFORM_WEB)) +ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW PLATFORM_DESKTOP_SDL PLATFORM_DESKTOP_RGFW PLATFORM_WEB PLATFORM_WEB_RGFW)) # No uname.exe on MinGW!, but OS=Windows_NT on Windows! # ifeq ($(UNAME),Msys) -> Windows ifeq ($(OS),Windows_NT) @@ -158,7 +160,7 @@ endif # Define raylib release directory for compiled library RAYLIB_RELEASE_PATH ?= $(RAYLIB_PATH)/src -ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) +ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) ifeq ($(PLATFORM_OS),WINDOWS) # Emscripten required variables EMSDK_PATH ?= C:/raylib/emsdk @@ -184,8 +186,8 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW) CC = clang endif endif -ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) - # HTML5 emscripten compiler +ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) + # HTML5 emscripten compiler # WARNING: To compile to HTML5, code must be redesigned # to use emscripten.h and emscripten_set_main_loop() CC = emcc @@ -203,7 +205,7 @@ endif ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID) MAKE = mingw32-make endif -ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) +ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) ifeq ($(OS),Windows_NT) MAKE = mingw32-make else @@ -231,11 +233,11 @@ CFLAGS = -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces -Wunused-result ifeq ($(BUILD_MODE),DEBUG) CFLAGS += -g -D_DEBUG - ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) + ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) CFLAGS += -sASSERTIONS=1 --profiling endif -else - ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) +else + ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) ifeq ($(BUILD_WEB_ASYNCIFY),TRUE) CFLAGS += -O3 else @@ -325,7 +327,7 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_SDL) endif LDFLAGS += -L$(SDL_LIBRARY_PATH) endif -ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) +ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) # -Os # size optimization # -O2 # optimization level 2, if used, also set --memory-init-file 0 # -sUSE_GLFW=3 # Use glfw3 library (context/input management) @@ -341,9 +343,14 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) # --memory-init-file 0 # to avoid an external memory initialization code file (.mem) # --preload-file resources # specify a resources folder for data compilation # --source-map-base # allow debugging in browser with source map - LDFLAGS += -sUSE_GLFW=3 -sTOTAL_MEMORY=$(BUILD_WEB_HEAP_SIZE) -sFORCE_FILESYSTEM=1 - # Build using asyncify + ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) + LDFLAGS += -sUSE_GLFW=3 + endif + + LDFLAGS += -sTOTAL_MEMORY=$(BUILD_WEB_HEAP_SIZE) -sFORCE_FILESYSTEM=1 + + # Build using asyncify ifeq ($(BUILD_WEB_ASYNCIFY),TRUE) LDFLAGS += -sASYNCIFY endif @@ -480,7 +487,7 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DRM) # NOTE: Required packages: libasound2-dev (ALSA) LDLIBS = -lraylib -lGLESv2 -lEGL -lpthread -lrt -lm -lgbm -ldrm -ldl -latomic endif -ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) +ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) # Libraries for web (HTML5) compiling LDLIBS = $(RAYLIB_RELEASE_PATH)/libraylib.web.a endif @@ -681,7 +688,7 @@ others: $(OTHERS) %: %.c ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID) $(MAKE) -f Makefile.Android PROJECT_NAME=$@ PROJECT_SOURCE_FILES=$< -else ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) +else ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) $(MAKE) -f Makefile.Web $@ else $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -D$(TARGET_PLATFORM) @@ -710,7 +717,7 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DRM) find . -type f -executable -delete rm -fv *.o endif -ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) +ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) ifeq ($(PLATFORM_OS),WINDOWS) del *.wasm *.html *.js *.data else diff --git a/examples/Makefile.Web b/examples/Makefile.Web index 92bcfa229..a4470e09f 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -65,7 +65,7 @@ BUILD_WEB_HEAP_SIZE ?= 134217728 USE_WEBGL2 ?= FALSE # Determine PLATFORM_OS in case PLATFORM_DESKTOP or PLATFORM_WEB selected -ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_DESKTOP PLATFORM_WEB)) +ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_DESKTOP PLATFORM_WEB PLATFORM_WEB_RGFW)) # No uname.exe on MinGW!, but OS=Windows_NT on Windows! # ifeq ($(UNAME),Msys) -> Windows ifeq ($(OS),Windows_NT) @@ -116,7 +116,7 @@ endif # Define raylib release directory for compiled library RAYLIB_RELEASE_PATH ?= $(RAYLIB_PATH)/src -ifeq ($(PLATFORM),PLATFORM_WEB) +ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) ifeq ($(PLATFORM_OS),WINDOWS) # Emscripten required variables EMSDK_PATH ?= C:/raylib/emsdk @@ -142,7 +142,7 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) CC = clang endif endif -ifeq ($(PLATFORM),PLATFORM_WEB) +ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) # HTML5 emscripten compiler # WARNING: To compile to HTML5, code must be redesigned # to use emscripten.h and emscripten_set_main_loop() @@ -161,7 +161,7 @@ endif ifeq ($(PLATFORM),PLATFORM_ANDROID) MAKE = mingw32-make endif -ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) +ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) ifeq ($(OS),Windows_NT) MAKE = mingw32-make else @@ -189,11 +189,11 @@ CFLAGS = -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces -Wunused-result ifeq ($(BUILD_MODE),DEBUG) CFLAGS += -g -D_DEBUG - ifeq ($(PLATFORM),PLATFORM_WEB) + ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) CFLAGS += -sASSERTIONS=1 --profiling endif else - ifeq ($(PLATFORM),PLATFORM_WEB) + ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) ifeq ($(BUILD_WEB_ASYNCIFY),TRUE) CFLAGS += -O3 else @@ -263,7 +263,7 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) LDFLAGS += -Lsrc -L$(RAYLIB_LIB_PATH) endif endif -ifeq ($(PLATFORM),PLATFORM_WEB) +ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) # -Os # size optimization # -O2 # optimization level 2, if used, also set --memory-init-file 0 # -sUSE_GLFW=3 # Use glfw3 library (context/input management) @@ -279,7 +279,12 @@ ifeq ($(PLATFORM),PLATFORM_WEB) # --memory-init-file 0 # to avoid an external memory initialization code file (.mem) # --preload-file resources # specify a resources folder for data compilation # --source-map-base # allow debugging in browser with source map - LDFLAGS += -sUSE_GLFW=3 -sEXPORTED_RUNTIME_METHODS=ccall + + ifeq ($(PLATFORM),PLATFORM_WEB) + LDFLAGS += -sUSE_GLFW=3 + endif + + LDFLAGS += -sEXPORTED_RUNTIME_METHODS=ccall # Build using asyncify ifeq ($(BUILD_WEB_ASYNCIFY),TRUE) @@ -363,7 +368,7 @@ ifeq ($(PLATFORM),PLATFORM_DRM) # NOTE: Required packages: libasound2-dev (ALSA) LDLIBS = -lraylib -lGLESv2 -lEGL -lpthread -lrt -lm -lgbm -ldrm -ldl -latomic endif -ifeq ($(PLATFORM),PLATFORM_WEB) +ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) # Libraries for web (HTML5) compiling LDLIBS = $(RAYLIB_RELEASE_PATH)/libraylib.web.a endif @@ -1225,7 +1230,7 @@ ifeq ($(PLATFORM),PLATFORM_DRM) find . -type f -executable -delete rm -fv *.o endif -ifeq ($(PLATFORM),PLATFORM_WEB) +ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) del *.o *.html *.js endif @echo Cleaning done diff --git a/src/Makefile b/src/Makefile index 1e3ddb791..4797b587f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -20,6 +20,8 @@ # - Linux (X11 desktop mode) # - macOS/OSX (x64, arm64 (not tested)) # - Others (not tested) +# > PLATFORM_WEB_RGFW: +# - HTML5 (WebAssembly) # > PLATFORM_WEB: # - HTML5 (WebAssembly) # > PLATFORM_DRM: @@ -130,7 +132,7 @@ HOST_PLATFORM_OS ?= WINDOWS PLATFORM_OS ?= WINDOWS # Determine PLATFORM_OS when required -ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW PLATFORM_DESKTOP_SDL PLATFORM_DESKTOP_RGFW PLATFORM_WEB PLATFORM_ANDROID)) +ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW PLATFORM_DESKTOP_SDL PLATFORM_DESKTOP_RGFW PLATFORM_WEB PLATFORM_WEB_RGFW PLATFORM_ANDROID)) # No uname.exe on MinGW!, but OS=Windows_NT on Windows! # ifeq ($(UNAME),Msys) -> Windows ifeq ($(OS),Windows_NT) @@ -172,7 +174,7 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DRM) PLATFORM_SHELL = sh endif endif -ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) +ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) ifeq ($(PLATFORM_OS),LINUX) ifndef PLATFORM_SHELL PLATFORM_SHELL = sh @@ -180,7 +182,7 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) endif endif -ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) +ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) ifeq ($(PLATFORM_OS), WINDOWS) # Emscripten required variables EMSDK_PATH ?= C:/raylib/emsdk @@ -254,7 +256,7 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DRM) # On DRM OpenGL ES 2.0 must be used GRAPHICS = GRAPHICS_API_OPENGL_ES2 endif -ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) +ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) # On HTML5 OpenGL ES 2.0 is used, emscripten translates it to WebGL 1.0 GRAPHICS = GRAPHICS_API_OPENGL_ES2 #GRAPHICS = GRAPHICS_API_OPENGL_ES3 @@ -288,7 +290,7 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DRM) AR = $(RPI_TOOLCHAIN)/bin/$(RPI_TOOLCHAIN_NAME)-ar endif endif -ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) +ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) # HTML5 emscripten compiler CC = emcc AR = emar @@ -331,7 +333,7 @@ ifneq ($(RAYLIB_CONFIG_FLAGS), NONE) CFLAGS += -DEXTERNAL_CONFIG_FLAGS $(RAYLIB_CONFIG_FLAGS) endif -ifeq ($(TARGET_PLATFORM), PLATFORM_WEB) +ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) # NOTE: When using multi-threading in the user code, it requires -pthread enabled CFLAGS += -std=gnu99 else @@ -347,7 +349,7 @@ ifeq ($(RAYLIB_BUILD_MODE),DEBUG) endif ifeq ($(RAYLIB_BUILD_MODE),RELEASE) - ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) + ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) CFLAGS += -Os endif ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW) @@ -366,7 +368,7 @@ endif ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW) CFLAGS += -Werror=implicit-function-declaration endif -ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) +ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) # -Os # size optimization # -O2 # optimization level 2, if used, also set --memory-init-file 0 # -sUSE_GLFW=3 # Use glfw3 library (context/input management) -> Only for linker! @@ -659,7 +661,7 @@ all: raylib # Compile raylib library # NOTE: Release directory is created if not exist raylib: $(OBJS) -ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) +ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) # Compile raylib libray for web #$(CC) $(OBJS) -r -o $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).bc $(AR) rcs $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).web.a $(OBJS) diff --git a/src/external/RGFW.h b/src/external/RGFW.h index 978536f2d..2a10eda2c 100644 --- a/src/external/RGFW.h +++ b/src/external/RGFW.h @@ -59,9 +59,72 @@ #define RGFW_EXPORT - Use when building RGFW #define RGFW_IMPORT - Use when linking with RGFW (not as a single-header) - #define RGFW_STD_INT - force the use stdint.h (for systems that might not have stdint.h (msvc)) + #define RGFW_USE_INT - force the use c-types rather than stdint.h (for systems that might not have stdint.h (msvc)) */ +/* +Example to get you started : + +linux : gcc main.c -lX11 -lXrandr -lGL +windows : gcc main.c -lopengl32 -lwinmm -lshell32 -lgdi32 +macos : gcc main.c -framework Foundation -framework AppKit -framework OpenGL -framework CoreVideo + +#define RGFW_IMPLEMENTATION +#include "RGFW.h" + +u8 icon[4 * 3 * 3] = {0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF}; + +int main() { + RGFW_window* win = RGFW_createWindow("name", RGFW_RECT(500, 500, 500, 500), (u64)0); + + RGFW_window_setIcon(win, icon, RGFW_AREA(3, 3), 4); + + for (;;) { + RGFW_window_checkEvent(win); // NOTE: checking events outside of a while loop may cause input lag + if (win->event.type == RGFW_quit || RGFW_isPressed(win, RGFW_Escape)) + break; + + RGFW_window_swapBuffers(win); + + glClearColor(0xFF, 0XFF, 0xFF, 0xFF); + glClear(GL_COLOR_BUFFER_BIT); + } + + RGFW_window_close(win); +} + + compiling : + + if you wish to compile the library all you have to do is create a new file with this in it + + rgfw.c + #define RGFW_IMPLEMENTATION + #include "RGFW.h" + + You may also want to add + `#define RGFW_EXPORT` when compiling and + `#define RGFW_IMPORT`when linking RGFW on it's own: + this reduces inline functions and prevents bloat in the object file + + then you can use gcc (or whatever compile you wish to use) to compile the library into object file + + ex. gcc -c RGFW.c -fPIC + + after you compile the library into an object file, you can also turn the object file into an static or shared library + + (commands ar and gcc can be replaced with whatever equivalent your system uses) + static : ar rcs RGFW.a RGFW.o + shared : + windows: + gcc -shared RGFW.o -lwinmm -lopengl32 -lshell32 -lgdi32 -o RGFW.dll + linux: + gcc -shared RGFW.o -lX11 -lGL -lXrandr -o RGFW.so + macos: + gcc -shared RGFW.o -framework Foundation -framework AppKit -framework OpenGL -framework CoreVideo +*/ + + + /* Credits : EimaMei/Sacode : Much of the code for creating windows using winapi, Wrote the Silicon library, helped with MacOS Support, siliapp.h -> referencing @@ -88,6 +151,7 @@ Joshua Rowe (omnisci3nce) - bug fix, review (macOS) @lesleyrs -> bug fix, review (OpenGL) Nick Porcino (meshula) - testing, organization, review (MacOS, examples) + @DarekParodia -> code review (X11) (C++) */ #if _MSC_VER @@ -168,15 +232,15 @@ #define RGFW_HEADER #if !defined(u8) - #if ((defined(_MSC_VER) || defined(__SYMBIAN32__)) && !defined(RGFW_STD_INT)) /* MSVC might not have stdint.h */ + #ifdef RGFW_USE_INT /* optional for any system that might not have stdint.h */ typedef unsigned char u8; typedef signed char i8; typedef unsigned short u16; typedef signed short i16; - typedef unsigned int u32; - typedef signed int i32; - typedef unsigned long u64; - typedef signed long i64; + typedef unsigned long int u32; + typedef signed long int i32; + typedef unsigned long long u64; + typedef signed long long i64; #else /* use stdint standard types instead of c ""standard"" types */ #include @@ -344,12 +408,12 @@ typedef RGFW_ENUM(u8, RGFW_event_types) { RGFW_Event.button holds which mouse button was pressed */ - RGFW_jsButtonPressed, /*!< a joystick button was pressed */ - RGFW_jsButtonReleased, /*!< a joystick button was released */ - RGFW_jsAxisMove, /*!< an axis of a joystick was moved*/ - /*! joystick event note - RGFW_Event.joystick holds which joystick was altered, if any - RGFW_Event.button holds which joystick button was pressed + RGFW_gpButtonPressed, /*!< a gamepad button was pressed */ + RGFW_gpButtonReleased, /*!< a gamepad button was released */ + RGFW_gpAxisMove, /*!< an axis of a gamepad was moved*/ + /*! gamepad event note + RGFW_Event.gamepad holds which gamepad was altered, if any + RGFW_Event.button holds which gamepad button was pressed RGFW_Event.axis holds the data of all the axis RGFW_Event.axisCount says how many axis there are @@ -398,24 +462,26 @@ typedef RGFW_ENUM(u8, RGFW_event_types) { #define RGFW_CAPSLOCK (1L << 1) #define RGFW_NUMLOCK (1L << 2) -/*! joystick button codes (based on xbox/playstation), you may need to change these values per controller */ -#ifndef RGFW_joystick_codes - typedef RGFW_ENUM(u8, RGFW_joystick_codes) { - RGFW_JS_A = 0, /*!< or PS X button */ - RGFW_JS_B = 1, /*!< or PS circle button */ - RGFW_JS_Y = 2, /*!< or PS triangle button */ - RGFW_JS_X = 3, /*!< or PS square button */ - RGFW_JS_START = 9, /*!< start button */ - RGFW_JS_SELECT = 8, /*!< select button */ - RGFW_JS_HOME = 10, /*!< home button */ - RGFW_JS_UP = 13, /*!< dpad up */ - RGFW_JS_DOWN = 14, /*!< dpad down*/ - RGFW_JS_LEFT = 15, /*!< dpad left */ - RGFW_JS_RIGHT = 16, /*!< dpad right */ - RGFW_JS_L1 = 4, /*!< left bump */ - RGFW_JS_L2 = 5, /*!< left trigger*/ - RGFW_JS_R1 = 6, /*!< right bumper */ - RGFW_JS_R2 = 7, /*!< right trigger */ +/*! gamepad button codes (based on xbox/playstation), you may need to change these values per controller */ +#ifndef RGFW_gamepad_codes + typedef RGFW_ENUM(u8, RGFW_gamepad_codes) { + RGFW_GP_A = 0, /*!< or PS X button */ + RGFW_GP_B = 1, /*!< or PS circle button */ + RGFW_GP_Y = 2, /*!< or PS triangle button */ + RGFW_GP_X = 3, /*!< or PS square button */ + RGFW_GP_START = 9, /*!< start button */ + RGFW_GP_SELECT = 8, /*!< select button */ + RGFW_GP_HOME = 10, /*!< home button */ + RGFW_GP_UP = 13, /*!< dpad up */ + RGFW_GP_DOWN = 14, /*!< dpad down*/ + RGFW_GP_LEFT = 15, /*!< dpad left */ + RGFW_GP_RIGHT = 16, /*!< dpad right */ + RGFW_GP_L1 = 4, /*!< left bump */ + RGFW_GP_L2 = 5, /*!< left trigger*/ + RGFW_GP_R1 = 6, /*!< right bumper */ + RGFW_GP_R2 = 7, /*!< right trigger */ + RGFW_GP_L3 = 11, /* left thumb stick */ + RGFW_GP_R3 = 12 /*!< right thumb stick */ }; #endif @@ -450,7 +516,7 @@ typedef RGFW_ENUM(u8, RGFW_event_types) { char name[128]; /*!< monitor name */ RGFW_rect rect; /*!< monitor Workarea */ float scaleX, scaleY; /*!< monitor content scale*/ - float physW, physH; /*!< monitor physical size */ + float physW, physH; /*!< monitor physical size in inches*/ } RGFW_monitor; /* @@ -487,12 +553,14 @@ typedef struct RGFW_Event { u8 lockState; - u8 button; /* !< which mouse button was pressed */ + u8 button; /* !< which mouse (or gamepad) button was pressed */ double scroll; /*!< the raw mouse scroll value */ - u16 joystick; /*! which joystick this event applies to (if applicable to any) */ + u16 gamepad; /*! which gamepad this event applies to (if applicable to any) */ u8 axisesCount; /*!< number of axises */ - RGFW_point axis[2]; /*!< x, y of axises (-100 to 100) */ + + u8 whichAxis; /* which axis was effected */ + RGFW_point axis[4]; /*!< x, y of axises (-100 to 100) */ u64 frameTime, frameTime2; /*!< this is used for counting the fps */ } RGFW_Event; @@ -630,6 +698,8 @@ RGFWDEF void RGFW_setClassName(char* name); /*! this has to be set before createWindow is called, else the fulscreen size is used */ RGFWDEF void RGFW_setBufferSize(RGFW_area size); /*!< the buffer cannot be resized (by RGFW) */ +/* NOTE: (windows)If the executable has an icon resource named RGFW_ICON, it will be set as the initial icon for the window.*/ + RGFWDEF RGFW_window* RGFW_createWindow( const char* name, /* name of the window */ RGFW_rect rect, /* rect of window */ @@ -869,10 +939,10 @@ typedef void (* RGFW_windowrefreshfunc)(RGFW_window* win); typedef void (* RGFW_keyfunc)(RGFW_window* win, u32 keycode, char keyName[16], u8 lockState, b8 pressed); /*! RGFW_mouseButtonPressed / RGFW_mouseButtonReleased, the window that got the event, the button that was pressed, the scroll value, if it was a press (else it's a release) */ typedef void (* RGFW_mousebuttonfunc)(RGFW_window* win, u8 button, double scroll, b8 pressed); -/*! RGFW_jsButtonPressed / RGFW_jsButtonReleased, the window that got the event, the button that was pressed, the scroll value, if it was a press (else it's a release) */ -typedef void (* RGFW_jsButtonfunc)(RGFW_window* win, u16 joystick, u8 button, b8 pressed); -/*! RGFW_jsAxisMove, the window that got the event, the joystick in question, the axis values and the amount of axises */ -typedef void (* RGFW_jsAxisfunc)(RGFW_window* win, u16 joystick, RGFW_point axis[2], u8 axisesCount); +/*!gp /gp, the window that got the event, the button that was pressed, the scroll value, if it was a press (else it's a release) */ +typedef void (* RGFW_gpButtonfunc)(RGFW_window* win, u16 gamepad, u8 button, b8 pressed); +/*! RGFW_gpAxisMove, the window that got the event, the gamepad in question, the axis values and the amount of axises */ +typedef void (* RGFW_gpAxisfunc)(RGFW_window* win, u16 gamepad, RGFW_point axis[2], u8 axisesCount); /*! RGFW_dnd, the window that had the drop, the drop data and the amount files dropped returns previous callback function (if it was set) */ @@ -904,9 +974,9 @@ RGFWDEF RGFW_keyfunc RGFW_setKeyCallback(RGFW_keyfunc func); /*! set callback for a mouse button (press / release ) event returns previous callback function (if it was set) */ RGFWDEF RGFW_mousebuttonfunc RGFW_setMouseButtonCallback(RGFW_mousebuttonfunc func); /*! set callback for a controller button (press / release ) event returns previous callback function (if it was set) */ -RGFWDEF RGFW_jsButtonfunc RGFW_setjsButtonCallback(RGFW_jsButtonfunc func); -/*! set callback for a joystick axis mov event returns previous callback function (if it was set) */ -RGFWDEF RGFW_jsAxisfunc RGFW_setjsAxisCallback(RGFW_jsAxisfunc func); +RGFWDEF RGFW_gpButtonfunc RGFW_setgpButtonCallback(RGFW_gpButtonfunc func); +/*! set callback for a gamepad axis mov event returns previous callback function (if it was set) */ +RGFWDEF RGFW_gpAxisfunc RGFW_setgpAxisCallback(RGFW_gpAxisfunc func); /** @} */ @@ -937,15 +1007,15 @@ RGFWDEF RGFW_jsAxisfunc RGFW_setjsAxisCallback(RGFW_jsAxisfunc func); /** @} */ -/** * @defgroup joystick +/** * @defgroup gamepad * @{ */ -/*! joystick count starts at 0*/ -/*!< register joystick to window based on a number (the number is based on when it was connected eg. /dev/js0)*/ -RGFWDEF u16 RGFW_registerJoystick(RGFW_window* win, i32 jsNumber); -RGFWDEF u16 RGFW_registerJoystickF(RGFW_window* win, char* file); +/*! gamepad count starts at 0*/ +/*!< register gamepad to window based on a number (the number is based on when it was connected eg. /dev/js0)*/ +RGFWDEF u16 RGFW_registerGamepad(RGFW_window* win, i32 gpNumber); +RGFWDEF u16 RGFW_registerGamepadF(RGFW_window* win, char* file); -RGFWDEF u32 RGFW_isPressedJS(RGFW_window* win, u16 controller, u8 button); +RGFWDEF u32 RGFW_isPressedGP(RGFW_window* win, u16 controller, u8 button); /** @} */ @@ -1144,63 +1214,6 @@ typedef RGFW_ENUM(u8, RGFW_mouseIcons) { /** @} */ #endif /* RGFW_HEADER */ - -/* -Example to get you started : - -linux : gcc main.c -lX11 -lXcursor -lGL -windows : gcc main.c -lopengl32 -lshell32 -lgdi32 -macos : gcc main.c -framework Foundation -framework AppKit -framework OpenGL -framework CoreVideo - -#define RGFW_IMPLEMENTATION -#include "RGFW.h" - -u8 icon[4 * 3 * 3] = {0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF}; - -int main() { - RGFW_window* win = RGFW_createWindow("name", RGFW_RECT(500, 500, 500, 500), (u64)0); - - RGFW_window_setIcon(win, icon, RGFW_AREA(3, 3), 4); - - for (;;) { - RGFW_window_checkEvent(win); // NOTE: checking events outside of a while loop may cause input lag - if (win->event.type == RGFW_quit || RGFW_isPressed(win, RGFW_Escape)) - break; - - RGFW_window_swapBuffers(win); - - glClearColor(0xFF, 0XFF, 0xFF, 0xFF); - glClear(GL_COLOR_BUFFER_BIT); - } - - RGFW_window_close(win); -} - - compiling : - - if you wish to compile the library all you have to do is create a new file with this in it - - rgfw.c - #define RGFW_IMPLEMENTATION - #include "RGFW.h" - - then you can use gcc (or whatever compile you wish to use) to compile the library into object file - - ex. gcc -c RGFW.c -fPIC - - after you compile the library into an object file, you can also turn the object file into an static or shared library - - (commands ar and gcc can be replaced with whatever equivalent your system uses) - static : ar rcs RGFW.a RGFW.o - shared : - windows: - gcc -shared RGFW.o -lwinmm -lopengl32 -lshell32 -lgdi32 -o RGFW.dll - linux: - gcc -shared RGFW.o -lX11 -lXcursor -lGL -lXrandr -o RGFW.so - macos: - gcc -shared RGFW.o -framework Foundation -framework AppKit -framework OpenGL -framework CoreVideo -*/ - #ifdef RGFW_X11 #define RGFW_OS_BASED_VALUE(l, w, m, h, ww) l #elif defined(RGFW_WINDOWS) @@ -1442,11 +1455,11 @@ char RGFW_keyCodeToCharAuto(u32 keycode, u8 lockState) { return RGFW_keyCodeToCh this is the end of keycode data */ -/* joystick data */ -u8 RGFW_jsPressed[4][16]; /*!< if a key is currently pressed or not (per joystick) */ +/* gamepad data */ +u8 RGFW_gpPressed[4][16]; /*!< if a key is currently pressed or not (per gamepad) */ -i32 RGFW_joysticks[4]; /*!< limit of 4 joysticks at a time */ -u16 RGFW_joystickCount; /*!< the actual amount of joysticks */ +i32 RGFW_gamepads[4]; /*!< limit of 4 gamepads at a time */ +u16 RGFW_gamepadCount; /*!< the actual amount of gamepads */ /* event callback defines start here @@ -1468,8 +1481,8 @@ void RGFW_dndInitfuncEMPTY(RGFW_window* win, RGFW_point point) {RGFW_UNUSED(win) void RGFW_windowrefreshfuncEMPTY(RGFW_window* win) {RGFW_UNUSED(win); } void RGFW_keyfuncEMPTY(RGFW_window* win, u32 keycode, char keyName[16], u8 lockState, b8 pressed) {RGFW_UNUSED(win); RGFW_UNUSED(keycode); RGFW_UNUSED(keyName); RGFW_UNUSED(lockState); RGFW_UNUSED(pressed);} void RGFW_mousebuttonfuncEMPTY(RGFW_window* win, u8 button, double scroll, b8 pressed) {RGFW_UNUSED(win); RGFW_UNUSED(button); RGFW_UNUSED(scroll); RGFW_UNUSED(pressed);} -void RGFW_jsButtonfuncEMPTY(RGFW_window* win, u16 joystick, u8 button, b8 pressed){RGFW_UNUSED(win); RGFW_UNUSED(joystick); RGFW_UNUSED(button); RGFW_UNUSED(pressed); } -void RGFW_jsAxisfuncEMPTY(RGFW_window* win, u16 joystick, RGFW_point axis[2], u8 axisesCount){RGFW_UNUSED(win); RGFW_UNUSED(joystick); RGFW_UNUSED(axis); RGFW_UNUSED(axisesCount); } +void RGFW_gpButtonfuncEMPTY(RGFW_window* win, u16 gamepad, u8 button, b8 pressed){RGFW_UNUSED(win); RGFW_UNUSED(gamepad); RGFW_UNUSED(button); RGFW_UNUSED(pressed); } +void RGFW_gpAxisfuncEMPTY(RGFW_window* win, u16 gamepad, RGFW_point axis[2], u8 axisesCount){RGFW_UNUSED(win); RGFW_UNUSED(gamepad); RGFW_UNUSED(axis); RGFW_UNUSED(axisesCount); } #ifdef RGFW_ALLOC_DROPFILES void RGFW_dndfuncEMPTY(RGFW_window* win, char** droppedFiles, u32 droppedFilesCount) {RGFW_UNUSED(win); RGFW_UNUSED(droppedFiles); RGFW_UNUSED(droppedFilesCount);} @@ -1488,8 +1501,8 @@ RGFW_dndfunc RGFW_dndCallback = RGFW_dndfuncEMPTY; RGFW_dndInitfunc RGFW_dndInitCallback = RGFW_dndInitfuncEMPTY; RGFW_keyfunc RGFW_keyCallback = RGFW_keyfuncEMPTY; RGFW_mousebuttonfunc RGFW_mouseButtonCallback = RGFW_mousebuttonfuncEMPTY; -RGFW_jsButtonfunc RGFW_jsButtonCallback = RGFW_jsButtonfuncEMPTY; -RGFW_jsAxisfunc RGFW_jsAxisCallback = RGFW_jsAxisfuncEMPTY; +RGFW_gpButtonfunc RGFW_gpButtonCallback = RGFW_gpButtonfuncEMPTY; +RGFW_gpAxisfunc RGFW_gpAxisCallback = RGFW_gpAxisfuncEMPTY; void RGFW_window_checkEvents(RGFW_window* win, i32 waitMS) { RGFW_window_eventWait(win, waitMS); @@ -1560,14 +1573,14 @@ RGFW_mousebuttonfunc RGFW_setMouseButtonCallback(RGFW_mousebuttonfunc func) { RGFW_mouseButtonCallback = func; return prev; } -RGFW_jsButtonfunc RGFW_setjsButtonCallback(RGFW_jsButtonfunc func) { - RGFW_jsButtonfunc prev = (RGFW_jsButtonCallback == RGFW_jsButtonfuncEMPTY) ? NULL : RGFW_jsButtonCallback; - RGFW_jsButtonCallback = func; +RGFW_gpButtonfunc RGFW_setgpButtonCallback(RGFW_gpButtonfunc func) { + RGFW_gpButtonfunc prev = (RGFW_gpButtonCallback == RGFW_gpButtonfuncEMPTY) ? NULL : RGFW_gpButtonCallback; + RGFW_gpButtonCallback = func; return prev; } -RGFW_jsAxisfunc RGFW_setjsAxisCallback(RGFW_jsAxisfunc func) { - RGFW_jsAxisfunc prev = (RGFW_jsAxisCallback == RGFW_jsAxisfuncEMPTY) ? NULL : RGFW_jsAxisCallback; - RGFW_jsAxisCallback = func; +RGFW_gpAxisfunc RGFW_setgpAxisCallback(RGFW_gpAxisfunc func) { + RGFW_gpAxisfunc prev = (RGFW_gpAxisCallback == RGFW_gpAxisfuncEMPTY) ? NULL : RGFW_gpAxisCallback; + RGFW_gpAxisCallback = func; return prev; } /* @@ -1629,7 +1642,7 @@ RGFW_window* RGFW_window_basic_init(RGFW_rect rect, u16 args) { win->r = rect; win->event.inFocus = 1; win->event.droppedFilesCount = 0; - RGFW_joystickCount = 0; + RGFW_gamepadCount = 0; win->_winArgs = 0; win->event.lockState = 0; @@ -1640,7 +1653,7 @@ RGFW_window* RGFW_window_basic_init(RGFW_rect rect, u16 args) { void RGFW_window_scaleToMonitor(RGFW_window* win) { RGFW_monitor monitor = RGFW_window_getMonitor(win); - RGFW_window_resize(win, RGFW_AREA((u32)(monitor.scaleX * (float)win->r.w), (u32)(monitor.scaleX * (float)win->r.h))); + RGFW_window_resize(win, RGFW_AREA((u32)(monitor.scaleX * (float)win->r.w), (u32)(monitor.scaleY * (float)win->r.h))); } #endif @@ -1808,9 +1821,9 @@ u32 RGFW_window_checkFPS(RGFW_window* win, u32 fpsCap) { return output_fps; } -u32 RGFW_isPressedJS(RGFW_window* win, u16 c, u8 button) { +u32 RGFW_isPressedGP(RGFW_window* win, u16 c, u8 button) { RGFW_UNUSED(win); - return RGFW_jsPressed[c][button]; + return RGFW_gpPressed[c][button]; } #if defined(RGFW_X11) || defined(RGFW_WINDOWS) @@ -2261,48 +2274,56 @@ This is where OS specific stuff starts #if defined(RGFW_WAYLAND) || defined(RGFW_X11) int RGFW_eventWait_forceStop[] = {0, 0, 0}; /* for wait events */ + + #ifdef __linux__ #include #include #include - - RGFW_Event* RGFW_linux_updateJoystick(RGFW_window* win) { - static int xAxis = 0, yAxis = 0; + + RGFW_Event* RGFW_linux_updateGamepad(RGFW_window* win) { u8 i; - for (i = 0; i < RGFW_joystickCount; i++) { + for (i = 0; i < RGFW_gamepadCount; i++) { struct js_event e; - if (RGFW_joysticks[i] == 0) + if (RGFW_gamepads[i] == 0) continue; - i32 flags = fcntl(RGFW_joysticks[i], F_GETFL, 0); - fcntl(RGFW_joysticks[i], F_SETFL, flags | O_NONBLOCK); + i32 flags = fcntl(RGFW_gamepads[i], F_GETFL, 0); + fcntl(RGFW_gamepads[i], F_SETFL, flags | O_NONBLOCK); ssize_t bytes; - while ((bytes = read(RGFW_joysticks[i], &e, sizeof(e))) > 0) { + while ((bytes = read(RGFW_gamepads[i], &e, sizeof(e))) > 0) { switch (e.type) { case JS_EVENT_BUTTON: - win->event.type = e.value ? RGFW_jsButtonPressed : RGFW_jsButtonReleased; + win->event.type = e.value ? RGFW_gpButtonPressed : RGFW_gpButtonReleased; win->event.button = e.number; - RGFW_jsPressed[i][e.number] = e.value; - RGFW_jsButtonCallback(win, i, e.number, e.value); - return &win->event; - case JS_EVENT_AXIS: - ioctl(RGFW_joysticks[i], JSIOCGAXES, &win->event.axisesCount); - - if ((e.number == 0 || e.number % 2) && e.number != 1) - xAxis = e.value; - else - yAxis = e.value; - - win->event.axis[e.number / 2].x = xAxis; - win->event.axis[e.number / 2].y = yAxis; - win->event.type = RGFW_jsAxisMove; - win->event.joystick = i; - RGFW_jsAxisCallback(win, i, win->event.axis, win->event.axisesCount); + RGFW_gpPressed[i][e.number + 1] = e.value; + RGFW_gpButtonCallback(win, i, e.number, e.value); + return &win->event; + case JS_EVENT_AXIS: { + size_t axis = e.number / 2; + if (axis == 2) axis = 1; + ioctl(RGFW_gamepads[i], JSIOCGAXES, &win->event.axisesCount); + win->event.axisesCount = 2; + + if (axis < 3) { + if (e.number == 0 || e.number == 3) + win->event.axis[axis].x = (e.value / 32767.0f) * 100; + else if (e.number == 1 || e.number == 4) { + win->event.axis[axis].y = (e.value / 32767.0f) * 100; + } + } + + win->event.type = RGFW_gpAxisMove; + win->event.gamepad = i; + win->event.whichAxis = axis; + RGFW_gpAxisCallback(win, i, win->event.axis, win->event.axisesCount); + return &win->event; + } default: break; } } @@ -2647,580 +2668,594 @@ Start of Linux / Unix defines } if (args & RGFW_NO_RESIZE) { /* make it so the user can't resize the window*/ - XSizeHints* sh = XAllocSizeHints(); - sh->flags = (1L << 4) | (1L << 5); - sh->min_width = sh->max_width = win->r.w; - sh->min_height = sh->max_height = win->r.h; + XSizeHints sh = {0}; + sh.flags = (1L << 4) | (1L << 5); + sh.min_width = sh.max_width = win->r.w; + sh.min_height = sh.max_height = win->r.h; - XSetWMSizeHints((Display*) win->src.display, (Drawable) win->src.window, sh, XA_WM_NORMAL_HINTS); - XFree(sh); - } + XSetWMSizeHints((Display*) win->src.display, (Drawable) win->src.window, &sh, XA_WM_NORMAL_HINTS); - if (args & RGFW_NO_BORDER) { - RGFW_window_setBorder(win, 0); + win->_winArgs |= RGFW_NO_RESIZE; } - XSelectInput((Display*) win->src.display, (Drawable) win->src.window, event_mask); /*!< tell X11 what events we want*/ + if (args & RGFW_NO_BORDER) { + RGFW_window_setBorder(win, 0); + } - /* make it so the user can't close the window until the program does*/ - if (wm_delete_window == 0) - wm_delete_window = XInternAtom((Display*) win->src.display, "WM_DELETE_WINDOW", False); + XSelectInput((Display*) win->src.display, (Drawable) win->src.window, event_mask); /*!< tell X11 what events we want*/ - XSetWMProtocols((Display*) win->src.display, (Drawable) win->src.window, &wm_delete_window, 1); + /* make it so the user can't close the window until the program does*/ + if (wm_delete_window == 0) + wm_delete_window = XInternAtom((Display*) win->src.display, "WM_DELETE_WINDOW", False); - /* connect the context to the window*/ + XSetWMProtocols((Display*) win->src.display, (Drawable) win->src.window, &wm_delete_window, 1); + + /* connect the context to the window*/ #ifdef RGFW_OPENGL - if ((args & RGFW_NO_INIT_API) == 0) - glXMakeCurrent((Display*) win->src.display, (Drawable) win->src.window, (GLXContext) win->src.ctx); + if ((args & RGFW_NO_INIT_API) == 0) + glXMakeCurrent((Display*) win->src.display, (Drawable) win->src.window, (GLXContext) win->src.ctx); #endif - /* set the background*/ - XStoreName((Display*) win->src.display, (Drawable) win->src.window, name); /*!< set the name*/ + /* set the background*/ + XStoreName((Display*) win->src.display, (Drawable) win->src.window, name); /*!< set the name*/ - XMapWindow((Display*) win->src.display, (Drawable) win->src.window); /* draw the window*/ - XMoveWindow((Display*) win->src.display, (Drawable) win->src.window, win->r.x, win->r.y); /*!< move the window to it's proper cords*/ + XMapWindow((Display*) win->src.display, (Drawable) win->src.window); /* draw the window*/ + XMoveWindow((Display*) win->src.display, (Drawable) win->src.window, win->r.x, win->r.y); /*!< move the window to it's proper cords*/ - if (args & RGFW_ALLOW_DND) { /* init drag and drop atoms and turn on drag and drop for this window */ - win->_winArgs |= RGFW_ALLOW_DND; + if (args & RGFW_ALLOW_DND) { /* init drag and drop atoms and turn on drag and drop for this window */ + win->_winArgs |= RGFW_ALLOW_DND; - XdndTypeList = XInternAtom((Display*) win->src.display, "XdndTypeList", False); - XdndSelection = XInternAtom((Display*) win->src.display, "XdndSelection", False); + XdndTypeList = XInternAtom((Display*) win->src.display, "XdndTypeList", False); + XdndSelection = XInternAtom((Display*) win->src.display, "XdndSelection", False); - /* client messages */ - XdndEnter = XInternAtom((Display*) win->src.display, "XdndEnter", False); - XdndPosition = XInternAtom((Display*) win->src.display, "XdndPosition", False); - XdndStatus = XInternAtom((Display*) win->src.display, "XdndStatus", False); - XdndLeave = XInternAtom((Display*) win->src.display, "XdndLeave", False); - XdndDrop = XInternAtom((Display*) win->src.display, "XdndDrop", False); - XdndFinished = XInternAtom((Display*) win->src.display, "XdndFinished", False); + /* client messages */ + XdndEnter = XInternAtom((Display*) win->src.display, "XdndEnter", False); + XdndPosition = XInternAtom((Display*) win->src.display, "XdndPosition", False); + XdndStatus = XInternAtom((Display*) win->src.display, "XdndStatus", False); + XdndLeave = XInternAtom((Display*) win->src.display, "XdndLeave", False); + XdndDrop = XInternAtom((Display*) win->src.display, "XdndDrop", False); + XdndFinished = XInternAtom((Display*) win->src.display, "XdndFinished", False); - /* actions */ - XdndActionCopy = XInternAtom((Display*) win->src.display, "XdndActionCopy", False); + /* actions */ + XdndActionCopy = XInternAtom((Display*) win->src.display, "XdndActionCopy", False); - XtextUriList = XInternAtom((Display*) win->src.display, "text/uri-list", False); - XtextPlain = XInternAtom((Display*) win->src.display, "text/plain", False); + XtextUriList = XInternAtom((Display*) win->src.display, "text/uri-list", False); + XtextPlain = XInternAtom((Display*) win->src.display, "text/plain", False); - XdndAware = XInternAtom((Display*) win->src.display, "XdndAware", False); - const u8 version = 5; + XdndAware = XInternAtom((Display*) win->src.display, "XdndAware", False); + const u8 version = 5; - XChangeProperty((Display*) win->src.display, (Window) win->src.window, - XdndAware, 4, 32, - PropModeReplace, &version, 1); /*!< turns on drag and drop */ - } + XChangeProperty((Display*) win->src.display, (Window) win->src.window, + XdndAware, 4, 32, + PropModeReplace, &version, 1); /*!< turns on drag and drop */ + } - #ifdef RGFW_EGL - if ((args & RGFW_NO_INIT_API) == 0) - RGFW_createOpenGLContext(win); - #endif + #ifdef RGFW_EGL + if ((args & RGFW_NO_INIT_API) == 0) + RGFW_createOpenGLContext(win); + #endif - RGFW_window_setMouseDefault(win); + RGFW_window_setMouseDefault(win); - RGFW_windowsOpen++; + RGFW_windowsOpen++; - return win; /*return newly created window*/ - } + return win; /*return newly created window*/ + } - RGFW_area RGFW_getScreenSize(void) { - assert(RGFW_root != NULL); + RGFW_area RGFW_getScreenSize(void) { + assert(RGFW_root != NULL); - Screen* scrn = DefaultScreenOfDisplay((Display*) RGFW_root->src.display); - return RGFW_AREA(scrn->width, scrn->height); - } + Screen* scrn = DefaultScreenOfDisplay((Display*) RGFW_root->src.display); + return RGFW_AREA(scrn->width, scrn->height); + } - RGFW_point RGFW_getGlobalMousePoint(void) { - assert(RGFW_root != NULL); + RGFW_point RGFW_getGlobalMousePoint(void) { + assert(RGFW_root != NULL); - RGFW_point RGFWMouse; + RGFW_point RGFWMouse; - i32 x, y; - u32 z; - Window window1, window2; - XQueryPointer((Display*) RGFW_root->src.display, XDefaultRootWindow((Display*) RGFW_root->src.display), &window1, &window2, &RGFWMouse.x, &RGFWMouse.y, &x, &y, &z); - - return RGFWMouse; - } + i32 x, y; + u32 z; + Window window1, window2; + XQueryPointer((Display*) RGFW_root->src.display, XDefaultRootWindow((Display*) RGFW_root->src.display), &window1, &window2, &RGFWMouse.x, &RGFWMouse.y, &x, &y, &z); + + return RGFWMouse; + } - RGFW_point RGFW_window_getMousePoint(RGFW_window* win) { - assert(win != NULL); + RGFW_point RGFW_window_getMousePoint(RGFW_window* win) { + assert(win != NULL); - RGFW_point RGFWMouse; + RGFW_point RGFWMouse; - i32 x, y; - u32 z; - Window window1, window2; - XQueryPointer((Display*) win->src.display, win->src.window, &window1, &window2, &x, &y, &RGFWMouse.x, &RGFWMouse.y, &z); + i32 x, y; + u32 z; + Window window1, window2; + XQueryPointer((Display*) win->src.display, win->src.window, &window1, &window2, &x, &y, &RGFWMouse.x, &RGFWMouse.y, &z); - return RGFWMouse; - } + return RGFWMouse; + } - int xAxis = 0, yAxis = 0; + int xAxis = 0, yAxis = 0; - RGFW_Event* RGFW_window_checkEvent(RGFW_window* win) { - assert(win != NULL); + RGFW_Event* RGFW_window_checkEvent(RGFW_window* win) { + assert(win != NULL); - static struct { - long source, version; - i32 format; - } xdnd; + static struct { + long source, version; + i32 format; + } xdnd; - if (win->event.type == 0) - RGFW_resetKey(); + if (win->event.type == 0) + RGFW_resetKey(); - if (win->event.type == RGFW_quit) { - return NULL; - } + if (win->event.type == RGFW_quit) { + return NULL; + } - win->event.type = 0; + win->event.type = 0; #ifdef __linux__ - RGFW_Event* event = RGFW_linux_updateJoystick(win); - if (event != NULL) - return event; + RGFW_Event* event = RGFW_linux_updateGamepad(win); + if (event != NULL) + return event; #endif - XPending(win->src.display); + XPending(win->src.display); - XEvent E; /*!< raw X11 event */ - - /* if there is no unread qued events, get a new one */ - if ((QLength(win->src.display) || XEventsQueued((Display*) win->src.display, QueuedAlready) + XEventsQueued((Display*) win->src.display, QueuedAfterReading)) - && win->event.type != RGFW_quit - ) - XNextEvent((Display*) win->src.display, &E); - else { - return NULL; - } - - u32 i; - win->event.type = 0; + XEvent E; /*!< raw X11 event */ + /* if there is no unread qued events, get a new one */ + if ((QLength(win->src.display) || XEventsQueued((Display*) win->src.display, QueuedAlready) + XEventsQueued((Display*) win->src.display, QueuedAfterReading)) + && win->event.type != RGFW_quit + ) + XNextEvent((Display*) win->src.display, &E); + else { + return NULL; + } - switch (E.type) { - case KeyPress: - case KeyRelease: { - win->event.repeat = RGFW_FALSE; - /* check if it's a real key release */ - if (E.type == KeyRelease && XEventsQueued((Display*) win->src.display, QueuedAfterReading)) { /* get next event if there is one*/ - XEvent NE; - XPeekEvent((Display*) win->src.display, &NE); + u32 i; + win->event.type = 0; + XEvent reply = { ClientMessage }; - if (E.xkey.time == NE.xkey.time && E.xkey.keycode == NE.xkey.keycode) /* check if the current and next are both the same*/ - win->event.repeat = RGFW_TRUE; - } + switch (E.type) { + case KeyPress: + case KeyRelease: { + win->event.repeat = RGFW_FALSE; + /* check if it's a real key release */ + if (E.type == KeyRelease && XEventsQueued((Display*) win->src.display, QueuedAfterReading)) { /* get next event if there is one*/ + XEvent NE; + XPeekEvent((Display*) win->src.display, &NE); + + if (E.xkey.time == NE.xkey.time && E.xkey.keycode == NE.xkey.keycode) /* check if the current and next are both the same*/ + win->event.repeat = RGFW_TRUE; + } - /* set event key data */ - KeySym sym = (KeySym)XkbKeycodeToKeysym((Display*) win->src.display, E.xkey.keycode, 0, E.xkey.state & ShiftMask ? 1 : 0); - win->event.keyCode = RGFW_apiKeyCodeToRGFW(E.xkey.keycode); - - char* str = (char*)XKeysymToString(sym); - if (str != NULL) - strncpy(win->event.keyName, str, 16); + /* set event key data */ + KeySym sym = (KeySym)XkbKeycodeToKeysym((Display*) win->src.display, E.xkey.keycode, 0, E.xkey.state & ShiftMask ? 1 : 0); + win->event.keyCode = RGFW_apiKeyCodeToRGFW(E.xkey.keycode); + + char* str = (char*)XKeysymToString(sym); + if (str != NULL) + strncpy(win->event.keyName, str, 16); - win->event.keyName[15] = '\0'; + win->event.keyName[15] = '\0'; - RGFW_keyboard[win->event.keyCode].prev = RGFW_isPressed(win, win->event.keyCode); - - /* get keystate data */ - win->event.type = (E.type == KeyPress) ? RGFW_keyPressed : RGFW_keyReleased; + RGFW_keyboard[win->event.keyCode].prev = RGFW_isPressed(win, win->event.keyCode); + + /* get keystate data */ + win->event.type = (E.type == KeyPress) ? RGFW_keyPressed : RGFW_keyReleased; - XKeyboardState keystate; - XGetKeyboardControl((Display*) win->src.display, &keystate); + XKeyboardState keystate; + XGetKeyboardControl((Display*) win->src.display, &keystate); - RGFW_updateLockState(win, (keystate.led_mask & 1), (keystate.led_mask & 2)); - RGFW_keyboard[win->event.keyCode].current = (E.type == KeyPress); - RGFW_keyCallback(win, win->event.keyCode, win->event.keyName, win->event.lockState, (E.type == KeyPress)); - break; - } - case ButtonPress: - case ButtonRelease: - win->event.type = RGFW_mouseButtonPressed + (E.type == ButtonRelease); // the events match - - switch(win->event.button) { - case RGFW_mouseScrollUp: - win->event.scroll = 1; - break; - case RGFW_mouseScrollDown: - win->event.scroll = -1; - break; - default: break; + RGFW_updateLockState(win, (keystate.led_mask & 1), (keystate.led_mask & 2)); + RGFW_keyboard[win->event.keyCode].current = (E.type == KeyPress); + RGFW_keyCallback(win, win->event.keyCode, win->event.keyName, win->event.lockState, (E.type == KeyPress)); + break; } + case ButtonPress: + case ButtonRelease: + win->event.type = RGFW_mouseButtonPressed + (E.type == ButtonRelease); // the events match + + switch(win->event.button) { + case RGFW_mouseScrollUp: + win->event.scroll = 1; + break; + case RGFW_mouseScrollDown: + win->event.scroll = -1; + break; + default: break; + } - win->event.button = E.xbutton.button; - RGFW_mouseButtons[win->event.button].prev = RGFW_mouseButtons[win->event.button].current; + win->event.button = E.xbutton.button; + RGFW_mouseButtons[win->event.button].prev = RGFW_mouseButtons[win->event.button].current; - if (win->event.repeat == RGFW_FALSE) - win->event.repeat = RGFW_isPressed(win, win->event.keyCode); + if (win->event.repeat == RGFW_FALSE) + win->event.repeat = RGFW_isPressed(win, win->event.keyCode); - RGFW_mouseButtons[win->event.button].current = (E.type == ButtonPress); - RGFW_mouseButtonCallback(win, win->event.button, win->event.scroll, (E.type == ButtonPress)); - break; + RGFW_mouseButtons[win->event.button].current = (E.type == ButtonPress); + RGFW_mouseButtonCallback(win, win->event.button, win->event.scroll, (E.type == ButtonPress)); + break; - case MotionNotify: - win->event.point.x = E.xmotion.x; - win->event.point.y = E.xmotion.y; - - if ((win->_winArgs & RGFW_HOLD_MOUSE)) { + case MotionNotify: + win->event.point.x = E.xmotion.x; win->event.point.y = E.xmotion.y; + + if ((win->_winArgs & RGFW_HOLD_MOUSE)) { + win->event.point.y = E.xmotion.y; - win->event.point.x = win->_lastMousePoint.x - abs(win->event.point.x); - win->event.point.y = win->_lastMousePoint.y - abs(win->event.point.y); - } - - win->_lastMousePoint = RGFW_POINT(E.xmotion.x, E.xmotion.y); + win->event.point.x = win->_lastMousePoint.x - abs(win->event.point.x); + win->event.point.y = win->_lastMousePoint.y - abs(win->event.point.y); + } - win->event.type = RGFW_mousePosChanged; - RGFW_mousePosCallback(win, win->event.point); - break; + win->_lastMousePoint = RGFW_POINT(E.xmotion.x, E.xmotion.y); - case GenericEvent: { - /* MotionNotify is used for mouse events if the mouse isn't held */ - if (!(win->_winArgs & RGFW_HOLD_MOUSE)) { - XFreeEventData(win->src.display, &E.xcookie); + win->event.type = RGFW_mousePosChanged; + RGFW_mousePosCallback(win, win->event.point); break; - } - - XGetEventData(win->src.display, &E.xcookie); - if (E.xcookie.evtype == XI_RawMotion) { - XIRawEvent *raw = (XIRawEvent *)E.xcookie.data; - if (raw->valuators.mask_len == 0) { + + case GenericEvent: { + /* MotionNotify is used for mouse events if the mouse isn't held */ + if (!(win->_winArgs & RGFW_HOLD_MOUSE)) { XFreeEventData(win->src.display, &E.xcookie); break; } + + XGetEventData(win->src.display, &E.xcookie); + if (E.xcookie.evtype == XI_RawMotion) { + XIRawEvent *raw = (XIRawEvent *)E.xcookie.data; + if (raw->valuators.mask_len == 0) { + XFreeEventData(win->src.display, &E.xcookie); + break; + } - double deltaX = 0.0f; - double deltaY = 0.0f; - - /* check if relative motion data exists where we think it does */ - if (XIMaskIsSet(raw->valuators.mask, 0) != 0) - deltaX += raw->raw_values[0]; - if (XIMaskIsSet(raw->valuators.mask, 1) != 0) - deltaY += raw->raw_values[1]; + double deltaX = 0.0f; + double deltaY = 0.0f; - win->event.point = RGFW_POINT((i32)deltaX, (i32)deltaY); - - RGFW_window_moveMouse(win, RGFW_POINT(win->r.x + (win->r.w / 2), win->r.y + (win->r.h / 2))); + /* check if relative motion data exists where we think it does */ + if (XIMaskIsSet(raw->valuators.mask, 0) != 0) + deltaX += raw->raw_values[0]; + if (XIMaskIsSet(raw->valuators.mask, 1) != 0) + deltaY += raw->raw_values[1]; - win->event.type = RGFW_mousePosChanged; - RGFW_mousePosCallback(win, win->event.point); - } + win->event.point = RGFW_POINT((i32)deltaX, (i32)deltaY); + + RGFW_window_moveMouse(win, RGFW_POINT(win->r.x + (win->r.w / 2), win->r.y + (win->r.h / 2))); - XFreeEventData(win->src.display, &E.xcookie); - break; - } - - case Expose: - win->event.type = RGFW_windowRefresh; - RGFW_windowRefreshCallback(win); - break; + win->event.type = RGFW_mousePosChanged; + RGFW_mousePosCallback(win, win->event.point); + } - case ClientMessage: - /* if the client closed the window*/ - if (E.xclient.data.l[0] == (i64) wm_delete_window) { - win->event.type = RGFW_quit; - RGFW_windowQuitCallback(win); + XFreeEventData(win->src.display, &E.xcookie); break; } - /* reset DND values */ - if (win->event.droppedFilesCount) { - for (i = 0; i < win->event.droppedFilesCount; i++) - win->event.droppedFiles[i][0] = '\0'; - } + case Expose: + win->event.type = RGFW_windowRefresh; + RGFW_windowRefreshCallback(win); + break; - win->event.droppedFilesCount = 0; + case ClientMessage: + /* if the client closed the window*/ + if (E.xclient.data.l[0] == (i64) wm_delete_window) { + win->event.type = RGFW_quit; + RGFW_windowQuitCallback(win); + break; + } + + /* reset DND values */ + if (win->event.droppedFilesCount) { + for (i = 0; i < win->event.droppedFilesCount; i++) + win->event.droppedFiles[i][0] = '\0'; + } - if ((win->_winArgs & RGFW_ALLOW_DND) == 0) - break; + win->event.droppedFilesCount = 0; - XEvent reply = { ClientMessage }; - reply.xclient.window = xdnd.source; - reply.xclient.format = 32; - reply.xclient.data.l[0] = (long) win->src.window; - reply.xclient.data.l[1] = 0; - reply.xclient.data.l[2] = None; + if ((win->_winArgs & RGFW_ALLOW_DND) == 0) + break; - if (E.xclient.message_type == XdndEnter) { - unsigned long count; - Atom* formats; - Atom real_formats[6]; + reply.xclient.window = xdnd.source; + reply.xclient.format = 32; + reply.xclient.data.l[0] = (long) win->src.window; + reply.xclient.data.l[1] = 0; + reply.xclient.data.l[2] = None; - Bool list = E.xclient.data.l[1] & 1; + if (E.xclient.message_type == XdndEnter) { + unsigned long count; + Atom* formats; + Atom real_formats[6]; - xdnd.source = E.xclient.data.l[0]; - xdnd.version = E.xclient.data.l[1] >> 24; - xdnd.format = None; + Bool list = E.xclient.data.l[1] & 1; - if (xdnd.version > 5) - break; + xdnd.source = E.xclient.data.l[0]; + xdnd.version = E.xclient.data.l[1] >> 24; - if (list) { - Atom actualType; - i32 actualFormat; - unsigned long bytesAfter; - - XGetWindowProperty((Display*) win->src.display, - xdnd.source, - XdndTypeList, - 0, - LONG_MAX, - False, - 4, - &actualType, - &actualFormat, - &count, - &bytesAfter, - (u8**) &formats); - } else { - count = 0; - - if (E.xclient.data.l[2] != None) - real_formats[count++] = E.xclient.data.l[2]; - if (E.xclient.data.l[3] != None) - real_formats[count++] = E.xclient.data.l[3]; - if (E.xclient.data.l[4] != None) - real_formats[count++] = E.xclient.data.l[4]; - - formats = real_formats; - } + xdnd.format = None; - unsigned long i; - for (i = 0; i < count; i++) { - if (formats[i] == XtextUriList || formats[i] == XtextPlain) { - xdnd.format = formats[i]; + if (xdnd.version > 5) break; + + if (list) { + Atom actualType; + i32 actualFormat; + unsigned long bytesAfter; + + XGetWindowProperty((Display*) win->src.display, + xdnd.source, + XdndTypeList, + 0, + LONG_MAX, + False, + 4, + &actualType, + &actualFormat, + &count, + &bytesAfter, + (u8**) &formats); + } else { + count = 0; + + if (E.xclient.data.l[2] != None) + real_formats[count++] = E.xclient.data.l[2]; + if (E.xclient.data.l[3] != None) + real_formats[count++] = E.xclient.data.l[3]; + if (E.xclient.data.l[4] != None) + real_formats[count++] = E.xclient.data.l[4]; + + formats = real_formats; } - } - if (list) { - XFree(formats); - } + unsigned long i; + for (i = 0; i < count; i++) { + if (formats[i] == XtextUriList || formats[i] == XtextPlain) { + xdnd.format = formats[i]; + break; + } + } - break; - } - if (E.xclient.message_type == XdndPosition) { - const i32 xabs = (E.xclient.data.l[2] >> 16) & 0xffff; - const i32 yabs = (E.xclient.data.l[2]) & 0xffff; - Window dummy; - i32 xpos, ypos; + if (list) { + XFree(formats); + } - if (xdnd.version > 5) break; + } + if (E.xclient.message_type == XdndPosition) { + const i32 xabs = (E.xclient.data.l[2] >> 16) & 0xffff; + const i32 yabs = (E.xclient.data.l[2]) & 0xffff; + Window dummy; + i32 xpos, ypos; - XTranslateCoordinates((Display*) win->src.display, - XDefaultRootWindow((Display*) win->src.display), - (Window) win->src.window, - xabs, yabs, - &xpos, &ypos, - &dummy); + if (xdnd.version > 5) + break; - win->event.point.x = xpos; - win->event.point.y = ypos; + XTranslateCoordinates((Display*) win->src.display, + XDefaultRootWindow((Display*) win->src.display), + (Window) win->src.window, + xabs, yabs, + &xpos, &ypos, + &dummy); - reply.xclient.window = xdnd.source; - reply.xclient.message_type = XdndStatus; + win->event.point.x = xpos; + win->event.point.y = ypos; - if (xdnd.format) { - reply.xclient.data.l[1] = 1; - if (xdnd.version >= 2) - reply.xclient.data.l[4] = XdndActionCopy; - } + reply.xclient.window = xdnd.source; + reply.xclient.message_type = XdndStatus; - XSendEvent((Display*) win->src.display, xdnd.source, False, NoEventMask, &reply); - XFlush((Display*) win->src.display); - break; - } + if (xdnd.format) { + reply.xclient.data.l[1] = 1; + if (xdnd.version >= 2) + reply.xclient.data.l[4] = XdndActionCopy; + } - if (E.xclient.message_type != XdndDrop) - break; + XSendEvent((Display*) win->src.display, xdnd.source, False, NoEventMask, &reply); + XFlush((Display*) win->src.display); + break; + } - if (xdnd.version > 5) - break; + if (E.xclient.message_type != XdndDrop) + break; - win->event.type = RGFW_dnd_init; + if (xdnd.version > 5) + break; - if (xdnd.format) { - Time time = CurrentTime; + win->event.type = RGFW_dnd_init; - if (xdnd.version >= 1) - time = E.xclient.data.l[2]; + if (xdnd.format) { + Time time = CurrentTime; + + if (xdnd.version >= 1) + time = E.xclient.data.l[2]; + + XConvertSelection((Display*) win->src.display, + XdndSelection, + xdnd.format, + XdndSelection, + (Window) win->src.window, + time); + } else if (xdnd.version >= 2) { + XEvent reply = { ClientMessage }; + + XSendEvent((Display*) win->src.display, xdnd.source, + False, NoEventMask, &reply); + XFlush((Display*) win->src.display); + } - XConvertSelection((Display*) win->src.display, - XdndSelection, - xdnd.format, - XdndSelection, - (Window) win->src.window, - time); - } else if (xdnd.version >= 2) { - XEvent reply = { ClientMessage }; + RGFW_dndInitCallback(win, win->event.point); + break; + case SelectionNotify: { + /* this is only for checking for xdnd drops */ + if (E.xselection.property != XdndSelection || !(win->_winArgs | RGFW_ALLOW_DND)) + break; - XSendEvent((Display*) win->src.display, xdnd.source, - False, NoEventMask, &reply); - XFlush((Display*) win->src.display); - } + char* data; + unsigned long result; - RGFW_dndInitCallback(win, win->event.point); - break; - case SelectionNotify: { - /* this is only for checking for xdnd drops */ - if (E.xselection.property != XdndSelection || !(win->_winArgs | RGFW_ALLOW_DND)) - break; + Atom actualType; + i32 actualFormat; + unsigned long bytesAfter; - char* data; - unsigned long result; + XGetWindowProperty((Display*) win->src.display, E.xselection.requestor, E.xselection.property, 0, LONG_MAX, False, E.xselection.target, &actualType, &actualFormat, &result, &bytesAfter, (u8**) &data); - Atom actualType; - i32 actualFormat; - unsigned long bytesAfter; + if (result == 0) + break; - XGetWindowProperty((Display*) win->src.display, E.xselection.requestor, E.xselection.property, 0, LONG_MAX, False, E.xselection.target, &actualType, &actualFormat, &result, &bytesAfter, (u8**) &data); + /* + SOURCED FROM GLFW _glfwParseUriList + Copyright (c) 2002-2006 Marcus Geelnard + Copyright (c) 2006-2019 Camilla Löwy + */ - if (result == 0) - break; + const char* prefix = (const char*)"file://"; - /* - SOURCED FROM GLFW _glfwParseUriList - Copyright (c) 2002-2006 Marcus Geelnard - Copyright (c) 2006-2019 Camilla Löwy - */ + char* line; - const char* prefix = (const char*)"file://"; + win->event.droppedFilesCount = 0; - char* line; + win->event.type = RGFW_dnd; - win->event.droppedFilesCount = 0; + while ((line = strtok(data, "\r\n"))) { + char path[RGFW_MAX_PATH]; - win->event.type = RGFW_dnd; + data = NULL; - while ((line = strtok(data, "\r\n"))) { - char path[RGFW_MAX_PATH]; + if (line[0] == '#') + continue; - data = NULL; + char* l; + for (l = line; 1; l++) { + if ((l - line) > 7) + break; + else if (*l != prefix[(l - line)]) + break; + else if (*l == '\0' && prefix[(l - line)] == '\0') { + line += 7; + while (*line != '/') + line++; + break; + } else if (*l == '\0') + break; + } - if (line[0] == '#') - continue; + win->event.droppedFilesCount++; - char* l; - for (l = line; 1; l++) { - if ((l - line) > 7) - break; - else if (*l != prefix[(l - line)]) - break; - else if (*l == '\0' && prefix[(l - line)] == '\0') { - line += 7; - while (*line != '/') - line++; - break; - } else if (*l == '\0') - break; + size_t index = 0; + while (*line) { + if (line[0] == '%' && line[1] && line[2]) { + const char digits[3] = { line[1], line[2], '\0' }; + path[index] = (char) strtol(digits, NULL, 16); + line += 2; + } else + path[index] = *line; + + index++; + line++; + } + path[index] = '\0'; + strncpy(win->event.droppedFiles[win->event.droppedFilesCount - 1], path, index + 1); } - win->event.droppedFilesCount++; + if (data) + XFree(data); - size_t index = 0; - while (*line) { - if (line[0] == '%' && line[1] && line[2]) { - const char digits[3] = { line[1], line[2], '\0' }; - path[index] = (char) strtol(digits, NULL, 16); - line += 2; - } else - path[index] = *line; + if (xdnd.version >= 2) { + XEvent reply = { ClientMessage }; + reply.xclient.format = 32; + reply.xclient.message_type = XdndFinished; + reply.xclient.data.l[1] = result; + reply.xclient.data.l[2] = XdndActionCopy; - index++; - line++; + XSendEvent((Display*) win->src.display, xdnd.source, False, NoEventMask, &reply); + XFlush((Display*) win->src.display); } - path[index] = '\0'; - strncpy(win->event.droppedFiles[win->event.droppedFilesCount - 1], path, index + 1); - } - if (data) - XFree(data); + RGFW_dndCallback(win, win->event.droppedFiles, win->event.droppedFilesCount); + break; + } + case FocusIn: + win->event.inFocus = 1; + win->event.type = RGFW_focusIn; + RGFW_focusCallback(win, 1); + break; - if (xdnd.version >= 2) { - reply.xclient.message_type = XdndFinished; - reply.xclient.data.l[1] = result; - reply.xclient.data.l[2] = XdndActionCopy; + break; + case FocusOut: + win->event.inFocus = 0; + win->event.type = RGFW_focusOut; + RGFW_focusCallback(win, 0); + break; + + case EnterNotify: { + win->event.type = RGFW_mouseEnter; + win->event.point.x = E.xcrossing.x; + win->event.point.y = E.xcrossing.y; + RGFW_mouseNotifyCallBack(win, win->event.point, 1); + break; + } - XSendEvent((Display*) win->src.display, xdnd.source, False, NoEventMask, &reply); - XFlush((Display*) win->src.display); + case LeaveNotify: { + win->event.type = RGFW_mouseLeave; + RGFW_mouseNotifyCallBack(win, win->event.point, 0); + break; } - RGFW_dndCallback(win, win->event.droppedFiles, win->event.droppedFilesCount); - break; - } - case FocusIn: - win->event.inFocus = 1; - win->event.type = RGFW_focusIn; - RGFW_focusCallback(win, 1); - break; + case ConfigureNotify: { + /* detect resize */ + if (E.xconfigure.width != win->r.w || E.xconfigure.height != win->r.h) { + win->event.type = RGFW_windowResized; + win->r = RGFW_RECT(win->r.x, win->r.y, E.xconfigure.width, E.xconfigure.height); + RGFW_windowResizeCallback(win, win->r); + break; + } + + /* detect move */ + if (E.xconfigure.x != win->r.x || E.xconfigure.y != win->r.y) { + win->event.type = RGFW_windowMoved; + win->r = RGFW_RECT(E.xconfigure.x, E.xconfigure.y, win->r.w, win->r.h); + RGFW_windowMoveCallback(win, win->r); + break; + } - break; - case FocusOut: - win->event.inFocus = 0; - win->event.type = RGFW_focusOut; - RGFW_focusCallback(win, 0); - break; - - case EnterNotify: { - win->event.type = RGFW_mouseEnter; - win->event.point.x = E.xcrossing.x; - win->event.point.y = E.xcrossing.y; - RGFW_mouseNotifyCallBack(win, win->event.point, 1); - break; - } + break; + } + default: { + break; + } + } - case LeaveNotify: { - win->event.type = RGFW_mouseLeave; - RGFW_mouseNotifyCallBack(win, win->event.point, 0); - break; + XFlush((Display*) win->src.display); + + if (win->event.type) + return &win->event; + else + return NULL; } - case ConfigureNotify: { - /* detect resize */ - if (E.xconfigure.width != win->r.w || E.xconfigure.height != win->r.h) { - win->event.type = RGFW_windowResized; - win->r = RGFW_RECT(win->r.x, win->r.y, E.xconfigure.width, E.xconfigure.height); - RGFW_windowResizeCallback(win, win->r); - break; - } - - /* detect move */ - if (E.xconfigure.x != win->r.x || E.xconfigure.y != win->r.y) { - win->event.type = RGFW_windowMoved; - win->r = RGFW_RECT(E.xconfigure.x, E.xconfigure.y, win->r.w, win->r.h); - RGFW_windowMoveCallback(win, win->r); - break; - } + void RGFW_window_move(RGFW_window* win, RGFW_point v) { + assert(win != NULL); + win->r.x = v.x; + win->r.y = v.y; - break; - } - default: { - break; + XMoveWindow((Display*) win->src.display, (Window) win->src.window, v.x, v.y); } - } - - XFlush((Display*) win->src.display); - if (win->event.type) - return &win->event; - else - return NULL; - } - void RGFW_window_move(RGFW_window* win, RGFW_point v) { - assert(win != NULL); - win->r.x = v.x; - win->r.y = v.y; + void RGFW_window_resize(RGFW_window* win, RGFW_area a) { + assert(win != NULL); + win->r.w = a.w; + win->r.h = a.h; - XMoveWindow((Display*) win->src.display, (Window) win->src.window, v.x, v.y); - } + XResizeWindow((Display*) win->src.display, (Window) win->src.window, a.w, a.h); + + if (!(win->_winArgs & RGFW_NO_RESIZE)) + return; - void RGFW_window_resize(RGFW_window* win, RGFW_area a) { - assert(win != NULL); - win->r.w = a.w; - win->r.h = a.h; + XSizeHints sh = {0}; + sh.flags = (1L << 4) | (1L << 5); + sh.min_width = sh.max_width = a.w; + sh.min_height = sh.max_height = a.h; - XResizeWindow((Display*) win->src.display, (Window) win->src.window, a.w, a.h); + XSetWMSizeHints((Display*) win->src.display, (Drawable) win->src.window, &sh, XA_WM_NORMAL_HINTS); } void RGFW_window_setMinSize(RGFW_window* win, RGFW_area a) { @@ -3727,8 +3762,8 @@ Start of Linux / Unix defines RGFW_area size = RGFW_getScreenSize(); monitor.rect = RGFW_RECT(0, 0, size.w, size.h); - monitor.physW = DisplayWidthMM(display, screen); - monitor.physH = DisplayHeightMM(display, screen); + monitor.physW = DisplayWidthMM(display, screen) / 25.4; + monitor.physH = DisplayHeightMM(display, screen) / 25.4; XGetSystemContentScale(display, &monitor.scaleX, &monitor.scaleY); XRRScreenResources* sr = XRRGetScreenResourcesCurrent(display, RootWindow(display, screen)); @@ -3741,8 +3776,8 @@ Start of Linux / Unix defines } if (ci == NULL) { - float dpi_width = round((double)monitor.rect.w/(((double)monitor.physW)/25.4)); - float dpi_height = round((double)monitor.rect.h/(((double)monitor.physH)/25.4)); + float dpi_width = round((double)monitor.rect.w/(double)monitor.physW); + float dpi_height = round((double)monitor.rect.h/(double)monitor.physH); monitor.scaleX = (float) (dpi_width) / (float) 96; monitor.scaleY = (float) (dpi_height) / (float) 96; @@ -3752,24 +3787,24 @@ Start of Linux / Unix defines } XRROutputInfo* info = XRRGetOutputInfo (display, sr, sr->outputs[screen]); - monitor.physW = info->mm_width; - monitor.physH = info->mm_height; + monitor.physW = info->mm_width / 25.4; + monitor.physH = info->mm_height / 25.4; monitor.rect.x = ci->x; monitor.rect.y = ci->y; monitor.rect.w = ci->width; monitor.rect.h = ci->height; - float dpi_width = round((double)monitor.rect.w/(((double)monitor.physW)/25.4)); - float dpi_height = round((double)monitor.rect.h/(((double)monitor.physH)/25.4)); + float dpi_width = round((double)monitor.rect.w/(double)monitor.physW); + float dpi_height = round((double)monitor.rect.h/(double)monitor.physH); monitor.scaleX = (float) (dpi_width) / (float) 96; monitor.scaleY = (float) (dpi_height) / (float) 96; - if (monitor.scaleX > 1 && monitor.scaleX < 1.1) + if (isinf(monitor.scaleX) || (monitor.scaleX > 1 && monitor.scaleX < 1.1)) monitor.scaleX = 1; - if (monitor.scaleY > 1 && monitor.scaleY < 1.1) + if (isinf(monitor.scaleY) || (monitor.scaleY > 1 && monitor.scaleY < 1.1)) monitor.scaleY = 1; XRRFreeCrtcInfo(ci); @@ -3951,8 +3986,8 @@ Start of Linux / Unix defines } u8 i; - for (i = 0; i < RGFW_joystickCount; i++) - close(RGFW_joysticks[i]); + for (i = 0; i < RGFW_gamepadCount; i++) + close(RGFW_gamepads[i]); } /* set cleared display / window to NULL for error checking */ @@ -3975,43 +4010,43 @@ Start of Linux / Unix defines #include #include #include - u16 RGFW_registerJoystickF(RGFW_window* win, char* file) { + u16 RGFW_registerGamepadF(RGFW_window* win, char* file) { assert(win != NULL); #ifdef __linux__ i32 js = open(file, O_RDONLY); - if (js && RGFW_joystickCount < 4) { - RGFW_joystickCount++; + if (js && RGFW_gamepadCount < 4) { + RGFW_gamepadCount++; - RGFW_joysticks[RGFW_joystickCount - 1] = open(file, O_RDONLY); + RGFW_gamepads[RGFW_gamepadCount - 1] = open(file, O_RDONLY); u8 i; for (i = 0; i < 16; i++) - RGFW_jsPressed[RGFW_joystickCount - 1][i] = 0; + RGFW_gpPressed[RGFW_gamepadCount - 1][i] = 0; } else { #ifdef RGFW_PRINT_ERRORS RGFW_error = 1; - fprintf(stderr, "Error RGFW_registerJoystickF : Cannot open file %s\n", file); + fprintf(stderr, "Error RGFW_registerGamepadF : Cannot open file %s\n", file); #endif } - return RGFW_joystickCount - 1; + return RGFW_gamepadCount - 1; #endif } - u16 RGFW_registerJoystick(RGFW_window* win, i32 jsNumber) { + u16 RGFW_registerGamepad(RGFW_window* win, i32 gpNumber) { assert(win != NULL); #ifdef __linux__ char file[15]; - sprintf(file, "/dev/input/js%i", jsNumber); + sprintf(file, "/dev/input/js%i", gpNumber); - return RGFW_registerJoystickF(win, file); + return RGFW_registerGamepadF(win, file); #endif } @@ -4047,7 +4082,7 @@ Start of Linux / Unix defines { ConnectionNumber(win->src.display), POLLIN, 0 }, #endif { RGFW_eventWait_forceStop[0], POLLIN, 0 }, - #ifdef __linux__ /* blank space for 4 joystick files*/ + #ifdef __linux__ /* blank space for 4 gamepad files*/ { -1, POLLIN, 0 }, {-1, POLLIN, 0 }, {-1, POLLIN, 0 }, {-1, POLLIN, 0} #endif }; @@ -4055,11 +4090,11 @@ Start of Linux / Unix defines u8 index = 2; #if defined(__linux__) - for (i = 0; i < RGFW_joystickCount; i++) { - if (RGFW_joysticks[i] == 0) + for (i = 0; i < RGFW_gamepadCount; i++) { + if (RGFW_gamepads[i] == 0) continue; - fds[index].fd = RGFW_joysticks[i]; + fds[index].fd = RGFW_gamepads[i]; index++; } #endif @@ -4745,7 +4780,7 @@ static const struct wl_callback_listener wl_surface_frame_listener = { } #ifdef __linux__ - RGFW_Event* event = RGFW_linux_updateJoystick(win); + RGFW_Event* event = RGFW_linux_updateGamepad(win); if (event != NULL) return event; #endif @@ -5071,7 +5106,7 @@ static const struct wl_callback_listener wl_surface_frame_listener = { #define wglGetSwapIntervalEXT wglGetSwapIntervalEXTSrc - void* RGFWjoystickApi = NULL; + void* RGFWgamepadApi = NULL; /* these two wgl functions need to be preloaded */ typedef HGLRC (WINAPI *PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC hdc, HGLRC hglrc, const int *attribList); @@ -5186,22 +5221,29 @@ static HMODULE wglinstance = NULL; u32 i; static const char* names[] = { "xinput1_4.dll", - "xinput1_3.dll", "xinput9_1_0.dll", "xinput1_2.dll", "xinput1_1.dll" }; - for (i = 0; i < sizeof(names) / sizeof(const char*); i++) { + for (i = 0; i < sizeof(names) / sizeof(const char*) && (XInputGetStateSRC == NULL || XInputGetStateSRC != NULL); i++) { RGFW_XInput_dll = LoadLibraryA(names[i]); - if (RGFW_XInput_dll) { + if (RGFW_XInput_dll == NULL) + continue; + + if (XInputGetStateSRC == NULL) XInputGetStateSRC = (PFN_XInputGetState)(void*)GetProcAddress(RGFW_XInput_dll, "XInputGetState"); - - if (XInputGetStateSRC == NULL) - printf("Failed to load XInputGetState"); - } + + if (XInputGetKeystrokeSRC == NULL) + XInputGetKeystrokeSRC = (PFN_XInputGetKeystroke)(void*)GetProcAddress(RGFW_XInput_dll, "XInputGetKeystroke"); } + + if (XInputGetStateSRC == NULL) + printf("RGFW ERR: Failed to load XInputGetState\n"); + if (XInputGetKeystrokeSRC == NULL) + printf("RGFW ERR: Failed to load XInputGetKeystroke\n"); + } #endif @@ -5276,7 +5318,9 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */ if (RGFW_Shcore_dll == NULL) { RGFW_Shcore_dll = LoadLibraryA("shcore.dll"); GetDpiForMonitorSRC = (PFN_GetDpiForMonitor)(void*)GetProcAddress(RGFW_Shcore_dll, "GetDpiForMonitor"); - SetProcessDPIAware(); + #if (_WIN32_WINNT >= 0x0600) + SetProcessDPIAware(); + #endif } #endif @@ -5319,6 +5363,11 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */ Class.hCursor = LoadCursor(NULL, IDC_ARROW); Class.lpfnWndProc = WndProc; + Class.hIcon = LoadImageA(GetModuleHandleW(NULL), "RGFW_ICON", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); + if (Class.hIcon == NULL) { + Class.hIcon = LoadImageA(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); + } + RegisterClassA(&Class); DWORD window_style = WS_CLIPSIBLINGS | WS_CLIPCHILDREN; @@ -5331,7 +5380,8 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */ if (!(args & RGFW_NO_RESIZE)) window_style |= WS_SIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME; } else - window_style |= WS_POPUP | WS_VISIBLE | WS_SYSMENU | WS_MINIMIZEBOX; + window_style |= WS_POPUP | WS_VISIBLE | WS_SYSMENU | WS_MINIMIZEBOX; + HWND dummyWin = CreateWindowA(Class.lpszClassName, name, window_style, win->r.x, win->r.y, win->r.w, win->r.h, 0, 0, inh, 0); @@ -5623,26 +5673,27 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */ u8 RGFW_xinput2RGFW[] = { - RGFW_JS_A, /* or PS X button */ - RGFW_JS_B, /* or PS circle button */ - RGFW_JS_X, /* or PS square button */ - RGFW_JS_Y, /* or PS triangle button */ - RGFW_JS_R1, /* right bumper */ - RGFW_JS_L1, /* left bump */ - RGFW_JS_L2, /* left trigger*/ - RGFW_JS_R2, /* right trigger */ + RGFW_GP_A, /* or PS X button */ + RGFW_GP_B, /* or PS circle button */ + RGFW_GP_X, /* or PS square button */ + RGFW_GP_Y, /* or PS triangle button */ + RGFW_GP_R1, /* right bumper */ + RGFW_GP_L1, /* left bump */ + RGFW_GP_L2, /* left trigger*/ + RGFW_GP_R2, /* right trigger */ 0, 0, 0, 0, 0, 0, 0, 0, - RGFW_JS_UP, /* dpad up */ - RGFW_JS_DOWN, /* dpad down*/ - RGFW_JS_LEFT, /* dpad left */ - RGFW_JS_RIGHT, /* dpad right */ - RGFW_JS_START, /* start button */ - RGFW_JS_SELECT/* select button */ + RGFW_GP_UP, /* dpad up */ + RGFW_GP_DOWN, /* dpad down*/ + RGFW_GP_LEFT, /* dpad left */ + RGFW_GP_RIGHT, /* dpad right */ + RGFW_GP_START, /* start button */ + RGFW_GP_SELECT,/* select button */ + RGFW_GP_L3, + RGFW_GP_R3, }; static i32 RGFW_checkXInput(RGFW_window* win, RGFW_Event* e) { RGFW_UNUSED(win) - size_t i; for (i = 0; i < 4; i++) { XINPUT_KEYSTROKE keystroke; @@ -5655,14 +5706,14 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */ if ((keystroke.Flags & XINPUT_KEYSTROKE_REPEAT) == 0 && result != ERROR_EMPTY) { if (result != ERROR_SUCCESS) return 0; - - if (keystroke.VirtualKey > VK_PAD_BACK) + + if (keystroke.VirtualKey > VK_PAD_RTHUMB_PRESS) continue; - - // RGFW_jsButtonPressed + 1 = RGFW_jsButtonReleased - e->type = RGFW_jsButtonPressed + !(keystroke.Flags & XINPUT_KEYSTROKE_KEYDOWN); + + //gp + 1 = RGFW_gpButtonReleased + e->type = RGFW_gpButtonPressed + !(keystroke.Flags & XINPUT_KEYSTROKE_KEYDOWN); e->button = RGFW_xinput2RGFW[keystroke.VirtualKey - 0x5800]; - RGFW_jsPressed[i][e->button] = !(keystroke.Flags & XINPUT_KEYSTROKE_KEYDOWN); + RGFW_gpPressed[i][e->button] = !(keystroke.Flags & XINPUT_KEYSTROKE_KEYDOWN); return 1; } @@ -5672,6 +5723,7 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */ XInputGetState((DWORD) i, &state) == ERROR_DEVICE_NOT_CONNECTED ) return 0; + #define INPUT_DEADZONE ( 0.24f * (float)(0x7FFF) ) // Default to 24% of the +/- 32767 range. This is a reasonable default value but can be altered if needed. if ((state.Gamepad.sThumbLX < INPUT_DEADZONE && @@ -5693,20 +5745,26 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */ } e->axisesCount = 2; - RGFW_point axis1 = RGFW_POINT(state.Gamepad.sThumbLX, state.Gamepad.sThumbLY); - RGFW_point axis2 = RGFW_POINT(state.Gamepad.sThumbRX, state.Gamepad.sThumbRY); + RGFW_point axis1 = RGFW_POINT(((float)state.Gamepad.sThumbLX / 32768.0f) * 100, ((float)state.Gamepad.sThumbLY / -32768.0f) * 100); + RGFW_point axis2 = RGFW_POINT(((float)state.Gamepad.sThumbRX / 32768.0f) * 100, ((float)state.Gamepad.sThumbRY / -32768.0f) * 100); - if (axis1.x != e->axis[0].x || axis1.y != e->axis[0].y || axis2.x != e->axis[1].x || axis2.y != e->axis[1].y) { - e->type = RGFW_jsAxisMove; + if (axis1.x != e->axis[0].x || axis1.y != e->axis[0].y){ + win->event.whichAxis = 0; + + e->type = RGFW_gpAxisMove; e->axis[0] = axis1; - e->axis[1] = axis2; return 1; } - e->axis[0] = axis1; - e->axis[1] = axis2; + if (axis2.x != e->axis[1].x || axis2.y != e->axis[1].y) { + win->event.whichAxis = 1; + e->type = RGFW_gpAxisMove; + e->axis[1] = axis2; + + return 1; + } } return 0; @@ -6501,19 +6559,19 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */ CloseClipboard(); } - u16 RGFW_registerJoystick(RGFW_window* win, i32 jsNumber) { + u16 RGFW_registerGamepad(RGFW_window* win, i32 gpNumber) { assert(win != NULL); - RGFW_UNUSED(jsNumber) + RGFW_UNUSED(gpNumber) - return RGFW_registerJoystickF(win, (char*) ""); + return RGFW_registerGamepadF(win, (char*) ""); } - u16 RGFW_registerJoystickF(RGFW_window* win, char* file) { + u16 RGFW_registerGamepadF(RGFW_window* win, char* file) { assert(win != NULL); RGFW_UNUSED(file) - return RGFW_joystickCount - 1; + return RGFW_gamepadCount - 1; } void RGFW_window_moveMouse(RGFW_window* win, RGFW_point p) { @@ -8046,11 +8104,20 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */ monitor.rect = RGFW_RECT((int) bounds.origin.x, (int) bounds.origin.y, (int) bounds.size.width, (int) bounds.size.height); CGSize screenSizeMM = CGDisplayScreenSize(display); - monitor.physW = screenSizeMM.width; - monitor.physH = screenSizeMM.height; + monitor.physW = (float)screenSizeMM.width / 25.4f; + monitor.physH = (float)screenSizeMM.height / 25.4f; - monitor.scaleX = ((monitor.rect.w / (screenSizeMM.width / 25.4)) / 96) + 0.25; - monitor.scaleY = ((monitor.rect.h / (screenSizeMM.height / 25.4)) / 96) + 0.25; + float dpi_width = round((double)monitor.rect.w/(double)monitor.physW); + float dpi_height = round((double)monitor.rect.h/(double)monitor.physH); + + monitor.scaleX = (float) (dpi_width) / (float) 96; + monitor.scaleY = (float) (dpi_height) / (float) 96; + + if (isinf(monitor.scaleX) || (monitor.scaleX > 1 && monitor.scaleX < 1.1)) + monitor.scaleX = 1; + + if (isinf(monitor.scaleY) || (monitor.scaleY > 1 && monitor.scaleY < 1.1)) + monitor.scaleY = 1; return monitor; } @@ -8111,20 +8178,20 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */ NSPasteBoard_setString(NSPasteboard_generalPasteboard(), text, NSPasteboardTypeString); } - u16 RGFW_registerJoystick(RGFW_window* win, i32 jsNumber) { - RGFW_UNUSED(jsNumber); + u16 RGFW_registerGamepad(RGFW_window* win, i32 gpNumber) { + RGFW_UNUSED(gpNumber); assert(win != NULL); - return RGFW_registerJoystickF(win, (char*) ""); + return RGFW_registerGamepadF(win, (char*) ""); } - u16 RGFW_registerJoystickF(RGFW_window* win, char* file) { + u16 RGFW_registerGamepadF(RGFW_window* win, char* file) { RGFW_UNUSED(file); assert(win != NULL); - return RGFW_joystickCount - 1; + return RGFW_gamepadCount - 1; } #ifdef RGFW_OPENGL @@ -8311,16 +8378,47 @@ EM_BOOL Emscripten_on_resize(int eventType, const EmscriptenUiEvent* e, void* us } EM_BOOL Emscripten_on_fullscreenchange(int eventType, const EmscriptenFullscreenChangeEvent* e, void* userData) { - RGFW_UNUSED(eventType); RGFW_UNUSED(userData); + static u8 fullscreen = RGFW_FALSE; + static RGFW_rect ogRect; + + if (fullscreen == RGFW_FALSE) { + ogRect = RGFW_root->r; + } + fullscreen = !fullscreen; + + RGFW_UNUSED(eventType); RGFW_UNUSED(userData); + RGFW_events[RGFW_eventLen].type = RGFW_windowResized; RGFW_eventLen++; + + RGFW_root->r = RGFW_RECT(0, 0, e->screenWidth, e->screenHeight); + + EM_ASM("Module.canvas.focus();"); + + if (fullscreen == RGFW_FALSE) { + RGFW_root->r = RGFW_RECT(0, 0, ogRect.w, ogRect.h); + // emscripten_request_fullscreen("#canvas", 0); + } else { + #if __EMSCRIPTEN_major__ >= 1 && __EMSCRIPTEN_minor__ >= 29 && __EMSCRIPTEN_tiny__ >= 0 + EmscriptenFullscreenStrategy FSStrat = {0}; + FSStrat.scaleMode = EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH;//EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT;// : EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH; + FSStrat.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF; + FSStrat.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT; + emscripten_request_fullscreen_strategy("#canvas", 1, &FSStrat); + #else + emscripten_request_fullscreen("#canvas", 1); + #endif + } + + emscripten_set_canvas_element_size("#canvas", RGFW_root->r.w, RGFW_root->r.h); - RGFW_root->r = RGFW_RECT(0, 0, e->elementWidth, e->elementHeight); RGFW_windowResizeCallback(RGFW_root, RGFW_root->r); - return EM_TRUE; + return EM_TRUE; } + + EM_BOOL Emscripten_on_focusin(int eventType, const EmscriptenFocusEvent* e, void* userData) { RGFW_UNUSED(eventType); RGFW_UNUSED(userData); RGFW_UNUSED(e); @@ -8399,7 +8497,7 @@ EM_BOOL Emscripten_on_wheel(int eventType, const EmscriptenWheelEvent* e, void* RGFW_events[RGFW_eventLen].type = RGFW_mouseButtonPressed; RGFW_events[RGFW_eventLen].point = RGFW_POINT(e->mouse.targetX, e->mouse.targetY); RGFW_events[RGFW_eventLen].button = RGFW_mouseScrollUp + (e->deltaY < 0); - RGFW_events[RGFW_eventLen].scroll = e->deltaY; + RGFW_events[RGFW_eventLen].scroll = e->deltaY < 0 ? 1 : -1; RGFW_mouseButtons[RGFW_events[RGFW_eventLen].button].prev = RGFW_mouseButtons[RGFW_events[RGFW_eventLen].button].current; RGFW_mouseButtons[RGFW_events[RGFW_eventLen].button].current = 1; @@ -8472,8 +8570,8 @@ EM_BOOL Emscripten_on_gamepad(int eventType, const EmscriptenGamepadEvent *gamep if (gamepadEvent->index >= 4) return 0; - - RGFW_joysticks[gamepadEvent->index] = gamepadEvent->connected; + + RGFW_gamepads[gamepadEvent->index] = gamepadEvent->connected; return 1; // The event was consumed by the callback handler } @@ -8532,8 +8630,7 @@ void EMSCRIPTEN_KEEPALIVE RGFW_makeSetValue(size_t index, char* file) { */ RGFW_events[RGFW_eventLen].type = RGFW_dnd; - char** arr = (char**)&RGFW_events[RGFW_eventLen].droppedFiles[index]; - *arr = file; + strcpy((char*)RGFW_events[RGFW_eventLen].droppedFiles[index], file); } #include @@ -8687,49 +8784,58 @@ RGFW_window* RGFW_createWindow(const char* name, RGFW_rect rect, u16 args) { RGFW_Event* RGFW_window_checkEvent(RGFW_window* win) { static u8 index = 0; - if (index == 0) + if (index == 0) { RGFW_resetKey(); - + } + + emscripten_sample_gamepad_data(); /* check gamepads */ for (int i = 0; (i < emscripten_get_num_gamepads()) && (i < 4); i++) { - if (RGFW_joysticks[i] == 0) - continue;; - + if (RGFW_gamepads[i] == 0) + continue; EmscriptenGamepadEvent gamepadState; if (emscripten_get_gamepad_status(i, &gamepadState) != EMSCRIPTEN_RESULT_SUCCESS) break; - + // Register buttons data for every connected gamepad for (int j = 0; (j < gamepadState.numButtons) && (j < 16); j++) { u32 map[] = { - RGFW_JS_A, RGFW_JS_X, RGFW_JS_B, RGFW_JS_Y, - RGFW_JS_L1, RGFW_JS_R1, RGFW_JS_L2, RGFW_JS_R2, - RGFW_JS_SELECT, RGFW_JS_START, - 0, 0, - RGFW_JS_UP, RGFW_JS_DOWN, RGFW_JS_LEFT, RGFW_JS_RIGHT + RGFW_GP_A, RGFW_GP_B, RGFW_GP_X, RGFW_GP_Y, + RGFW_GP_L1, RGFW_GP_R1, RGFW_GP_L2, RGFW_GP_R2, + RGFW_GP_SELECT, RGFW_GP_START, + RGFW_GP_L3, RGFW_GP_R3, + RGFW_GP_UP, RGFW_GP_DOWN, RGFW_GP_LEFT, RGFW_GP_RIGHT }; + u32 button = map[j]; - if (RGFW_jsPressed[i][button] != gamepadState.digitalButton[j]) { - win->event.type = RGFW_jsButtonPressed; - win->event.joystick = i; + if (button == 404) + continue; + + if (RGFW_gpPressed[i][button] != gamepadState.digitalButton[j]) { + if (gamepadState.digitalButton[j]) + win->event.type = RGFW_gpButtonPressed; + else + win->event.type = RGFW_gpButtonReleased; + + win->event.gamepad = i; win->event.button = map[j]; + RGFW_gpPressed[i][button] = gamepadState.digitalButton[j]; return &win->event; } - - RGFW_jsPressed[i][button] = gamepadState.digitalButton[j]; } for (int j = 0; (j < gamepadState.numAxes) && (j < 4); j += 2) { - win->event.axisesCount = gamepadState.numAxes; - if (win->event.axis[j].x != gamepadState.axis[j] || - win->event.axis[j].y != gamepadState.axis[j + 1] + win->event.axisesCount = gamepadState.numAxes / 2; + if (win->event.axis[j / 2].x != (i8)(gamepadState.axis[j] * 100.0f) || + win->event.axis[j / 2].y != (i8)(gamepadState.axis[j + 1] * 100.0f) ) { - win->event.axis[j].x = gamepadState.axis[j]; - win->event.axis[j].y = gamepadState.axis[j + 1]; - win->event.type = RGFW_jsAxisMove; - win->event.joystick = i; + win->event.axis[j / 2].x = (i8)(gamepadState.axis[j] * 100.0f); + win->event.axis[j / 2].y = (i8)(gamepadState.axis[j + 1] * 100.0f); + win->event.type = RGFW_gpAxisMove; + win->event.gamepad = i; + win->event.whichAxis = j / 2; return &win->event; } } @@ -8738,7 +8844,7 @@ RGFW_Event* RGFW_window_checkEvent(RGFW_window* win) { /* check queued events */ if (RGFW_eventLen == 0) return NULL; - + RGFW_events[index].frameTime = win->event.frameTime; RGFW_events[index].frameTime2 = win->event.frameTime2; RGFW_events[index].inFocus = win->event.inFocus; diff --git a/src/platforms/rcore_desktop_rgfw.c b/src/platforms/rcore_desktop_rgfw.c index 3cf005f25..d9ba8185c 100644 --- a/src/platforms/rcore_desktop_rgfw.c +++ b/src/platforms/rcore_desktop_rgfw.c @@ -6,6 +6,8 @@ * - Windows (Win32, Win64) * - Linux (X11/Wayland desktop mode) * - MacOS (Cocoa) +* - HTML5 (Emscripten) +* - Others (untested) * * LIMITATIONS: * - TODO @@ -46,7 +48,11 @@ * **********************************************************************************************/ -#if defined(GRAPHICS_API_OPENGL_ES2) +#if defined(PLATFORM_WEB_RGFW) +#define RGFW_NO_GL_HEADER +#endif + +#if defined(GRAPHICS_API_OPENGL_ES2) && !defined(PLATFORM_WEB_RGFW) #define RGFW_OPENGL_ES2 #endif @@ -80,6 +86,10 @@ void CloseWindow(void); #define Size NSSIZE #endif +#define RGFW_MALLOC RL_MALLOC +#define RGFW_FREE RL_FREE +#define RGFW_CALLOC RL_CALLOC + #include "../external/RGFW.h" #if defined(_WIN32) || defined(_WIN64) @@ -118,6 +128,7 @@ static bool RGFW_disableCursor = false; static const unsigned short keyMappingRGFW[] = { [RGFW_KEY_NULL] = KEY_NULL, + [RGFW_Return] = KEY_ENTER, [RGFW_Quote] = KEY_APOSTROPHE, [RGFW_Comma] = KEY_COMMA, [RGFW_Minus] = KEY_MINUS, @@ -246,7 +257,7 @@ bool WindowShouldClose(void) // Toggle fullscreen mode void ToggleFullscreen(void) -{ +{ RGFW_window_maximize(platform.window); ToggleBorderlessWindowed(); } @@ -611,7 +622,7 @@ int GetMonitorPhysicalWidth(int monitor) { RGFW_monitor *mons = RGFW_getMonitors(); - return (int)mons[monitor].physW; + return mons[monitor].physW; } // Get selected monitor physical height in millimetres @@ -664,39 +675,42 @@ const char *GetClipboardText(void) return RGFW_readClipboard(NULL); } + #if defined(SUPPORT_CLIPBOARD_IMAGE) -#if defined(_WIN32) - #define WIN32_CLIPBOARD_IMPLEMENTATION - #define WINUSER_ALREADY_INCLUDED - #define WINBASE_ALREADY_INCLUDED - #define WINGDI_ALREADY_INCLUDED - #include "../external/win32_clipboard.h" + +#ifdef _WIN32 +# define WIN32_CLIPBOARD_IMPLEMENTATION +# define WINUSER_ALREADY_INCLUDED +# define WINBASE_ALREADY_INCLUDED +# define WINGDI_ALREADY_INCLUDED +# include "../external/win32_clipboard.h" #endif -#endif // SUPPORT_CLIPBOARD_IMAGE // Get clipboard image Image GetClipboardImage(void) { - Image image = { 0 }; - -#if defined(SUPPORT_CLIPBOARD_IMAGE) -#if defined(_WIN32) + Image image = {0}; unsigned long long int dataSize = 0; - void *fileData = NULL; - int width = 0; - int height = 0; + void* fileData = NULL; +#ifdef _WIN32 + int width, height; fileData = (void*)Win32GetClipboardImageData(&width, &height, &dataSize); - - if (fileData == NULL) TRACELOG(LOG_WARNING, "Clipboard image: Couldn't get clipboard data."); - else image = LoadImageFromMemory(".bmp", fileData, (int)dataSize); #else - TRACELOG(LOG_WARNING, "GetClipboardImage() not implemented on target platform"); + TRACELOG(LOG_WARNING, "Clipboard image: PLATFORM_DESKTOP_RGFW doesn't implement `GetClipboardImage` for this OS"); #endif -#endif // SUPPORT_CLIPBOARD_IMAGE + if (fileData == NULL) + { + TRACELOG(LOG_WARNING, "Clipboard image: Couldn't get clipboard data."); + } + else + { + image = LoadImageFromMemory(".bmp", fileData, dataSize); + } return image; } +#endif // SUPPORT_CLIPBOARD_IMAGE // Show mouse cursor void ShowCursor(void) @@ -861,6 +875,28 @@ char RSGL_keystrToChar(const char *str) return '\0'; } +int RGFW_gpConvTable[18] = { + [RGFW_GP_Y] = GAMEPAD_BUTTON_RIGHT_FACE_UP, + [RGFW_GP_B] = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT, + [RGFW_GP_A] = GAMEPAD_BUTTON_RIGHT_FACE_DOWN, + [RGFW_GP_X] = GAMEPAD_BUTTON_RIGHT_FACE_LEFT, + [RGFW_GP_L1] = GAMEPAD_BUTTON_LEFT_TRIGGER_1, + [RGFW_GP_R1] = GAMEPAD_BUTTON_RIGHT_TRIGGER_1, + [RGFW_GP_L2] = GAMEPAD_BUTTON_LEFT_TRIGGER_2, + [RGFW_GP_R2] = GAMEPAD_BUTTON_RIGHT_TRIGGER_2, + [RGFW_GP_SELECT] = GAMEPAD_BUTTON_MIDDLE_LEFT, + [RGFW_GP_HOME] = GAMEPAD_BUTTON_MIDDLE, + [RGFW_GP_START] = GAMEPAD_BUTTON_MIDDLE_RIGHT, + [RGFW_GP_UP] = GAMEPAD_BUTTON_LEFT_FACE_UP, + [RGFW_GP_RIGHT] = GAMEPAD_BUTTON_LEFT_FACE_RIGHT, + [RGFW_GP_DOWN] = GAMEPAD_BUTTON_LEFT_FACE_DOWN, + [RGFW_GP_LEFT] = GAMEPAD_BUTTON_LEFT_FACE_LEFT, + [RGFW_GP_L3] = GAMEPAD_BUTTON_LEFT_THUMB, + [RGFW_GP_R3] = GAMEPAD_BUTTON_RIGHT_THUMB, +}; + + + // Register all input events void PollInputEvents(void) { @@ -869,7 +905,7 @@ void PollInputEvents(void) // 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; @@ -933,27 +969,27 @@ void PollInputEvents(void) while (RGFW_window_checkEvent(platform.window)) { - if ((platform.window->event.type >= RGFW_jsButtonPressed) && (platform.window->event.type <= RGFW_jsAxisMove)) + if ((platform.window->event.type >= RGFW_gpButtonPressed) && (platform.window->event.type <= RGFW_gpAxisMove)) { - if (!CORE.Input.Gamepad.ready[platform.window->event.joystick]) + if (!CORE.Input.Gamepad.ready[platform.window->event.gamepad]) { - 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; + CORE.Input.Gamepad.ready[platform.window->event.gamepad] = true; + CORE.Input.Gamepad.axisCount[platform.window->event.gamepad] = platform.window->event.axisesCount; + CORE.Input.Gamepad.name[platform.window->event.gamepad][0] = '\0'; + CORE.Input.Gamepad.axisState[platform.window->event.gamepad][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f; + CORE.Input.Gamepad.axisState[platform.window->event.gamepad][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f; } } RGFW_Event *event = &platform.window->event; - // All input events can be processed after polling - switch (event->type) + + switch (event->type) { case RGFW_quit: CORE.Window.shouldClose = true; break; case RGFW_dnd: // Dropped file { - for (u32 i = 0; i < event->droppedFilesCount; i++) + for (int i = 0; i < event->droppedFilesCount; i++) { if (CORE.Window.dropFileCount == 0) { @@ -964,7 +1000,7 @@ void PollInputEvents(void) 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) @@ -998,7 +1034,6 @@ void PollInputEvents(void) case RGFW_keyPressed: { KeyboardKey key = ConvertScancodeToKey(event->keyCode); - if (key != KEY_NULL) { // If key was up, add it to the key pressed queue @@ -1037,7 +1072,7 @@ void PollInputEvents(void) { if ((event->button == RGFW_mouseScrollUp) || (event->button == RGFW_mouseScrollDown)) { - CORE.Input.Mouse.currentWheelMove.y = (float)event->scroll; + CORE.Input.Mouse.currentWheelMove.y = event->scroll; break; } @@ -1053,10 +1088,9 @@ void PollInputEvents(void) } break; case RGFW_mouseButtonReleased: { - if ((event->button == RGFW_mouseScrollUp) || (event->button == RGFW_mouseScrollDown)) { - CORE.Input.Mouse.currentWheelMove.y = (float)event->scroll; + CORE.Input.Mouse.currentWheelMove.y = event->scroll; break; } @@ -1087,124 +1121,53 @@ void PollInputEvents(void) CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; touchAction = 2; } break; - case RGFW_jsButtonPressed: + case RGFW_gpButtonPressed: { - 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; - } + int button = RGFW_gpConvTable[event->button]; if (button >= 0) { - CORE.Input.Gamepad.currentButtonState[event->joystick][button] = 1; + CORE.Input.Gamepad.currentButtonState[event->gamepad][button] = 1; CORE.Input.Gamepad.lastButtonPressed = button; } } break; - case RGFW_jsButtonReleased: + case RGFW_gpButtonReleased: { - 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; - } + int button = RGFW_gpConvTable[event->button]; - if (button >= 0) - { - CORE.Input.Gamepad.currentButtonState[event->joystick][button] = 0; - if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0; - } + CORE.Input.Gamepad.currentButtonState[event->gamepad][button] = 0; + if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0; } break; - case RGFW_jsAxisMove: + case RGFW_gpAxisMove: { int axis = -1; - for (int 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; - } - } + float value = 0; + switch(event->whichAxis) + { + case 0: + { + CORE.Input.Gamepad.axisState[event->gamepad][GAMEPAD_AXIS_LEFT_X] = event->axis[0].x / 100.0f; + CORE.Input.Gamepad.axisState[event->gamepad][GAMEPAD_AXIS_LEFT_Y] = event->axis[0].y / 100.0f; + } break; + case 1: + { + CORE.Input.Gamepad.axisState[event->gamepad][GAMEPAD_AXIS_RIGHT_X] = event->axis[1].x / 100.0f; + CORE.Input.Gamepad.axisState[event->gamepad][GAMEPAD_AXIS_RIGHT_Y] = event->axis[1].y / 100.0f; + } break; + case 2: axis = GAMEPAD_AXIS_LEFT_TRIGGER; + case 3: + { + if (axis == -1) 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->gamepad][button] = pressed; + + if (pressed) CORE.Input.Gamepad.lastButtonPressed = button; + else if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0; + } + default: break; + } } break; default: break; } @@ -1289,17 +1252,22 @@ int InitPlatform(void) platform.window = RGFW_createWindow(CORE.Window.title, RGFW_RECT(0, 0, CORE.Window.screen.width, CORE.Window.screen.height), flags); + +#ifndef PLATFORM_WEB_RGFW RGFW_area screenSize = RGFW_getScreenSize(); CORE.Window.display.width = screenSize.w; CORE.Window.display.height = screenSize.h; - /* - I think this is needed by Raylib now ? +#else + CORE.Window.display.width = CORE.Window.screen.width; + CORE.Window.display.height = CORE.Window.screen.height; +#endif + /* + I think this is needed by Raylib now ? If so, rcore_destkop_sdl should be updated too */ - SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height); - - if (CORE.Window.flags & FLAG_VSYNC_HINT) RGFW_window_swapInterval(platform.window, 1); - + //SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height); + + if (CORE.Window.flags & FLAG_VSYNC_HINT) RGFW_window_swapInterval(platform.window, 1); RGFW_window_makeCurrent(platform.window); // Check surface and context activation @@ -1311,12 +1279,6 @@ int InitPlatform(void) 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 { @@ -1366,12 +1328,11 @@ int InitPlatform(void) #ifdef RGFW_X11 for (int i = 0; (i < 4) && (i < MAX_GAMEPADS); i++) { - RGFW_registerJoystick(platform.window, i); + RGFW_registergamepad(platform.window, i); } #endif TRACELOG(LOG_INFO, "PLATFORM: CUSTOM: Initialized successfully"); - return 0; } @@ -1385,6 +1346,6 @@ void ClosePlatform(void) static KeyboardKey ConvertScancodeToKey(u32 keycode) { if (keycode > sizeof(keyMappingRGFW)/sizeof(unsigned short)) return 0; - - return keyMappingRGFW[keycode]; + + return keyMappingRGFW[keycode]; } diff --git a/src/rcore.c b/src/rcore.c index 571abf97c..40167718c 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -12,6 +12,13 @@ * - Windows (Win32, Win64) * - Linux (X11/Wayland desktop mode) * - Others (not tested) +* > PLATFORM_DESKTOP_RGFW (RGFW backend): +* - Windows (Win32, Win64) +* - Linux (X11/Wayland desktop mode) +* - macOS/OSX (x64, arm64) +* - Others (not tested) +* > PLATFORM_WEB_RGFW: +* - HTML5 (WebAssembly) * > PLATFORM_WEB: * - HTML5 (WebAssembly) * > PLATFORM_DRM: @@ -85,12 +92,12 @@ //---------------------------------------------------------------------------------- // Feature Test Macros required for this module //---------------------------------------------------------------------------------- -#if (defined(__linux__) || defined(PLATFORM_WEB)) && (_XOPEN_SOURCE < 500) +#if (defined(__linux__) || defined(PLATFORM_WEB) || defined(PLATFORM_WEB_RGFW)) && (_XOPEN_SOURCE < 500) #undef _XOPEN_SOURCE #define _XOPEN_SOURCE 500 // Required for: readlink if compiled with c99 without gnu ext. #endif -#if (defined(__linux__) || defined(PLATFORM_WEB)) && (_POSIX_C_SOURCE < 199309L) +#if (defined(__linux__) || defined(PLATFORM_WEB) || defined(PLATFORM_WEB_RGFW)) && (_POSIX_C_SOURCE < 199309L) #undef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 199309L // Required for: CLOCK_MONOTONIC if compiled with c99 without gnu ext. #endif @@ -540,7 +547,7 @@ const char *TextFormat(const char *text, ...); // Formatting of tex #include "platforms/rcore_desktop_glfw.c" #elif defined(PLATFORM_DESKTOP_SDL) #include "platforms/rcore_desktop_sdl.c" -#elif defined(PLATFORM_DESKTOP_RGFW) +#elif (defined(PLATFORM_DESKTOP_RGFW) || defined(PLATFORM_WEB_RGFW)) #include "platforms/rcore_desktop_rgfw.c" #elif defined(PLATFORM_WEB) #include "platforms/rcore_web.c" @@ -611,6 +618,8 @@ void InitWindow(int width, int height, const char *title) TRACELOG(LOG_INFO, "Platform backend: DESKTOP (SDL)"); #elif defined(PLATFORM_DESKTOP_RGFW) TRACELOG(LOG_INFO, "Platform backend: DESKTOP (RGFW)"); +#elif defined(PLATFORM_WEB_RGFW) + TRACELOG(LOG_INFO, "Platform backend: WEB (RGFW) (HTML5)"); #elif defined(PLATFORM_WEB) TRACELOG(LOG_INFO, "Platform backend: WEB (HTML5)"); #elif defined(PLATFORM_DRM) @@ -3573,7 +3582,7 @@ void SetupViewport(int width, int height) // NOTE: Global variables CORE.Window.render.width/CORE.Window.render.height and CORE.Window.renderOffset.x/CORE.Window.renderOffset.y can be modified void SetupFramebuffer(int width, int height) { - // Calculate CORE.Window.render.width and CORE.Window.render.height, we have the display size (input params) and the desired screen size (global var) + // Calculate CORE.Window.render.width and CORE.Window.render.height, we have the display size (input params) and the desired screen size (global var) if ((CORE.Window.screen.width > CORE.Window.display.width) || (CORE.Window.screen.height > CORE.Window.display.height)) { TRACELOG(LOG_WARNING, "DISPLAY: Downscaling required: Screen size (%ix%i) is bigger than display size (%ix%i)", CORE.Window.screen.width, CORE.Window.screen.height, CORE.Window.display.width, CORE.Window.display.height);