diff --git a/.github/workflows/webassembly.yml b/.github/workflows/webassembly.yml index b50cd8c46..9374cb9eb 100644 --- a/.github/workflows/webassembly.yml +++ b/.github/workflows/webassembly.yml @@ -27,7 +27,7 @@ jobs: uses: actions/checkout@master - name: Setup emsdk - uses: mymindstorm/setup-emsdk@v11 + uses: mymindstorm/setup-emsdk@v12 with: version: 3.1.30 actions-cache-folder: 'emsdk-cache' diff --git a/BINDINGS.md b/BINDINGS.md index bdd5e2558..28e2c542e 100644 --- a/BINDINGS.md +++ b/BINDINGS.md @@ -12,6 +12,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to | Raylib-CsLo | 4.2 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 | https://github.com/NotNotTech/Raylib-CsLo | | cl-raylib | 4.0 | [Common Lisp](https://common-lisp.net/) | MIT | https://github.com/longlene/cl-raylib | | claylib/wrap | **4.5** | [Common Lisp](https://common-lisp.net/) | Zlib | https://github.com/defun-games/claylib | +| claw-raylib | **auto** | [Common Lisp](https://common-lisp.net/) | Apache-2.0 | https://github.com/bohonghuang/claw-raylib | | chez-raylib | **auto** | [Chez Scheme](https://cisco.github.io/ChezScheme/) | GPLv3 | https://github.com/Yunoinsky/chez-raylib | | raylib-cr | **4.6-dev (5e1a81)** | [Crystal](https://crystal-lang.org/) | Apache-2.0 | https://github.com/sol-vin/raylib-cr | | ray-cyber | 4.5 | [Cyber](https://cyberscript.dev) | MIT | https://github.com/fubark/ray-cyber | @@ -37,7 +38,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to | raylib-j | 4.0 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | Zlib | https://github.com/CreedVI/Raylib-J | | raylib.jl | 4.2 | [Julia](https://julialang.org/) | Zlib | https://github.com/irishgreencitrus/raylib.jl | | kaylib | 3.7 | [Kotlin/native](https://kotlinlang.org) | ? | https://github.com/electronstudio/kaylib | -| kaylib | **4.5**| [Kotlin/native](https://kotlinlang.org) | Zlib | https://codeberg.org/Soutaisei/Kaylib | +| KaylibKit | **4.5**| [Kotlin/native](https://kotlinlang.org) | Zlib | https://codeberg.org/Kenta/KaylibKit | | raylib-lua | **4.5** | [Lua](http://www.lua.org/) | ISC | https://github.com/TSnake41/raylib-lua | | raylua | 4.0 | [Lua](http://www.lua.org/) | MIT | https://github.com/Rabios/raylua | | nelua-raylib | 4.0 | [nelua](https://nelua.io/) | MIT | https://github.com/AKDev21/nelua-raylib | diff --git a/src/build.zig b/src/build.zig index 09d954bf5..27250f5ff 100644 --- a/src/build.zig +++ b/src/build.zig @@ -6,7 +6,6 @@ pub fn addRaylib(b: *std.Build, target: std.zig.CrossTarget, optimize: std.built "-std=gnu99", "-D_GNU_SOURCE", "-DGL_SILENCE_DEPRECATION=199309L", - "-fno-sanitize=undefined", // https://github.com/raysan5/raylib/issues/1891 }; const raylib = b.addStaticLibrary(.{ diff --git a/src/raylib.h b/src/raylib.h index 4f3e35380..07b64aeb6 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -918,8 +918,8 @@ typedef enum { // Callbacks to hook some internal functions // WARNING: These callbacks are intended for advance users typedef void (*TraceLogCallback)(int logLevel, const char *text, va_list args); // Logging: Redirect trace log messages -typedef unsigned char *(*LoadFileDataCallback)(const char *fileName, unsigned int *bytesRead); // FileIO: Load binary data -typedef bool (*SaveFileDataCallback)(const char *fileName, void *data, unsigned int bytesToWrite); // FileIO: Save binary data +typedef unsigned char *(*LoadFileDataCallback)(const char *fileName, int *dataSize); // FileIO: Load binary data +typedef bool (*SaveFileDataCallback)(const char *fileName, void *data, int dataSize); // FileIO: Save binary data typedef char *(*LoadFileTextCallback)(const char *fileName); // FileIO: Load text data typedef bool (*SaveFileTextCallback)(const char *fileName, char *text); // FileIO: Save text data @@ -961,6 +961,7 @@ RLAPI void SetWindowTitle(const char *title); // Set title f RLAPI void SetWindowPosition(int x, int y); // Set window position on screen (only PLATFORM_DESKTOP) RLAPI void SetWindowMonitor(int monitor); // Set monitor for the current window RLAPI void SetWindowMinSize(int width, int height); // Set window minimum dimensions (for FLAG_WINDOW_RESIZABLE) +RLAPI void SetWindowMaxSize(int width, int height); // Set window maximum dimensions (for FLAG_WINDOW_RESIZABLE) RLAPI void SetWindowSize(int width, int height); // Set window dimensions RLAPI void SetWindowOpacity(float opacity); // Set window opacity [0.0f..1.0f] (only PLATFORM_DESKTOP) RLAPI void SetWindowFocused(void); // Set window focused (only PLATFORM_DESKTOP) diff --git a/src/rcore.c b/src/rcore.c index 6ba4d8204..05a0853ad 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -1312,9 +1312,36 @@ void SetWindowMonitor(int monitor) // Set window minimum dimensions (FLAG_WINDOW_RESIZABLE) void SetWindowMinSize(int width, int height) { + CORE.Window.windowMin.width = width; + CORE.Window.windowMin.height = height; #if defined(PLATFORM_DESKTOP) - const GLFWvidmode *mode = glfwGetVideoMode(glfwGetPrimaryMonitor()); - glfwSetWindowSizeLimits(CORE.Window.handle, width, height, mode->width, mode->height); + int minWidth = (CORE.Window.windowMin.width == 0) ? GLFW_DONT_CARE : CORE.Window.windowMin.width; + int minHeight = (CORE.Window.windowMin.height == 0) ? GLFW_DONT_CARE : CORE.Window.windowMin.height; + int maxWidth = (CORE.Window.windowMax.width == 0) ? GLFW_DONT_CARE : CORE.Window.windowMax.width; + int maxHeight = (CORE.Window.windowMax.height == 0) ? GLFW_DONT_CARE : CORE.Window.windowMax.height; + glfwSetWindowSizeLimits(CORE.Window.handle, minWidth, minHeight, maxWidth, maxHeight); +#endif +#if defined(PLATFORM_WEB) + // Trigger the resize event once to update the window minimum width and height + if ((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) != 0) EmscriptenResizeCallback(EMSCRIPTEN_EVENT_RESIZE, NULL, NULL); +#endif +} + +// Set window maximum dimensions (FLAG_WINDOW_RESIZABLE) +void SetWindowMaxSize(int width, int height) +{ + CORE.Window.windowMax.width = width; + CORE.Window.windowMax.height = height; +#if defined(PLATFORM_DESKTOP) + int minWidth = (CORE.Window.windowMin.width == 0) ? GLFW_DONT_CARE : CORE.Window.windowMin.width; + int minHeight = (CORE.Window.windowMin.height == 0) ? GLFW_DONT_CARE : CORE.Window.windowMin.height; + int maxWidth = (CORE.Window.windowMax.width == 0) ? GLFW_DONT_CARE : CORE.Window.windowMax.width; + int maxHeight = (CORE.Window.windowMax.height == 0) ? GLFW_DONT_CARE : CORE.Window.windowMax.height; + glfwSetWindowSizeLimits(CORE.Window.handle, minWidth, minHeight, maxWidth, maxHeight); +#endif +#if defined(PLATFORM_WEB) + // Trigger the resize event once to update the window maximum width and height + if ((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) != 0) EmscriptenResizeCallback(EMSCRIPTEN_EVENT_RESIZE, NULL, NULL); #endif } @@ -2707,7 +2734,7 @@ bool DirectoryExists(const char *dirPath) int GetFileLength(const char *fileName) { int size = 0; - + // NOTE: On Unix-like systems, it can by used the POSIX system call: stat(), // but depending on the platform that call could not be available //struct stat result = { 0 }; @@ -2720,11 +2747,11 @@ int GetFileLength(const char *fileName) { fseek(file, 0L, SEEK_END); long int fileSize = ftell(file); - + // Check for size overflow (INT_MAX) if (fileSize > 2147483647) TRACELOG(LOG_WARNING, "[%s] File size overflows expected limit, do not use GetFileLength()", fileName); else size = (int)fileSize; - + fclose(file); } @@ -3290,12 +3317,12 @@ bool IsKeyPressed(int key) bool IsKeyPressedRepeat(int key) { bool repeat = false; - + if ((key > 0) && (key < MAX_KEYBOARD_KEYS)) { if (CORE.Input.Keyboard.keyRepeatInFrame[key] == 1) repeat = true; } - + return repeat; } @@ -3303,12 +3330,12 @@ bool IsKeyPressedRepeat(int key) bool IsKeyDown(int key) { bool down = false; - + if ((key > 0) && (key < MAX_KEYBOARD_KEYS)) { if (CORE.Input.Keyboard.currentKeyState[key] == 1) down = true; } - + return down; } @@ -3316,7 +3343,7 @@ bool IsKeyDown(int key) bool IsKeyReleased(int key) { bool released = false; - + if ((key > 0) && (key < MAX_KEYBOARD_KEYS)) { if ((CORE.Input.Keyboard.previousKeyState[key] == 1) && (CORE.Input.Keyboard.currentKeyState[key] == 0)) released = true; @@ -3329,12 +3356,12 @@ bool IsKeyReleased(int key) bool IsKeyUp(int key) { bool up = false; - + if ((key > 0) && (key < MAX_KEYBOARD_KEYS)) { if (CORE.Input.Keyboard.currentKeyState[key] == 0) up = true; } - + return up; } @@ -3412,7 +3439,7 @@ const char *GetGamepadName(int gamepad) if (CORE.Input.Gamepad.ready[gamepad]) name = glfwGetJoystickName(gamepad); #endif #if defined(PLATFORM_DRM) - if (CORE.Input.Gamepad.ready[gamepad]) + if (CORE.Input.Gamepad.ready[gamepad]) { ioctl(CORE.Input.Gamepad.streamId[gamepad], JSIOCGNAME(64), &CORE.Input.Gamepad.name[gamepad]); name = CORE.Input.Gamepad.name[gamepad]; @@ -3586,7 +3613,7 @@ int GetMouseY(void) Vector2 GetMousePosition(void) { Vector2 position = { 0 }; - + // TODO: Review touch position on PLATFORM_WEB #if defined(PLATFORM_ANDROID) //|| defined(PLATFORM_WEB) @@ -3745,6 +3772,12 @@ static bool InitGraphicsDevice(int width, int height) CORE.Window.screen.height = height; // User desired height CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default + // Set the window minimum and maximum default values to 0 + CORE.Window.windowMin.width = 0; + CORE.Window.windowMin.height = 0; + CORE.Window.windowMax.width = 0; + CORE.Window.windowMax.height = 0; + // NOTE: Framebuffer (render area - CORE.Window.render.width, CORE.Window.render.height) could include black bars... // ...in top-down or left-right to match display aspect ratio (no weird scaling) diff --git a/src/rtext.c b/src/rtext.c index 146fc68f4..fb8440131 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -1676,6 +1676,7 @@ const char *TextToPascal(const char *text) { // Upper case first character if ((text[0] >= 'a') && (text[0] <= 'z')) buffer[0] = text[0] - 32; + else buffer[0] = text[0]; // Check for next separator to upper case another character for (int i = 1, j = 1; (i < MAX_TEXT_BUFFER_LENGTH - 1) && (text[j] != '\0'); i++, j++) diff --git a/src/rtextures.c b/src/rtextures.c index 4e2fdbd91..a6741ee2a 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -322,9 +322,10 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int Image LoadImageSvg(const char *fileNameOrString, int width, int height) { Image image = { 0 }; + +#if defined(SUPPORT_FILEFORMAT_SVG) bool isSvgStringValid = false; -#if defined(SUPPORT_FILEFORMAT_SVG) // Validate fileName or string if (fileNameOrString != NULL) { @@ -3481,7 +3482,7 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color // Destination rectangle out-of-bounds security checks if (dstRec.x < 0) { - srcRec.x = -dstRec.x; + srcRec.x -= dstRec.x; srcRec.width += dstRec.x; dstRec.x = 0; } @@ -3489,7 +3490,7 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color if (dstRec.y < 0) { - srcRec.y = -dstRec.y; + srcRec.y -= dstRec.y; srcRec.height += dstRec.y; dstRec.y = 0; }