diff --git a/.gitignore b/.gitignore index b5be212d7..848a653b8 100644 --- a/.gitignore +++ b/.gitignore @@ -65,7 +65,7 @@ src/external/SDL3 # Emscripten emsdk -# Ignore wasm data in examples/ +# Ignore binaries generated in examples/ examples/**/* !examples/**/*.* !examples/**/*/ diff --git a/BINDINGS.md b/BINDINGS.md index d6fd107bd..7d350a9b0 100644 --- a/BINDINGS.md +++ b/BINDINGS.md @@ -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.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 | -| [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 | | [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 | @@ -105,7 +105,8 @@ Some people ported raylib to other languages in the form of bindings or wrappers | [raylib-jai](https://github.com/ahmedqarmout2/raylib-jai) | **5.5** | [Jai](https://github.com/BSVino/JaiPrimer/blob/master/JaiPrimer.md) | 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/) | **???** | -| [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 diff --git a/CMakeLists.txt b/CMakeLists.txt index da1b3bfe7..f1d319e8d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,7 +29,7 @@ include(CompilerFlags) # Registers build options that are exposed to cmake 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) message(FATAL_ERROR "Cannot disable both Wayland and X11") endif() diff --git a/CMakeOptions.txt b/CMakeOptions.txt index 5eff4c311..9e253dc55 100644 --- a/CMakeOptions.txt +++ b/CMakeOptions.txt @@ -6,7 +6,7 @@ if(EMSCRIPTEN) # 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.") 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?") diff --git a/build.zig b/build.zig index 5485cda47..8d8b2d353 100644 --- a/build.zig +++ b/build.zig @@ -739,7 +739,6 @@ fn addExamples( .root_module = exe_mod, .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 }) }); diff --git a/cmake/LibraryConfigurations.cmake b/cmake/LibraryConfigurations.cmake index 18680491d..262150be0 100644 --- a/cmake/LibraryConfigurations.cmake +++ b/cmake/LibraryConfigurations.cmake @@ -7,6 +7,30 @@ if(POLICY CMP0072) cmake_policy(SET CMP0072 NEW) 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)") if (${PLATFORM} STREQUAL "Desktop") @@ -67,6 +91,21 @@ if (${PLATFORM} STREQUAL "Desktop") 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") set(PLATFORM_CPP "PLATFORM_WEB") if(NOT GRAPHICS) @@ -222,6 +261,14 @@ endif () 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") set(LIBS_PRIVATE ${LIBS_PRIVATE} glfw) endif () diff --git a/examples/Makefile b/examples/Makefile index 334f59694..3e1844fc3 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -20,6 +20,8 @@ # - Linux (X11 desktop mode) # - macOS/OSX (x64, arm64 (not tested)) # - Others (not tested) +# > PLATFORM_DESKTOP_WIN32 (native Win32): +# - Windows (Win32, Win64) # > PLATFORM_WEB_RGFW: # - HTML5 (WebAssembly) # > PLATFORM_WEB: @@ -794,6 +796,23 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW) rm -f *.o 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) find . -type f -executable -delete rm -fv *.o diff --git a/examples/others/raylib_opengl_interop.c b/examples/others/raylib_opengl_interop.c index 540a623ab..3e4cf8839 100644 --- a/examples/others/raylib_opengl_interop.c +++ b/examples/others/raylib_opengl_interop.c @@ -28,7 +28,7 @@ #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) #include "glad_gles2.h" // Required for: OpenGL functionality #define glGenVertexArrays glGenVertexArraysOES diff --git a/src/Makefile b/src/Makefile index 118e6aae7..13f132707 100644 --- a/src/Makefile +++ b/src/Makefile @@ -119,7 +119,7 @@ USE_EXTERNAL_GLFW ?= FALSE # Enable support for X11 by default on Linux when using GLFW # 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 # Enable support for X11 by default on Linux when using RGFW diff --git a/src/external/jar_mod.h b/src/external/jar_mod.h index 7ecf9f437..12b8101c4 100644 --- a/src/external/jar_mod.h +++ b/src/external/jar_mod.h @@ -1538,10 +1538,10 @@ mulong jar_mod_load_file(jar_mod_context_t * modctx, const char* filename) modctx->modfile = (muchar *) JARMOD_MALLOC(fsize); modctx->modfilesize = fsize; memset(modctx->modfile, 0, fsize); - fread(modctx->modfile, fsize, 1, f); + if(fread(modctx->modfile, fsize, 1, f) != 1) fsize = 0; 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; } return fsize; diff --git a/src/external/miniaudio.h b/src/external/miniaudio.h index 24e676bb2..441f8de62 100644 --- a/src/external/miniaudio.h +++ b/src/external/miniaudio.h @@ -41495,11 +41495,11 @@ Web Audio Backend #ifdef MA_HAS_WEBAUDIO #include -#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 #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 #endif #endif diff --git a/src/external/rlsw.h b/src/external/rlsw.h index 7a7788f4b..85e4e8740 100644 --- a/src/external/rlsw.h +++ b/src/external/rlsw.h @@ -166,16 +166,15 @@ // Fast power-of-two texture wrap (SW_REPEAT mode only) // 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 -// signed `%` chain in the linear sampler. Saves a software divide on Xtensa -// and a few instructions everywhere. NPOT textures keep using the original -// path via a runtime `(size & (size-1)) == 0` check, so SW_REPEAT remains -// correct for them. The only observable behavior change is for POT textures -// sampled with negative UV coordinates: bitmask wrap (two's complement) can -// differ from `sw_fract` by one texel. Off by default to keep bit-for-bit -// behavior; opt in if you control your asset UVs. +// wrap (`x & (size-1)`) instead of `floorf`-based fractional wrap or the signed `%` chain in the linear sampler +// Saves a software divide on Xtensa and a few instructions everywhere +// NPOT textures keep using the original path via a runtime `(size & (size-1)) == 0` check, +// so SW_REPEAT remains correct for them +// The only observable behavior change is for POT textures sampled with negative UV coordinates: +// bitmask wrap (two's complement) can differ from `sw_fract` by one texel +// Off by default to keep bit-for-bit behavior; opt in if you control your asset UVs // -// #define SW_TEXTURE_REPEAT_POT_FAST +//#define SW_TEXTURE_REPEAT_POT_FAST //---------------------------------------------------------------------------------- // OpenGL Compatibility Types @@ -860,11 +859,9 @@ SWAPI void swGetFramebufferAttachmentParameteriv(SWattachment attachment, SWatta #endif // ESP-DSP acceleration: ESP-IDF ships an optimized math library that includes -// `dspm_mult_4x4x4_f32` (4x4 matrix multiply) and `dspm_mult_4x4x1_f32` -// (matrix * vector). These are S3-tuned hand-vectorized kernels that beat the -// scalar versions for both throughput and code-size. Detection is opt-in to -// 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). +// `dspm_mult_4x4x4_f32` (4x4 matrix multiply) and `dspm_mult_4x4x1_f32` (matrix * vector) +// These are S3-tuned hand-vectorized kernels that beat the scalar versions for both throughput and code-size +// Detection is opt-in to keep the dependency optional: define SW_USE_ESP_DSP from your build system #if defined(ESP_PLATFORM) && defined(SW_USE_ESP_DSP) #define SW_HAS_ESP_DSP #include "dspm_mult.h" @@ -884,41 +881,41 @@ SWAPI void swGetFramebufferAttachmentParameteriv(SWattachment attachment, SWatta #define SW_DEG2RAD (SW_PI/180.0f) #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 // the frustum (6 planes) then the scissor rectangle (4 planes): -// 4 + 6 + 4 = 14 vertices maximum. -#define SW_MAX_CLIPPED_POLYGON_VERTICES 14 -#define SW_CLIP_EPSILON 1e-4f +// 4 + 6 + 4 = 14 vertices maximum +#define SW_MAX_CLIPPED_POLYGON_VERTICES 14 +#define SW_CLIP_EPSILON 1e-4f -#define SW_HANDLE_NULL 0u -#define SW_POOL_SLOT_LIVE 0x80u // bit7 of the generation byte -#define SW_POOL_SLOT_VER_MASK 0x7Fu // bits6:0 = anti-ABA counter +#define SW_HANDLE_NULL 0u +#define SW_POOL_SLOT_LIVE 0x80u // bit7 of the generation byte +#define SW_POOL_SLOT_VER_MASK 0x7Fu // bits6:0 = anti-ABA counter -#define SW_CONCAT(a, b) a##b -#define SW_CONCATX(a, b) SW_CONCAT(a, b) +#define SW_CONCAT(a, b) a##b +#define SW_CONCATX(a, b) SW_CONCAT(a, b) -#define SW_FRAMEBUFFER_COLOR8_GET(c,p,o) SW_CONCATX(sw_pixel_read_color8_, SW_FRAMEBUFFER_COLOR_TYPE)((c),(p),(o)) -#define SW_FRAMEBUFFER_COLOR_GET(c,p,o) SW_CONCATX(sw_pixel_read_color_, SW_FRAMEBUFFER_COLOR_TYPE)((c),(p),(o)) -#define SW_FRAMEBUFFER_COLOR_SET(p,c,o) SW_CONCATX(sw_pixel_write_color_, SW_FRAMEBUFFER_COLOR_TYPE)((p),(c),(o)) +#define SW_FRAMEBUFFER_COLOR8_GET(c,p,o) SW_CONCATX(sw_pixel_read_color8_, SW_FRAMEBUFFER_COLOR_TYPE)((c),(p),(o)) +#define SW_FRAMEBUFFER_COLOR_GET(c,p,o) SW_CONCATX(sw_pixel_read_color_, SW_FRAMEBUFFER_COLOR_TYPE)((c),(p),(o)) +#define SW_FRAMEBUFFER_COLOR_SET(p,c,o) SW_CONCATX(sw_pixel_write_color_, SW_FRAMEBUFFER_COLOR_TYPE)((p),(c),(o)) -#define SW_FRAMEBUFFER_DEPTH_GET(p,o) SW_CONCATX(sw_pixel_read_depth_, SW_FRAMEBUFFER_DEPTH_TYPE)((p),(o)) -#define SW_FRAMEBUFFER_DEPTH_SET(p,d,o) SW_CONCATX(sw_pixel_write_depth_, SW_FRAMEBUFFER_DEPTH_TYPE)((p),(d),(o)) +#define SW_FRAMEBUFFER_DEPTH_GET(p,o) SW_CONCATX(sw_pixel_read_depth_, SW_FRAMEBUFFER_DEPTH_TYPE)((p),(o)) +#define SW_FRAMEBUFFER_DEPTH_SET(p,d,o) SW_CONCATX(sw_pixel_write_depth_, SW_FRAMEBUFFER_DEPTH_TYPE)((p),(d),(o)) -#define SW_FRAMEBUFFER_COLOR_FORMAT SW_CONCATX(SW_PIXELFORMAT_COLOR_, SW_FRAMEBUFFER_COLOR_TYPE) -#define SW_FRAMEBUFFER_DEPTH_FORMAT SW_CONCATX(SW_PIXELFORMAT_DEPTH_, SW_FRAMEBUFFER_DEPTH_TYPE) +#define SW_FRAMEBUFFER_COLOR_FORMAT SW_CONCATX(SW_PIXELFORMAT_COLOR_, SW_FRAMEBUFFER_COLOR_TYPE) +#define SW_FRAMEBUFFER_DEPTH_FORMAT SW_CONCATX(SW_PIXELFORMAT_DEPTH_, SW_FRAMEBUFFER_DEPTH_TYPE) -#define SW_FRAMEBUFFER_COLOR_SIZE SW_PIXELFORMAT_SIZE[SW_FRAMEBUFFER_COLOR_FORMAT] -#define SW_FRAMEBUFFER_DEPTH_SIZE SW_PIXELFORMAT_SIZE[SW_FRAMEBUFFER_DEPTH_FORMAT] +#define SW_FRAMEBUFFER_COLOR_SIZE SW_PIXELFORMAT_SIZE[SW_FRAMEBUFFER_COLOR_FORMAT] +#define SW_FRAMEBUFFER_DEPTH_SIZE SW_PIXELFORMAT_SIZE[SW_FRAMEBUFFER_DEPTH_FORMAT] -#define SW_STATE_SCISSOR_TEST (1 << 0) -#define SW_STATE_TEXTURE_2D (1 << 1) -#define SW_STATE_DEPTH_TEST (1 << 2) -#define SW_STATE_CULL_FACE (1 << 3) -#define SW_STATE_BLEND (1 << 4) +#define SW_STATE_SCISSOR_TEST (1 << 0) +#define SW_STATE_TEXTURE_2D (1 << 1) +#define SW_STATE_DEPTH_TEST (1 << 2) +#define SW_STATE_CULL_FACE (1 << 3) +#define SW_STATE_BLEND (1 << 4) -#define SW_BLEND_FLAG_NOOP (1 << 0) -#define SW_BLEND_FLAG_NEEDS_ALPHA (1 << 1) +#define SW_BLEND_FLAG_NOOP (1 << 0) +#define SW_BLEND_FLAG_NEEDS_ALPHA (1 << 1) //---------------------------------------------------------------------------------- // Module Types and Structures Definition @@ -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: // 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) - // -- exactly the semantic the scalar fallback below has. + // -- exactly the semantic the scalar fallback below has dspm_mult_4x4x4_f32(left, right, dst); #else 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)); } -// Fast reciprocal: 1-ULP accurate in ~7 instructions on Xtensa using the -// hardware `recip0.s` seed + two Newton-Raphson refinement steps. All work -// stays in FPU registers — no `__divsf3` software call. Hot-path divisions -// in the rasterizer (span/triangle setup, perspective divide, etc.) call -// this. On non-Xtensa targets it transparently expands to `1.0f / x`, so -// generated code is identical to before. +// Xtensa architecture optimization +// Fast reciprocal: 1-ULP accurate in ~7 instructions using the +// hardware `recip0.s` seed + two Newton-Raphson refinement steps +// All work stays in FPU registers — no `__divsf3` software call +// Hot-path divisions in the rasterizer (span/triangle setup, perspective divide, etc.) call this +// On non-Xtensa targets it transparently expands to `1.0f / x`, so generated code is identical to before #if defined(__XTENSA__) __attribute__((always_inline)) 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 // A value of 0 for sgnArea means P0, P1, P2 are collinear in (x, y, w) // space, which corresponds to a degenerate triangle projection - // Such quads might also be degenerate or non-planar. They are typically - // not culled by this test (0 < 0 is false, 0 > 0 is false) + // Such quads might also be degenerate or non-planar + // 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 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) { - // NOTE: Any checks to ensure command recording can start - // must be performed before calling this function. + // NOTE: Any checks to ensure command recording can start must be performed before calling this function // Recalculate the MVP if this is needed if (RLSW.isDirtyMVP) @@ -3891,8 +3887,8 @@ static void sw_immediate_begin(SWdraw mode) #ifdef SW_HAS_ESP_DSP // 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 - // per MVP update vs. saving ~20 cycles per vertex transform. + // computes M*v directly in the per-vertex hot path; 16 scalar copies + // per MVP update vs saving ~20 cycles per vertex transform for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) @@ -3955,7 +3951,7 @@ static void sw_immediate_push_vertex(const float position[4]) // Calculate clip coordinates #ifdef SW_HAS_ESP_DSP // 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); #else const float *m = RLSW.matMVP; @@ -5580,7 +5576,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; } // 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 y1 = v1->position[1]; float y2 = v2->position[1]; diff --git a/src/external/rprand.h b/src/external/rprand.h index cdef03c01..b71395415 100644 --- a/src/external/rprand.h +++ b/src/external/rprand.h @@ -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: * - 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 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 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; } +int rprand_get_value_raw(void) +{ + int value = rprand_xoshiro(); + + return value; +} + // Load pseudo-random numbers sequence with no duplicates, min and max included int *rprand_load_sequence(unsigned int count, int min, int max) { diff --git a/src/external/win32_clipboard.h b/src/external/win32_clipboard.h index 5c30fbd2e..ea0a34bd3 100644 --- a/src/external/win32_clipboard.h +++ b/src/external/win32_clipboard.h @@ -4,14 +4,14 @@ #ifndef 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_ #ifdef WIN32_CLIPBOARD_IMPLEMENTATION #include #include #include -#include +#include // 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. ) 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 //---------------------------------------------------------------------------------- -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; @@ -228,7 +228,7 @@ unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned long *width = bmpInfoHeader->biWidth; *height = bmpInfoHeader->biHeight; SIZE_T clipDataSize = GlobalSize(clipHandle); - if (clipDataSize >= sizeof(BITMAPINFOHEADER)) + if ((clipDataSize >= sizeof(BITMAPINFOHEADER)) && (clipDataSize < INT_MAX)) { int pixelOffset = GetPixelDataOffset(*bmpInfoHeader); @@ -236,7 +236,7 @@ unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned long //------------------------------------------------------------------------ BITMAPFILEHEADER bmpFileHeader = { 0 }; SIZE_T bmpFileSize = sizeof(bmpFileHeader) + clipDataSize; - *dataSize = bmpFileSize; + *dataSize = (unsigned int)bmpFileSize; bmpFileHeader.bfType = 0x4D42; // BMP fil type constant bmpFileHeader.bfSize = (DWORD)bmpFileSize; // Up to 4GB works fine @@ -254,7 +254,7 @@ unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned long } else { - TRACELOG(LOG_WARNING, "Clipboard data is malformed"); + TRACELOG(LOG_WARNING, "Clipboard data is not supported (>2GB?)"); GlobalUnlock(clipHandle); CloseClipboard(); } diff --git a/src/platforms/rcore_android.c b/src/platforms/rcore_android.c index c427d7a58..990b2fe6a 100644 --- a/src/platforms/rcore_android.c +++ b/src/platforms/rcore_android.c @@ -656,9 +656,9 @@ double GetTime(void) double time = 0.0; struct timespec ts = { 0 }; clock_gettime(CLOCK_MONOTONIC, &ts); - unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec; + 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; } @@ -1273,27 +1273,28 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) int32_t keycode = AKeyEvent_getKeyCode(event); //int32_t AKeyEvent_getMetaState(event); - // Handle gamepad button presses and releases - // NOTE: Skip gamepad handling if this is a keyboard event, as some devices - // report both AINPUT_SOURCE_KEYBOARD and AINPUT_SOURCE_GAMEPAD flags - if ((FLAG_IS_SET(source, AINPUT_SOURCE_JOYSTICK) || - FLAG_IS_SET(source, AINPUT_SOURCE_GAMEPAD)) && - !FLAG_IS_SET(source, AINPUT_SOURCE_KEYBOARD)) + // Handle gamepad button presses and releases. AOSP stamps the + // KEYBOARD source bit on every key event from a gamepad, so + // discriminate on the keycode rather than gating on source bits. + if (FLAG_IS_SET(source, AINPUT_SOURCE_JOYSTICK) || + FLAG_IS_SET(source, AINPUT_SOURCE_GAMEPAD)) { - // Assuming a single gamepad, "detected" on its input event - 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 (button != GAMEPAD_BUTTON_UNKNOWN) { - CORE.Input.Gamepad.currentButtonState[0][button] = 1; - } - else CORE.Input.Gamepad.currentButtonState[0][button] = 0; // Key up + // Assuming a single gamepad, "detected" on its input event + CORE.Input.Gamepad.ready[0] = true; - return 1; // Handled gamepad button + if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN) + { + CORE.Input.Gamepad.currentButtonState[0][button] = 1; + } + else CORE.Input.Gamepad.currentButtonState[0][button] = 0; // Key up + + 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; diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index 191a3130e..6def8e77a 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -1042,11 +1042,6 @@ const char *GetClipboardText(void) return glfwGetClipboardString(platform.handle); } -#if SUPPORT_CLIPBOARD_IMAGE && defined(__linux__) && defined(_GLFW_X11) - #include - #include -#endif - // Get clipboard image Image GetClipboardImage(void) { @@ -1054,43 +1049,42 @@ Image GetClipboardImage(void) #if SUPPORT_CLIPBOARD_IMAGE && SUPPORT_MODULE_RTEXTURES #if defined(_WIN32) - unsigned long long int dataSize = 0; + + unsigned int dataSize = 0; void *bmpData = NULL; int width = 0; int height = 0; - bmpData = (void *)Win32GetClipboardImageData(&width, &height, &dataSize); + bmpData = (void *)Win32GetClipboardImageData(&width, &height, &dataSize); if (bmpData == NULL) TRACELOG(LOG_WARNING, "Clipboard image: Couldn't get clipboard data."); else image = LoadImageFromMemory(".bmp", (const unsigned char *)bmpData, (int)dataSize); #elif defined(__linux__) && defined(_GLFW_X11) - // REF: https://github.com/ColleagueRiley/Clipboard-Copy-Paste/blob/main/x11.c - Display *dpy = XOpenDisplay(NULL); - if (!dpy) return image; - Window root = DefaultRootWindow(dpy); - Window win = XCreateSimpleWindow( - dpy, // The connection to the X Server - 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 - ); + static Atom clipboard = 0; + static Atom targetType = 0; + static Atom property = 0; - Atom clipboard = XInternAtom(dpy, "CLIPBOARD", False); - Atom targetType = XInternAtom(dpy, "image/png", False); // Ask for PNG - Atom property = XInternAtom(dpy, "RAYLIB_CLIPBOARD_MANAGER", False); + Display *display = glfwGetX11Display(); + XID window = glfwGetX11Window(platform.handle); - // Request the data: "Convert whatever is in CLIPBOARD to image/png and put it in RAYLIB_CLIPBOARD_MANAGER" - XConvertSelection(dpy, clipboard, targetType, property, win, CurrentTime); + // Lazy-load X11 atoms + 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 }; - XNextEvent(dpy, &ev); + + // Keep calling until we get SelectionNotify + while (XCheckTypedEvent(display, SelectionNotify, &ev) == False); Atom actualType = { 0 }; int actualFormat = 0; @@ -1098,9 +1092,8 @@ Image GetClipboardImage(void) unsigned long bytesAfter = 0; unsigned char *data = NULL; - // Read the data from our ghost window's property - XGetWindowProperty(dpy, win, property, 0, ~0L, False, AnyPropertyType, - &actualType, &actualFormat, &nitems, &bytesAfter, &data); + XGetWindowProperty(display, window, property, 0, ~0L, False, AnyPropertyType, + &actualType, &actualFormat, &nitems, &bytesAfter, &data); if (data != NULL) { @@ -1108,11 +1101,9 @@ Image GetClipboardImage(void) XFree(data); } - XDestroyWindow(dpy, win); - XCloseDisplay(dpy); #else TRACELOG(LOG_WARNING, "GetClipboardImage() not implemented on target platform"); -#endif // defined(_WIN32) +#endif // _WIN32 #else TRACELOG(LOG_WARNING, "Clipboard image: SUPPORT_CLIPBOARD_IMAGE requires SUPPORT_MODULE_RTEXTURES to work properly"); #endif // SUPPORT_CLIPBOARD_IMAGE diff --git a/src/platforms/rcore_desktop_rgfw.c b/src/platforms/rcore_desktop_rgfw.c old mode 100755 new mode 100644 index e9263cb04..1cb38ff61 --- a/src/platforms/rcore_desktop_rgfw.c +++ b/src/platforms/rcore_desktop_rgfw.c @@ -810,8 +810,8 @@ void SetWindowSize(int width, int height) RGFW_monitor* currentMonitor = RGFW_window_getMonitor(platform.window); CORE.Window.screenScale = MatrixScale(currentMonitor->pixelRatio, currentMonitor->pixelRatio, 1.0f); - CORE.Window.render.width = CORE.Window.screen.width * currentMonitor->pixelRatio; - CORE.Window.render.height = CORE.Window.screen.height * currentMonitor->pixelRatio; + CORE.Window.render.width = CORE.Window.screen.width*currentMonitor->pixelRatio; + CORE.Window.render.height = CORE.Window.screen.height*currentMonitor->pixelRatio; CORE.Window.currentFbo.width = CORE.Window.render.width; CORE.Window.currentFbo.height = CORE.Window.render.height; #else @@ -1024,15 +1024,15 @@ Image GetClipboardImage(void) #if SUPPORT_CLIPBOARD_IMAGE && SUPPORT_MODULE_RTEXTURES #if defined(_WIN32) - unsigned long long int dataSize = 0; // moved into _WIN32 scope until other platforms gain support - void *fileData = NULL; // moved into _WIN32 scope until other platforms gain support + unsigned int dataSize = 0; + void *fileData = NULL; int width = 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"); - 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) @@ -1082,7 +1082,7 @@ Image GetClipboardImage(void) XCloseDisplay(dpy); #else TRACELOG(LOG_WARNING, "Clipboard image: PLATFORM_DESKTOP_RGFW doesn't implement GetClipboardImage() for this OS"); -#endif // defined(_WIN32) +#endif // _WIN32 #else TRACELOG(LOG_WARNING, "Clipboard image: SUPPORT_CLIPBOARD_IMAGE requires SUPPORT_MODULE_RTEXTURES to work properly"); #endif // SUPPORT_CLIPBOARD_IMAGE @@ -1132,16 +1132,16 @@ void SwapScreenBuffer(void) { if (platform.surface) { - // copy rlsw pixel data to the surface framebuffer - swReadPixels(0, 0, platform.surfaceWidth, platform.surfaceHeight, SW_RGBA, SW_UNSIGNED_BYTE, platform.surfacePixels); + // Copy rlsw pixel data to the surface framebuffer + 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 #if defined(__APPLE__) unsigned char temp = 0; 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]; p[0] = p[2]; p[2] = temp; @@ -1357,13 +1357,13 @@ void PollInputEvents(void) if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) { 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.screen.width = platform.window->w; CORE.Window.screen.height = platform.window->h; - CORE.Window.render.width = CORE.Window.screen.width * currentMonitor->pixelRatio; - CORE.Window.render.height = CORE.Window.screen.height * currentMonitor->pixelRatio; + CORE.Window.render.width = CORE.Window.screen.width*currentMonitor->pixelRatio; + CORE.Window.render.height = CORE.Window.screen.height*currentMonitor->pixelRatio; } else { @@ -1406,10 +1406,10 @@ void PollInputEvents(void) #if defined(__APPLE__) RGFW_monitor* currentMonitor = RGFW_window_getMonitor(platform.window); 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.height = CORE.Window.screen.height * currentMonitor->pixelRatio; + CORE.Window.render.width = CORE.Window.screen.width*currentMonitor->pixelRatio; + CORE.Window.render.height = CORE.Window.screen.height*currentMonitor->pixelRatio; CORE.Window.currentFbo.width = CORE.Window.render.width; CORE.Window.currentFbo.height = CORE.Window.render.height; #endif @@ -1427,7 +1427,7 @@ void PollInputEvents(void) if (platform.surfacePixels != NULL) { 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) @@ -1677,10 +1677,62 @@ int InitPlatform(void) // Initialize RGFW internal global state, only required systems 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 + + // Init window in fullscreen mode if requested + // NOTE: Keeping original screen size for toggle if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) { 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)) @@ -1688,16 +1740,16 @@ int InitPlatform(void) 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_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_FULLSCREEN_MODE)) FLAG_SET(flags, RGFW_windowFullscreen); - 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_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 + } // NOTE: Some OpenGL context attributes must be set before window creation // Check selection OpenGL version - RGFW_glHints* hints = RGFW_getGlobalHints_OpenGL(); if (rlGetVersion() == RL_OPENGL_21) { @@ -1720,20 +1772,9 @@ int InitPlatform(void) hints->minor = 1; 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_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); + 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 @@ -1787,8 +1828,8 @@ int InitPlatform(void) RGFW_monitor* currentMonitor = RGFW_window_getMonitor(platform.window); CORE.Window.screenScale = MatrixScale(currentMonitor->pixelRatio, currentMonitor->pixelRatio, 1.0f); - CORE.Window.render.width = CORE.Window.screen.width * currentMonitor->pixelRatio; - CORE.Window.render.height = CORE.Window.screen.height * currentMonitor->pixelRatio; + CORE.Window.render.width = CORE.Window.screen.width*currentMonitor->pixelRatio; + CORE.Window.render.height = CORE.Window.screen.height*currentMonitor->pixelRatio; CORE.Window.currentFbo.width = CORE.Window.render.width; CORE.Window.currentFbo.height = CORE.Window.render.height; #else @@ -1805,8 +1846,8 @@ int InitPlatform(void) RGFW_monitor* currentMonitor = RGFW_window_getMonitor(platform.window); CORE.Window.screenScale = MatrixScale(currentMonitor->pixelRatio, currentMonitor->pixelRatio, 1.0f); - CORE.Window.render.width = CORE.Window.screen.width * currentMonitor->pixelRatio; - CORE.Window.render.height = CORE.Window.screen.height * currentMonitor->pixelRatio; + CORE.Window.render.width = CORE.Window.screen.width*currentMonitor->pixelRatio; + CORE.Window.render.height = CORE.Window.screen.height*currentMonitor->pixelRatio; CORE.Window.currentFbo.width = CORE.Window.render.width; CORE.Window.currentFbo.height = CORE.Window.render.height; #endif @@ -1814,7 +1855,7 @@ int InitPlatform(void) platform.surfaceWidth = CORE.Window.currentFbo.width; 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) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize software pixel buffer"); diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index 748b8aab8..659c80011 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -1006,9 +1006,9 @@ double GetTime(void) double time = 0.0; struct timespec ts = { 0 }; clock_gettime(CLOCK_MONOTONIC, &ts); - unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec; + 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; } diff --git a/src/platforms/rcore_memory.c b/src/platforms/rcore_memory.c index b06187018..155073ad1 100644 --- a/src/platforms/rcore_memory.c +++ b/src/platforms/rcore_memory.c @@ -364,14 +364,18 @@ double GetTime(void) { double time = 0.0; #if defined(_WIN32) - LARGE_INTEGER now = { 0 }; - QueryPerformanceCounter(&now); - return (double)(now.QuadPart - CORE.Time.base)/(double)platform.timerFrequency.QuadPart; + LARGE_INTEGER currentTicks = { 0 }; + QueryPerformanceCounter(¤tTicks); + + time = (double)(currentTicks.QuadPart - CORE.Time.base)/(double)platform.timerFrequency.QuadPart; #elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__EMSCRIPTEN__) struct timespec ts = { 0 }; clock_gettime(CLOCK_MONOTONIC, &ts); - unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec; - time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer() + 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() +#elif defined(PICO_RP2350) + time = (double)to_ms_since_boot(get_absolute_time())/1000.0; #endif return time; } diff --git a/src/platforms/rcore_template.c b/src/platforms/rcore_template.c index ee766867a..353d32d11 100644 --- a/src/platforms/rcore_template.c +++ b/src/platforms/rcore_template.c @@ -341,10 +341,12 @@ void SwapScreenBuffer(void) double GetTime(void) { double time = 0.0; + struct timespec ts = { 0 }; clock_gettime(CLOCK_MONOTONIC, &ts); - unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec; - time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer() + 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() return time; } diff --git a/src/raudio.c b/src/raudio.c index a007a1092..ff90d8e43 100644 --- a/src/raudio.c +++ b/src/raudio.c @@ -858,7 +858,7 @@ Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int else if ((strcmp(fileType, ".mp3") == 0) || (strcmp(fileType, ".MP3") == 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 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.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"); @@ -896,13 +896,13 @@ Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int #if SUPPORT_FILEFORMAT_FLAC 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 wave.data = drflac_open_memory_and_read_pcm_frames_s16(fileData, dataSize, &wave.channels, &wave.sampleRate, &totalFrameCount, NULL); 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"); } #endif @@ -1048,6 +1048,7 @@ void UnloadSoundAlias(Sound alias) { UntrackAudioBuffer(alias.stream.buffer); ma_data_converter_uninit(&alias.stream.buffer->converter, NULL); + RL_FREE(alias.stream.buffer->converterResidual); RL_FREE(alias.stream.buffer); } } diff --git a/src/rcore.c b/src/rcore.c index 6672302dd..74774e77b 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -385,7 +385,7 @@ typedef struct CoreData { double draw; // Time measure for frame draw (seconds) double frame; // Time measure for one frame (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) } 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' #endif +// NOTE: PLATFORM_DESKTOP defaults to GLFW backend #if defined(PLATFORM_DESKTOP) #define PLATFORM_DESKTOP_GLFW #endif - // Include platform-specific submodules #if defined(PLATFORM_DESKTOP_GLFW) #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); // 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) { 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; - if (ACCESS(fileName) != -1) result = true; + if ((fileName != NULL) && (ACCESS(fileName) != -1)) result = true; // NOTE: Alternatively, stat() can be used instead of access() //#include @@ -3336,15 +3336,15 @@ unsigned int *ComputeSHA1(const unsigned char *data, int dataSize) memcpy(msg, data, dataSize); msg[dataSize] = 128; // Write the '1' bit - unsigned long long bitsLen = 8ULL * dataSize; - msg[newDataSize-1] = (unsigned char)(bitsLen); - msg[newDataSize-2] = (unsigned char)(bitsLen >> 8); - msg[newDataSize-3] = (unsigned char)(bitsLen >> 16); - msg[newDataSize-4] = (unsigned char)(bitsLen >> 24); - msg[newDataSize-5] = (unsigned char)(bitsLen >> 32); - msg[newDataSize-6] = (unsigned char)(bitsLen >> 40); - msg[newDataSize-7] = (unsigned char)(bitsLen >> 48); - msg[newDataSize-8] = (unsigned char)(bitsLen >> 56); + unsigned long long bitsLen = 8ULL*dataSize; + msg[newDataSize - 1] = (unsigned char)(bitsLen); + msg[newDataSize - 2] = (unsigned char)(bitsLen >> 8); + msg[newDataSize - 3] = (unsigned char)(bitsLen >> 16); + msg[newDataSize - 4] = (unsigned char)(bitsLen >> 24); + msg[newDataSize - 5] = (unsigned char)(bitsLen >> 32); + msg[newDataSize - 6] = (unsigned char)(bitsLen >> 40); + msg[newDataSize - 7] = (unsigned char)(bitsLen >> 48); + msg[newDataSize - 8] = (unsigned char)(bitsLen >> 56); // Process the message in successive 512-bit chunks 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[7] = 0x5be0cd19; - const unsigned long long int bitLen = ((unsigned long long int)dataSize)*8; - unsigned long long int paddedSize = dataSize + sizeof(dataSize); + const unsigned long long bitLen = 8ULL*dataSize; + unsigned long long paddedSize = dataSize + sizeof(dataSize); paddedSize += (64 - (paddedSize%64)); 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; } - 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 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 (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 ch = ((e & f) ^ (~e & g)); @@ -4219,7 +4219,7 @@ void InitTimer(void) 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"); #endif diff --git a/src/rgestures.h b/src/rgestures.h index 734d33f0f..248e1f71a 100644 --- a/src/rgestures.h +++ b/src/rgestures.h @@ -157,8 +157,8 @@ float GetGesturePinchAngle(void); // Get gesture pinch ang extern "C" { // Prevents name mangling of functions #endif // Functions required to query time on Windows - int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount); - int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency); + int __stdcall QueryPerformanceCounter(unsigned long long *lpPerformanceCount); + int __stdcall QueryPerformanceFrequency(unsigned long long *lpFrequency); #if defined(__cplusplus) } #endif @@ -518,37 +518,36 @@ static double rgGetCurrentTime(void) time = GetTime(); #else #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! - QueryPerformanceCounter(¤tTime); + QueryPerformanceCounter(¤tClockTicks); - time = (double)currentTime/clockFrequency; // Time in seconds + time = (double)currentClockTicks/clockFrequency; // Time in seconds #endif - #if defined(__linux__) // NOTE: Only for Linux-based systems - struct timespec now; + struct timespec now = { 0 }; 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 - #if defined(__APPLE__) //#define CLOCK_REALTIME CALENDAR_CLOCK // returns UTC time since 1970-01-01 //#define CLOCK_MONOTONIC SYSTEM_CLOCK // returns the time since boot time - clock_serv_t cclock; - mach_timespec_t now; + clock_serv_t cclock = { 0 }; + mach_timespec_t now = { 0 }; host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock); // NOTE: OS X does not have clock_gettime(), using clock_get_time() clock_get_time(cclock, &now); 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 diff --git a/src/rlgl.h b/src/rlgl.h index 76b765e2e..ea5673397 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -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_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; - #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_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 diff --git a/src/rshapes.c b/src/rshapes.c index c06f20462..69c1dacea 100644 --- a/src/rshapes.c +++ b/src/rshapes.c @@ -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) 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)/2.0f); if (segments <= 0) segments = 4; } diff --git a/src/rtext.c b/src/rtext.c index a3ec016f5..c0434db63 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -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); } - 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 + TRACELOG(LOG_WARNING, "FONT: Font is not supported by LoadFontEx/LoadFontFromMemory or no glyphs found, reverted to default font"); font = GetFontDefault(); #endif