38 Commits

Author SHA1 Message Date
34b06ca587 Update BINDINGS.md (#5887) 2026-05-25 16:05:20 +02:00
4d845608b8 Update listed Raylib version for zig bindings (#5886)
As per the README at https://github.com/raylib-zig/raylib-zig, raylib-zig now supports raylib 6.0
2026-05-25 08:32:52 +02:00
Ray
eaf32c83bf REXM: Latest w64devkit supports make directly, simplifying code to avoid mingw32-make 2026-05-25 00:26:26 +02:00
808e6b9b20 Raylib-lua version to 5.5 (#5884)
raylib-lua from 5.0 to 5.5 in bindings.
2026-05-24 17:36:12 +02:00
7dd72e7328 rlparser: update raylib_api.* by CI 2026-05-24 07:25:01 +00:00
Ray
f8270483e1 Merge branch 'master' of https://github.com/raysan5/raylib 2026-05-24 09:24:33 +02:00
Ray
f17babfe8a REVIEWED: #5879 2026-05-24 09:24:26 +02:00
f65d5ad7a9 rshapes: fix auto segment rounded-corner math and rounding (#5883) 2026-05-24 08:55:08 +02:00
Ray
0d78f10161 Reviewed comments formating 2026-05-20 09:16:16 +02:00
7d5b61ce01 [rlsw][SEGFAULT] Fix triangle and quad spans applying pixels out of bounds (#5849)
* fix triangle and quad spans applying pixels out of bounds

* remove off by one errors on x/y LoopMax

* apply the RASTER_QUAD offset at the loop start so it increments correctly

* fix missing endif

* remove include guard to allow dyMin usage

* early exit if nothing to draw on a span

* incorporate dxStart into xSubstep to make xOffset calculate a single time

* remove ghost comment

* early exit for quads, with a float cast on the left and top distance calculation

* remove duplicate xLoopEnd
2026-05-20 09:12:20 +02:00
Ray
b48933b096 Merge branch 'master' of https://github.com/raysan5/raylib 2026-05-19 18:59:30 +02:00
Ray
fd1dfd7d65 ADDED: rprand_get_value_raw() 2026-05-19 18:59:23 +02:00
be56f2c524 [rcore][GLFW] Fix GetClipboardImage() creating new connection under X11 (#5871)
* Improve GetClipboardImage implementation under X11

* Remove code for creating new connection, handle selection in GLFW connection instead.

* `GetClipboardImage()`: Small fix to remove unnecessary boolean
2026-05-19 18:57:42 +02:00
d31c10a01e Adjust segment calculation in DrawRectangleRounded to be consistent with DrawRectangleRoundedLinesEx (#5875) 2026-05-19 18:48:28 +02:00
c04e57399a Fix compilation for -DPLATFORM=RGFW (#5870)
When compiling with
cmake -S . -B build-desktop-rgfw -DPLATFORM=RGFW -DCMAKE_BUILD_TYPE=Release
cmake --build build-desktop-rgfw

these errors appeared:
raylib/examples/others/raylib_opengl_interop.c💯5: error: unknown type name ‘GLuint’
  100 |     GLuint vao = 0;
[etc]
2026-05-15 17:40:26 +02:00
6c090f6193 Fix build.zig building examples all the time (#5869) 2026-05-15 17:39:27 +02:00
Ray
5ca45bce37 Update rcore.c 2026-05-14 20:05:25 +02:00
Ray
729327a078 Update .gitignore 2026-05-14 20:05:21 +02:00
ea76845ecb [cmake]: remove GLFW_BUILD warnings for when platform is SDL (#5865) 2026-05-14 13:02:38 +02:00
5506aed190 BINDINGS.md: update golang binding to v6.0 (#5866) 2026-05-14 13:00:40 +02:00
Ray
43366d1c6a Some formatting tweaks 2026-05-13 09:28:08 +02:00
Ray
f35f4b9fad REVIEWED: GetTime(), small addition for RPI Pico 2 2026-05-13 09:17:04 +02:00
Ray
c4b4fcc17e Format review 2026-05-13 09:16:29 +02:00
Ray
fbf132d1d1 Use rlgl provided interface instead of rlsw direct access 2026-05-13 09:16:19 +02:00
Ray
e274c195af Update rcore.c 2026-05-13 09:15:50 +02:00
fd28dc5644 [rtext] add warning for loadfontex/loadfontfrommemory (#5864)
* add warning for loadfontex/loadfontfrommemory

* bump to re-run build tests
2026-05-13 08:56:13 +02:00
Ray
5aa3de194c Updated miniaudio warnings with emscripten 2026-05-12 20:33:20 +02:00
9400199b80 [rcore][RGFW] Add fullscreen behaviour on size 0 window creation (#5859)
* port glfw's behaviour on size 0 window creation to rgfw

* updates with change suggestions

* don't do the FLAG_FULLSCREEN_MODE check twice for no reason

---------

Co-authored-by: CrackedPixel <5776225+CrackedPixel@users.noreply.github.com>
2026-05-11 23:25:00 +02:00
Ray
200d344dee Merge branch 'master' of https://github.com/raysan5/raylib 2026-05-10 19:31:22 +02:00
Ray
094edcd32e Update Makefile 2026-05-10 19:31:19 +02:00
a005a044da [rcore_android] Restore face-button input on Android gamepads (#5824)
The KEYBOARD-source veto added in #5439 drops face-button key
events that arrive with both AINPUT_SOURCE_KEYBOARD and
AINPUT_SOURCE_GAMEPAD set on the source bitmask. Confirmed
reproducible on GameSir X2 Type-C and 8BitDo Ultimate Bluetooth,
both reporting source 0x501 on every face-button key event.

This source-bit pattern is general AOSP behaviour since Android
3.2 (commit 6f2fba4 in frameworks/base, Feb 2011): EventHub adds
InputDeviceClass::KEYBOARD to any device whose evdev keyBitmask
claims gamepad buttons (BTN_JOYSTICK..BTN_DIGI), and
KeyboardInputMapper::getEventSource stamps the resulting
KEYBOARD|GAMEPAD source on every outgoing key event.

Use AndroidTranslateGamepadButton(keycode) as the discriminator
instead. Recognised gamepad keycodes route to the gamepad path;
unknown keycodes fall through to the keyboard handler.

Assisted-by: Claude:claude-opus-4-7
2026-05-10 19:20:35 +02:00
ae315eecb9 added win32 to cmake + examples (#5855) 2026-05-10 19:09:24 +02:00
dcb0ca5d14 [raudio]: free converterResidual in UnloadSoundAlias to prevent leak (#5857)
The example audio_sound_multi was leaking memory every single time the spacebar was pressed.

```c
Direct leak of 576 byte(s) in 9 object(s) allocated from:
    #0 0x758a41019447 in calloc (/usr/lib/liblsan.so.0+0x19447) (BuildId: 8ee115309adc591d231c961c43d245cfa68d9aa7)
    #1 0x562dfbd2c4f3 in LoadAudioBuffer (/home/peter/raylib/examples/audio/audio_sound_multi+0xfa4f3) (BuildId: ea2a6f45d724abeccf904143a32012266f259f93)
```

This patch fixes that leak.
2026-05-10 15:01:38 +02:00
07b729d5d6 fix: check fread return value in jar_mod_load_file (#5840) 2026-05-09 18:55:02 +02:00
cd4599b447 Update BINDINGS.md (#5850) 2026-05-09 18:48:10 +02:00
Ray
b2ea5eae5e REVIEWED: long long usage in all raylib, minimize
REVIEWED: Using `long long` format instead of `long long int`, more consistent with the `short` alternative for smaller `int`, instead of `short int`
2026-05-08 22:59:55 +02:00
mjt
29ff1f02e9 Update Makefile comment (#5846) 2026-05-08 20:19:08 +02:00
d840a100a7 [CMake] Add configure-time test for libatomic requirement (#5847)
CMake now checks if -latomic is required for 64-bit atomics, and links
it if it's required. Miniaudio is the only thing in raylib that needs
it, so it's put behind SUPPORT_MODULE_RAUDIO.
2026-05-08 20:16:45 +02:00
32 changed files with 418 additions and 264 deletions

2
.gitignore vendored
View File

@ -65,7 +65,7 @@ src/external/SDL3
# Emscripten # Emscripten
emsdk emsdk
# Ignore wasm data in examples/ # Ignore binaries generated in examples/
examples/**/* examples/**/*
!examples/**/*.* !examples/**/*.*
!examples/**/*/ !examples/**/*/

View File

@ -11,7 +11,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| [raylib-beef](https://github.com/Starpelly/raylib-beef) | **5.5** | [Beef](https://www.beeflang.org) | MIT | | [raylib-beef](https://github.com/Starpelly/raylib-beef) | **5.5** | [Beef](https://www.beeflang.org) | MIT |
| [raybit](https://github.com/Alex-Velez/raybit) | **5.0** | [Brainfuck](https://en.wikipedia.org/wiki/Brainfuck) | MIT | | [raybit](https://github.com/Alex-Velez/raybit) | **5.0** | [Brainfuck](https://en.wikipedia.org/wiki/Brainfuck) | MIT |
| [raylib-c3](https://github.com/c3lang/vendor/tree/main/libraries/raylib6.c3l) | **6** | [C3](https://c3-lang.org) | MIT | | [raylib-c3](https://github.com/c3lang/vendor/tree/main/libraries/raylib6.c3l) | **6** | [C3](https://c3-lang.org) | MIT |
| [raylib-cs](https://github.com/raylib-cs/raylib-cs) | **5.5** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | Zlib | | [raylib-cs](https://github.com/raylib-cs/raylib-cs) | **6.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | Zlib |
| [Raylib-CsLo](https://github.com/NotNotTech/Raylib-CsLo) | 4.2 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 | | [Raylib-CsLo](https://github.com/NotNotTech/Raylib-CsLo) | 4.2 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 |
| [Raylib-CSharp-Vinculum](https://github.com/ZeroElectric/Raylib-CSharp-Vinculum) | **5.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 | | [Raylib-CSharp-Vinculum](https://github.com/ZeroElectric/Raylib-CSharp-Vinculum) | **5.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 |
| [Raylib-CSharp](https://github.com/MrScautHD/Raylib-CSharp) | **5.5** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MIT | | [Raylib-CSharp](https://github.com/MrScautHD/Raylib-CSharp) | **5.5** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MIT |
@ -37,7 +37,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| [raylib-freebasic](https://github.com/WIITD/raylib-freebasic) | **5.0** | [FreeBASIC](https://www.freebasic.net) | MIT | | [raylib-freebasic](https://github.com/WIITD/raylib-freebasic) | **5.0** | [FreeBASIC](https://www.freebasic.net) | MIT |
| [raylib.f](https://github.com/cthulhuology/raylib.f) | **5.5** | [Forth](https://forth.com) | Zlib | | [raylib.f](https://github.com/cthulhuology/raylib.f) | **5.5** | [Forth](https://forth.com) | Zlib |
| [fortran-raylib](https://github.com/interkosmos/fortran-raylib) | **5.5** | [Fortran](https://fortran-lang.org) | ISC | | [fortran-raylib](https://github.com/interkosmos/fortran-raylib) | **5.5** | [Fortran](https://fortran-lang.org) | ISC |
| [raylib-go](https://github.com/gen2brain/raylib-go) | **5.5** | [Go](https://golang.org) | Zlib | | [raylib-go](https://github.com/gen2brain/raylib-go) | **6.0** | [Go](https://golang.org) | Zlib |
| [raylib-guile](https://github.com/petelliott/raylib-guile) | **auto** | [Guile](https://www.gnu.org/software/guile) | Zlib | | [raylib-guile](https://github.com/petelliott/raylib-guile) | **auto** | [Guile](https://www.gnu.org/software/guile) | Zlib |
| [gforth-raylib](https://github.com/ArnautDaniel/gforth-raylib) | 3.5 | [Gforth](https://gforth.org) | **???** | | [gforth-raylib](https://github.com/ArnautDaniel/gforth-raylib) | 3.5 | [Gforth](https://gforth.org) | **???** |
| [h-raylib](https://github.com/Anut-py/h-raylib) | **5.5-dev** | [Haskell](https://haskell.org) | Apache-2.0 | | [h-raylib](https://github.com/Anut-py/h-raylib) | **5.5-dev** | [Haskell](https://haskell.org) | Apache-2.0 |
@ -49,7 +49,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| [Raylib.jl](https://github.com/chengchingwen/Raylib.jl) | 4.2 | [Julia](https://julialang.org) | Zlib | | [Raylib.jl](https://github.com/chengchingwen/Raylib.jl) | 4.2 | [Julia](https://julialang.org) | Zlib |
| [kaylib](https://github.com/electronstudio/kaylib) | 3.7 | [Kotlin/native](https://kotlinlang.org) | **???** | | [kaylib](https://github.com/electronstudio/kaylib) | 3.7 | [Kotlin/native](https://kotlinlang.org) | **???** |
| [KaylibKit](https://codeberg.org/Kenta/KaylibKit) | 4.5 | [Kotlin/native](https://kotlinlang.org) | Zlib | | [KaylibKit](https://codeberg.org/Kenta/KaylibKit) | 4.5 | [Kotlin/native](https://kotlinlang.org) | Zlib |
| [raylib-lua](https://github.com/TSnake41/raylib-lua) | 5.0 | [Lua](http://www.lua.org) | ISC | | [raylib-lua](https://github.com/TSnake41/raylib-lua) | 5.5 | [Lua](http://www.lua.org) | ISC |
| [raylib-lua-bindings (WIP)](https://github.com/legendaryredfox/raylib-lua-bindings) | 5.5 | [Lua](http://www.lua.org) | ISC | | [raylib-lua-bindings (WIP)](https://github.com/legendaryredfox/raylib-lua-bindings) | 5.5 | [Lua](http://www.lua.org) | ISC |
| [ReiLua](https://github.com/nullstare/ReiLua) | 5.5 | [Lua](http://www.lua.org) | MIT | | [ReiLua](https://github.com/nullstare/ReiLua) | 5.5 | [Lua](http://www.lua.org) | MIT |
| [raylib-lua-sol](https://github.com/RobLoach/raylib-lua-sol) | 5.5 | [Lua](http://www.lua.org) | Zlib | | [raylib-lua-sol](https://github.com/RobLoach/raylib-lua-sol) | 5.5 | [Lua](http://www.lua.org) | Zlib |
@ -90,7 +90,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| [raylib-vapi](https://github.com/lxmcf/raylib-vapi) | **6.0** | [Vala](https://vala.dev) | Zlib | | [raylib-vapi](https://github.com/lxmcf/raylib-vapi) | **6.0** | [Vala](https://vala.dev) | Zlib |
| [raylib-wave](https://github.com/wavefnd/raylib-wave) | **auto** |[Wave](http://wave-lang.dev) | Zlib | | [raylib-wave](https://github.com/wavefnd/raylib-wave) | **auto** |[Wave](http://wave-lang.dev) | Zlib |
| [raylib-wren](https://github.com/TSnake41/raylib-wren) | 4.5 | [Wren](http://wren.io) | ISC | | [raylib-wren](https://github.com/TSnake41/raylib-wren) | 4.5 | [Wren](http://wren.io) | ISC |
| [raylib-zig](https://github.com/raylib-zig/raylib-zig) | **5.6-dev** | [Zig](https://ziglang.org) | MIT | | [raylib-zig](https://github.com/raylib-zig/raylib-zig) | **6.0** | [Zig](https://ziglang.org) | MIT |
| [raylib.zig](https://github.com/ryupold/raylib.zig) | **5.1-dev** | [Zig](https://ziglang.org) | MIT | | [raylib.zig](https://github.com/ryupold/raylib.zig) | **5.1-dev** | [Zig](https://ziglang.org) | MIT |
| [raylib-zig-bindings](https://github.com/L-Briand/raylib-zig-bindings) | **5.0** | [Zig](https://ziglang.org) | Zlib | | [raylib-zig-bindings](https://github.com/L-Briand/raylib-zig-bindings) | **5.0** | [Zig](https://ziglang.org) | Zlib |
| [hare-raylib](https://git.sr.ht/~evantj/hare-raylib) | **auto** | [Hare](https://harelang.org) | Zlib | | [hare-raylib](https://git.sr.ht/~evantj/hare-raylib) | **auto** | [Hare](https://harelang.org) | Zlib |
@ -106,6 +106,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| [fnl-raylib](https://github.com/0riginaln0/fnl-raylib) | **5.5** | [Fennel](https://fennel-lang.org/) | MIT | | [fnl-raylib](https://github.com/0riginaln0/fnl-raylib) | **5.5** | [Fennel](https://fennel-lang.org/) | MIT |
| [Rayua](https://github.com/uiua-lang/rayua) | **5.5** | [Uiua](https://www.uiua.org/) | **???** | | [Rayua](https://github.com/uiua-lang/rayua) | **5.5** | [Uiua](https://www.uiua.org/) | **???** |
| [Target](https://github.com/FinnDemonCat/Target/tree/main/libs/raylib) | **5.5** | [Dart](https://dart.dev/) | Apache-2.0 license | | [Target](https://github.com/FinnDemonCat/Target/tree/main/libs/raylib) | **5.5** | [Dart](https://dart.dev/) | Apache-2.0 license |
| [gclang-raylib](https://github.com/gnuchanos/gcLang_Compiler/tree/main/windows_version/raylib_version)| **6.0** | [gclang](https://github.com/gnuchanos/gcLang_Compiler) | AGPL-3.0 |
### Utility Wrapers ### Utility Wrapers

View File

@ -29,7 +29,7 @@ include(CompilerFlags)
# Registers build options that are exposed to cmake # Registers build options that are exposed to cmake
include(CMakeOptions.txt) include(CMakeOptions.txt)
if (UNIX AND NOT APPLE AND NOT "${PLATFORM}" MATCHES "DRM" AND NOT "${PLATFORM}" MATCHES "Web") if (UNIX AND NOT APPLE AND NOT "${PLATFORM}" MATCHES "DRM" AND NOT "${PLATFORM}" MATCHES "Web" AND NOT "${PLATFORM}" MATCHES "SDL")
if (NOT GLFW_BUILD_WAYLAND AND NOT GLFW_BUILD_X11) if (NOT GLFW_BUILD_WAYLAND AND NOT GLFW_BUILD_X11)
message(FATAL_ERROR "Cannot disable both Wayland and X11") message(FATAL_ERROR "Cannot disable both Wayland and X11")
endif() endif()

View File

@ -6,7 +6,7 @@ if(EMSCRIPTEN)
# When configuring web builds with "emcmake cmake -B build -S .", set PLATFORM to Web by default # When configuring web builds with "emcmake cmake -B build -S .", set PLATFORM to Web by default
SET(PLATFORM Web CACHE STRING "Platform to build for.") SET(PLATFORM Web CACHE STRING "Platform to build for.")
endif() endif()
enum_option(PLATFORM "Desktop;Web;WebRGFW;Android;Raspberry Pi;DRM;SDL;RGFW;Memory" "Platform to build for.") enum_option(PLATFORM "Desktop;Win32;Web;WebRGFW;Android;Raspberry Pi;DRM;SDL;RGFW;Memory" "Platform to build for.")
enum_option(OPENGL_VERSION "OFF;4.3;3.3;2.1;1.1;ES 2.0;ES 3.0;Software" "Force a specific OpenGL Version?") enum_option(OPENGL_VERSION "OFF;4.3;3.3;2.1;1.1;ES 2.0;ES 3.0;Software" "Force a specific OpenGL Version?")

View File

@ -739,7 +739,6 @@ fn addExamples(
.root_module = exe_mod, .root_module = exe_mod,
.use_lld = target.result.os.tag == .windows, .use_lld = target.result.os.tag == .windows,
}); });
b.installArtifact(exe);
const install_cmd = b.addInstallArtifact(exe, .{ .dest_sub_path = b.fmt("{s}/{s}", .{ module, filename }) }); const install_cmd = b.addInstallArtifact(exe, .{ .dest_sub_path = b.fmt("{s}/{s}", .{ module, filename }) });

View File

@ -7,6 +7,30 @@ if(POLICY CMP0072)
cmake_policy(SET CMP0072 NEW) cmake_policy(SET CMP0072 NEW)
endif() endif()
include(CheckCSourceCompiles)
include(CMakePushCheckState)
function(raylib_check_libatomic_required result)
set(_atomic_test_source "
int main(void)
{
volatile long long value = 0;
return (int)__atomic_fetch_add(&value, 1, __ATOMIC_SEQ_CST);
}")
check_c_source_compiles("${_atomic_test_source}" RAYLIB_ATOMICS_WITHOUT_LIBATOMIC)
if (RAYLIB_ATOMICS_WITHOUT_LIBATOMIC)
set(${result} FALSE PARENT_SCOPE)
else ()
cmake_push_check_state()
list(APPEND CMAKE_REQUIRED_LIBRARIES atomic)
check_c_source_compiles("${_atomic_test_source}" RAYLIB_ATOMICS_WITH_LIBATOMIC)
cmake_pop_check_state()
set(${result} ${RAYLIB_ATOMICS_WITH_LIBATOMIC} PARENT_SCOPE)
endif ()
endfunction()
set(RAYLIB_DEPENDENCIES "include(CMakeFindDependencyMacro)") set(RAYLIB_DEPENDENCIES "include(CMakeFindDependencyMacro)")
if (${PLATFORM} STREQUAL "Desktop") if (${PLATFORM} STREQUAL "Desktop")
@ -67,6 +91,21 @@ if (${PLATFORM} STREQUAL "Desktop")
endif () endif ()
endif () endif ()
elseif (${PLATFORM} STREQUAL "Win32")
if ((NOT WIN32) AND (NOT CMAKE_C_COMPILER MATCHES "mingw|mingw32|mingw64"))
message(FATAL_ERROR "Win32 platform requires Windows or a cross compiler.")
endif ()
set(PLATFORM_CPP "PLATFORM_DESKTOP_WIN32")
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
if (${OPENGL_VERSION} MATCHES "Software")
set(GRAPHICS "GRAPHICS_API_OPENGL_SOFTWARE")
endif ()
find_package(OpenGL QUIET)
set(LIBS_PRIVATE ${OPENGL_LIBRARIES} winmm)
elseif (${PLATFORM} STREQUAL "Web") elseif (${PLATFORM} STREQUAL "Web")
set(PLATFORM_CPP "PLATFORM_WEB") set(PLATFORM_CPP "PLATFORM_WEB")
if(NOT GRAPHICS) if(NOT GRAPHICS)
@ -222,6 +261,14 @@ endif ()
set(LIBS_PRIVATE ${LIBS_PRIVATE} ${OPENAL_LIBRARY}) set(LIBS_PRIVATE ${LIBS_PRIVATE} ${OPENAL_LIBRARY})
if (SUPPORT_MODULE_RAUDIO AND UNIX AND NOT APPLE)
raylib_check_libatomic_required(RAYLIB_LIBATOMIC_REQUIRED)
if (RAYLIB_LIBATOMIC_REQUIRED)
message(STATUS "64-bit atomics require libatomic")
list(APPEND LIBS_PRIVATE atomic)
endif ()
endif ()
if (${PLATFORM} MATCHES "Desktop") if (${PLATFORM} MATCHES "Desktop")
set(LIBS_PRIVATE ${LIBS_PRIVATE} glfw) set(LIBS_PRIVATE ${LIBS_PRIVATE} glfw)
endif () endif ()

View File

@ -20,6 +20,8 @@
# - Linux (X11 desktop mode) # - Linux (X11 desktop mode)
# - macOS/OSX (x64, arm64 (not tested)) # - macOS/OSX (x64, arm64 (not tested))
# - Others (not tested) # - Others (not tested)
# > PLATFORM_DESKTOP_WIN32 (native Win32):
# - Windows (Win32, Win64)
# > PLATFORM_WEB_RGFW: # > PLATFORM_WEB_RGFW:
# - HTML5 (WebAssembly) # - HTML5 (WebAssembly)
# > PLATFORM_WEB: # > PLATFORM_WEB:
@ -794,6 +796,23 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
rm -f *.o rm -f *.o
endif endif
endif endif
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_WIN32)
ifeq ($(PLATFORM_OS),WINDOWS)
del *.o *.exe /s
endif
ifeq ($(PLATFORM_OS),BSD)
find . -type f -perm -ugo+x -delete
rm -fv *.o
endif
ifeq ($(PLATFORM_OS),LINUX)
find . -type f -executable -delete
rm -fv *.o
endif
ifeq ($(PLATFORM_OS),OSX)
find . -type f -perm +ugo+x -delete
rm -f *.o
endif
endif
ifeq ($(TARGET_PLATFORM),PLATFORM_DRM) ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
find . -type f -executable -delete find . -type f -executable -delete
rm -fv *.o rm -fv *.o

View File

@ -28,7 +28,7 @@
#include "raylib.h" #include "raylib.h"
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_DESKTOP_SDL) #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_DESKTOP_SDL) || defined(PLATFORM_DESKTOP_RGFW)
#if defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_ES2)
#include "glad_gles2.h" // Required for: OpenGL functionality #include "glad_gles2.h" // Required for: OpenGL functionality
#define glGenVertexArrays glGenVertexArraysOES #define glGenVertexArrays glGenVertexArraysOES

View File

@ -119,7 +119,7 @@ USE_EXTERNAL_GLFW ?= FALSE
# Enable support for X11 by default on Linux when using GLFW # Enable support for X11 by default on Linux when using GLFW
# NOTE: Wayland is disabled by default, only enable if you are sure # NOTE: Wayland is disabled by default, only enable if you are sure
GLFW_LINUX_ENABLE_WAYLAND ?= TRUE GLFW_LINUX_ENABLE_WAYLAND ?= FALSE
GLFW_LINUX_ENABLE_X11 ?= TRUE GLFW_LINUX_ENABLE_X11 ?= TRUE
# Enable support for X11 by default on Linux when using RGFW # Enable support for X11 by default on Linux when using RGFW

View File

@ -1538,10 +1538,10 @@ mulong jar_mod_load_file(jar_mod_context_t * modctx, const char* filename)
modctx->modfile = (muchar *) JARMOD_MALLOC(fsize); modctx->modfile = (muchar *) JARMOD_MALLOC(fsize);
modctx->modfilesize = fsize; modctx->modfilesize = fsize;
memset(modctx->modfile, 0, fsize); memset(modctx->modfile, 0, fsize);
fread(modctx->modfile, fsize, 1, f); if(fread(modctx->modfile, fsize, 1, f) != 1) fsize = 0;
fclose(f); fclose(f);
if(!jar_mod_load(modctx, (void *)modctx->modfile, fsize)) fsize = 0; if(fsize && !jar_mod_load(modctx, (void *)modctx->modfile, fsize)) fsize = 0;
} else fsize = 0; } else fsize = 0;
} }
return fsize; return fsize;

View File

@ -41495,11 +41495,11 @@ Web Audio Backend
#ifdef MA_HAS_WEBAUDIO #ifdef MA_HAS_WEBAUDIO
#include <emscripten/emscripten.h> #include <emscripten/emscripten.h>
#if (__EMSCRIPTEN_major__ > 3) || (__EMSCRIPTEN_major__ == 3 && (__EMSCRIPTEN_minor__ > 1 || (__EMSCRIPTEN_minor__ == 1 && __EMSCRIPTEN_tiny__ >= 32))) #if (__EMSCRIPTEN_MAJOR__ > 3) || (__EMSCRIPTEN_MAJOR__ == 3 && (__EMSCRIPTEN_MINOR__ > 1 || (__EMSCRIPTEN_MINOR__ == 1 && __EMSCRIPTEN_TINY__ >= 32)))
#include <emscripten/webaudio.h> #include <emscripten/webaudio.h>
#define MA_SUPPORT_AUDIO_WORKLETS #define MA_SUPPORT_AUDIO_WORKLETS
#if (__EMSCRIPTEN_major__ > 3) || (__EMSCRIPTEN_major__ == 3 && (__EMSCRIPTEN_minor__ > 1 || (__EMSCRIPTEN_minor__ == 1 && __EMSCRIPTEN_tiny__ >= 70))) #if (__EMSCRIPTEN_MAJOR__ > 3) || (__EMSCRIPTEN_MAJOR__ == 3 && (__EMSCRIPTEN_MINOR__ > 1 || (__EMSCRIPTEN_MINOR__ == 1 && __EMSCRIPTEN_TINY__ >= 70)))
#define MA_SUPPORT_AUDIO_WORKLETS_VARIABLE_BUFFER_SIZE #define MA_SUPPORT_AUDIO_WORKLETS_VARIABLE_BUFFER_SIZE
#endif #endif
#endif #endif

139
src/external/rlsw.h vendored
View File

@ -166,16 +166,15 @@
// Fast power-of-two texture wrap (SW_REPEAT mode only) // Fast power-of-two texture wrap (SW_REPEAT mode only)
// When defined, textures whose width/height are powers of two use a bitmask // When defined, textures whose width/height are powers of two use a bitmask
// wrap (`x & (size-1)`) instead of `floorf`-based fractional wrap or the // wrap (`x & (size-1)`) instead of `floorf`-based fractional wrap or the signed `%` chain in the linear sampler
// signed `%` chain in the linear sampler. Saves a software divide on Xtensa // Saves a software divide on Xtensa and a few instructions everywhere
// and a few instructions everywhere. NPOT textures keep using the original // NPOT textures keep using the original path via a runtime `(size & (size-1)) == 0` check,
// path via a runtime `(size & (size-1)) == 0` check, so SW_REPEAT remains // so SW_REPEAT remains correct for them
// correct for them. The only observable behavior change is for POT textures // The only observable behavior change is for POT textures sampled with negative UV coordinates:
// sampled with negative UV coordinates: bitmask wrap (two's complement) can // bitmask wrap (two's complement) can differ from `sw_fract` by one texel
// differ from `sw_fract` by one texel. Off by default to keep bit-for-bit // Off by default to keep bit-for-bit behavior; opt in if you control your asset UVs
// behavior; opt in if you control your asset UVs.
// //
// #define SW_TEXTURE_REPEAT_POT_FAST //#define SW_TEXTURE_REPEAT_POT_FAST
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// OpenGL Compatibility Types // OpenGL Compatibility Types
@ -860,11 +859,9 @@ SWAPI void swGetFramebufferAttachmentParameteriv(SWattachment attachment, SWatta
#endif #endif
// ESP-DSP acceleration: ESP-IDF ships an optimized math library that includes // ESP-DSP acceleration: ESP-IDF ships an optimized math library that includes
// `dspm_mult_4x4x4_f32` (4x4 matrix multiply) and `dspm_mult_4x4x1_f32` // `dspm_mult_4x4x4_f32` (4x4 matrix multiply) and `dspm_mult_4x4x1_f32` (matrix * vector)
// (matrix * vector). These are S3-tuned hand-vectorized kernels that beat the // These are S3-tuned hand-vectorized kernels that beat the scalar versions for both throughput and code-size
// scalar versions for both throughput and code-size. Detection is opt-in to // Detection is opt-in to keep the dependency optional: define SW_USE_ESP_DSP from your build system
// keep the dependency optional: define SW_USE_ESP_DSP from your build system
// (or rely on the `idf_component.yml` example shown in the rlsw docs).
#if defined(ESP_PLATFORM) && defined(SW_USE_ESP_DSP) #if defined(ESP_PLATFORM) && defined(SW_USE_ESP_DSP)
#define SW_HAS_ESP_DSP #define SW_HAS_ESP_DSP
#include "dspm_mult.h" #include "dspm_mult.h"
@ -884,10 +881,10 @@ SWAPI void swGetFramebufferAttachmentParameteriv(SWattachment attachment, SWatta
#define SW_DEG2RAD (SW_PI/180.0f) #define SW_DEG2RAD (SW_PI/180.0f)
#define SW_RAD2DEG (180.0f/SW_PI) #define SW_RAD2DEG (180.0f/SW_PI)
// When clipping a convex polygon against a plane, at most one vertex is added. // When clipping a convex polygon against a plane, at most one vertex is added
// Starting from a quadrilateral (4 vertices), clipped sequentially against // Starting from a quadrilateral (4 vertices), clipped sequentially against
// the frustum (6 planes) then the scissor rectangle (4 planes): // the frustum (6 planes) then the scissor rectangle (4 planes):
// 4 + 6 + 4 = 14 vertices maximum. // 4 + 6 + 4 = 14 vertices maximum
#define SW_MAX_CLIPPED_POLYGON_VERTICES 14 #define SW_MAX_CLIPPED_POLYGON_VERTICES 14
#define SW_CLIP_EPSILON 1e-4f #define SW_CLIP_EPSILON 1e-4f
@ -1175,7 +1172,7 @@ static inline void sw_matrix_mul_rst(float *SW_RESTRICT dst, const float *SW_RES
// column-major, so passing them flat is equivalent to passing transposes: // column-major, so passing them flat is equivalent to passing transposes:
// dspm_mult(L^T, R^T) computes (L^T)*(R^T) = (R*L)^T, written back into a // dspm_mult(L^T, R^T) computes (L^T)*(R^T) = (R*L)^T, written back into a
// flat array gives the same bit pattern as the column-major product (R*L) // flat array gives the same bit pattern as the column-major product (R*L)
// -- exactly the semantic the scalar fallback below has. // -- exactly the semantic the scalar fallback below has
dspm_mult_4x4x4_f32(left, right, dst); dspm_mult_4x4x4_f32(left, right, dst);
#else #else
float l00 = left[0], l01 = left[1], l02 = left[2], l03 = left[3]; float l00 = left[0], l01 = left[1], l02 = left[2], l03 = left[3];
@ -1248,12 +1245,12 @@ static inline float sw_fract(float x)
return (x - floorf(x)); return (x - floorf(x));
} }
// Fast reciprocal: 1-ULP accurate in ~7 instructions on Xtensa using the // Xtensa architecture optimization
// hardware `recip0.s` seed + two Newton-Raphson refinement steps. All work // Fast reciprocal: 1-ULP accurate in ~7 instructions using the
// stays in FPU registers — no `__divsf3` software call. Hot-path divisions // hardware `recip0.s` seed + two Newton-Raphson refinement steps
// in the rasterizer (span/triangle setup, perspective divide, etc.) call // All work stays in FPU registers — no `__divsf3` software call
// this. On non-Xtensa targets it transparently expands to `1.0f / x`, so // Hot-path divisions in the rasterizer (span/triangle setup, perspective divide, etc.) call this
// generated code is identical to before. // On non-Xtensa targets it transparently expands to `1.0f / x`, so generated code is identical to before
#if defined(__XTENSA__) #if defined(__XTENSA__)
__attribute__((always_inline)) __attribute__((always_inline))
static inline float sw_rcp(float x) static inline float sw_rcp(float x)
@ -3558,8 +3555,8 @@ static inline bool sw_quad_face_culling(void)
// winding in the projected space when all w > 0 // winding in the projected space when all w > 0
// A value of 0 for sgnArea means P0, P1, P2 are collinear in (x, y, w) // A value of 0 for sgnArea means P0, P1, P2 are collinear in (x, y, w)
// space, which corresponds to a degenerate triangle projection // space, which corresponds to a degenerate triangle projection
// Such quads might also be degenerate or non-planar. They are typically // Such quads might also be degenerate or non-planar
// not culled by this test (0 < 0 is false, 0 > 0 is false) // They are typically not culled by this test (0 < 0 is false, 0 > 0 is false)
// and should be handled by the clipper if necessary // and should be handled by the clipper if necessary
return (RLSW.cullFace == SW_FRONT)? (sgnArea < 0.0f) : (sgnArea > 0.0f); // Cull if winding is "clockwise" : "counter-clockwise" return (RLSW.cullFace == SW_FRONT)? (sgnArea < 0.0f) : (sgnArea > 0.0f); // Cull if winding is "clockwise" : "counter-clockwise"
@ -3879,8 +3876,7 @@ static inline void sw_poly_fill_render(uint32_t state)
//------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------
static void sw_immediate_begin(SWdraw mode) static void sw_immediate_begin(SWdraw mode)
{ {
// NOTE: Any checks to ensure command recording can start // NOTE: Any checks to ensure command recording can start must be performed before calling this function
// must be performed before calling this function.
// Recalculate the MVP if this is needed // Recalculate the MVP if this is needed
if (RLSW.isDirtyMVP) if (RLSW.isDirtyMVP)
@ -3891,8 +3887,8 @@ static void sw_immediate_begin(SWdraw mode)
#ifdef SW_HAS_ESP_DSP #ifdef SW_HAS_ESP_DSP
// Pre-transpose to row-major so dspm_mult_4x4x1_f32(matMVP_rm, v, out) // Pre-transpose to row-major so dspm_mult_4x4x1_f32(matMVP_rm, v, out)
// computes M*v directly in the per-vertex hot path. 16 scalar copies // computes M*v directly in the per-vertex hot path; 16 scalar copies
// per MVP update vs. saving ~20 cycles per vertex transform. // per MVP update vs saving ~20 cycles per vertex transform
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
for (int j = 0; j < 4; j++) for (int j = 0; j < 4; j++)
@ -3955,7 +3951,7 @@ static void sw_immediate_push_vertex(const float position[4])
// Calculate clip coordinates // Calculate clip coordinates
#ifdef SW_HAS_ESP_DSP #ifdef SW_HAS_ESP_DSP
// dspm_mult_4x4x1_f32 declares its inputs non-const; rlsw treats them as // dspm_mult_4x4x1_f32 declares its inputs non-const; rlsw treats them as
// read-only and the cast is safe (the kernel only loads from B). // read-only and the cast is safe (the kernel only loads from B)
dspm_mult_4x4x1_f32(RLSW.matMVP_rm, (float *)position, vertex->position); dspm_mult_4x4x1_f32(RLSW.matMVP_rm, (float *)position, vertex->position);
#else #else
const float *m = RLSW.matMVP; const float *m = RLSW.matMVP;
@ -5389,6 +5385,16 @@ static void SW_RASTER_TRIANGLE_SPAN(const sw_vertex_t *start, const sw_vertex_t
int xEnd = (int)end->position[0]; int xEnd = (int)end->position[0];
if (xStart == xEnd) return; if (xStart == xEnd) return;
// Intercept the span bounds to ensure to not write before the framebuffer
int xLoopStart = (xStart >= 0)? xStart : 0;
int xLoopEnd = (xEnd <= RLSW.colorBuffer->width)? xEnd : RLSW.colorBuffer->width;
if (xLoopStart >= xLoopEnd) return; // Nothing to draw
// Get the current row and skip if outside the framebuffer
// Maybe this check is better suited elsewhere?
int y = (int)start->position[1];
if (y < 0 || y >= RLSW.colorBuffer->height) return;
// Compute the inverse horizontal distance along the X axis // Compute the inverse horizontal distance along the X axis
float dxRcp = sw_rcp(end->position[0] - start->position[0]); float dxRcp = sw_rcp(end->position[0] - start->position[0]);
@ -5409,27 +5415,29 @@ static void SW_RASTER_TRIANGLE_SPAN(const sw_vertex_t *start, const sw_vertex_t
#endif #endif
// Compute the subpixel distance to traverse before the first pixel // Compute the subpixel distance to traverse before the first pixel
// Also step further into them to move away from the colorbuffer edge
float xSubstep = 1.0f - sw_fract(start->position[0]); float xSubstep = 1.0f - sw_fract(start->position[0]);
float dxStart = (float)(xLoopStart - xStart);
float xOffset = xSubstep + dxStart;
// Initializing the interpolation starting values // Initializing the interpolation starting values
float w = start->position[3] + dWdx*xSubstep; float w = start->position[3] + dWdx*xOffset;
float color[4] = { float color[4] = {
start->color[0] + dCdx[0]*xSubstep, start->color[0] + dCdx[0]*xOffset,
start->color[1] + dCdx[1]*xSubstep, start->color[1] + dCdx[1]*xOffset,
start->color[2] + dCdx[2]*xSubstep, start->color[2] + dCdx[2]*xOffset,
start->color[3] + dCdx[3]*xSubstep start->color[3] + dCdx[3]*xOffset
}; };
#ifdef SW_ENABLE_DEPTH_TEST #ifdef SW_ENABLE_DEPTH_TEST
float z = start->position[2] + dZdx*xSubstep; float z = start->position[2] + dZdx*xOffset;
#endif #endif
#ifdef SW_ENABLE_TEXTURE #ifdef SW_ENABLE_TEXTURE
float u = start->texcoord[0] + dUdx*xSubstep; float u = start->texcoord[0] + dUdx*xOffset;
float v = start->texcoord[1] + dVdx*xSubstep; float v = start->texcoord[1] + dVdx*xOffset;
#endif #endif
// Pre-calculate the starting pointers for the framebuffer row // Pre-calculate the starting pointers for the framebuffer row
int y = (int)start->position[1]; int baseOffset = y*RLSW.colorBuffer->width + xLoopStart;
int baseOffset = y*RLSW.colorBuffer->width + xStart;
uint8_t *cPtr = (uint8_t *)(RLSW.colorBuffer->pixels) + baseOffset*SW_FRAMEBUFFER_COLOR_SIZE; uint8_t *cPtr = (uint8_t *)(RLSW.colorBuffer->pixels) + baseOffset*SW_FRAMEBUFFER_COLOR_SIZE;
#ifdef SW_ENABLE_DEPTH_TEST #ifdef SW_ENABLE_DEPTH_TEST
uint8_t *dPtr = (uint8_t *)(RLSW.depthBuffer->pixels) + baseOffset*SW_FRAMEBUFFER_DEPTH_SIZE; uint8_t *dPtr = (uint8_t *)(RLSW.depthBuffer->pixels) + baseOffset*SW_FRAMEBUFFER_DEPTH_SIZE;
@ -5437,12 +5445,12 @@ static void SW_RASTER_TRIANGLE_SPAN(const sw_vertex_t *start, const sw_vertex_t
#define SW_AFFINE_BLOCK 16 #define SW_AFFINE_BLOCK 16
int x = xStart; int x = xLoopStart;
while (x < xEnd) while (x < xLoopEnd)
{ {
// Clamp last block to remaining pixels // Clamp last block to remaining pixels
int blockEnd = x + SW_AFFINE_BLOCK; int blockEnd = x + SW_AFFINE_BLOCK;
if (blockEnd > xEnd) blockEnd = xEnd; if (blockEnd > xLoopEnd) blockEnd = xLoopEnd;
float blockLenF = (float)(blockEnd - x); float blockLenF = (float)(blockEnd - x);
float blockLenRcp = sw_rcp(blockLenF); float blockLenRcp = sw_rcp(blockLenF);
@ -5567,7 +5575,7 @@ static void SW_RASTER_TRIANGLE(const sw_vertex_t *v0, const sw_vertex_t *v1, con
if (v0->position[1] > v1->position[1]) { const sw_vertex_t *tmp = v0; v0 = v1; v1 = tmp; } if (v0->position[1] > v1->position[1]) { const sw_vertex_t *tmp = v0; v0 = v1; v1 = tmp; }
// Extracting coordinates from the sorted vertices // Extracting coordinates from the sorted vertices
// Put x away for safe keeping. Only y is used right now. Silences warnings. // Put x away for safe keeping; only y is used right now; silences warnings
float y0 = v0->position[1]; float y0 = v0->position[1];
float y1 = v1->position[1]; float y1 = v1->position[1];
float y2 = v2->position[1]; float y2 = v2->position[1];
@ -5677,6 +5685,14 @@ static void SW_RASTER_QUAD(const sw_vertex_t *a, const sw_vertex_t *b,
int xMax = (int)br->position[0]; int xMax = (int)br->position[0];
int yMax = (int)br->position[1]; int yMax = (int)br->position[1];
// Exit early if no pixels to draw. Use these later for loop boundaries
int yLoopMin = (yMin >= 0)? yMin : 0;
int xLoopMin = (xMin >= 0)? xMin : 0;
int yLoopMax = (yMax <= RLSW.colorBuffer->height)? yMax : RLSW.colorBuffer->height;
int xLoopMax = (xMax <= RLSW.colorBuffer->width)? xMax : RLSW.colorBuffer->width;
if (yLoopMin >= yLoopMax || xLoopMin >= xLoopMax) return;
float w = (float)(xMax - xMin); float w = (float)(xMax - xMin);
float h = (float)(yMax - yMin); float h = (float)(yMax - yMin);
if ((w <= 0) || (h <= 0)) return; if ((w <= 0) || (h <= 0)) return;
@ -5730,21 +5746,44 @@ static void SW_RASTER_QUAD(const sw_vertex_t *a, const sw_vertex_t *b,
uint8_t *dPixels = RLSW.depthBuffer->pixels; uint8_t *dPixels = RLSW.depthBuffer->pixels;
#endif #endif
for (int y = yMin; y < yMax; y++) // Calculate the distance the in-bounds boundary is from the quad's edges, only on the left and top
float dxMin = (float)(xLoopMin - xMin);
float dyMin = (float)(yLoopMin - yMin);
// Correct our start by how far it's clipped outside the framebuffer
cRow[0] += dCdx[0]*dxMin + dCdy[0]*dyMin;
cRow[1] += dCdx[1]*dxMin + dCdy[1]*dyMin;
cRow[2] += dCdx[2]*dxMin + dCdy[2]*dyMin;
cRow[3] += dCdx[3]*dxMin + dCdy[3]*dyMin;
#ifdef SW_ENABLE_DEPTH_TEST
zRow += dZdy*dyMin + dZdx*dxMin;
#endif
#ifdef SW_ENABLE_TEXTURE
uRow += dUdy*dyMin + dUdx*dxMin;
vRow += dVdy*dyMin + dVdx*dxMin;
#endif
for (int y = yLoopMin; y < yLoopMax; y++)
{ {
int baseOffset = y*stride + xMin; int baseOffset = y*stride + xLoopMin;
uint8_t *cPtr = cPixels + baseOffset*SW_FRAMEBUFFER_COLOR_SIZE; uint8_t *cPtr = cPixels + baseOffset*SW_FRAMEBUFFER_COLOR_SIZE;
#ifdef SW_ENABLE_DEPTH_TEST #ifdef SW_ENABLE_DEPTH_TEST
uint8_t *dPtr = dPixels + baseOffset*SW_FRAMEBUFFER_DEPTH_SIZE; uint8_t *dPtr = dPixels + baseOffset*SW_FRAMEBUFFER_DEPTH_SIZE;
// Copy the cursors without destroying the offset maths
float z = zRow; float z = zRow;
#endif #endif
#ifdef SW_ENABLE_TEXTURE #ifdef SW_ENABLE_TEXTURE
float u = uRow; float u = uRow;
float v = vRow; float v = vRow;
#endif #endif
float color[4] = { cRow[0], cRow[1], cRow[2], cRow[3] }; float color[4] = {
cRow[0],
cRow[1],
cRow[2],
cRow[3]
};
for (int x = xMin; x < xMax; x++) for (int x = xLoopMin; x < xLoopMax; x++)
{ {
float srcColor[4] = { color[0], color[1], color[2], color[3] }; float srcColor[4] = { color[0], color[1], color[2], color[3] };
@ -5783,6 +5822,7 @@ static void SW_RASTER_QUAD(const sw_vertex_t *a, const sw_vertex_t *b,
#ifdef SW_ENABLE_DEPTH_TEST #ifdef SW_ENABLE_DEPTH_TEST
discard: discard:
#endif #endif
// Move one pixel over without touching the original "start offset"
color[0] += dCdx[0]; color[0] += dCdx[0];
color[1] += dCdx[1]; color[1] += dCdx[1];
color[2] += dCdx[2]; color[2] += dCdx[2];
@ -5805,6 +5845,9 @@ static void SW_RASTER_QUAD(const sw_vertex_t *a, const sw_vertex_t *b,
cPtr += SW_FRAMEBUFFER_COLOR_SIZE; cPtr += SW_FRAMEBUFFER_COLOR_SIZE;
} }
// The for loop is clamped to the right side of the screen
// However, these cursor start vars are still on the left
// That's fine, advancing to the next row
cRow[0] += dCdy[0]; cRow[0] += dCdy[0];
cRow[1] += dCdy[1]; cRow[1] += dCdy[1];
cRow[2] += dCdy[2]; cRow[2] += dCdy[2];

10
src/external/rprand.h vendored
View File

@ -1,6 +1,6 @@
/********************************************************************************************** /**********************************************************************************************
* *
* rprand v1.0 - A simple and easy-to-use pseudo-random numbers generator (PRNG) * rprand v1.1 - A simple and easy-to-use pseudo-random numbers generator (PRNG)
* *
* FEATURES: * FEATURES:
* - Pseudo-random values generation, 32 bits: [0..4294967295] * - Pseudo-random values generation, 32 bits: [0..4294967295]
@ -118,6 +118,7 @@ extern "C" { // Prevents name mangling of functions
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
RPRANDAPI void rprand_set_seed(unsigned long long seed); // Set rprand_state for Xoshiro128**, seed is 64bit RPRANDAPI void rprand_set_seed(unsigned long long seed); // Set rprand_state for Xoshiro128**, seed is 64bit
RPRANDAPI int rprand_get_value(int min, int max); // Get random value within a range, min and max included RPRANDAPI int rprand_get_value(int min, int max); // Get random value within a range, min and max included
RPRANDAPI int rprand_get_value_raw(void); // Get random value, Xoshiro128** generator (uses global rprand_state)
RPRANDAPI int *rprand_load_sequence(unsigned int count, int min, int max); // Load pseudo-random numbers sequence with no duplicates RPRANDAPI int *rprand_load_sequence(unsigned int count, int min, int max); // Load pseudo-random numbers sequence with no duplicates
RPRANDAPI void rprand_unload_sequence(int *sequence); // Unload pseudo-random numbers sequence RPRANDAPI void rprand_unload_sequence(int *sequence); // Unload pseudo-random numbers sequence
@ -186,6 +187,13 @@ int rprand_get_value(int min, int max)
return value; return value;
} }
int rprand_get_value_raw(void)
{
int value = rprand_xoshiro();
return value;
}
// Load pseudo-random numbers sequence with no duplicates, min and max included // Load pseudo-random numbers sequence with no duplicates, min and max included
int *rprand_load_sequence(unsigned int count, int min, int max) int *rprand_load_sequence(unsigned int count, int min, int max)
{ {

View File

@ -4,14 +4,14 @@
#ifndef WIN32_CLIPBOARD_ #ifndef WIN32_CLIPBOARD_
#define WIN32_CLIPBOARD_ #define WIN32_CLIPBOARD_
unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned long long int *dataSize); unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned int *dataSize);
#endif // WIN32_CLIPBOARD_ #endif // WIN32_CLIPBOARD_
#ifdef WIN32_CLIPBOARD_IMPLEMENTATION #ifdef WIN32_CLIPBOARD_IMPLEMENTATION
#include <stdio.h> #include <stdio.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <limits.h>
// NOTE: These search for architecture is taken from "windows.h", and it's necessary to avoid including windows.h // NOTE: These search for architecture is taken from "windows.h", and it's necessary to avoid including windows.h
// and still make it compile on msvc, because import indirectly importing "winnt.h" (e.g. <minwindef.h>) can cause problems is these are not defined // and still make it compile on msvc, because import indirectly importing "winnt.h" (e.g. <minwindef.h>) can cause problems is these are not defined
@ -213,7 +213,7 @@ static int GetPixelDataOffset(BITMAPINFOHEADER bih); // Get pixel data offset fr
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module Functions Definition // Module Functions Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned long long int *dataSize) unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned int *dataSize)
{ {
unsigned char *bmpData = NULL; unsigned char *bmpData = NULL;
@ -228,7 +228,7 @@ unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned long
*width = bmpInfoHeader->biWidth; *width = bmpInfoHeader->biWidth;
*height = bmpInfoHeader->biHeight; *height = bmpInfoHeader->biHeight;
SIZE_T clipDataSize = GlobalSize(clipHandle); SIZE_T clipDataSize = GlobalSize(clipHandle);
if (clipDataSize >= sizeof(BITMAPINFOHEADER)) if ((clipDataSize >= sizeof(BITMAPINFOHEADER)) && (clipDataSize < INT_MAX))
{ {
int pixelOffset = GetPixelDataOffset(*bmpInfoHeader); int pixelOffset = GetPixelDataOffset(*bmpInfoHeader);
@ -236,7 +236,7 @@ unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned long
//------------------------------------------------------------------------ //------------------------------------------------------------------------
BITMAPFILEHEADER bmpFileHeader = { 0 }; BITMAPFILEHEADER bmpFileHeader = { 0 };
SIZE_T bmpFileSize = sizeof(bmpFileHeader) + clipDataSize; SIZE_T bmpFileSize = sizeof(bmpFileHeader) + clipDataSize;
*dataSize = bmpFileSize; *dataSize = (unsigned int)bmpFileSize;
bmpFileHeader.bfType = 0x4D42; // BMP fil type constant bmpFileHeader.bfType = 0x4D42; // BMP fil type constant
bmpFileHeader.bfSize = (DWORD)bmpFileSize; // Up to 4GB works fine bmpFileHeader.bfSize = (DWORD)bmpFileSize; // Up to 4GB works fine
@ -254,7 +254,7 @@ unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned long
} }
else else
{ {
TRACELOG(LOG_WARNING, "Clipboard data is malformed"); TRACELOG(LOG_WARNING, "Clipboard data is not supported (>2GB?)");
GlobalUnlock(clipHandle); GlobalUnlock(clipHandle);
CloseClipboard(); CloseClipboard();
} }

View File

@ -656,7 +656,7 @@ double GetTime(void)
double time = 0.0; double time = 0.0;
struct timespec ts = { 0 }; struct timespec ts = { 0 };
clock_gettime(CLOCK_MONOTONIC, &ts); clock_gettime(CLOCK_MONOTONIC, &ts);
unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec; unsigned long long nanoSeconds = (unsigned long long)ts.tv_sec*1000000000LLU + (unsigned long long)ts.tv_nsec;
time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer() time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer()
@ -1273,20 +1273,19 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
int32_t keycode = AKeyEvent_getKeyCode(event); int32_t keycode = AKeyEvent_getKeyCode(event);
//int32_t AKeyEvent_getMetaState(event); //int32_t AKeyEvent_getMetaState(event);
// Handle gamepad button presses and releases // Handle gamepad button presses and releases. AOSP stamps the
// NOTE: Skip gamepad handling if this is a keyboard event, as some devices // KEYBOARD source bit on every key event from a gamepad, so
// report both AINPUT_SOURCE_KEYBOARD and AINPUT_SOURCE_GAMEPAD flags // discriminate on the keycode rather than gating on source bits.
if ((FLAG_IS_SET(source, AINPUT_SOURCE_JOYSTICK) || if (FLAG_IS_SET(source, AINPUT_SOURCE_JOYSTICK) ||
FLAG_IS_SET(source, AINPUT_SOURCE_GAMEPAD)) && FLAG_IS_SET(source, AINPUT_SOURCE_GAMEPAD))
!FLAG_IS_SET(source, AINPUT_SOURCE_KEYBOARD)) {
GamepadButton button = AndroidTranslateGamepadButton(keycode);
if (button != GAMEPAD_BUTTON_UNKNOWN)
{ {
// Assuming a single gamepad, "detected" on its input event // Assuming a single gamepad, "detected" on its input event
CORE.Input.Gamepad.ready[0] = true; CORE.Input.Gamepad.ready[0] = true;
GamepadButton button = AndroidTranslateGamepadButton(keycode);
if (button == GAMEPAD_BUTTON_UNKNOWN) return 1;
if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN) if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN)
{ {
CORE.Input.Gamepad.currentButtonState[0][button] = 1; CORE.Input.Gamepad.currentButtonState[0][button] = 1;
@ -1295,6 +1294,8 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
return 1; // Handled gamepad button return 1; // Handled gamepad button
} }
// Unknown keycode: fall through to the keyboard handler below.
}
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) if (key != KEY_NULL)

View File

@ -1042,11 +1042,6 @@ const char *GetClipboardText(void)
return glfwGetClipboardString(platform.handle); return glfwGetClipboardString(platform.handle);
} }
#if SUPPORT_CLIPBOARD_IMAGE && defined(__linux__) && defined(_GLFW_X11)
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#endif
// Get clipboard image // Get clipboard image
Image GetClipboardImage(void) Image GetClipboardImage(void)
{ {
@ -1054,7 +1049,8 @@ Image GetClipboardImage(void)
#if SUPPORT_CLIPBOARD_IMAGE && SUPPORT_MODULE_RTEXTURES #if SUPPORT_CLIPBOARD_IMAGE && SUPPORT_MODULE_RTEXTURES
#if defined(_WIN32) #if defined(_WIN32)
unsigned long long int dataSize = 0;
unsigned int dataSize = 0;
void *bmpData = NULL; void *bmpData = NULL;
int width = 0; int width = 0;
int height = 0; int height = 0;
@ -1065,32 +1061,30 @@ Image GetClipboardImage(void)
else image = LoadImageFromMemory(".bmp", (const unsigned char *)bmpData, (int)dataSize); else image = LoadImageFromMemory(".bmp", (const unsigned char *)bmpData, (int)dataSize);
#elif defined(__linux__) && defined(_GLFW_X11) #elif defined(__linux__) && defined(_GLFW_X11)
// REF: https://github.com/ColleagueRiley/Clipboard-Copy-Paste/blob/main/x11.c // REF: https://github.com/ColleagueRiley/Clipboard-Copy-Paste/blob/main/x11.c
Display *dpy = XOpenDisplay(NULL);
if (!dpy) return image;
Window root = DefaultRootWindow(dpy); static Atom clipboard = 0;
Window win = XCreateSimpleWindow( static Atom targetType = 0;
dpy, // The connection to the X Server static Atom property = 0;
root, // The 'Parent' window (usually the desktop/root)
0, 0, // X and Y position on the screen
1, 1, // Width and Height (1x1 pixel)
0, // Border width
0, // Border color
0 // Background color
);
Atom clipboard = XInternAtom(dpy, "CLIPBOARD", False); Display *display = glfwGetX11Display();
Atom targetType = XInternAtom(dpy, "image/png", False); // Ask for PNG XID window = glfwGetX11Window(platform.handle);
Atom property = XInternAtom(dpy, "RAYLIB_CLIPBOARD_MANAGER", False);
// Request the data: "Convert whatever is in CLIPBOARD to image/png and put it in RAYLIB_CLIPBOARD_MANAGER" // Lazy-load X11 atoms
XConvertSelection(dpy, clipboard, targetType, property, win, CurrentTime); if(clipboard == 0)
{
clipboard = XInternAtom(display, "CLIPBOARD", False);
targetType = XInternAtom(display, "image/png", False);
property = XInternAtom(display, "RAYLIB_CLIPBOARD_MANAGER", False);
}
XConvertSelection(display, clipboard, targetType, property, window, CurrentTime);
XSync(display, 0);
// Wait for the SelectionNotify event
XEvent ev = { 0 }; XEvent ev = { 0 };
XNextEvent(dpy, &ev);
// Keep calling until we get SelectionNotify
while (XCheckTypedEvent(display, SelectionNotify, &ev) == False);
Atom actualType = { 0 }; Atom actualType = { 0 };
int actualFormat = 0; int actualFormat = 0;
@ -1098,8 +1092,7 @@ Image GetClipboardImage(void)
unsigned long bytesAfter = 0; unsigned long bytesAfter = 0;
unsigned char *data = NULL; unsigned char *data = NULL;
// Read the data from our ghost window's property XGetWindowProperty(display, window, property, 0, ~0L, False, AnyPropertyType,
XGetWindowProperty(dpy, win, property, 0, ~0L, False, AnyPropertyType,
&actualType, &actualFormat, &nitems, &bytesAfter, &data); &actualType, &actualFormat, &nitems, &bytesAfter, &data);
if (data != NULL) if (data != NULL)
@ -1108,11 +1101,9 @@ Image GetClipboardImage(void)
XFree(data); XFree(data);
} }
XDestroyWindow(dpy, win);
XCloseDisplay(dpy);
#else #else
TRACELOG(LOG_WARNING, "GetClipboardImage() not implemented on target platform"); TRACELOG(LOG_WARNING, "GetClipboardImage() not implemented on target platform");
#endif // defined(_WIN32) #endif // _WIN32
#else #else
TRACELOG(LOG_WARNING, "Clipboard image: SUPPORT_CLIPBOARD_IMAGE requires SUPPORT_MODULE_RTEXTURES to work properly"); TRACELOG(LOG_WARNING, "Clipboard image: SUPPORT_CLIPBOARD_IMAGE requires SUPPORT_MODULE_RTEXTURES to work properly");
#endif // SUPPORT_CLIPBOARD_IMAGE #endif // SUPPORT_CLIPBOARD_IMAGE

123
src/platforms/rcore_desktop_rgfw.c Executable file → Normal file
View File

@ -810,8 +810,8 @@ void SetWindowSize(int width, int height)
RGFW_monitor* currentMonitor = RGFW_window_getMonitor(platform.window); RGFW_monitor* currentMonitor = RGFW_window_getMonitor(platform.window);
CORE.Window.screenScale = MatrixScale(currentMonitor->pixelRatio, currentMonitor->pixelRatio, 1.0f); CORE.Window.screenScale = MatrixScale(currentMonitor->pixelRatio, currentMonitor->pixelRatio, 1.0f);
CORE.Window.render.width = CORE.Window.screen.width * currentMonitor->pixelRatio; CORE.Window.render.width = CORE.Window.screen.width*currentMonitor->pixelRatio;
CORE.Window.render.height = CORE.Window.screen.height * currentMonitor->pixelRatio; CORE.Window.render.height = CORE.Window.screen.height*currentMonitor->pixelRatio;
CORE.Window.currentFbo.width = CORE.Window.render.width; CORE.Window.currentFbo.width = CORE.Window.render.width;
CORE.Window.currentFbo.height = CORE.Window.render.height; CORE.Window.currentFbo.height = CORE.Window.render.height;
#else #else
@ -1024,15 +1024,15 @@ Image GetClipboardImage(void)
#if SUPPORT_CLIPBOARD_IMAGE && SUPPORT_MODULE_RTEXTURES #if SUPPORT_CLIPBOARD_IMAGE && SUPPORT_MODULE_RTEXTURES
#if defined(_WIN32) #if defined(_WIN32)
unsigned long long int dataSize = 0; // moved into _WIN32 scope until other platforms gain support unsigned int dataSize = 0;
void *fileData = NULL; // moved into _WIN32 scope until other platforms gain support void *fileData = NULL;
int width = 0; int width = 0;
int height = 0; int height = 0;
fileData = (void *)Win32GetClipboardImageData(&width, &height, &dataSize); fileData = (void *)Win32GetClipboardImageData(&width, &height, &dataSize);
if (fileData == NULL) TRACELOG(LOG_WARNING, "Clipboard image: Couldn't get clipboard data"); if (fileData == NULL) TRACELOG(LOG_WARNING, "Clipboard image: Couldn't get clipboard data");
else image = LoadImageFromMemory(".bmp", (const unsigned char *)fileData, dataSize); else image = LoadImageFromMemory(".bmp", (const unsigned char *)fileData, (int)dataSize);
#elif defined(__linux__) && defined(DRGFW_X11) #elif defined(__linux__) && defined(DRGFW_X11)
@ -1082,7 +1082,7 @@ Image GetClipboardImage(void)
XCloseDisplay(dpy); XCloseDisplay(dpy);
#else #else
TRACELOG(LOG_WARNING, "Clipboard image: PLATFORM_DESKTOP_RGFW doesn't implement GetClipboardImage() for this OS"); TRACELOG(LOG_WARNING, "Clipboard image: PLATFORM_DESKTOP_RGFW doesn't implement GetClipboardImage() for this OS");
#endif // defined(_WIN32) #endif // _WIN32
#else #else
TRACELOG(LOG_WARNING, "Clipboard image: SUPPORT_CLIPBOARD_IMAGE requires SUPPORT_MODULE_RTEXTURES to work properly"); TRACELOG(LOG_WARNING, "Clipboard image: SUPPORT_CLIPBOARD_IMAGE requires SUPPORT_MODULE_RTEXTURES to work properly");
#endif // SUPPORT_CLIPBOARD_IMAGE #endif // SUPPORT_CLIPBOARD_IMAGE
@ -1132,16 +1132,16 @@ void SwapScreenBuffer(void)
{ {
if (platform.surface) if (platform.surface)
{ {
// copy rlsw pixel data to the surface framebuffer // Copy rlsw pixel data to the surface framebuffer
swReadPixels(0, 0, platform.surfaceWidth, platform.surfaceHeight, SW_RGBA, SW_UNSIGNED_BYTE, platform.surfacePixels); rlCopyFramebuffer(0, 0, platform.surfaceWidth, platform.surfaceHeight, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, platform.surfacePixels);
// Mac wants a different pixel order. I cant seem to get this to work any other way // Mac wants a different pixel order. I cant seem to get this to work any other way
#if defined(__APPLE__) #if defined(__APPLE__)
unsigned char temp = 0; unsigned char temp = 0;
unsigned char *p = NULL; unsigned char *p = NULL;
for (int i = 0; i < (platform.surfaceWidth * platform.surfaceHeight); i += 1) for (int i = 0; i < (platform.surfaceWidth*platform.surfaceHeight); i += 1)
{ {
p = platform.surfacePixels + (i * 4); p = platform.surfacePixels + (i*4);
temp = p[0]; temp = p[0];
p[0] = p[2]; p[0] = p[2];
p[2] = temp; p[2] = temp;
@ -1357,13 +1357,13 @@ void PollInputEvents(void)
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI))
{ {
RGFW_monitor* currentMonitor = RGFW_window_getMonitor(platform.window); RGFW_monitor* currentMonitor = RGFW_window_getMonitor(platform.window);
SetupViewport(platform.window->w * currentMonitor->pixelRatio, platform.window->h * currentMonitor->pixelRatio); SetupViewport(platform.window->w*currentMonitor->pixelRatio, platform.window->h*currentMonitor->pixelRatio);
CORE.Window.screenScale = MatrixScale(currentMonitor->pixelRatio, currentMonitor->pixelRatio, 1.0f); CORE.Window.screenScale = MatrixScale(currentMonitor->pixelRatio, currentMonitor->pixelRatio, 1.0f);
CORE.Window.screen.width = platform.window->w; CORE.Window.screen.width = platform.window->w;
CORE.Window.screen.height = platform.window->h; CORE.Window.screen.height = platform.window->h;
CORE.Window.render.width = CORE.Window.screen.width * currentMonitor->pixelRatio; CORE.Window.render.width = CORE.Window.screen.width*currentMonitor->pixelRatio;
CORE.Window.render.height = CORE.Window.screen.height * currentMonitor->pixelRatio; CORE.Window.render.height = CORE.Window.screen.height*currentMonitor->pixelRatio;
} }
else else
{ {
@ -1406,10 +1406,10 @@ void PollInputEvents(void)
#if defined(__APPLE__) #if defined(__APPLE__)
RGFW_monitor* currentMonitor = RGFW_window_getMonitor(platform.window); RGFW_monitor* currentMonitor = RGFW_window_getMonitor(platform.window);
CORE.Window.screenScale = MatrixScale(currentMonitor->pixelRatio, currentMonitor->pixelRatio, 1.0f); CORE.Window.screenScale = MatrixScale(currentMonitor->pixelRatio, currentMonitor->pixelRatio, 1.0f);
SetupViewport(platform.window->w * currentMonitor->pixelRatio, platform.window->h * currentMonitor->pixelRatio); SetupViewport(platform.window->w*currentMonitor->pixelRatio, platform.window->h*currentMonitor->pixelRatio);
CORE.Window.render.width = CORE.Window.screen.width * currentMonitor->pixelRatio; CORE.Window.render.width = CORE.Window.screen.width*currentMonitor->pixelRatio;
CORE.Window.render.height = CORE.Window.screen.height * currentMonitor->pixelRatio; CORE.Window.render.height = CORE.Window.screen.height*currentMonitor->pixelRatio;
CORE.Window.currentFbo.width = CORE.Window.render.width; CORE.Window.currentFbo.width = CORE.Window.render.width;
CORE.Window.currentFbo.height = CORE.Window.render.height; CORE.Window.currentFbo.height = CORE.Window.render.height;
#endif #endif
@ -1427,7 +1427,7 @@ void PollInputEvents(void)
if (platform.surfacePixels != NULL) if (platform.surfacePixels != NULL)
{ {
RL_FREE(platform.surfacePixels); RL_FREE(platform.surfacePixels);
platform.surfacePixels = RL_MALLOC(platform.surfaceWidth * platform.surfaceHeight * 4); platform.surfacePixels = RL_MALLOC(platform.surfaceWidth*platform.surfaceHeight*4);
} }
if (platform.surface != NULL) if (platform.surface != NULL)
@ -1677,10 +1677,62 @@ int InitPlatform(void)
// Initialize RGFW internal global state, only required systems // Initialize RGFW internal global state, only required systems
unsigned int flags = RGFW_windowCenter | RGFW_windowAllowDND; unsigned int flags = RGFW_windowCenter | RGFW_windowAllowDND;
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNDECORATED)) FLAG_SET(flags, RGFW_windowNoBorder);
if (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_RESIZABLE)) FLAG_SET(flags, RGFW_windowNoResize);
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_TRANSPARENT)) FLAG_SET(flags, RGFW_windowTransparent);
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)) FLAG_SET(flags, RGFW_windowHide);
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED)) FLAG_SET(flags, RGFW_windowMaximize);
if (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED)) FLAG_SET(flags, RGFW_windowFocusOnShow | RGFW_windowFocus);
if ((CORE.Window.screen.width == 0) || (CORE.Window.screen.height == 0))
{
FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
}
// Check window creation flags // Check window creation flags
// Init window in fullscreen mode if requested
// NOTE: Keeping original screen size for toggle
if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE))
{ {
FLAG_SET(flags, RGFW_windowFullscreen); FLAG_SET(flags, RGFW_windowFullscreen);
int result = RGFW_init();
if (result != 0)
{
TRACELOG(LOG_WARNING, "RGFW: Failed to initialize RGFW");
return -1;
}
// NOTE: Fullscreen applications default to the primary monitor
RGFW_monitor *monitor = RGFW_getPrimaryMonitor();
if (!monitor)
{
TRACELOG(LOG_WARNING, "RGFW: Failed to get primary monitor");
return -1;
}
// Default display resolution to that of the current mode
CORE.Window.display.width = monitor->mode.w;
CORE.Window.display.height = monitor->mode.h;
// Check if user requested some screen size
if ((CORE.Window.screen.width == 0) || (CORE.Window.screen.height == 0))
{
// Set some default screen size in case user decides to exit fullscreen mode
CORE.Window.previousScreen.width = 800;
CORE.Window.previousScreen.height = 450;
CORE.Window.previousPosition.x = (CORE.Window.display.width - CORE.Window.previousScreen.width)/2;
CORE.Window.previousPosition.y = (CORE.Window.display.height - CORE.Window.previousScreen.height)/2;
// Set screen width/height to the display width/height
if (CORE.Window.screen.width == 0) CORE.Window.screen.width = CORE.Window.display.width;
if (CORE.Window.screen.height == 0) CORE.Window.screen.height = CORE.Window.display.height;
}
else
{
CORE.Window.previousScreen = CORE.Window.screen;
CORE.Window.screen = CORE.Window.display;
}
} }
if (FLAG_IS_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE)) if (FLAG_IS_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE))
@ -1688,16 +1740,16 @@ int InitPlatform(void)
FLAG_SET(flags, RGFW_windowedFullscreen); FLAG_SET(flags, RGFW_windowedFullscreen);
} }
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNDECORATED)) FLAG_SET(flags, RGFW_windowNoBorder); if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI))
if (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_RESIZABLE)) FLAG_SET(flags, RGFW_windowNoResize); {
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_TRANSPARENT)) FLAG_SET(flags, RGFW_windowTransparent); #if !defined(__APPLE__)
if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) FLAG_SET(flags, RGFW_windowFullscreen); CORE.Window.screen.width = CORE.Window.screen.width*GetWindowScaleDPI().x;
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)) FLAG_SET(flags, RGFW_windowHide); CORE.Window.screen.height = CORE.Window.screen.height*GetWindowScaleDPI().y;
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED)) FLAG_SET(flags, RGFW_windowMaximize); #endif
}
// NOTE: Some OpenGL context attributes must be set before window creation // NOTE: Some OpenGL context attributes must be set before window creation
// Check selection OpenGL version // Check selection OpenGL version
RGFW_glHints* hints = RGFW_getGlobalHints_OpenGL(); RGFW_glHints* hints = RGFW_getGlobalHints_OpenGL();
if (rlGetVersion() == RL_OPENGL_21) if (rlGetVersion() == RL_OPENGL_21)
{ {
@ -1720,20 +1772,9 @@ int InitPlatform(void)
hints->minor = 1; hints->minor = 1;
hints->renderer = RGFW_glSoftware; hints->renderer = RGFW_glSoftware;
} }
if (FLAG_IS_SET(CORE.Window.flags, FLAG_MSAA_4X_HINT)) hints->samples = 4; if (FLAG_IS_SET(CORE.Window.flags, FLAG_MSAA_4X_HINT)) hints->samples = 4;
if (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED)) FLAG_SET(flags, RGFW_windowFocusOnShow | RGFW_windowFocus);
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI))
{
#if !defined(__APPLE__)
CORE.Window.screen.width = CORE.Window.screen.width * GetWindowScaleDPI().x;
CORE.Window.screen.height = CORE.Window.screen.height * GetWindowScaleDPI().y;
#endif
}
RGFW_setGlobalHints_OpenGL(hints); RGFW_setGlobalHints_OpenGL(hints);
platform.window = RGFW_createWindow((CORE.Window.title != 0)? CORE.Window.title : " ", 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, flags | RGFW_windowOpenGL); platform.window = RGFW_createWindow((CORE.Window.title != 0)? CORE.Window.title : " ", 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, flags | RGFW_windowOpenGL);
#ifndef PLATFORM_WEB_RGFW #ifndef PLATFORM_WEB_RGFW
@ -1787,8 +1828,8 @@ int InitPlatform(void)
RGFW_monitor* currentMonitor = RGFW_window_getMonitor(platform.window); RGFW_monitor* currentMonitor = RGFW_window_getMonitor(platform.window);
CORE.Window.screenScale = MatrixScale(currentMonitor->pixelRatio, currentMonitor->pixelRatio, 1.0f); CORE.Window.screenScale = MatrixScale(currentMonitor->pixelRatio, currentMonitor->pixelRatio, 1.0f);
CORE.Window.render.width = CORE.Window.screen.width * currentMonitor->pixelRatio; CORE.Window.render.width = CORE.Window.screen.width*currentMonitor->pixelRatio;
CORE.Window.render.height = CORE.Window.screen.height * currentMonitor->pixelRatio; CORE.Window.render.height = CORE.Window.screen.height*currentMonitor->pixelRatio;
CORE.Window.currentFbo.width = CORE.Window.render.width; CORE.Window.currentFbo.width = CORE.Window.render.width;
CORE.Window.currentFbo.height = CORE.Window.render.height; CORE.Window.currentFbo.height = CORE.Window.render.height;
#else #else
@ -1805,8 +1846,8 @@ int InitPlatform(void)
RGFW_monitor* currentMonitor = RGFW_window_getMonitor(platform.window); RGFW_monitor* currentMonitor = RGFW_window_getMonitor(platform.window);
CORE.Window.screenScale = MatrixScale(currentMonitor->pixelRatio, currentMonitor->pixelRatio, 1.0f); CORE.Window.screenScale = MatrixScale(currentMonitor->pixelRatio, currentMonitor->pixelRatio, 1.0f);
CORE.Window.render.width = CORE.Window.screen.width * currentMonitor->pixelRatio; CORE.Window.render.width = CORE.Window.screen.width*currentMonitor->pixelRatio;
CORE.Window.render.height = CORE.Window.screen.height * currentMonitor->pixelRatio; CORE.Window.render.height = CORE.Window.screen.height*currentMonitor->pixelRatio;
CORE.Window.currentFbo.width = CORE.Window.render.width; CORE.Window.currentFbo.width = CORE.Window.render.width;
CORE.Window.currentFbo.height = CORE.Window.render.height; CORE.Window.currentFbo.height = CORE.Window.render.height;
#endif #endif
@ -1814,7 +1855,7 @@ int InitPlatform(void)
platform.surfaceWidth = CORE.Window.currentFbo.width; platform.surfaceWidth = CORE.Window.currentFbo.width;
platform.surfaceHeight = CORE.Window.currentFbo.height; platform.surfaceHeight = CORE.Window.currentFbo.height;
platform.surfacePixels = RL_MALLOC(platform.surfaceWidth * platform.surfaceHeight * 4); platform.surfacePixels = RL_MALLOC(platform.surfaceWidth*platform.surfaceHeight*4);
if (platform.surfacePixels == NULL) if (platform.surfacePixels == NULL)
{ {
TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize software pixel buffer"); TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize software pixel buffer");

View File

@ -1006,7 +1006,7 @@ double GetTime(void)
double time = 0.0; double time = 0.0;
struct timespec ts = { 0 }; struct timespec ts = { 0 };
clock_gettime(CLOCK_MONOTONIC, &ts); clock_gettime(CLOCK_MONOTONIC, &ts);
unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec; unsigned long long nanoSeconds = (unsigned long long)ts.tv_sec*1000000000LLU + (unsigned long long)ts.tv_nsec;
time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer() time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer()

View File

@ -364,14 +364,18 @@ double GetTime(void)
{ {
double time = 0.0; double time = 0.0;
#if defined(_WIN32) #if defined(_WIN32)
LARGE_INTEGER now = { 0 }; LARGE_INTEGER currentTicks = { 0 };
QueryPerformanceCounter(&now); QueryPerformanceCounter(&currentTicks);
return (double)(now.QuadPart - CORE.Time.base)/(double)platform.timerFrequency.QuadPart;
time = (double)(currentTicks.QuadPart - CORE.Time.base)/(double)platform.timerFrequency.QuadPart;
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__EMSCRIPTEN__) #elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__EMSCRIPTEN__)
struct timespec ts = { 0 }; struct timespec ts = { 0 };
clock_gettime(CLOCK_MONOTONIC, &ts); clock_gettime(CLOCK_MONOTONIC, &ts);
unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec; unsigned long long nanoSeconds = (unsigned long long)ts.tv_sec*1000000000LLU + (unsigned long long)ts.tv_nsec;
time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer() time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer()
#elif defined(PICO_RP2350)
time = (double)to_ms_since_boot(get_absolute_time())/1000.0;
#endif #endif
return time; return time;
} }

View File

@ -341,9 +341,11 @@ void SwapScreenBuffer(void)
double GetTime(void) double GetTime(void)
{ {
double time = 0.0; double time = 0.0;
struct timespec ts = { 0 }; struct timespec ts = { 0 };
clock_gettime(CLOCK_MONOTONIC, &ts); clock_gettime(CLOCK_MONOTONIC, &ts);
unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec; unsigned long long nanoSeconds = (unsigned long long)ts.tv_sec*1000000000LLU + (unsigned long long)ts.tv_nsec;
time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer() time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer()
return time; return time;

View File

@ -858,7 +858,7 @@ Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int
else if ((strcmp(fileType, ".mp3") == 0) || (strcmp(fileType, ".MP3") == 0)) else if ((strcmp(fileType, ".mp3") == 0) || (strcmp(fileType, ".MP3") == 0))
{ {
drmp3_config config = { 0 }; drmp3_config config = { 0 };
unsigned long long int totalFrameCount = 0; unsigned long long totalFrameCount = 0;
// NOTE: Forcing conversion to 32bit float sample size on reading // NOTE: Forcing conversion to 32bit float sample size on reading
wave.data = drmp3_open_memory_and_read_pcm_frames_f32(fileData, dataSize, &config, &totalFrameCount, NULL); wave.data = drmp3_open_memory_and_read_pcm_frames_f32(fileData, dataSize, &config, &totalFrameCount, NULL);
@ -868,7 +868,7 @@ Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int
{ {
wave.channels = config.channels; wave.channels = config.channels;
wave.sampleRate = config.sampleRate; wave.sampleRate = config.sampleRate;
wave.frameCount = (int)totalFrameCount; wave.frameCount = (unsigned int)totalFrameCount; // WARNING: Potential loss of data
} }
else TRACELOG(LOG_WARNING, "WAVE: Failed to load MP3 data"); else TRACELOG(LOG_WARNING, "WAVE: Failed to load MP3 data");
@ -896,13 +896,13 @@ Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int
#if SUPPORT_FILEFORMAT_FLAC #if SUPPORT_FILEFORMAT_FLAC
else if ((strcmp(fileType, ".flac") == 0) || (strcmp(fileType, ".FLAC") == 0)) else if ((strcmp(fileType, ".flac") == 0) || (strcmp(fileType, ".FLAC") == 0))
{ {
unsigned long long int totalFrameCount = 0; unsigned long long totalFrameCount = 0;
// NOTE: Forcing conversion to 16bit sample size on reading // NOTE: Forcing conversion to 16bit sample size on reading
wave.data = drflac_open_memory_and_read_pcm_frames_s16(fileData, dataSize, &wave.channels, &wave.sampleRate, &totalFrameCount, NULL); wave.data = drflac_open_memory_and_read_pcm_frames_s16(fileData, dataSize, &wave.channels, &wave.sampleRate, &totalFrameCount, NULL);
wave.sampleSize = 16; wave.sampleSize = 16;
if (wave.data != NULL) wave.frameCount = (unsigned int)totalFrameCount; if (wave.data != NULL) wave.frameCount = (unsigned int)totalFrameCount; // WARNING: Potential loss of data
else TRACELOG(LOG_WARNING, "WAVE: Failed to load FLAC data"); else TRACELOG(LOG_WARNING, "WAVE: Failed to load FLAC data");
} }
#endif #endif
@ -1048,6 +1048,7 @@ void UnloadSoundAlias(Sound alias)
{ {
UntrackAudioBuffer(alias.stream.buffer); UntrackAudioBuffer(alias.stream.buffer);
ma_data_converter_uninit(&alias.stream.buffer->converter, NULL); ma_data_converter_uninit(&alias.stream.buffer->converter, NULL);
RL_FREE(alias.stream.buffer->converterResidual);
RL_FREE(alias.stream.buffer); RL_FREE(alias.stream.buffer);
} }
} }

View File

@ -1164,7 +1164,7 @@ RLAPI bool ChangeDirectory(const char *dirPath); // Change wo
RLAPI bool IsPathFile(const char *path); // Check if a given path is a file or a directory RLAPI bool IsPathFile(const char *path); // Check if a given path is a file or a directory
RLAPI bool IsFileNameValid(const char *fileName); // Check if fileName is valid for the platform/OS RLAPI bool IsFileNameValid(const char *fileName); // Check if fileName is valid for the platform/OS
RLAPI FilePathList LoadDirectoryFiles(const char *dirPath); // Load directory filepaths, files and directories, no subdirs scan RLAPI FilePathList LoadDirectoryFiles(const char *dirPath); // Load directory filepaths, files and directories, no subdirs scan
RLAPI FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs); // Load directory filepaths with extension filtering and subdir scan; some filters available: `*.*`,`FILES*`,`DIRS*` RLAPI FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs); // Load directory filepaths with extension filtering and subdir scan; some filters available: '*.*','FILES*','DIRS*'
RLAPI void UnloadDirectoryFiles(FilePathList files); // Unload filepaths RLAPI void UnloadDirectoryFiles(FilePathList files); // Unload filepaths
RLAPI bool IsFileDropped(void); // Check if a file has been dropped into window RLAPI bool IsFileDropped(void); // Check if a file has been dropped into window
RLAPI FilePathList LoadDroppedFiles(void); // Load dropped filepaths RLAPI FilePathList LoadDroppedFiles(void); // Load dropped filepaths

View File

@ -385,7 +385,7 @@ typedef struct CoreData {
double draw; // Time measure for frame draw (seconds) double draw; // Time measure for frame draw (seconds)
double frame; // Time measure for one frame (seconds) double frame; // Time measure for one frame (seconds)
double target; // Desired time for one frame, if 0 not applied (seconds) double target; // Desired time for one frame, if 0 not applied (seconds)
unsigned long long int base; // Base time measure for hi-res timer (ticks or nanoseconds) unsigned long long base; // Base time measure for hi-res timer (ticks or nanoseconds)
unsigned int frameCounter; // Frame counter (frames) unsigned int frameCounter; // Frame counter (frames)
} Time; } Time;
@ -506,11 +506,11 @@ __declspec(dllimport) void __stdcall Sleep(unsigned long msTimeout); // Required
const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed' const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed'
#endif #endif
// NOTE: PLATFORM_DESKTOP defaults to GLFW backend
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP)
#define PLATFORM_DESKTOP_GLFW #define PLATFORM_DESKTOP_GLFW
#endif #endif
// Include platform-specific submodules // Include platform-specific submodules
#if defined(PLATFORM_DESKTOP_GLFW) #if defined(PLATFORM_DESKTOP_GLFW)
#include "platforms/rcore_desktop_glfw.c" #include "platforms/rcore_desktop_glfw.c"
@ -1970,7 +1970,7 @@ unsigned char *LoadFileData(const char *fileName, int *dataSize)
size_t count = fread(data, sizeof(unsigned char), size, file); size_t count = fread(data, sizeof(unsigned char), size, file);
// WARNING: fread() returns a size_t value, usually 'unsigned int' (32bit compilation) and 'unsigned long long' (64bit compilation) // WARNING: fread() returns a size_t value, usually 'unsigned int' (32bit compilation) and 'unsigned long long' (64bit compilation)
// dataSize is unified along raylib as a 'int' type, so, for file-sizes > INT_MAX (2147483647 bytes) there is a limitation // dataSize is unified along raylib as a 'int' type, so, for file-sizes >INT_MAX (2147483647 bytes) there is a limitation
if (count > 2147483647) if (count > 2147483647)
{ {
TRACELOG(LOG_WARNING, "FILEIO: [%s] File is bigger than 2147483647 bytes, avoid using LoadFileData()", fileName); TRACELOG(LOG_WARNING, "FILEIO: [%s] File is bigger than 2147483647 bytes, avoid using LoadFileData()", fileName);
@ -2318,7 +2318,7 @@ bool FileExists(const char *fileName)
{ {
bool result = false; bool result = false;
if (ACCESS(fileName) != -1) result = true; if ((fileName != NULL) && (ACCESS(fileName) != -1)) result = true;
// NOTE: Alternatively, stat() can be used instead of access() // NOTE: Alternatively, stat() can be used instead of access()
//#include <sys/stat.h> //#include <sys/stat.h>
@ -3336,15 +3336,15 @@ unsigned int *ComputeSHA1(const unsigned char *data, int dataSize)
memcpy(msg, data, dataSize); memcpy(msg, data, dataSize);
msg[dataSize] = 128; // Write the '1' bit msg[dataSize] = 128; // Write the '1' bit
unsigned long long bitsLen = 8ULL * dataSize; unsigned long long bitsLen = 8ULL*dataSize;
msg[newDataSize-1] = (unsigned char)(bitsLen); msg[newDataSize - 1] = (unsigned char)(bitsLen);
msg[newDataSize-2] = (unsigned char)(bitsLen >> 8); msg[newDataSize - 2] = (unsigned char)(bitsLen >> 8);
msg[newDataSize-3] = (unsigned char)(bitsLen >> 16); msg[newDataSize - 3] = (unsigned char)(bitsLen >> 16);
msg[newDataSize-4] = (unsigned char)(bitsLen >> 24); msg[newDataSize - 4] = (unsigned char)(bitsLen >> 24);
msg[newDataSize-5] = (unsigned char)(bitsLen >> 32); msg[newDataSize - 5] = (unsigned char)(bitsLen >> 32);
msg[newDataSize-6] = (unsigned char)(bitsLen >> 40); msg[newDataSize - 6] = (unsigned char)(bitsLen >> 40);
msg[newDataSize-7] = (unsigned char)(bitsLen >> 48); msg[newDataSize - 7] = (unsigned char)(bitsLen >> 48);
msg[newDataSize-8] = (unsigned char)(bitsLen >> 56); msg[newDataSize - 8] = (unsigned char)(bitsLen >> 56);
// Process the message in successive 512-bit chunks // Process the message in successive 512-bit chunks
for (int offset = 0; offset < newDataSize; offset += (512/8)) for (int offset = 0; offset < newDataSize; offset += (512/8))
@ -3453,8 +3453,8 @@ unsigned int *ComputeSHA256(const unsigned char *data, int dataSize)
hash[6] = 0x1f83d9ab; hash[6] = 0x1f83d9ab;
hash[7] = 0x5be0cd19; hash[7] = 0x5be0cd19;
const unsigned long long int bitLen = ((unsigned long long int)dataSize)*8; const unsigned long long bitLen = 8ULL*dataSize;
unsigned long long int paddedSize = dataSize + sizeof(dataSize); unsigned long long paddedSize = dataSize + sizeof(dataSize);
paddedSize += (64 - (paddedSize%64)); paddedSize += (64 - (paddedSize%64));
unsigned char *buffer = (unsigned char *)RL_CALLOC(paddedSize, sizeof(unsigned char)); unsigned char *buffer = (unsigned char *)RL_CALLOC(paddedSize, sizeof(unsigned char));
@ -3465,7 +3465,7 @@ unsigned int *ComputeSHA256(const unsigned char *data, int dataSize)
buffer[(paddedSize - sizeof(bitLen)) + (i - 1)] = (bitLen >> (8*(sizeof(bitLen) - i))) & 0xFF; buffer[(paddedSize - sizeof(bitLen)) + (i - 1)] = (bitLen >> (8*(sizeof(bitLen) - i))) & 0xFF;
} }
for (unsigned long long int blockN = 0; blockN < paddedSize/64; blockN++) for (unsigned long long blockN = 0; blockN < paddedSize/64; blockN++)
{ {
unsigned int a = hash[0]; unsigned int a = hash[0];
unsigned int b = hash[1]; unsigned int b = hash[1];
@ -3487,7 +3487,7 @@ unsigned int *ComputeSHA256(const unsigned char *data, int dataSize)
} }
for (int t = 16; t < 64; t++) w[t] = SHA256_A1(w[t - 2]) + w[t - 7] + SHA256_A0(w[t - 15]) + w[t - 16]; for (int t = 16; t < 64; t++) w[t] = SHA256_A1(w[t - 2]) + w[t - 7] + SHA256_A0(w[t - 15]) + w[t - 16];
for (unsigned long long int t = 0; t < 64; t++) for (int t = 0; t < 64; t++)
{ {
unsigned int e1 = (SHA256_ROTATE_RIGHT(e, 6) ^ SHA256_ROTATE_RIGHT(e, 11) ^ SHA256_ROTATE_RIGHT(e, 25)); unsigned int e1 = (SHA256_ROTATE_RIGHT(e, 6) ^ SHA256_ROTATE_RIGHT(e, 11) ^ SHA256_ROTATE_RIGHT(e, 25));
unsigned int ch = ((e & f) ^ (~e & g)); unsigned int ch = ((e & f) ^ (~e & g));
@ -4219,7 +4219,7 @@ void InitTimer(void)
if (clock_gettime(CLOCK_MONOTONIC, &now) == 0) // Success if (clock_gettime(CLOCK_MONOTONIC, &now) == 0) // Success
{ {
CORE.Time.base = (unsigned long long int)now.tv_sec*1000000000LLU + (unsigned long long int)now.tv_nsec; CORE.Time.base = (unsigned long long)now.tv_sec*1000000000LLU + (unsigned long long)now.tv_nsec;
} }
else TRACELOG(LOG_WARNING, "TIMER: Hi-resolution timer not available"); else TRACELOG(LOG_WARNING, "TIMER: Hi-resolution timer not available");
#endif #endif

View File

@ -157,8 +157,8 @@ float GetGesturePinchAngle(void); // Get gesture pinch ang
extern "C" { // Prevents name mangling of functions extern "C" { // Prevents name mangling of functions
#endif #endif
// Functions required to query time on Windows // Functions required to query time on Windows
int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount); int __stdcall QueryPerformanceCounter(unsigned long long *lpPerformanceCount);
int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency); int __stdcall QueryPerformanceFrequency(unsigned long long *lpFrequency);
#if defined(__cplusplus) #if defined(__cplusplus)
} }
#endif #endif
@ -518,37 +518,36 @@ static double rgGetCurrentTime(void)
time = GetTime(); time = GetTime();
#else #else
#if defined(_WIN32) #if defined(_WIN32)
unsigned long long int clockFrequency, currentTime; unsigned long long clockFrequency = 0;
unsigned long long currentClockTicks = 0;
QueryPerformanceFrequency(&clockFrequency); // BE CAREFUL: Costly operation! QueryPerformanceFrequency(&clockFrequency); // BE CAREFUL: Costly operation!
QueryPerformanceCounter(&currentTime); QueryPerformanceCounter(&currentClockTicks);
time = (double)currentTime/clockFrequency; // Time in seconds time = (double)currentClockTicks/clockFrequency; // Time in seconds
#endif #endif
#if defined(__linux__) #if defined(__linux__)
// NOTE: Only for Linux-based systems // NOTE: Only for Linux-based systems
struct timespec now; struct timespec now = { 0 };
clock_gettime(CLOCK_MONOTONIC, &now); clock_gettime(CLOCK_MONOTONIC, &now);
unsigned long long int nowTime = (unsigned long long int)now.tv_sec*1000000000LLU + (unsigned long long int)now.tv_nsec; // Time in nanoseconds unsigned long long nanoSeconds = (unsigned long long)now.tv_sec*1000000000LLU + (unsigned long long)now.tv_nsec;
time = ((double)nowTime*1e-9); // Time in seconds time = ((double)nanoSeconds*1e-9); // Time in seconds
#endif #endif
#if defined(__APPLE__) #if defined(__APPLE__)
//#define CLOCK_REALTIME CALENDAR_CLOCK // returns UTC time since 1970-01-01 //#define CLOCK_REALTIME CALENDAR_CLOCK // returns UTC time since 1970-01-01
//#define CLOCK_MONOTONIC SYSTEM_CLOCK // returns the time since boot time //#define CLOCK_MONOTONIC SYSTEM_CLOCK // returns the time since boot time
clock_serv_t cclock; clock_serv_t cclock = { 0 };
mach_timespec_t now; mach_timespec_t now = { 0 };
host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock); host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
// NOTE: OS X does not have clock_gettime(), using clock_get_time() // NOTE: OS X does not have clock_gettime(), using clock_get_time()
clock_get_time(cclock, &now); clock_get_time(cclock, &now);
mach_port_deallocate(mach_task_self(), cclock); mach_port_deallocate(mach_task_self(), cclock);
unsigned long long int nowTime = (unsigned long long int)now.tv_sec*1000000000LLU + (unsigned long long int)now.tv_nsec; // Time in nanoseconds unsigned long long nanoSeconds = (unsigned long long)now.tv_sec*1000000000LLU + (unsigned long long)now.tv_nsec;
time = ((double)nowTime*1e-9); // Time in seconds time = ((double)nanoSeconds*1e-9); // Time in seconds
#endif #endif
#endif #endif

View File

@ -3647,7 +3647,7 @@ void rlGetGlTextureFormats(int format, unsigned int *glInternalFormat, unsigned
case RL_PIXELFORMAT_UNCOMPRESSED_R16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_LUMINANCE; *glFormat = GL_LUMINANCE; *glType = GL_HALF_FLOAT_ARB; break; case RL_PIXELFORMAT_UNCOMPRESSED_R16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_LUMINANCE; *glFormat = GL_LUMINANCE; *glType = GL_HALF_FLOAT_ARB; break;
case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGB; *glFormat = GL_RGB; *glType = GL_HALF_FLOAT_ARB; break; case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGB; *glFormat = GL_RGB; *glType = GL_HALF_FLOAT_ARB; break;
case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_HALF_FLOAT_ARB; break; case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_HALF_FLOAT_ARB; break;
#else // defined(GRAPHICS_API_OPENGL_ES2) #else // GRAPHICS_API_OPENGL_ES2
case RL_PIXELFORMAT_UNCOMPRESSED_R16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_LUMINANCE; *glFormat = GL_LUMINANCE; *glType = GL_HALF_FLOAT_OES; break; // NOTE: Requires extension OES_texture_half_float case RL_PIXELFORMAT_UNCOMPRESSED_R16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_LUMINANCE; *glFormat = GL_LUMINANCE; *glType = GL_HALF_FLOAT_OES; break; // NOTE: Requires extension OES_texture_half_float
case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGB; *glFormat = GL_RGB; *glType = GL_HALF_FLOAT_OES; break; // NOTE: Requires extension OES_texture_half_float case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGB; *glFormat = GL_RGB; *glType = GL_HALF_FLOAT_OES; break; // NOTE: Requires extension OES_texture_half_float
case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_HALF_FLOAT_OES; break; // NOTE: Requires extension OES_texture_half_float case RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: if (RLGL.ExtSupported.texFloat16) *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_HALF_FLOAT_OES; break; // NOTE: Requires extension OES_texture_half_float

View File

@ -361,7 +361,7 @@ void DrawCircleSector(Vector2 center, float radius, float startAngle, float endA
{ {
// Calculate the maximum angle between segments based on the error rate (usually 0.5f) // Calculate the maximum angle between segments based on the error rate (usually 0.5f)
float th = acosf(2*powf(1 - SMOOTH_CIRCLE_ERROR_RATE/radius, 2) - 1); float th = acosf(2*powf(1 - SMOOTH_CIRCLE_ERROR_RATE/radius, 2) - 1);
segments = (int)((endAngle - startAngle)*ceilf(2*PI/th)/360); segments = (int)ceilf((endAngle - startAngle)*(2*PI/th)/360.0f);
if (segments <= 0) segments = minSegments; if (segments <= 0) segments = minSegments;
} }
@ -453,7 +453,7 @@ void DrawCircleSectorLines(Vector2 center, float radius, float startAngle, float
{ {
// Calculate the maximum angle between segments based on the error rate (usually 0.5f) // Calculate the maximum angle between segments based on the error rate (usually 0.5f)
float th = acosf(2*powf(1 - SMOOTH_CIRCLE_ERROR_RATE/radius, 2) - 1); float th = acosf(2*powf(1 - SMOOTH_CIRCLE_ERROR_RATE/radius, 2) - 1);
segments = (int)((endAngle - startAngle)*ceilf(2*PI/th)/360); segments = (int)ceilf((endAngle - startAngle)*(2*PI/th)/360.0f);
if (segments <= 0) segments = minSegments; if (segments <= 0) segments = minSegments;
} }
@ -579,7 +579,7 @@ void DrawRing(Vector2 center, float innerRadius, float outerRadius, float startA
{ {
// Calculate the maximum angle between segments based on the error rate (usually 0.5f) // Calculate the maximum angle between segments based on the error rate (usually 0.5f)
float th = acosf(2*powf(1 - SMOOTH_CIRCLE_ERROR_RATE/outerRadius, 2) - 1); float th = acosf(2*powf(1 - SMOOTH_CIRCLE_ERROR_RATE/outerRadius, 2) - 1);
segments = (int)((endAngle - startAngle)*ceilf(2*PI/th)/360); segments = (int)ceilf((endAngle - startAngle)*(2*PI/th)/360.0f);
if (segments <= 0) segments = minSegments; if (segments <= 0) segments = minSegments;
} }
@ -670,7 +670,7 @@ void DrawRingLines(Vector2 center, float innerRadius, float outerRadius, float s
{ {
// Calculate the maximum angle between segments based on the error rate (usually 0.5f) // Calculate the maximum angle between segments based on the error rate (usually 0.5f)
float th = acosf(2*powf(1 - SMOOTH_CIRCLE_ERROR_RATE/outerRadius, 2) - 1); float th = acosf(2*powf(1 - SMOOTH_CIRCLE_ERROR_RATE/outerRadius, 2) - 1);
segments = (int)((endAngle - startAngle)*ceilf(2*PI/th)/360); segments = (int)ceilf((endAngle - startAngle)*(2*PI/th)/360.0f);
if (segments <= 0) segments = minSegments; if (segments <= 0) segments = minSegments;
} }
@ -960,7 +960,7 @@ void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color co
{ {
// Calculate the maximum angle between segments based on the error rate (usually 0.5f) // Calculate the maximum angle between segments based on the error rate (usually 0.5f)
float th = acosf(2*powf(1 - SMOOTH_CIRCLE_ERROR_RATE/radius, 2) - 1); float th = acosf(2*powf(1 - SMOOTH_CIRCLE_ERROR_RATE/radius, 2) - 1);
segments = (int)(ceilf(2*PI/th)/4.0f); segments = (int)ceilf((2*PI/th)/4.0f);
if (segments <= 0) segments = 4; if (segments <= 0) segments = 4;
} }
@ -1195,7 +1195,7 @@ void DrawRectangleRoundedLinesEx(Rectangle rec, float roundness, int segments, f
{ {
// Calculate the maximum angle between segments based on the error rate (usually 0.5f) // Calculate the maximum angle between segments based on the error rate (usually 0.5f)
float th = acosf(2*powf(1 - SMOOTH_CIRCLE_ERROR_RATE/radius, 2) - 1); float th = acosf(2*powf(1 - SMOOTH_CIRCLE_ERROR_RATE/radius, 2) - 1);
segments = (int)(ceilf(2*PI/th)/2.0f); segments = (int)ceilf((2*PI/th)/4.0f);
if (segments <= 0) segments = 4; if (segments <= 0) segments = 4;
} }

View File

@ -580,8 +580,13 @@ Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int
TRACELOG(LOG_INFO, "FONT: Data loaded successfully (%i pixel size | %i glyphs)", font.baseSize, font.glyphCount); TRACELOG(LOG_INFO, "FONT: Data loaded successfully (%i pixel size | %i glyphs)", font.baseSize, font.glyphCount);
} }
else font = GetFontDefault(); else
{
TRACELOG(LOG_WARNING, "FONT: Font is not supported by LoadFontEx/LoadFontFromMemory or no glyphs found, reverted to default font");
font = GetFontDefault();
}
#else #else
TRACELOG(LOG_WARNING, "FONT: Font is not supported by LoadFontEx/LoadFontFromMemory or no glyphs found, reverted to default font");
font = GetFontDefault(); font = GetFontDefault();
#endif #endif

View File

@ -675,13 +675,12 @@ int main(int argc, char *argv[])
// WARNING 2: raylib.a and raylib.web.a must be available when compiling locally // WARNING 2: raylib.a and raylib.web.a must be available when compiling locally
#if defined(_WIN32) #if defined(_WIN32)
LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: Win32)\n", GetFileNameWithoutExt(inFileName)); LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: Win32)\n", GetFileNameWithoutExt(inFileName));
//putenv("RAYLIB_DIR=C:\\GitHub\\raylib");
_putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin"); _putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin");
system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName));
#else #else
LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: POSIX)\n", GetFileNameWithoutExt(inFileName)); LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: POSIX)\n", GetFileNameWithoutExt(inFileName));
system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName));
#endif #endif
system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName));
// Update generated .html metadata // Update generated .html metadata
LOG("INFO: [%s] Updating HTML Metadata...\n", TextFormat("%s.html", exName)); LOG("INFO: [%s] Updating HTML Metadata...\n", TextFormat("%s.html", exName));
UpdateWebMetadata(TextFormat("%s/%s/%s.html", exBasePath, exCategory, exName), UpdateWebMetadata(TextFormat("%s/%s/%s.html", exBasePath, exCategory, exName),
@ -778,10 +777,9 @@ int main(int argc, char *argv[])
// WARNING: EMSDK_PATH must be set to proper location when calling from GitHub Actions // WARNING: EMSDK_PATH must be set to proper location when calling from GitHub Actions
#if defined(_WIN32) #if defined(_WIN32)
_putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin"); _putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin");
system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exRecategory, exRename));
#else
system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exRecategory, exRename));
#endif #endif
system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exRecategory, exRename));
// Update generated .html metadata // Update generated .html metadata
UpdateWebMetadata(TextFormat("%s/%s/%s.html", exBasePath, exCategory, exRename), UpdateWebMetadata(TextFormat("%s/%s/%s.html", exBasePath, exCategory, exRename),
TextFormat("%s/%s/%s.c", exBasePath, exCategory, exRename)); TextFormat("%s/%s/%s.c", exBasePath, exCategory, exRename));
@ -917,7 +915,7 @@ int main(int argc, char *argv[])
// Set required environment variables // Set required environment variables
//putenv(TextFormat("RAYLIB_DIR=%s\\..", exBasePath)); //putenv(TextFormat("RAYLIB_DIR=%s\\..", exBasePath));
_putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin"); _putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin");
//putenv("MAKE=mingw32-make"); //putenv("MAKE=make");
//ChangeDirectory(exBasePath); //ChangeDirectory(exBasePath);
#endif #endif
for (int i = 0; i < exBuildListCount; i++) for (int i = 0; i < exBuildListCount; i++)
@ -933,7 +931,7 @@ int main(int argc, char *argv[])
// Build example for PLATFORM_DESKTOP // Build example for PLATFORM_DESKTOP
#if defined(_WIN32) #if defined(_WIN32)
LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: Win32)\n", exName); LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: Win32)\n", exName);
system(TextFormat("mingw32-make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exCategory, exName)); system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exCategory, exName));
#elif defined(PLATFORM_DRM) #elif defined(PLATFORM_DRM)
LOG("INFO: [%s] Building example for PLATFORM_DRM (Host: POSIX)\n", exName); LOG("INFO: [%s] Building example for PLATFORM_DRM (Host: POSIX)\n", exName);
system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DRM -B > %s/%s/logs/%s.build.log 2>&1", system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DRM -B > %s/%s/logs/%s.build.log 2>&1",
@ -949,13 +947,9 @@ int main(int argc, char *argv[])
// Build: raylib.com/examples/<category>/<category>_example_name.data // Build: raylib.com/examples/<category>/<category>_example_name.data
// Build: raylib.com/examples/<category>/<category>_example_name.wasm // Build: raylib.com/examples/<category>/<category>_example_name.wasm
// Build: raylib.com/examples/<category>/<category>_example_name.js // Build: raylib.com/examples/<category>/<category>_example_name.js
#if defined(_WIN32) LOG("INFO: [%s] Building example for PLATFORM_WEB\n", exName);
LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: Win32)\n", exName);
system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName));
#else
LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: POSIX)\n", exName);
system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName)); system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName));
#endif
// Update generated .html metadata // Update generated .html metadata
LOG("INFO: [%s] Updating HTML Metadata...\n", TextFormat("%s.html", exName)); LOG("INFO: [%s] Updating HTML Metadata...\n", TextFormat("%s.html", exName));
UpdateWebMetadata(TextFormat("%s/%s/%s.html", exBasePath, exCategory, exName), UpdateWebMetadata(TextFormat("%s/%s/%s.html", exBasePath, exCategory, exName),
@ -1312,11 +1306,10 @@ int main(int argc, char *argv[])
#if defined(_WIN32) #if defined(_WIN32)
LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: Win32)\n", exInfo->name); LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: Win32)\n", exInfo->name);
_putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin"); _putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin");
system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exInfo->category, exInfo->name));
#else #else
LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: POSIX)\n", exInfo->name); LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: POSIX)\n", exInfo->name);
system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exInfo->category, exInfo->name));
#endif #endif
system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exInfo->category, exInfo->name));
// Update generated .html metadata // Update generated .html metadata
LOG("INFO: [%s.html] Updating HTML Metadata...\n", exInfo->name); LOG("INFO: [%s.html] Updating HTML Metadata...\n", exInfo->name);
@ -1495,7 +1488,7 @@ int main(int argc, char *argv[])
// Set required environment variables // Set required environment variables
//putenv(TextFormat("RAYLIB_DIR=%s\\..", exBasePath)); //putenv(TextFormat("RAYLIB_DIR=%s\\..", exBasePath));
//_putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin"); //_putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin");
//putenv("MAKE=mingw32-make"); //putenv("MAKE=make");
//ChangeDirectory(exBasePath); //ChangeDirectory(exBasePath);
//_putenv("MAKE_PATH=C:\\raylib\\w64devkit\\bin"); //_putenv("MAKE_PATH=C:\\raylib\\w64devkit\\bin");
//_putenv("EMSDK_PATH = C:\\raylib\\emsdk"); //_putenv("EMSDK_PATH = C:\\raylib\\emsdk");
@ -1592,7 +1585,7 @@ int main(int argc, char *argv[])
// Build: raylib.com/examples/<category>/<category>_example_name.js // Build: raylib.com/examples/<category>/<category>_example_name.js
#if defined(_WIN32) #if defined(_WIN32)
LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: Win32)\n", exName); LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: Win32)\n", exName);
system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B > %s/%s/logs/%s.build.log 2>&1", system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B > %s/%s/logs/%s.build.log 2>&1",
exBasePath, exCategory, exName, exBasePath, exCategory, exName)); exBasePath, exCategory, exName, exBasePath, exCategory, exName));
#else #else
LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: POSIX)\n", exName); LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: POSIX)\n", exName);
@ -1641,13 +1634,13 @@ int main(int argc, char *argv[])
// Set required environment variables // Set required environment variables
//putenv(TextFormat("RAYLIB_DIR=%s\\..", exBasePath)); //putenv(TextFormat("RAYLIB_DIR=%s\\..", exBasePath));
_putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin"); _putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin");
//putenv("MAKE=mingw32-make"); //putenv("MAKE=make");
//ChangeDirectory(exBasePath); //ChangeDirectory(exBasePath);
#endif #endif
// Build example for PLATFORM_DESKTOP // Build example for PLATFORM_DESKTOP
#if defined(_WIN32) #if defined(_WIN32)
LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: Win32)\n", exName); LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: Win32)\n", exName);
system(TextFormat("mingw32-make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B > %s/%s/logs/%s.build.log 2>&1", system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B > %s/%s/logs/%s.build.log 2>&1",
exBasePath, exCategory, exName, exBasePath, exCategory, exName)); exBasePath, exCategory, exName, exBasePath, exCategory, exName));
#elif defined(PLATFORM_DRM) #elif defined(PLATFORM_DRM)
LOG("INFO: [%s] Building example for PLATFORM_DRM (Host: POSIX)\n", exName); LOG("INFO: [%s] Building example for PLATFORM_DRM (Host: POSIX)\n", exName);

View File

@ -4696,7 +4696,7 @@
}, },
{ {
"name": "LoadDirectoryFilesEx", "name": "LoadDirectoryFilesEx",
"description": "Load directory filepaths with extension filtering and subdir scan; some filters available: `*.*`,`FILES*`,`DIRS*`", "description": "Load directory filepaths with extension filtering and subdir scan; some filters available: '*.*','FILES*','DIRS*'",
"returnType": "FilePathList", "returnType": "FilePathList",
"params": [ "params": [
{ {

View File

@ -4207,7 +4207,7 @@ return {
}, },
{ {
name = "LoadDirectoryFilesEx", name = "LoadDirectoryFilesEx",
description = "Load directory filepaths with extension filtering and subdir scan; some filters available: `*.*`,`FILES*`,`DIRS*`", description = "Load directory filepaths with extension filtering and subdir scan; some filters available: '*.*','FILES*','DIRS*'",
returnType = "FilePathList", returnType = "FilePathList",
params = { params = {
{type = "const char *", name = "basePath"}, {type = "const char *", name = "basePath"},

View File

@ -1789,7 +1789,7 @@ Function 146: LoadDirectoryFiles() (1 input parameters)
Function 147: LoadDirectoryFilesEx() (3 input parameters) Function 147: LoadDirectoryFilesEx() (3 input parameters)
Name: LoadDirectoryFilesEx Name: LoadDirectoryFilesEx
Return type: FilePathList Return type: FilePathList
Description: Load directory filepaths with extension filtering and subdir scan; some filters available: `*.*`,`FILES*`,`DIRS*` Description: Load directory filepaths with extension filtering and subdir scan; some filters available: '*.*','FILES*','DIRS*'
Param[1]: basePath (type: const char *) Param[1]: basePath (type: const char *)
Param[2]: filter (type: const char *) Param[2]: filter (type: const char *)
Param[3]: scanSubdirs (type: bool) Param[3]: scanSubdirs (type: bool)

View File

@ -1125,7 +1125,7 @@
<Function name="LoadDirectoryFiles" retType="FilePathList" paramCount="1" desc="Load directory filepaths, files and directories, no subdirs scan"> <Function name="LoadDirectoryFiles" retType="FilePathList" paramCount="1" desc="Load directory filepaths, files and directories, no subdirs scan">
<Param type="const char *" name="dirPath" desc="" /> <Param type="const char *" name="dirPath" desc="" />
</Function> </Function>
<Function name="LoadDirectoryFilesEx" retType="FilePathList" paramCount="3" desc="Load directory filepaths with extension filtering and subdir scan; some filters available: `*.*`,`FILES*`,`DIRS*`"> <Function name="LoadDirectoryFilesEx" retType="FilePathList" paramCount="3" desc="Load directory filepaths with extension filtering and subdir scan; some filters available: '*.*','FILES*','DIRS*'">
<Param type="const char *" name="basePath" desc="" /> <Param type="const char *" name="basePath" desc="" />
<Param type="const char *" name="filter" desc="" /> <Param type="const char *" name="filter" desc="" />
<Param type="bool" name="scanSubdirs" desc="" /> <Param type="bool" name="scanSubdirs" desc="" />