packages feed

h-raylib 5.5.1.0 → 5.5.2.0

raw patch · 29 files changed

+1039/−250 lines, 29 filesdep ~basedep ~containersdep ~exceptionsPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: base, containers, exceptions, lens, linear, template-haskell

API changes (from Hackage documentation)

- Raylib.Core: c'isShaderReady :: Ptr Shader -> IO CBool
- Raylib.Core: isShaderReady :: Shader -> IO Bool
- Raylib.Core.Audio: c'isAudioStreamReady :: Ptr AudioStream -> IO CBool
- Raylib.Core.Audio: c'isMusicReady :: Ptr Music -> IO CBool
- Raylib.Core.Audio: c'isSoundReady :: Ptr Sound -> IO CBool
- Raylib.Core.Audio: c'isWaveReady :: Ptr Wave -> IO CBool
- Raylib.Core.Audio: isAudioStreamReady :: AudioStream -> IO Bool
- Raylib.Core.Audio: isMusicReady :: Music -> IO Bool
- Raylib.Core.Audio: isSoundReady :: Sound -> IO Bool
- Raylib.Core.Audio: isWaveReady :: Wave -> IO Bool
- Raylib.Core.Models: c'isMaterialReady :: Ptr Material -> IO CBool
- Raylib.Core.Models: c'isModelReady :: Ptr Model -> IO CBool
- Raylib.Core.Models: isMaterialReady :: Material -> IO Bool
- Raylib.Core.Models: isModelReady :: Model -> IO Bool
- Raylib.Core.Text: c'isFontReady :: Ptr Font -> IO CBool
- Raylib.Core.Text: isFontReady :: Font -> IO Bool
- Raylib.Core.Textures: c'isImageReady :: Ptr Image -> IO CBool
- Raylib.Core.Textures: c'isRenderTextureReady :: Ptr RenderTexture -> IO CBool
- Raylib.Core.Textures: c'isTextureReady :: Ptr Texture -> IO CBool
- Raylib.Core.Textures: isImageReady :: Image -> IO Bool
- Raylib.Core.Textures: isRenderTextureReady :: RenderTexture -> IO Bool
- Raylib.Core.Textures: isTextureReady :: Texture -> IO Bool
+ Raylib.Core: c'computeCRC32 :: Ptr CUChar -> CInt -> IO CUInt
+ Raylib.Core: c'computeMD5 :: Ptr CUChar -> CInt -> IO (Ptr CUInt)
+ Raylib.Core: c'computeSHA1 :: Ptr CUChar -> CInt -> IO (Ptr CUInt)
+ Raylib.Core: c'isShaderValid :: Ptr Shader -> IO CBool
+ Raylib.Core: computeCRC32 :: [Integer] -> IO Integer
+ Raylib.Core: computeMD5 :: [Integer] -> IO [Integer]
+ Raylib.Core: computeSHA1 :: [Integer] -> IO [Integer]
+ Raylib.Core: isShaderValid :: Shader -> IO Bool
+ Raylib.Core.Audio: c'isAudioStreamValid :: Ptr AudioStream -> IO CBool
+ Raylib.Core.Audio: c'isMusicValid :: Ptr Music -> IO CBool
+ Raylib.Core.Audio: c'isSoundValid :: Ptr Sound -> IO CBool
+ Raylib.Core.Audio: c'isWaveValid :: Ptr Wave -> IO CBool
+ Raylib.Core.Audio: isAudioStreamValid :: AudioStream -> IO Bool
+ Raylib.Core.Audio: isMusicValid :: Music -> IO Bool
+ Raylib.Core.Audio: isSoundValid :: Sound -> IO Bool
+ Raylib.Core.Audio: isWaveValid :: Wave -> IO Bool
+ Raylib.Core.Models: c'isMaterialValid :: Ptr Material -> IO CBool
+ Raylib.Core.Models: c'isModelValid :: Ptr Model -> IO CBool
+ Raylib.Core.Models: isMaterialValid :: Material -> IO Bool
+ Raylib.Core.Models: isModelValid :: Model -> IO Bool
+ Raylib.Core.Text: c'isFontValid :: Ptr Font -> IO CBool
+ Raylib.Core.Text: isFontValid :: Font -> IO Bool
+ Raylib.Core.Textures: c'isImageValid :: Ptr Image -> IO CBool
+ Raylib.Core.Textures: c'isRenderTextureValid :: Ptr RenderTexture -> IO CBool
+ Raylib.Core.Textures: c'isTextureValid :: Ptr Texture -> IO CBool
+ Raylib.Core.Textures: isImageValid :: Image -> IO Bool
+ Raylib.Core.Textures: isRenderTextureValid :: RenderTexture -> IO Bool
+ Raylib.Core.Textures: isTextureValid :: Texture -> IO Bool
- Raylib.Core: c'setGamepadVibration :: CInt -> CFloat -> CFloat -> IO ()
+ Raylib.Core: c'setGamepadVibration :: CInt -> CFloat -> CFloat -> CFloat -> IO ()
- Raylib.Core: setGamepadVibration :: Int -> Float -> Float -> IO ()
+ Raylib.Core: setGamepadVibration :: Int -> Float -> Float -> Float -> IO ()
- Raylib.Types.Core: type C'LoadFileDataCallback = FunPtr CString -> Ptr CUInt -> IO Ptr CUChar
+ Raylib.Types.Core: type C'LoadFileDataCallback = FunPtr (CString -> Ptr CUInt -> IO (Ptr CUChar))
- Raylib.Types.Core: type C'LoadFileTextCallback = FunPtr CString -> IO CString
+ Raylib.Types.Core: type C'LoadFileTextCallback = FunPtr (CString -> IO CString)
- Raylib.Types.Core: type C'SaveFileDataCallback = FunPtr CString -> Ptr () -> CUInt -> IO CInt
+ Raylib.Types.Core: type C'SaveFileDataCallback = FunPtr (CString -> Ptr () -> CUInt -> IO CInt)
- Raylib.Types.Core: type C'SaveFileTextCallback = FunPtr CString -> CString -> IO CInt
+ Raylib.Types.Core: type C'SaveFileTextCallback = FunPtr (CString -> CString -> IO CInt)
- Raylib.Types.Core: type C'TraceLogCallback = FunPtr CInt -> CString -> IO ()
+ Raylib.Types.Core: type C'TraceLogCallback = FunPtr (CInt -> CString -> IO ())
- Raylib.Types.Core.Audio: type C'AudioCallback = FunPtr Ptr () -> CUInt -> IO ()
+ Raylib.Types.Core.Audio: type C'AudioCallback = FunPtr (Ptr () -> CUInt -> IO ())

Files

CHANGELOG.md view
@@ -8,6 +8,13 @@  h-raylib's version numbers do not follow the usual format. The first two numbers in the version track the underlying C raylib version. For example, `5.1.x.x` versions use raylib 5.1 under the hood. The third number represents breaking changes (renamed/deleted functions or modules). The last number represents non-breaking changes (new functions or modules, bug fixes, etc). The safest version bound format to use is `h-raylib >=x.y.z.w && <x.y.(z+1)` (instead of the usual `^>=` bound). +## Version 5.5.2.0+_21 October 2024_++- **BREAKING CHANGE**: `is*Ready` functions renamed to `is*Valid` (upstream change in raylib)+- **BREAKING CHANGE**: `setGamepadVibration` takes a fourth argument, `duration` (upstream change in raylib)+- Loosened the version bound on `base`+ ## Version 5.5.1.0 _11 October 2024_ 
DOCUMENTATION.md view
@@ -2,10 +2,6 @@  This file only contains h-raylib specific information. For documentation on individual functions, check the [raylib cheatsheet](https://www.raylib.com/cheatsheet/cheatsheet.html) and the [h-raylib Haddock documentation (incomplete)](https://hackage.haskell.org/package/h-raylib). You can also look at the examples included here in the `examples` directory (written in Haskell), or you can look at the more extensive set of examples [on the raylib website](https://www.raylib.com/examples.html) (written in C). For information about raylib in general, view the [raylib wiki](https://github.com/raysan5/raylib/wiki). -## Versioning scheme--The first two numbers in the version track the underlying C raylib version. For example, `5.1.x.x` versions use raylib 5.1 under the hood. The third number represents breaking changes (renamed/deleted functions or modules). The last number represents non-breaking changes (new functions or modules, bug fixes, etc).- ## Memory management  ### Automatic management flow (recommended)
default.nix view
@@ -3,7 +3,7 @@ }: mkDerivation {   pname = "h-raylib";-  version = "5.5.1.0";+  version = "5.5.2.0";   src = ./.;   isLibrary = true;   isExecutable = buildExamples;
flake.nix view
@@ -9,8 +9,8 @@       forAllSystems' = nixpkgs.lib.genAttrs;       forAllSystems = forAllSystems' supportedSystems; -      raylibRev = "f5328a9bb63a0e0eca7dead15cfa01a3ec1417c2";-      raylibHash = "sha256-gAv1jfMdbKWnlIqqBddVn+WE0BOIARMmagpK61bxVnU=";+      raylibRev = "2a0963ce0936abe0cd3ec32882638d860e435d16";+      raylibHash = "sha256-4p3nq04irS8AFojH88Bh1r8KiOjQhZf7nFmQhf1EDU8=";       rayguiRev = "1e03efca48c50c5ea4b4a053d5bf04bad58d3e43";       rayguiHash = "sha256-PzQZxCz63EPd7sVFBYY0T1s9jA5kOAxF9K4ojRoIMz4="; 
h-raylib.cabal view
@@ -1,6 +1,6 @@ cabal-version:      2.4 name:               h-raylib-version:            5.5.1.0+version:            5.5.2.0 synopsis:           Raylib bindings for Haskell category:           graphics description:@@ -239,7 +239,7 @@     Raylib.Internal.Web.Processable    build-depends:-    , base              >=4.0      && <4.20+    , base              >=4.0      && <4.21     , bytestring        >=0.11.0   && <0.13     , containers        >=0.6.0    && <0.7.0     , exceptions        >=0.10.4   && <0.10.8
lib/rl_bindings.c view
@@ -87,9 +87,9 @@     return ptr; } -RLBIND bool IsShaderReady_(Shader *a)+RLBIND bool IsShaderValid_(Shader *a) {-    return IsShaderReady(*a);+    return IsShaderValid(*a); }  RLBIND int GetShaderLocation_(Shader *a, char *b)@@ -678,9 +678,9 @@     return ptr; } -RLBIND bool IsImageReady_(Image *a)+RLBIND bool IsImageValid_(Image *a) {-    return IsImageReady(*a);+    return IsImageValid(*a); }  RLBIND void UnloadImage_(Image *a)@@ -993,9 +993,9 @@     return ptr; } -RLBIND bool IsTextureReady_(Texture *a)+RLBIND bool IsTextureValid_(Texture *a) {-    return IsTextureReady(*a);+    return IsTextureValid(*a); }  RLBIND void UnloadTexture_(Texture *a)@@ -1003,9 +1003,9 @@     UnloadTexture(*a); } -RLBIND bool IsRenderTextureReady_(RenderTexture *a)+RLBIND bool IsRenderTextureValid_(RenderTexture *a) {-    return IsRenderTextureReady(*a);+    return IsRenderTextureValid(*a); }  RLBIND void UnloadRenderTexture_(RenderTexture *a)@@ -1227,9 +1227,9 @@     return ptr; } -RLBIND bool IsFontReady_(Font *a)+RLBIND bool IsFontValid_(Font *a) {-    return IsFontReady(*a);+    return IsFontValid(*a); }  RLBIND void UnloadFont_(Font *a)@@ -1407,9 +1407,9 @@     return ptr; } -RLBIND bool IsModelReady_(Model *a)+RLBIND bool IsModelValid_(Model *a) {-    return IsModelReady(*a);+    return IsModelValid(*a); }  RLBIND void UnloadModel_(Model *a)@@ -1595,9 +1595,9 @@     return ptr; } -RLBIND bool IsMaterialReady_(Material *a)+RLBIND bool IsMaterialValid_(Material *a) {-    return IsMaterialReady(*a);+    return IsMaterialValid(*a); }  RLBIND void UnloadMaterial_(Material *a)@@ -1720,9 +1720,9 @@     UpdateSound(*a, b, c); } -RLBIND bool IsWaveReady_(Wave *a)+RLBIND bool IsWaveValid_(Wave *a) {-    return IsWaveReady(*a);+    return IsWaveValid(*a); }  RLBIND void UnloadWave_(Wave *a)@@ -1730,9 +1730,9 @@     UnloadWave(*a); } -RLBIND bool IsSoundReady_(Sound *a)+RLBIND bool IsSoundValid_(Sound *a) {-    return IsSoundReady(*a);+    return IsSoundValid(*a); }  RLBIND void UnloadSound_(Sound *a)@@ -1821,9 +1821,9 @@     return ptr; } -RLBIND bool IsMusicReady_(Music *a)+RLBIND bool IsMusicValid_(Music *a) {-    return IsMusicReady(*a);+    return IsMusicValid(*a); }  RLBIND void UnloadMusicStream_(Music *a)@@ -1898,9 +1898,9 @@     return ptr; } -RLBIND bool IsAudioStreamReady_(AudioStream *a)+RLBIND bool IsAudioStreamValid_(AudioStream *a) {-    return IsAudioStreamReady(*a);+    return IsAudioStreamValid(*a); }  RLBIND void UnloadAudioStream_(AudioStream *a)@@ -2554,6 +2554,21 @@     return DecodeDataBase64(a, b); } +RLBIND unsigned int ComputeCRC32_(unsigned char *a, int b)+{+    return ComputeCRC32(a, b);+}++RLBIND unsigned int *ComputeMD5_(unsigned char *a, int b)+{+    return ComputeMD5(a, b);+}++RLBIND unsigned int *ComputeSHA1_(unsigned char *a, int b)+{+    return ComputeSHA1(a, b);+}+ RLBIND void SetAutomationEventList_(AutomationEventList *a) {     SetAutomationEventList(a);@@ -2664,9 +2679,9 @@     return SetGamepadMappings(a); } -RLBIND void SetGamepadVibration_(int a, float b, float c)+RLBIND void SetGamepadVibration_(int a, float b, float c, float d) {-    SetGamepadVibration(a, b, c);+    SetGamepadVibration(a, b, c, d); }  RLBIND bool IsMouseButtonPressed_(int a)
lib/rl_bindings.h view
@@ -40,7 +40,7 @@  Shader *LoadShaderFromMemory_(char *a, char *b); -bool IsShaderReady_(Shader *a);+bool IsShaderValid_(Shader *a);  int GetShaderLocation_(Shader *a, char *b); @@ -250,7 +250,7 @@  Image *LoadImageFromScreen_(); -bool IsImageReady_(Image *a);+bool IsImageValid_(Image *a);  void UnloadImage_(Image *a); @@ -360,11 +360,11 @@  RenderTexture *LoadRenderTexture_(int a, int b); -bool IsTextureReady_(Texture *a);+bool IsTextureValid_(Texture *a);  void UnloadTexture_(Texture *a); -bool IsRenderTextureReady_(RenderTexture *a);+bool IsRenderTextureValid_(RenderTexture *a);  void UnloadRenderTexture_(RenderTexture *a); @@ -426,7 +426,7 @@  Image *GenImageFontAtlas_(GlyphInfo *a, Rectangle **b, int c, int d, int e, int f); -bool IsFontReady_(Font *a);+bool IsFontValid_(Font *a);  void UnloadFont_(Font *a); @@ -498,7 +498,7 @@  Model *LoadModelFromMesh_(Mesh *a); -bool IsModelReady_(Model *a);+bool IsModelValid_(Model *a);  void UnloadModel_(Model *a); @@ -562,7 +562,7 @@  Material *LoadMaterialDefault_(); -bool IsMaterialReady_(Material *a);+bool IsMaterialValid_(Material *a);  void UnloadMaterial_(Material *a); @@ -604,11 +604,11 @@  void UpdateSound_(Sound *a, const void *b, int c); -bool IsWaveReady_(Wave *a);+bool IsWaveValid_(Wave *a);  void UnloadWave_(Wave *a); -bool IsSoundReady_(Sound *a);+bool IsSoundValid_(Sound *a);  void UnloadSound_(Sound *a); @@ -642,7 +642,7 @@  Music *LoadMusicStreamFromMemory_(char *a, unsigned char *b, int c); -bool IsMusicReady_(Music *a);+bool IsMusicValid_(Music *a);  void UnloadMusicStream_(Music *a); @@ -672,7 +672,7 @@  AudioStream *LoadAudioStream_(unsigned int a, unsigned int b, unsigned int c); -bool IsAudioStreamReady_(AudioStream *a);+bool IsAudioStreamValid_(AudioStream *a);  void UnloadAudioStream_(AudioStream *a); @@ -930,6 +930,12 @@  unsigned char *DecodeDataBase64_(const unsigned char *a, int *b); +unsigned int ComputeCRC32_(unsigned char *a, int b);++unsigned int *ComputeMD5_(unsigned char *a, int b);++unsigned int *ComputeSHA1_(unsigned char *a, int b);+ void SetAutomationEventList_(AutomationEventList *a);  void SetAutomationEventBaseFrame_(int a);@@ -974,7 +980,7 @@  int SetGamepadMappings_(const char *a); -void SetGamepadVibration_(int a, float b, float c);+void SetGamepadVibration_(int a, float b, float c, float d);  bool IsMouseButtonPressed_(int a); 
raylib/examples/models/models_gpu_skinning.c view
@@ -81,7 +81,6 @@         // Update model animation
         ModelAnimation anim = modelAnimations[animIndex];
         animCurrentFrame = (animCurrentFrame + 1)%anim.frameCount;
-        UpdateModelAnimationBoneMatrices(characterModel, anim, animCurrentFrame);
         //----------------------------------------------------------------------------------
 
         // Draw
raylib/src/external/rl_gputex.h view
@@ -185,6 +185,7 @@                 if (header->ddspf.flags == 0x40)        // No alpha channel                 {                     int data_size = image_pixel_size*sizeof(unsigned short);+                    if (header->mipmap_count > 1) data_size = data_size + data_size / 3;                     image_data = RL_MALLOC(data_size);                      memcpy(image_data, file_data_ptr, data_size);@@ -196,6 +197,7 @@                     if (header->ddspf.a_bit_mask == 0x8000)     // 1bit alpha                     {                         int data_size = image_pixel_size*sizeof(unsigned short);+                        if (header->mipmap_count > 1) data_size = data_size + data_size / 3;                         image_data = RL_MALLOC(data_size);                          memcpy(image_data, file_data_ptr, data_size);@@ -215,6 +217,7 @@                     else if (header->ddspf.a_bit_mask == 0xf000)   // 4bit alpha                     {                         int data_size = image_pixel_size*sizeof(unsigned short);+                        if (header->mipmap_count > 1) data_size = data_size + data_size / 3;                         image_data = RL_MALLOC(data_size);                          memcpy(image_data, file_data_ptr, data_size);@@ -236,6 +239,7 @@             else if ((header->ddspf.flags == 0x40) && (header->ddspf.rgb_bit_count == 24))   // DDS_RGB, no compressed             {                 int data_size = image_pixel_size*3*sizeof(unsigned char);+                if (header->mipmap_count > 1) data_size = data_size + data_size / 3;                 image_data = RL_MALLOC(data_size);                  memcpy(image_data, file_data_ptr, data_size);@@ -245,6 +249,7 @@             else if ((header->ddspf.flags == 0x41) && (header->ddspf.rgb_bit_count == 32)) // DDS_RGBA, no compressed             {                 int data_size = image_pixel_size*4*sizeof(unsigned char);+                if (header->mipmap_count > 1) data_size = data_size + data_size / 3;                 image_data = RL_MALLOC(data_size);                  memcpy(image_data, file_data_ptr, data_size);@@ -265,9 +270,11 @@             }             else if (((header->ddspf.flags == 0x04) || (header->ddspf.flags == 0x05)) && (header->ddspf.fourcc > 0)) // Compressed             {-                // NOTE: This forces only 1 mipmap to be loaded which is not really correct but it works-                int data_size = (header->pitch_or_linear_size < file_size - 0x80) ? header->pitch_or_linear_size : file_size - 0x80;-                *mips = 1;+                int data_size = 0;++                // Calculate data size, including all mipmaps+                if (header->mipmap_count > 1) data_size = header->pitch_or_linear_size + header->pitch_or_linear_size / 3;+                else data_size = header->pitch_or_linear_size;                  image_data = RL_MALLOC(data_size*sizeof(unsigned char)); 
raylib/src/platforms/rcore_android.c view
@@ -615,7 +615,7 @@ }  // Set gamepad vibration-void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor)+void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration) {     TRACELOG(LOG_WARNING, "GamepadSetVibration() not implemented on target platform"); }
raylib/src/platforms/rcore_desktop_glfw.c view
@@ -149,7 +149,7 @@     {         // Store previous window position (in case we exit fullscreen)         CORE.Window.previousPosition = CORE.Window.position;-        +         int monitorCount = 0;         int monitorIndex = GetCurrentMonitor();         GLFWmonitor **monitors = glfwGetMonitors(&monitorCount);@@ -1060,7 +1060,7 @@ }  // Set gamepad vibration-void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor)+void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration) {     TRACELOG(LOG_WARNING, "GamepadSetVibration() not available on target platform"); }@@ -1289,7 +1289,7 @@     // Disable GlFW auto iconify behaviour     // Auto Iconify automatically minimizes (iconifies) the window if the window loses focus     // additionally auto iconify restores the hardware resolution of the monitor if the window that loses focus is a fullscreen window-    glfwWindowHint(GLFW_AUTO_ICONIFY, 0); +    glfwWindowHint(GLFW_AUTO_ICONIFY, 0);      // Check window creation flags     if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) CORE.Window.fullscreen = true;@@ -1579,7 +1579,7 @@         int monitorWidth = 0;         int monitorHeight = 0;         glfwGetMonitorWorkarea(monitor, &monitorX, &monitorY, &monitorWidth, &monitorHeight);-        +         // Here CORE.Window.render.width/height should be used instead of CORE.Window.screen.width/height to center the window correctly when the high dpi flag is enabled.         int posX = monitorX + (monitorWidth - (int)CORE.Window.render.width)/2;         int posY = monitorY + (monitorHeight - (int)CORE.Window.render.height)/2;
raylib/src/platforms/rcore_desktop_sdl.c view
@@ -953,17 +953,17 @@ }  // Set gamepad vibration-void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor)+void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration) {-    // Limit input values to between 0.0f and 1.0f-    leftMotor  = (0.0f > leftMotor)? 0.0f : leftMotor;-    rightMotor = (0.0f > rightMotor)? 0.0f : rightMotor;-    leftMotor  = (1.0f < leftMotor)? 1.0f : leftMotor;-    rightMotor = (1.0f < rightMotor)? 1.0f : rightMotor;--    if (IsGamepadAvailable(gamepad))+    if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (duration > 0.0f))     {-        SDL_GameControllerRumble(platform.gamepad[gamepad], (Uint16)(leftMotor*65535.0f), (Uint16)(rightMotor*65535.0f), (Uint32)(MAX_GAMEPAD_VIBRATION_TIME*1000.0f));+        if (leftMotor < 0.0f) leftMotor = 0.0f;+        if (leftMotor > 1.0f) leftMotor = 1.0f;+        if (rightMotor < 0.0f) rightMotor = 0.0f;+        if (rightMotor > 1.0f) rightMotor = 1.0f;+        if (duration > MAX_GAMEPAD_VIBRATION_TIME) duration = MAX_GAMEPAD_VIBRATION_TIME;++        SDL_GameControllerRumble(platform.gamepad[gamepad], (Uint16)(leftMotor*65535.0f), (Uint16)(rightMotor*65535.0f), (Uint32)(duration*1000.0f));     } } @@ -1609,7 +1609,6 @@     //----------------------------------------------------------------------------     // Define base path for storage     CORE.Storage.basePath = SDL_GetBasePath(); // Alternative: GetWorkingDirectory();-    CHDIR(CORE.Storage.basePath);     //----------------------------------------------------------------------------      TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (SDL): Initialized successfully");
raylib/src/platforms/rcore_drm.c view
@@ -610,7 +610,7 @@ }  // Set gamepad vibration-void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor)+void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration) {     TRACELOG(LOG_WARNING, "GamepadSetVibration() not implemented on target platform"); }@@ -763,7 +763,7 @@          drmModeConnector *con = drmModeGetConnector(platform.fd, res->connectors[i]);         TRACELOG(LOG_TRACE, "DISPLAY: Connector modes detected: %i", con->count_modes);-        +         // In certain cases the status of the conneciton is reported as UKNOWN, but it is still connected.         // This might be a hardware or software limitation like on Raspberry Pi Zero with composite output.         if (((con->connection == DRM_MODE_CONNECTED) || (con->connection == DRM_MODE_UNKNOWNCONNECTION)) && (con->encoder_id))
raylib/src/platforms/rcore_web.c view
@@ -74,6 +74,8 @@ typedef struct {     GLFWwindow *handle;                 // GLFW window handle (graphic device)     bool ourFullscreen;                 // Internal var to filter our handling of fullscreen vs the user handling of fullscreen+    int unmaximizedWidth;               // Internal var to store the unmaximized window (canvas) width+    int unmaximizedHeight;              // Internal var to store the unmaximized window (canvas) height } PlatformData;  //----------------------------------------------------------------------------------@@ -317,7 +319,18 @@ // Set window state: maximized, if resizable void MaximizeWindow(void) {-    TRACELOG(LOG_WARNING, "MaximizeWindow() not available on target platform");+    if (glfwGetWindowAttrib(platform.handle, GLFW_RESIZABLE) == GLFW_TRUE && !(CORE.Window.flags & FLAG_WINDOW_MAXIMIZED))+    {+        platform.unmaximizedWidth = CORE.Window.screen.width;+        platform.unmaximizedHeight = CORE.Window.screen.height;++        const int tabWidth = EM_ASM_INT( { return window.innerWidth;  }, 0);+        const int tabHeight = EM_ASM_INT( { return window.innerHeight; }, 0);++        if (tabWidth && tabHeight) glfwSetWindowSize(platform.handle, tabWidth, tabHeight);++        CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED;+    } }  // Set window state: minimized@@ -329,7 +342,12 @@ // Set window state: not minimized/maximized void RestoreWindow(void) {-    TRACELOG(LOG_WARNING, "RestoreWindow() not available on target platform");+    if (glfwGetWindowAttrib(platform.handle, GLFW_RESIZABLE) == GLFW_TRUE && (CORE.Window.flags & FLAG_WINDOW_MAXIMIZED))+    {+        if (platform.unmaximizedWidth && platform.unmaximizedHeight) glfwSetWindowSize(platform.handle, platform.unmaximizedWidth, platform.unmaximizedHeight);++        CORE.Window.flags &= ~FLAG_WINDOW_MAXIMIZED;+    } }  // Set window configuration state using flags@@ -398,9 +416,20 @@     }      // State change: FLAG_WINDOW_MAXIMIZED-    if ((flags & FLAG_WINDOW_MAXIMIZED) > 0)+    if (((CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) != (flags & FLAG_WINDOW_MAXIMIZED)) && ((flags & FLAG_WINDOW_MAXIMIZED) > 0))     {-        TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_MAXIMIZED) not available on target platform");+        if (glfwGetWindowAttrib(platform.handle, GLFW_RESIZABLE) == GLFW_TRUE)+        {+            platform.unmaximizedWidth = CORE.Window.screen.width;+            platform.unmaximizedHeight = CORE.Window.screen.height;++            const int tabWidth = EM_ASM_INT( { return window.innerWidth;  }, 0);+            const int tabHeight = EM_ASM_INT( { return window.innerHeight; }, 0);++            if (tabWidth && tabHeight) glfwSetWindowSize(platform.handle, tabWidth, tabHeight);++            CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED;+        }     }      // State change: FLAG_WINDOW_UNFOCUSED@@ -516,9 +545,14 @@     }      // State change: FLAG_WINDOW_MAXIMIZED-    if ((flags & FLAG_WINDOW_MAXIMIZED) > 0)+    if (((CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) > 0) && ((flags & FLAG_WINDOW_MAXIMIZED) > 0))     {-        TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_MAXIMIZED) not available on target platform");+        if (glfwGetWindowAttrib(platform.handle, GLFW_RESIZABLE) == GLFW_TRUE)+        {+            if (platform.unmaximizedWidth && platform.unmaximizedHeight) glfwSetWindowSize(platform.handle, platform.unmaximizedWidth, platform.unmaximizedHeight);++            CORE.Window.flags &= ~FLAG_WINDOW_MAXIMIZED;+        }     }      // State change: FLAG_WINDOW_UNDECORATED@@ -639,7 +673,9 @@ // Set window opacity, value opacity is between 0.0 and 1.0 void SetWindowOpacity(float opacity) {-    TRACELOG(LOG_WARNING, "SetWindowOpacity() not available on target platform");+    if (opacity >= 1.0f) opacity = 1.0f;+    else if (opacity <= 0.0f) opacity = 0.0f;+    EM_ASM({ document.getElementById('canvas').style.opacity = $0; }, opacity); }  // Set window focused@@ -856,9 +892,34 @@ }  // Set gamepad vibration-void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor)+void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration) {-    TRACELOG(LOG_WARNING, "GamepadSetVibration() not implemented on target platform");+    if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (duration > 0.0f))+    {+        if (leftMotor < 0.0f) leftMotor = 0.0f;+        if (leftMotor > 1.0f) leftMotor = 1.0f;+        if (rightMotor < 0.0f) rightMotor = 0.0f;+        if (rightMotor > 1.0f) rightMotor = 1.0f;+        if (duration > MAX_GAMEPAD_VIBRATION_TIME) duration = MAX_GAMEPAD_VIBRATION_TIME;+        duration *= 1000.0f; // Convert duration to ms++        // Note: At the moment (2024.10.21) Chrome, Edge, Opera, Safari, Android Chrome, Android Webview only support the vibrationActuator API,+        //       and Firefox only supports the hapticActuators API+        EM_ASM({+            try+            {+                navigator.getGamepads()[$0].vibrationActuator.playEffect('dual-rumble', { startDelay: 0, duration: $3, weakMagnitude: $1, strongMagnitude: $2 });+            }+            catch (e)+            {+                try+                {+                    navigator.getGamepads()[$0].hapticActuators[0].pulse($2, $3);+                }+                catch (e) { }+            }+        }, gamepad, leftMotor, rightMotor, duration);+    } }  // Set mouse position XY
raylib/src/raudio.c view
@@ -892,8 +892,8 @@     return wave; } -// Checks if wave data is ready-bool IsWaveReady(Wave wave)+// Checks if wave data is valid (data loaded and parameters)+bool IsWaveValid(Wave wave) {     bool result = false; @@ -993,8 +993,8 @@ }  -// Checks if a sound is ready-bool IsSoundReady(Sound sound)+// Checks if a sound is valid (data loaded and buffers initialized)+bool IsSoundValid(Sound sound) {     bool result = false; @@ -1726,8 +1726,8 @@     return music; } -// Checks if a music stream is ready-bool IsMusicReady(Music music)+// Checks if a music stream is valid (context and buffers initialized)+bool IsMusicValid(Music music) {     return ((music.ctxData != NULL) &&          // Validate context loaded             (music.frameCount > 0) &&           // Validate audio frame count@@ -2119,8 +2119,8 @@     return stream; } -// Checks if an audio stream is ready-bool IsAudioStreamReady(AudioStream stream)+// Checks if an audio stream is valid (buffers initialized)+bool IsAudioStreamValid(AudioStream stream) {     return ((stream.buffer != NULL) &&    // Validate stream buffer             (stream.sampleRate > 0) &&    // Validate sample rate is supported
raylib/src/raylib.h view
@@ -1044,7 +1044,7 @@ // NOTE: Shader functionality is not available on OpenGL 1.1 RLAPI Shader LoadShader(const char *vsFileName, const char *fsFileName);   // Load shader from files and bind default locations RLAPI Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode); // Load shader from code strings and bind default locations-RLAPI bool IsShaderReady(Shader shader);                                   // Check if a shader is ready+RLAPI bool IsShaderValid(Shader shader);                                   // Check if a shader is valid (loaded on GPU) RLAPI int GetShaderLocation(Shader shader, const char *uniformName);       // Get shader uniform location RLAPI int GetShaderLocationAttrib(Shader shader, const char *attribName);  // Get shader attribute location RLAPI void SetShaderValue(Shader shader, int locIndex, const void *value, int uniformType);               // Set shader uniform value@@ -1144,7 +1144,11 @@ RLAPI unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize);  // Decompress data (DEFLATE algorithm), memory must be MemFree() RLAPI char *EncodeDataBase64(const unsigned char *data, int dataSize, int *outputSize);               // Encode data to Base64 string, memory must be MemFree() RLAPI unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize);                    // Decode Base64 string data, memory must be MemFree()+RLAPI unsigned int ComputeCRC32(unsigned char *data, int dataSize);     // Compute CRC32 hash code+RLAPI unsigned int *ComputeMD5(unsigned char *data, int dataSize);      // Compute MD5 hash code, returns static int[4] (16 bytes)+RLAPI unsigned int *ComputeSHA1(unsigned char *data, int dataSize);      // Compute SHA1 hash code, returns static int[5] (20 bytes) + // Automation events functionality RLAPI AutomationEventList LoadAutomationEventList(const char *fileName);                // Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS RLAPI void UnloadAutomationEventList(AutomationEventList list);                         // Unload automation events list from file@@ -1180,7 +1184,7 @@ RLAPI int GetGamepadAxisCount(int gamepad);                                        // Get gamepad axis count for a gamepad RLAPI float GetGamepadAxisMovement(int gamepad, int axis);                         // Get axis movement value for a gamepad axis RLAPI int SetGamepadMappings(const char *mappings);                                // Set internal gamepad mappings (SDL_GameControllerDB)-RLAPI void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor);    // Set gamepad vibration for both motors+RLAPI void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration); // Set gamepad vibration for both motors (duration in seconds)  // Input-related functions: mouse RLAPI bool IsMouseButtonPressed(int button);                  // Check if a mouse button has been pressed once@@ -1211,7 +1215,7 @@ RLAPI void SetGesturesEnabled(unsigned int flags);      // Enable a set of gestures using flags RLAPI bool IsGestureDetected(unsigned int gesture);     // Check if a gesture have been detected RLAPI int GetGestureDetected(void);                     // Get latest detected gesture-RLAPI float GetGestureHoldDuration(void);               // Get gesture hold time in milliseconds+RLAPI float GetGestureHoldDuration(void);               // Get gesture hold time in seconds RLAPI Vector2 GetGestureDragVector(void);               // Get gesture drag vector RLAPI float GetGestureDragAngle(void);                  // Get gesture drag angle RLAPI Vector2 GetGesturePinchVector(void);              // Get gesture pinch delta@@ -1317,7 +1321,7 @@ RLAPI Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, int dataSize);      // Load image from memory buffer, fileType refers to extension: i.e. '.png' RLAPI Image LoadImageFromTexture(Texture2D texture);                                                     // Load image from GPU texture data RLAPI Image LoadImageFromScreen(void);                                                                   // Load image from screen buffer and (screenshot)-RLAPI bool IsImageReady(Image image);                                                                    // Check if an image is ready+RLAPI bool IsImageValid(Image image);                                                                    // Check if an image is valid (data and parameters) RLAPI void UnloadImage(Image image);                                                                     // Unload image from CPU memory (RAM) RLAPI bool ExportImage(Image image, const char *fileName);                                               // Export image data to file, returns true on success RLAPI unsigned char *ExportImageToMemory(Image image, const char *fileType, int *fileSize);              // Export image to memory buffer@@ -1403,9 +1407,9 @@ RLAPI Texture2D LoadTextureFromImage(Image image);                                                       // Load texture from image data RLAPI TextureCubemap LoadTextureCubemap(Image image, int layout);                                        // Load cubemap from image, multiple image cubemap layouts supported RLAPI RenderTexture2D LoadRenderTexture(int width, int height);                                          // Load texture for rendering (framebuffer)-RLAPI bool IsTextureReady(Texture2D texture);                                                            // Check if a texture is ready+RLAPI bool IsTextureValid(Texture2D texture);                                                            // Check if a texture is valid (loaded in GPU) RLAPI void UnloadTexture(Texture2D texture);                                                             // Unload texture from GPU memory (VRAM)-RLAPI bool IsRenderTextureReady(RenderTexture2D target);                                                 // Check if a render texture is ready+RLAPI bool IsRenderTextureValid(RenderTexture2D target);                                                 // Check if a render texture is valid (loaded in GPU) RLAPI void UnloadRenderTexture(RenderTexture2D target);                                                  // Unload render texture from GPU memory (VRAM) RLAPI void UpdateTexture(Texture2D texture, const void *pixels);                                         // Update GPU texture with new data RLAPI void UpdateTextureRec(Texture2D texture, Rectangle rec, const void *pixels);                       // Update GPU texture rectangle with new data@@ -1452,7 +1456,7 @@ RLAPI Font LoadFontEx(const char *fileName, int fontSize, int *codepoints, int codepointCount); // Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set, font size is provided in pixels height RLAPI Font LoadFontFromImage(Image image, Color key, int firstChar);                        // Load font from Image (XNA style) RLAPI Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount); // Load font from memory buffer, fileType refers to extension: i.e. '.ttf'-RLAPI bool IsFontReady(Font font);                                                          // Check if a font is ready+RLAPI bool IsFontValid(Font font);                                                          // Check if a font is valid (font data loaded, WARNING: GPU texture not checked) RLAPI GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount, int type); // Load font data for further use RLAPI Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyphCount, int fontSize, int padding, int packMethod); // Generate image font atlas using chars info RLAPI void UnloadFontData(GlyphInfo *glyphs, int glyphCount);                               // Unload font chars info data (RAM)@@ -1542,7 +1546,7 @@ // Model management functions RLAPI Model LoadModel(const char *fileName);                                                // Load model from files (meshes and materials) RLAPI Model LoadModelFromMesh(Mesh mesh);                                                   // Load model from generated mesh (default material)-RLAPI bool IsModelReady(Model model);                                                       // Check if a model is ready+RLAPI bool IsModelValid(Model model);                                                       // Check if a model is valid (loaded in GPU, VAO/VBOs) RLAPI void UnloadModel(Model model);                                                        // Unload model (including meshes) from memory (RAM and/or VRAM) RLAPI BoundingBox GetModelBoundingBox(Model model);                                         // Compute model bounding box limits (considers all meshes) @@ -1585,7 +1589,7 @@ // Material loading/unloading functions RLAPI Material *LoadMaterials(const char *fileName, int *materialCount);                    // Load materials from model file RLAPI Material LoadMaterialDefault(void);                                                   // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps)-RLAPI bool IsMaterialReady(Material material);                                              // Check if a material is ready+RLAPI bool IsMaterialValid(Material material);                                              // Check if a material is valid (shader assigned, map textures loaded in GPU) RLAPI void UnloadMaterial(Material material);                                               // Unload material from GPU memory (VRAM) RLAPI void SetMaterialTexture(Material *material, int mapType, Texture2D texture);          // Set texture for a material map type (MATERIAL_MAP_DIFFUSE, MATERIAL_MAP_SPECULAR...) RLAPI void SetModelMeshMaterial(Model *model, int meshId, int materialId);                  // Set material for a mesh@@ -1623,11 +1627,11 @@ // Wave/Sound loading/unloading functions RLAPI Wave LoadWave(const char *fileName);                            // Load wave data from file RLAPI Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load wave from memory buffer, fileType refers to extension: i.e. '.wav'-RLAPI bool IsWaveReady(Wave wave);                                    // Checks if wave data is ready+RLAPI bool IsWaveValid(Wave wave);                                    // Checks if wave data is valid (data loaded and parameters) RLAPI Sound LoadSound(const char *fileName);                          // Load sound from file RLAPI Sound LoadSoundFromWave(Wave wave);                             // Load sound from wave data RLAPI Sound LoadSoundAlias(Sound source);                             // Create a new sound that shares the same sample data as the source sound, does not own the sound data-RLAPI bool IsSoundReady(Sound sound);                                 // Checks if a sound is ready+RLAPI bool IsSoundValid(Sound sound);                                 // Checks if a sound is valid (data loaded and buffers initialized) RLAPI void UpdateSound(Sound sound, const void *data, int sampleCount); // Update sound buffer with new data RLAPI void UnloadWave(Wave wave);                                     // Unload wave data RLAPI void UnloadSound(Sound sound);                                  // Unload sound@@ -1653,7 +1657,7 @@ // Music management functions RLAPI Music LoadMusicStream(const char *fileName);                    // Load music stream from file RLAPI Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data, int dataSize); // Load music stream from data-RLAPI bool IsMusicReady(Music music);                                 // Checks if a music stream is ready+RLAPI bool IsMusicValid(Music music);                                 // Checks if a music stream is valid (context and buffers initialized) RLAPI void UnloadMusicStream(Music music);                            // Unload music stream RLAPI void PlayMusicStream(Music music);                              // Start music playing RLAPI bool IsMusicStreamPlaying(Music music);                         // Check if music is playing@@ -1670,7 +1674,7 @@  // AudioStream management functions RLAPI AudioStream LoadAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels); // Load audio stream (to stream raw audio pcm data)-RLAPI bool IsAudioStreamReady(AudioStream stream);                    // Checks if an audio stream is ready+RLAPI bool IsAudioStreamValid(AudioStream stream);                    // Checks if an audio stream is valid (buffers initialized) RLAPI void UnloadAudioStream(AudioStream stream);                     // Unload audio stream and free memory RLAPI void UpdateAudioStream(AudioStream stream, const void *data, int frameCount); // Update audio stream buffers with data RLAPI bool IsAudioStreamProcessed(AudioStream stream);                // Check if any audio stream buffers requires refill
raylib/src/raymath.h view
@@ -1,6 +1,6 @@ /********************************************************************************************** *-*   raymath v1.5 - Math functions to work with Vector2, Vector3, Matrix and Quaternions+*   raymath v2.0 - Math functions to work with Vector2, Vector3, Matrix and Quaternions * *   CONVENTIONS: *     - Matrix structure is defined as row-major (memory layout) but parameters naming AND all@@ -12,7 +12,7 @@ *     - Functions are always self-contained, no function use another raymath function inside, *       required code is directly re-implemented inside *     - Functions input parameters are always received by value (2 unavoidable exceptions)-*     - Functions use always a "result" variable for return+*     - Functions use always a "result" variable for return (except C++ operators) *     - Functions are always defined inline *     - Angles are always in radians (DEG2RAD/RAD2DEG macros provided for convenience) *     - No compound literals used to make sure libray is compatible with C++@@ -27,6 +27,8 @@ *           Define static inline functions code, so #include header suffices for use. *           This may use up lots of memory. *+*       #define RAYMATH_DISABLE_CPP_OPERATORS+*           Disables C++ operator overloads for raymath types. * *   LICENSE: zlib/libpng *@@ -2579,5 +2581,355 @@         *rotation = QuaternionIdentity();     } }++#if defined(__cplusplus) && !defined(RAYMATH_DISABLE_CPP_OPERATORS)++// Optional C++ math operators+//-------------------------------------------------------------------------------++// Vector2 operators+static constexpr Vector2 Vector2Zeros = { 0, 0 };+static constexpr Vector2 Vector2Ones = { 1, 1 };+static constexpr Vector2 Vector2UnitX = { 1, 0 };+static constexpr Vector2 Vector2UnitY = { 0, 1 };++inline Vector2 operator + (const Vector2& lhs, const Vector2& rhs)+{+    return Vector2Add(lhs, rhs);+}++inline const Vector2& operator += (Vector2& lhs, const Vector2& rhs)+{+    lhs = Vector2Add(lhs, rhs);+    return lhs;+}++inline Vector2 operator - (const Vector2& lhs, const Vector2& rhs)+{+    return Vector2Subtract(lhs, rhs);+}++inline const Vector2& operator -= (Vector2& lhs, const Vector2& rhs)+{+    lhs = Vector2Subtract(lhs, rhs);+    return lhs;+}++inline Vector2 operator * (const Vector2& lhs, const float& rhs)+{+    return Vector2Scale(lhs, rhs);+}++inline const Vector2& operator *= (Vector2& lhs, const float& rhs)+{+    lhs = Vector2Scale(lhs, rhs);+    return lhs;+}++inline Vector2 operator * (const Vector2& lhs, const Vector2& rhs)+{+    return Vector2Multiply(lhs, rhs);+}++inline const Vector2& operator *= (Vector2& lhs, const Vector2& rhs)+{+    lhs = Vector2Multiply(lhs, rhs);+    return lhs;+}++inline Vector2 operator * (const Vector2& lhs, const Matrix& rhs)+{+    return Vector2Transform(lhs, rhs);+}++inline const Vector2& operator -= (Vector2& lhs, const Matrix& rhs)+{+    lhs = Vector2Transform(lhs, rhs);+    return lhs;+}++inline Vector2 operator / (const Vector2& lhs, const float& rhs)+{+    return Vector2Scale(lhs, 1.0f / rhs);+}++inline const Vector2& operator /= (Vector2& lhs, const float& rhs)+{+    lhs = Vector2Scale(lhs, rhs);+    return lhs;+}++inline Vector2 operator / (const Vector2& lhs, const Vector2& rhs)+{+    return Vector2Divide(lhs, rhs);+}++inline const Vector2& operator /= (Vector2& lhs, const Vector2& rhs)+{+    lhs = Vector2Divide(lhs, rhs);+    return lhs;+}++inline bool operator == (const Vector2& lhs, const Vector2& rhs)+{+    return FloatEquals(lhs.x, rhs.x) && FloatEquals(lhs.y, rhs.y);+}++inline bool operator != (const Vector2& lhs, const Vector2& rhs)+{+    return !FloatEquals(lhs.x, rhs.x) || !FloatEquals(lhs.y, rhs.y);+}++// Vector3 operators+static constexpr Vector3 Vector3Zeros = { 0, 0, 0 };+static constexpr Vector3 Vector3Ones = { 1, 1, 1 };+static constexpr Vector3 Vector3UnitX = { 1, 0, 0 };+static constexpr Vector3 Vector3UnitY = { 0, 1, 0 };+static constexpr Vector3 Vector3UnitZ = { 0, 0, 1 };++inline Vector3 operator + (const Vector3& lhs, const Vector3& rhs)+{+    return Vector3Add(lhs, rhs);+}++inline const Vector3& operator += (Vector3& lhs, const Vector3& rhs)+{+    lhs = Vector3Add(lhs, rhs);+    return lhs;+}++inline Vector3 operator - (const Vector3& lhs, const Vector3& rhs)+{+    return Vector3Subtract(lhs, rhs);+}++inline const Vector3& operator -= (Vector3& lhs, const Vector3& rhs)+{+    lhs = Vector3Subtract(lhs, rhs);+    return lhs;+}++inline Vector3 operator * (const Vector3& lhs, const float& rhs)+{+    return Vector3Scale(lhs, rhs);+}++inline const Vector3& operator *= (Vector3& lhs, const float& rhs)+{+    lhs = Vector3Scale(lhs, rhs);+    return lhs;+}++inline Vector3 operator * (const Vector3& lhs, const Vector3& rhs)+{+    return Vector3Multiply(lhs, rhs);+}++inline const Vector3& operator *= (Vector3& lhs, const Vector3& rhs)+{+    lhs = Vector3Multiply(lhs, rhs);+    return lhs;+}++inline Vector3 operator * (const Vector3& lhs, const Matrix& rhs)+{+    return Vector3Transform(lhs, rhs);+}++inline const Vector3& operator -= (Vector3& lhs, const Matrix& rhs)+{+    lhs = Vector3Transform(lhs, rhs);+    return lhs;+}++inline Vector3 operator / (const Vector3& lhs, const float& rhs)+{+    return Vector3Scale(lhs, 1.0f / rhs);+}++inline const Vector3& operator /= (Vector3& lhs, const float& rhs)+{+    lhs = Vector3Scale(lhs, rhs);+    return lhs;+}++inline Vector3 operator / (const Vector3& lhs, const Vector3& rhs)+{+    return Vector3Divide(lhs, rhs);+}++inline const Vector3& operator /= (Vector3& lhs, const Vector3& rhs)+{+    lhs = Vector3Divide(lhs, rhs);+    return lhs;+}++inline bool operator == (const Vector3& lhs, const Vector3& rhs)+{+    return FloatEquals(lhs.x, rhs.x) && FloatEquals(lhs.y, rhs.y) && FloatEquals(lhs.z, rhs.z);+}++inline bool operator != (const Vector3& lhs, const Vector3& rhs)+{+    return !FloatEquals(lhs.x, rhs.x) || !FloatEquals(lhs.y, rhs.y) || !FloatEquals(lhs.z, rhs.z);+}++// Vector4 operators+static constexpr Vector4 Vector4Zeros = { 0, 0, 0, 0 };+static constexpr Vector4 Vector4Ones = { 1, 1, 1, 1 };+static constexpr Vector4 Vector4UnitX = { 1, 0, 0, 0 };+static constexpr Vector4 Vector4UnitY = { 0, 1, 0, 0 };+static constexpr Vector4 Vector4UnitZ = { 0, 0, 1, 0 };+static constexpr Vector4 Vector4UnitW = { 0, 0, 0, 1 };++inline Vector4 operator + (const Vector4& lhs, const Vector4& rhs)+{+    return Vector4Add(lhs, rhs);+}++inline const Vector4& operator += (Vector4& lhs, const Vector4& rhs)+{+    lhs = Vector4Add(lhs, rhs);+    return lhs;+}++inline Vector4 operator - (const Vector4& lhs, const Vector4& rhs)+{+    return Vector4Subtract(lhs, rhs);+}++inline const Vector4& operator -= (Vector4& lhs, const Vector4& rhs)+{+    lhs = Vector4Subtract(lhs, rhs);+    return lhs;+}++inline Vector4 operator * (const Vector4& lhs, const float& rhs)+{+    return Vector4Scale(lhs, rhs);+}++inline const Vector4& operator *= (Vector4& lhs, const float& rhs)+{+    lhs = Vector4Scale(lhs, rhs);+    return lhs;+}++inline Vector4 operator * (const Vector4& lhs, const Vector4& rhs)+{+    return Vector4Multiply(lhs, rhs);+}++inline const Vector4& operator *= (Vector4& lhs, const Vector4& rhs)+{+    lhs = Vector4Multiply(lhs, rhs);+    return lhs;+}++inline Vector4 operator / (const Vector4& lhs, const float& rhs)+{+    return Vector4Scale(lhs, 1.0f / rhs);+}++inline const Vector4& operator /= (Vector4& lhs, const float& rhs)+{+    lhs = Vector4Scale(lhs, rhs);+    return lhs;+}++inline Vector4 operator / (const Vector4& lhs, const Vector4& rhs)+{+    return Vector4Divide(lhs, rhs);+}++inline const Vector4& operator /= (Vector4& lhs, const Vector4& rhs)+{+    lhs = Vector4Divide(lhs, rhs);+    return lhs;+}++inline bool operator == (const Vector4& lhs, const Vector4& rhs)+{+    return FloatEquals(lhs.x, rhs.x) && FloatEquals(lhs.y, rhs.y) && FloatEquals(lhs.z, rhs.z) && FloatEquals(lhs.w, rhs.w);+}++inline bool operator != (const Vector4& lhs, const Vector4& rhs)+{+    return !FloatEquals(lhs.x, rhs.x) || !FloatEquals(lhs.y, rhs.y) || !FloatEquals(lhs.z, rhs.z) || !FloatEquals(lhs.w, rhs.w);+}++// Quaternion operators+static constexpr Quaternion QuaternionZeros = { 0, 0, 0, 0 };+static constexpr Quaternion QuaternionOnes = { 1, 1, 1, 1 };+static constexpr Quaternion QuaternionUnitX = { 0, 0, 0, 1 };++inline Quaternion operator + (const Quaternion& lhs, const float& rhs)+{+    return QuaternionAddValue(lhs, rhs);+}++inline const Quaternion& operator += (Quaternion& lhs, const float& rhs)+{+    lhs = QuaternionAddValue(lhs, rhs);+    return lhs;+}++inline Quaternion operator - (const Quaternion& lhs, const float& rhs)+{+    return QuaternionSubtractValue(lhs, rhs);+}++inline const Quaternion& operator -= (Quaternion& lhs, const float& rhs)+{+    lhs = QuaternionSubtractValue(lhs, rhs);+    return lhs;+}++inline Quaternion operator * (const Quaternion& lhs, const Matrix& rhs)+{+    return QuaternionTransform(lhs, rhs);+}++inline const Quaternion& operator *= (Quaternion& lhs, const Matrix& rhs)+{+    lhs = QuaternionTransform(lhs, rhs);+    return lhs;+}++// Matrix operators+inline Matrix operator + (const Matrix& lhs, const Matrix& rhs)+{+    return MatrixAdd(lhs, rhs);+}++inline const Matrix& operator += (Matrix& lhs, const Matrix& rhs)+{+    lhs = MatrixAdd(lhs, rhs);+    return lhs;+}++inline Matrix operator - (const Matrix& lhs, const Matrix& rhs)+{+    return MatrixSubtract(lhs, rhs);+}++inline const Matrix& operator -= (Matrix& lhs, const Matrix& rhs)+{+    lhs = MatrixSubtract(lhs, rhs);+    return lhs;+}++inline Matrix operator * (const Matrix& lhs, const Matrix& rhs)+{+    return MatrixMultiply(lhs, rhs);+}++inline const Matrix& operator *= (Matrix& lhs, const Matrix& rhs)+{+    lhs = MatrixMultiply(lhs, rhs);+    return lhs;+}+//-------------------------------------------------------------------------------+#endif  // C++ operators  #endif  // RAYMATH_H
raylib/src/rcore.c view
@@ -691,7 +691,7 @@      // Initialize random seed     SetRandomSeed((unsigned int)time(NULL));-    +     TRACELOG(LOG_INFO, "SYSTEM: Working Directory: %s", GetWorkingDirectory()); } @@ -1342,10 +1342,10 @@     return shader; } -// Check if a shader is ready-bool IsShaderReady(Shader shader)+// Check if a shader is valid (loaded on GPU)+bool IsShaderValid(Shader shader) {-    return ((shader.id > 0) &&          // Validate shader id (loaded successfully)+    return ((shader.id > 0) &&          // Validate shader id (GPU loaded successfully)             (shader.locs != NULL));     // Validate memory has been allocated for default shader locations      // The following locations are tried to be set automatically (locs[i] >= 0),@@ -2577,6 +2577,265 @@     return decodedData; } +// Compute CRC32 hash code+unsigned int ComputeCRC32(unsigned char *data, int dataSize)+{+    static unsigned int crcTable[256] = {+        0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,+        0x0eDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,+        0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,+        0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,+        0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,+        0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,+        0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,+        0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,+        0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,+        0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,+        0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,+        0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,+        0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,+        0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,+        0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,+        0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,+        0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,+        0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,+        0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,+        0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,+        0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,+        0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,+        0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,+        0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,+        0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,+        0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,+        0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,+        0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,+        0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,+        0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,+        0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,+        0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D+    };++    unsigned int crc = ~0u;++    for (int i = 0; i < dataSize; i++) crc = (crc >> 8) ^ crcTable[data[i] ^ (crc & 0xff)];++    return ~crc;+}++// Compute MD5 hash code+// NOTE: Returns a static int[4] array (16 bytes)+unsigned int *ComputeMD5(unsigned char *data, int dataSize)+{+    #define ROTATE_LEFT(x, c) (((x) << (c)) | ((x) >> (32 - (c))))++    static unsigned int hash[4] = { 0 };  // Hash to be returned++    // WARNING: All variables are unsigned 32 bit and wrap modulo 2^32 when calculating++    // NOTE: r specifies the per-round shift amounts+    unsigned int r[] = {+        7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,+        5,  9, 14, 20, 5,  9, 14, 20, 5,  9, 14, 20, 5,  9, 14, 20,+        4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,+        6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21+    };++    // Using binary integer part of the sines of integers (in radians) as constants+    unsigned int k[] = {+        0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,+        0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,+        0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,+        0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,+        0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,+        0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,+        0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,+        0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,+        0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,+        0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,+        0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,+        0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,+        0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,+        0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,+        0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,+        0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391+    };++    hash[0] = 0x67452301;+    hash[1] = 0xefcdab89;+    hash[2] = 0x98badcfe;+    hash[3] = 0x10325476;++    // Pre-processing: adding a single 1 bit+    // Append '1' bit to message+    // NOTE: The input bytes are considered as bits strings,+    // where the first bit is the most significant bit of the byte++    // Pre-processing: padding with zeros+    // Append '0' bit until message length in bit 448 (mod 512)+    // Append length mod (2 pow 64) to message++    int newDataSize = ((((dataSize + 8)/64) + 1)*64) - 8;++    unsigned char *msg = RL_CALLOC(newDataSize + 64, 1); // Initialize with '0' bits, allocating 64 extra bytes+    memcpy(msg, data, dataSize);+    msg[dataSize] = 128; // Write the '1' bit++    unsigned int bitsLen = 8*dataSize;+    memcpy(msg + newDataSize, &bitsLen, 4); // Append the len in bits at the end of the buffer++    // Process the message in successive 512-bit chunks for each 512-bit chunk of message+    for (int offset = 0; offset < newDataSize; offset += (512/8))+    {+        // Break chunk into sixteen 32-bit words w[j], 0 <= j <= 15+        unsigned int *w = (unsigned int *)(msg + offset);++        // Initialize hash value for this chunk+        unsigned int a = hash[0];+        unsigned int b = hash[1];+        unsigned int c = hash[2];+        unsigned int d = hash[3];++        for (int i = 0; i < 64; i++)+        {+            unsigned int f = 0;+            unsigned int g = 0;++            if (i < 16)+            {+                f = (b & c) | ((~b) & d);+                g = i;+            }+            else if (i < 32)+            {+                f = (d & b) | ((~d) & c);+                g = (5*i + 1)%16;+            }+            else if (i < 48)+            {+                f = b ^ c ^ d;+                g = (3*i + 5)%16;+            }+            else+            {+                f = c ^ (b | (~d));+                g = (7*i)%16;+            }++            unsigned int temp = d;+            d = c;+            c = b;+            b = b + ROTATE_LEFT((a + f + k[i] + w[g]), r[i]);+            a = temp;+        }++        // Add chunk's hash to result so far+        hash[0] += a;+        hash[1] += b;+        hash[2] += c;+        hash[3] += d;+    }++    RL_FREE(msg);++    return hash;+}++// Compute SHA-1 hash code+// NOTE: Returns a static int[5] array (20 bytes)+unsigned int *ComputeSHA1(unsigned char *data, int dataSize) {+    #define ROTATE_LEFT(x, c) (((x) << (c)) | ((x) >> (32 - (c))))++    static unsigned int hash[5] = { 0 };  // Hash to be returned++    // Initialize hash values+    hash[0] = 0x67452301;+    hash[1] = 0xEFCDAB89;+    hash[2] = 0x98BADCFE;+    hash[3] = 0x10325476;+    hash[4] = 0xC3D2E1F0;++    // Pre-processing: adding a single 1 bit+    // Append '1' bit to message+    // NOTE: The input bytes are considered as bits strings,+    // where the first bit is the most significant bit of the byte++    // Pre-processing: padding with zeros+    // Append '0' bit until message length in bit 448 (mod 512)+    // Append length mod (2 pow 64) to message++    int newDataSize = ((((dataSize + 8)/64) + 1)*64);++    unsigned char *msg = RL_CALLOC(newDataSize, 1); // Initialize with '0' bits+    memcpy(msg, data, dataSize);+    msg[dataSize] = 128; // Write the '1' bit++    unsigned int bitsLen = 8*dataSize;+    msg[newDataSize-1] = bitsLen;++    // Process the message in successive 512-bit chunks+    for (int offset = 0; offset < newDataSize; offset += (512/8))+    {+        // Break chunk into sixteen 32-bit words w[j], 0 <= j <= 15+        unsigned int w[80] = {0};+        for (int i = 0; i < 16; i++) {+            w[i] = (msg[offset + (i * 4) + 0] << 24) |+                   (msg[offset + (i * 4) + 1] << 16) |+                   (msg[offset + (i * 4) + 2] << 8) |+                   (msg[offset + (i * 4) + 3]);+        }++        // Message schedule: extend the sixteen 32-bit words into eighty 32-bit words:+        for (int i = 16; i < 80; ++i) {+            w[i] = ROTATE_LEFT(w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16], 1);+        }++        // Initialize hash value for this chunk+        unsigned int a = hash[0];+        unsigned int b = hash[1];+        unsigned int c = hash[2];+        unsigned int d = hash[3];+        unsigned int e = hash[4];++        for (int i = 0; i < 80; i++)+        {+            unsigned int f = 0;+            unsigned int k = 0;++            if (i < 20) {+                f = (b & c) | ((~b) & d);+                k = 0x5A827999;+            } else if (i < 40) {+                f = b ^ c ^ d;+                k = 0x6ED9EBA1;+            } else if (i < 60) {+                f = (b & c) | (b & d) | (c & d);+                k = 0x8F1BBCDC;+            } else {+                f = b ^ c ^ d;+                k = 0xCA62C1D6;+            }++            unsigned int temp = ROTATE_LEFT(a, 5) + f + e + k + w[i];+            e = d;+            d = c;+            c = ROTATE_LEFT(b, 30);+            b = a;+            a = temp;+        }++        // Add this chunk's hash to result so far+        hash[0] += a;+        hash[1] += b;+        hash[2] += c;+        hash[3] += d;+        hash[4] += e;+    }++    free(msg);++    return hash;+}+ //---------------------------------------------------------------------------------- // Module Functions Definition: Automation Events Recording and Playing //----------------------------------------------------------------------------------@@ -3457,14 +3716,14 @@                         break;                     }                 }-                else +                else                 {                     if ((filter != NULL) && (TextFindIndex(filter, DIRECTORY_FILTER_TAG) >= 0))                     {                         strcpy(files->paths[files->count], path);                         files->count++;                     }-                    +                     if (files->count >= files->capacity)                     {                         TRACELOG(LOG_WARNING, "FILEIO: Maximum filepath scan capacity reached (%i files)", files->capacity);
raylib/src/rgestures.h view
@@ -434,7 +434,7 @@     return (GESTURES.enabledFlags & GESTURES.current); } -// Hold time measured in ms+// Hold time measured in seconds float GetGestureHoldDuration(void) {     // NOTE: time is calculated on current gesture HOLD@@ -517,7 +517,7 @@ #if defined(_WIN32)     unsigned long long int clockFrequency, currentTime; -    QueryPerformanceFrequency(&clockFrequency);     // BE CAREFUL: Costly operation!+    QueryPerformanceFrequency(&clockFrequency); // BE CAREFUL: Costly operation!     QueryPerformanceCounter(&currentTime);      time = (double)currentTime/clockFrequency;  // Time in seconds
raylib/src/rlgl.h view
@@ -347,7 +347,6 @@ #ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES     #define RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES     6 #endif- #ifdef RL_SUPPORT_MESH_GPU_SKINNING #ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS     #define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS     7@@ -2473,25 +2472,47 @@         }          // Check instanced rendering support-        if (strcmp(extList[i], (const char *)"GL_ANGLE_instanced_arrays") == 0)         // Web ANGLE+        if (strstr(extList[i], (const char*)"instanced_arrays") != NULL)   // Broad check for instanced_arrays         {-            glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedANGLE");-            glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedANGLE");-            glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISOREXTPROC)((rlglLoadProc)loader)("glVertexAttribDivisorANGLE");+            // Specific check+            if (strcmp(extList[i], (const char *)"GL_ANGLE_instanced_arrays") == 0)      // ANGLE+            {+                glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedANGLE");+                glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedANGLE");+                glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISOREXTPROC)((rlglLoadProc)loader)("glVertexAttribDivisorANGLE");+            }+            else if (strcmp(extList[i], (const char *)"GL_EXT_instanced_arrays") == 0)   // EXT+            {+                glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedEXT");+                glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedEXT");+                glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISOREXTPROC)((rlglLoadProc)loader)("glVertexAttribDivisorEXT");+            }+            else if (strcmp(extList[i], (const char *)"GL_NV_instanced_arrays") == 0)    // NVIDIA GLES+            {+                glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedNV");+                glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedNV");+                glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISOREXTPROC)((rlglLoadProc)loader)("glVertexAttribDivisorNV");+            } +            // The feature will only be marked as supported if the elements from GL_XXX_instanced_arrays are present             if ((glDrawArraysInstanced != NULL) && (glDrawElementsInstanced != NULL) && (glVertexAttribDivisor != NULL)) RLGL.ExtSupported.instancing = true;         }-        else+        else if (strstr(extList[i], (const char *)"draw_instanced") != NULL)         {-            if ((strcmp(extList[i], (const char *)"GL_EXT_draw_instanced") == 0) &&     // Standard EXT-                (strcmp(extList[i], (const char *)"GL_EXT_instanced_arrays") == 0))+            // GL_ANGLE_draw_instanced doesn't exist+            if (strcmp(extList[i], (const char *)"GL_EXT_draw_instanced") == 0)             {                 glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedEXT");                 glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedEXT");-                glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISOREXTPROC)((rlglLoadProc)loader)("glVertexAttribDivisorEXT");--                if ((glDrawArraysInstanced != NULL) && (glDrawElementsInstanced != NULL) && (glVertexAttribDivisor != NULL)) RLGL.ExtSupported.instancing = true;             }+            else if (strcmp(extList[i], (const char*)"GL_NV_draw_instanced") == 0)+            {+                glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedNV");+                glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedNV");+            }++            // But the functions will at least be loaded if only GL_XX_EXT_draw_instanced exist+            if ((glDrawArraysInstanced != NULL) && (glDrawElementsInstanced != NULL) && (glVertexAttribDivisor != NULL)) RLGL.ExtSupported.instancing = true;         }          // Check NPOT textures support
raylib/src/rmodels.c view
@@ -426,14 +426,14 @@ { #if 0     // Basic implementation, do not use it!-    // For a sphere with 16 rings and 16 slices it requires 8640 cos()/sin() function calls! +    // For a sphere with 16 rings and 16 slices it requires 8640 cos()/sin() function calls!     // New optimized version below only requires 4 cos()/sin() calls-    +     rlPushMatrix();         // NOTE: Transformation is applied in inverse order (scale -> translate)         rlTranslatef(centerPos.x, centerPos.y, centerPos.z);         rlScalef(radius, radius, radius);-        +         rlBegin(RL_TRIANGLES);             rlColor4ub(color.r, color.g, color.b, color.a); @@ -488,7 +488,7 @@              for (int i = 0; i < rings + 1; i++)             {-                for (int j = 0; j < slices; j++) +                for (int j = 0; j < slices; j++)                 {                     vertices[0] = vertices[2]; // Rotate around y axis to set up vertices for next face                     vertices[1] = vertices[3];@@ -1155,8 +1155,8 @@     return model; } -// Check if a model is ready-bool IsModelReady(Model model)+// Check if a model is valid (loaded in GPU, VAO/VBOs)+bool IsModelValid(Model model) {     bool result = false; @@ -1166,8 +1166,24 @@         (model.meshCount > 0) &&            // Validate mesh count         (model.materialCount > 0)) result = true; // Validate material count -    // NOTE: This is a very general model validation, many elements could be validated from a model...+    // NOTE: Many elements could be validated from a model, including every model mesh VAO/VBOs+    // but some VBOs could not be used, it depends on Mesh vertex data+    for (int i = 0; i < model.meshCount; i++)+    {+        if ((model.meshes[i].vertices != NULL) && (model.meshes[i].vboId[0] == 0)) { result = false; break; }  // Vertex position buffer not uploaded to GPU+        if ((model.meshes[i].texcoords != NULL) && (model.meshes[i].vboId[1] == 0)) { result = false; break; }  // Vertex textcoords buffer not uploaded to GPU+        if ((model.meshes[i].normals != NULL) && (model.meshes[i].vboId[2] == 0)) { result = false; break; }  // Vertex normals buffer not uploaded to GPU+        if ((model.meshes[i].colors != NULL) && (model.meshes[i].vboId[3] == 0)) { result = false; break; }  // Vertex colors buffer not uploaded to GPU+        if ((model.meshes[i].tangents != NULL) && (model.meshes[i].vboId[4] == 0)) { result = false; break; }  // Vertex tangents buffer not uploaded to GPU+        if ((model.meshes[i].texcoords2 != NULL) && (model.meshes[i].vboId[5] == 0)) { result = false; break; }  // Vertex texcoords2 buffer not uploaded to GPU+        if ((model.meshes[i].indices != NULL) && (model.meshes[i].vboId[6] == 0)) { result = false; break; }  // Vertex indices buffer not uploaded to GPU+        if ((model.meshes[i].boneIds != NULL) && (model.meshes[i].vboId[7] == 0)) { result = false; break; }  // Vertex boneIds buffer not uploaded to GPU+        if ((model.meshes[i].boneWeights != NULL) && (model.meshes[i].vboId[8] == 0)) { result = false; break; }  // Vertex boneWeights buffer not uploaded to GPU +        // NOTE: Some OpenGL versions do not support VAO, so we don't check it+        //if (model.meshes[i].vaoId == 0) { result = false; break }+    }+     return result; } @@ -1346,7 +1362,7 @@ #ifdef RL_SUPPORT_MESH_GPU_SKINNING     if (mesh->boneIds != NULL)     {-        // Enable vertex attribute: boneIds (shader-location = 6)+        // Enable vertex attribute: boneIds (shader-location = 7)         mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS] = rlLoadVertexBuffer(mesh->boneIds, mesh->vertexCount*4*sizeof(unsigned char), dynamic);         rlSetVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS, 4, RL_UNSIGNED_BYTE, 0, 0, 0);         rlEnableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS);@@ -1359,10 +1375,10 @@         rlSetVertexAttributeDefault(RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS, value, SHADER_ATTRIB_VEC4, 4);         rlDisableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS);     }-    +     if (mesh->boneWeights != NULL)     {-        // Enable vertex attribute: boneWeights (shader-location = 7)+        // Enable vertex attribute: boneWeights (shader-location = 8)         mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS] = rlLoadVertexBuffer(mesh->boneWeights, mesh->vertexCount*4*sizeof(float), dynamic);         rlSetVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS, 4, RL_FLOAT, 0, 0, 0);         rlEnableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS);@@ -1491,7 +1507,7 @@     if (material.shader.locs[SHADER_LOC_MATRIX_NORMAL] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_NORMAL], MatrixTranspose(MatrixInvert(matModel)));  #ifdef RL_SUPPORT_MESH_GPU_SKINNING-    // Upload Bone Transforms    +    // Upload Bone Transforms     if (material.shader.locs[SHADER_LOC_BONE_MATRICES] != -1 && mesh.boneMatrices)     {         rlSetUniformMatrices(material.shader.locs[SHADER_LOC_BONE_MATRICES], mesh.boneMatrices, mesh.boneCount);@@ -1584,7 +1600,7 @@             rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_BONEIDS], 4, RL_UNSIGNED_BYTE, 0, 0, 0);             rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_BONEIDS]);         }-        +         // Bind mesh VBO data: vertex bone weights (shader-location = 7, if available)         if (material.shader.locs[SHADER_LOC_VERTEX_BONEWEIGHTS] != -1)         {@@ -1735,15 +1751,15 @@      // Upload model normal matrix (if locations available)     if (material.shader.locs[SHADER_LOC_MATRIX_NORMAL] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_NORMAL], MatrixTranspose(MatrixInvert(matModel)));-    + #ifdef RL_SUPPORT_MESH_GPU_SKINNING-    // Upload Bone Transforms    +    // Upload Bone Transforms     if (material.shader.locs[SHADER_LOC_BONE_MATRICES] != -1 && mesh.boneMatrices)     {         rlSetUniformMatrices(material.shader.locs[SHADER_LOC_BONE_MATRICES], mesh.boneMatrices, mesh.boneCount);     } #endif-    +     //-----------------------------------------------------      // Bind active texture maps (if available)@@ -1829,7 +1845,7 @@             rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_BONEIDS], 4, RL_UNSIGNED_BYTE, 0, 0, 0);             rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_BONEIDS]);         }-        +         // Bind mesh VBO data: vertex bone weights (shader-location = 7, if available)         if (material.shader.locs[SHADER_LOC_VERTEX_BONEWEIGHTS] != -1)         {@@ -2182,14 +2198,16 @@     return material; } -// Check if a material is ready-bool IsMaterialReady(Material material)+// Check if a material is valid (map textures loaded in GPU)+bool IsMaterialValid(Material material) {     bool result = false;      if ((material.maps != NULL) &&      // Validate material contain some map         (material.shader.id > 0)) result = true; // Validate material shader is valid +    // TODO: Check if available maps contain loaded textures+     return result; } @@ -2350,20 +2368,20 @@ {     if ((anim.frameCount > 0) && (anim.bones != NULL) && (anim.framePoses != NULL))     {-        if (frame >= anim.frameCount) frame = frame%anim.frameCount;    -    +        if (frame >= anim.frameCount) frame = frame%anim.frameCount;+         for (int i = 0; i < model.meshCount; i++)         {             if (model.meshes[i].boneMatrices)             {                 assert(model.meshes[i].boneCount == anim.boneCount);-              +                 for (int boneId = 0; boneId < model.meshes[i].boneCount; boneId++)                 {                     Vector3 inTranslation = model.bindPose[boneId].translation;                     Quaternion inRotation = model.bindPose[boneId].rotation;                     Vector3 inScale = model.bindPose[boneId].scale;-                    +                     Vector3 outTranslation = anim.framePoses[frame][boneId].translation;                     Quaternion outRotation = anim.framePoses[frame][boneId].rotation;                     Vector3 outScale = anim.framePoses[frame][boneId].scale;@@ -2374,15 +2392,15 @@                      Vector3 boneTranslation = Vector3Add(                         Vector3RotateByQuaternion(Vector3Multiply(outScale, invTranslation),-                        outRotation), outTranslation); +                        outRotation), outTranslation);                     Quaternion boneRotation = QuaternionMultiply(outRotation, invRotation);                     Vector3 boneScale = Vector3Multiply(outScale, invScale);-                    +                     Matrix boneMatrix = MatrixMultiply(MatrixMultiply(                         QuaternionToMatrix(boneRotation),                         MatrixTranslate(boneTranslation.x, boneTranslation.y, boneTranslation.z)),                         MatrixScale(boneScale.x, boneScale.y, boneScale.z));-                    +                     model.meshes[i].boneMatrices[boneId] = boneMatrix;                 }             }@@ -4806,12 +4824,12 @@     }      BuildPoseFromParentJoints(model.bones, model.boneCount, model.bindPose);-    +     for (int i = 0; i < model.meshCount; i++)     {         model.meshes[i].boneCount = model.boneCount;         model.meshes[i].boneMatrices = RL_CALLOC(model.meshes[i].boneCount, sizeof(Matrix));-        +         for (int j = 0; j < model.meshes[i].boneCount; j++)         {             model.meshes[i].boneMatrices[j] = MatrixIdentity();@@ -5226,7 +5244,7 @@     ***********************************************************************************************/      // Macro to simplify attributes loading code-    #define LOAD_ATTRIBUTE(accesor, numComp, srcType, dstPtr) LOAD_ATTRIBUTE_CAST(accesor, numComp, srcType, dstPtr, srcType) +    #define LOAD_ATTRIBUTE(accesor, numComp, srcType, dstPtr) LOAD_ATTRIBUTE_CAST(accesor, numComp, srcType, dstPtr, srcType)      #define LOAD_ATTRIBUTE_CAST(accesor, numComp, srcType, dstPtr, dstType) \     { \@@ -5714,7 +5732,7 @@                          TRACELOG(LOG_WARNING, "MODEL: [%s] Indices data converted from u32 to u16, possible loss of data", fileName);                     }-                    else +                    else                     {                         TRACELOG(LOG_WARNING, "MODEL: [%s] Indices data format not supported, use u16", fileName);                     }@@ -5902,11 +5920,11 @@                 {                     memcpy(model.meshes[meshIndex].animNormals, model.meshes[meshIndex].normals, model.meshes[meshIndex].vertexCount*3*sizeof(float));                 }-                +                 // Bone Transform Matrices                 model.meshes[meshIndex].boneCount = model.boneCount;                 model.meshes[meshIndex].boneMatrices = RL_CALLOC(model.meshes[meshIndex].boneCount, sizeof(Matrix));-                +                 for (int j = 0; j < model.meshes[meshIndex].boneCount; j++)                 {                     model.meshes[meshIndex].boneMatrices[j] = MatrixIdentity();@@ -6227,7 +6245,7 @@                 RL_FREE(boneChannels);             }         }-        +         if (data->skins_count > 1)         {             TRACELOG(LOG_WARNING, "MODEL: [%s] expected exactly one skin to load animation data from, but found %i", fileName, data->skins_count);@@ -6683,7 +6701,7 @@             {                 memcpy(model.meshes[i].animVertices, model.meshes[i].vertices, model.meshes[i].vertexCount*3*sizeof(float));                 memcpy(model.meshes[i].animNormals, model.meshes[i].normals, model.meshes[i].vertexCount*3*sizeof(float));-                +                 model.meshes[i].boneCount = model.boneCount;                 model.meshes[i].boneMatrices = RL_CALLOC(model.meshes[i].boneCount, sizeof(Matrix));                 for (j = 0; j < model.meshes[i].boneCount; j++)
raylib/src/rshapes.c view
@@ -828,8 +828,8 @@ {     if ((lineThick > rec.width) || (lineThick > rec.height))     {-        if (rec.width > rec.height) lineThick = rec.height/2;-        else if (rec.width < rec.height) lineThick = rec.width/2;+        if (rec.width >= rec.height) lineThick = rec.height/2;+        else if (rec.width <= rec.height) lineThick = rec.width/2;     }      // When rec = { x, y, 8.0f, 6.0f } and lineThick = 2, the following
raylib/src/rtext.c view
@@ -581,17 +581,16 @@     return font; } -// Check if a font is ready-bool IsFontReady(Font font)+// Check if a font is valid (font data loaded)+// WARNING: GPU texture not checked+bool IsFontValid(Font font) {-    return ((font.texture.id > 0) &&    // Validate OpenGL id for font texture atlas-            (font.baseSize > 0) &&      // Validate font size+    return ((font.baseSize > 0) &&      // Validate font size             (font.glyphCount > 0) &&    // Validate font contains some glyph             (font.recs != NULL) &&      // Validate font recs defining glyphs on texture atlas             (font.glyphs != NULL));     // Validate glyph data is loaded -    // NOTE: Further validations could be done to verify if recs count and glyphs count-    // match glyphCount and to verify that data contained is valid (glyphs values, metrics...)+    // NOTE: Further validations could be done to verify if recs and glyphs contain valid data (glyphs values, metrics...) }  // Load font data for further use@@ -677,7 +676,7 @@                     {                         stbtt_GetCodepointHMetrics(&fontInfo, ch, &chars[i].advanceX, NULL);                         chars[i].advanceX = (int)((float)chars[i].advanceX*scaleFactor);-                        +                         if (chh > fontSize) TRACELOG(LOG_WARNING, "FONT: Character [0x%08x] size is bigger than expected font size", ch);                          // Load characters images@@ -1302,15 +1301,15 @@     {         byteCounter++; -        int next = 0;-        letter = GetCodepointNext(&text[i], &next);+        int codepointByteCount = 0;+        letter = GetCodepointNext(&text[i], &codepointByteCount);         index = GetGlyphIndex(font, letter); -        i += next;+        i += codepointByteCount;          if (letter != '\n')         {-            if (font.glyphs[index].advanceX != 0) textWidth += font.glyphs[index].advanceX;+            if (font.glyphs[index].advanceX > 0) textWidth += font.glyphs[index].advanceX;             else textWidth += (font.recs[index].width + font.glyphs[index].offsetX);         }         else@@ -1930,7 +1929,8 @@ const char *CodepointToUTF8(int codepoint, int *utf8Size) {     static char utf8[6] = { 0 };-    int size = 0;   // Byte size of codepoint+    memset(utf8, 0, 6); // Clear static array+    int size = 0;       // Byte size of codepoint      if (codepoint <= 0x7f)     {
raylib/src/rtextures.c view
@@ -506,10 +506,10 @@         if (fileData != NULL)         {             qoi_desc desc = { 0 };-            image.data = qoi_decode(fileData, dataSize, &desc, 4);+            image.data = qoi_decode(fileData, dataSize, &desc, (int) fileData[12]);             image.width = desc.width;             image.height = desc.height;-            image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;+            image.format = desc.channels == 4 ? PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 : PIXELFORMAT_UNCOMPRESSED_R8G8B8;             image.mipmaps = 1;         }     }@@ -600,15 +600,15 @@ }  // Check if an image is ready-bool IsImageReady(Image image)+bool IsImageValid(Image image) {     bool result = false;      if ((image.data != NULL) &&     // Validate pixel data available-        (image.width > 0) &&-        (image.height > 0) &&       // Validate image size+        (image.width > 0) &&        // Validate image width+        (image.height > 0) &&       // Validate image height         (image.format > 0) &&       // Validate image format-        (image.mipmaps > 0)) result = true;       // Validate image mipmaps (at least 1 for basic mipmap level)+        (image.mipmaps > 0)) result = true; // Validate image mipmaps (at least 1 for basic mipmap level)      return result; }@@ -1007,7 +1007,7 @@             // Apply aspect ratio compensation to wider side             if (width > height) nx *= aspectRatio;             else ny /= aspectRatio;-            +             // Basic perlin noise implementation (not used)             //float p = (stb_perlin_noise3(nx, ny, 0.0f, 0, 0, 0); @@ -3969,13 +3969,21 @@         //    [-] GetPixelColor(): Get Vector4 instead of Color, easier for ColorAlphaBlend()         //    [ ] Support f32bit channels drawing -        // TODO: Support PIXELFORMAT_UNCOMPRESSED_R32, PIXELFORMAT_UNCOMPRESSED_R32G32B32, PIXELFORMAT_UNCOMPRESSED_R32G32B32A32 and 16-bit equivalents+        // TODO: Support PIXELFORMAT_UNCOMPRESSED_R32G32B32A32 and PIXELFORMAT_UNCOMPRESSED_R1616B16A16          Color colSrc, colDst, blend;         bool blendRequired = true;          // Fast path: Avoid blend if source has no alpha to blend-        if ((tint.a == 255) && ((srcPtr->format == PIXELFORMAT_UNCOMPRESSED_GRAYSCALE) || (srcPtr->format == PIXELFORMAT_UNCOMPRESSED_R8G8B8) || (srcPtr->format == PIXELFORMAT_UNCOMPRESSED_R5G6B5))) blendRequired = false;+        if ((tint.a == 255) &&+            ((srcPtr->format == PIXELFORMAT_UNCOMPRESSED_GRAYSCALE) ||+            (srcPtr->format == PIXELFORMAT_UNCOMPRESSED_R5G6B5) ||+            (srcPtr->format == PIXELFORMAT_UNCOMPRESSED_R8G8B8) ||+            (srcPtr->format == PIXELFORMAT_UNCOMPRESSED_R32) ||+            (srcPtr->format == PIXELFORMAT_UNCOMPRESSED_R32G32B32) ||+            (srcPtr->format == PIXELFORMAT_UNCOMPRESSED_R16) ||+            (srcPtr->format == PIXELFORMAT_UNCOMPRESSED_R16G16B16)))+            blendRequired = false;          int strideDst = GetPixelDataSize(dst->width, 1, dst->format);         int bytesPerPixelDst = strideDst/(dst->width);@@ -4224,16 +4232,16 @@     return target; } -// Check if a texture is ready-bool IsTextureReady(Texture2D texture)+// Check if a texture is valid (loaded in GPU)+bool IsTextureValid(Texture2D texture) {     bool result = false; -    // TODO: Validate maximum texture size supported by GPU?+    // TODO: Validate maximum texture size supported by GPU -    if ((texture.id > 0) &&         // Validate OpenGL id-        (texture.width > 0) &&-        (texture.height > 0) &&     // Validate texture size+    if ((texture.id > 0) &&         // Validate OpenGL id (texture uplaoded to GPU)+        (texture.width > 0) &&      // Validate texture width+        (texture.height > 0) &&     // Validate texture height         (texture.format > 0) &&     // Validate texture pixel format         (texture.mipmaps > 0)) result = true;     // Validate texture mipmaps (at least 1 for basic mipmap level) @@ -4251,14 +4259,14 @@     } } -// Check if a render texture is ready-bool IsRenderTextureReady(RenderTexture2D target)+// Check if a render texture is valid (loaded in GPU)+bool IsRenderTextureValid(RenderTexture2D target) {     bool result = false; -    if ((target.id > 0) &&                  // Validate OpenGL id-        IsTextureReady(target.depth) &&     // Validate FBO depth texture/renderbuffer-        IsTextureReady(target.texture)) result = true;    // Validate FBO texture+    if ((target.id > 0) &&                  // Validate OpenGL id (loaded on GPU)+        IsTextureValid(target.depth) &&     // Validate FBO depth texture/renderbuffer attachment+        IsTextureValid(target.texture)) result = true; // Validate FBO texture attachment      return result; }@@ -4449,7 +4457,7 @@          if (source.width < 0) { flipX = true; source.width *= -1; }         if (source.height < 0) source.y -= source.height;-        +         if (dest.width < 0) dest.width *= -1;         if (dest.height < 0) dest.height *= -1; @@ -5071,10 +5079,10 @@ }  // Get color lerp interpolation between two colors, factor [0.0f..1.0f]-Color ColorLerp(Color color1, Color color2, float factor) -{ +Color ColorLerp(Color color1, Color color2, float factor)+{     Color color = { 0 };-    +     if (factor < 0.0f) factor = 0.0f;     else if (factor > 1.0f) factor = 1.0f; 
src/Raylib/Core.hs view
@@ -82,7 +82,7 @@     loadVrStereoConfig,     loadShader,     loadShaderFromMemory,-    isShaderReady,+    isShaderValid,     getShaderLocation,     getShaderLocationAttrib,     setShaderValue,@@ -146,6 +146,9 @@     decompressData,     encodeDataBase64,     decodeDataBase64,+    computeCRC32,+    computeMD5,+    computeSHA1,     loadAutomationEventList,     newAutomationEventList,     exportAutomationEventList,@@ -282,7 +285,7 @@     c'unloadVrStereoConfig,     c'loadShader,     c'loadShaderFromMemory,-    c'isShaderReady,+    c'isShaderValid,     c'getShaderLocation,     c'getShaderLocationAttrib,     c'setShaderValue,@@ -350,6 +353,9 @@     c'decompressData,     c'encodeDataBase64,     c'decodeDataBase64,+    c'computeCRC32,+    c'computeMD5,+    c'computeSHA1,     c'loadAutomationEventList,     c'exportAutomationEventList,     c'setAutomationEventList,@@ -444,7 +450,8 @@     withCString,   ) import Foreign.Ptr (nullPtr)-import Raylib.Internal (WindowResources, defaultWindowResources, shaderLocations, unloadSingleAutomationEventList, unloadSingleShader, releaseNonAudioWindowResources)+import GHC.IO (unsafePerformIO)+import Raylib.Internal (WindowResources, defaultWindowResources, releaseNonAudioWindowResources, shaderLocations, unloadSingleAutomationEventList, unloadSingleShader) import Raylib.Internal.Foreign (configsToBitflag, pop, popCArray, popCString, withFreeable, withFreeableArray, withFreeableArrayLen, withMaybeCString) import Raylib.Internal.TH (genNative) import Raylib.Types@@ -456,6 +463,7 @@     C'LoadFileTextCallback,     C'SaveFileDataCallback,     C'SaveFileTextCallback,+    C'TraceLogCallback,     Camera2D,     Camera3D,     Color,@@ -479,15 +487,15 @@     ShaderUniformData,     ShaderUniformDataV,     Texture,+    TraceLogCallback,     TraceLogLevel,     Vector2,     Vector3,     VrDeviceInfo,     VrStereoConfig,     unpackShaderUniformData,-    unpackShaderUniformDataV, C'TraceLogCallback, TraceLogCallback,+    unpackShaderUniformDataV,   )-import GHC.IO (unsafePerformIO)  $( genNative      [ ("c'initWindow", "InitWindow_", "rl_bindings.h", [t|CInt -> CInt -> CString -> IO ()|]),@@ -568,7 +576,7 @@        ("c'unloadVrStereoConfig", "UnloadVrStereoConfig_", "rl_bindings.h", [t|Ptr VrStereoConfig -> IO ()|]),        ("c'loadShader", "LoadShader_", "rl_bindings.h", [t|CString -> CString -> IO (Ptr Shader)|]),        ("c'loadShaderFromMemory", "LoadShaderFromMemory_", "rl_bindings.h", [t|CString -> CString -> IO (Ptr Shader)|]),-       ("c'isShaderReady", "IsShaderReady_", "rl_bindings.h", [t|Ptr Shader -> IO CBool|]),+       ("c'isShaderValid", "IsShaderValid_", "rl_bindings.h", [t|Ptr Shader -> IO CBool|]),        ("c'getShaderLocation", "GetShaderLocation_", "rl_bindings.h", [t|Ptr Shader -> CString -> IO CInt|]),        ("c'getShaderLocationAttrib", "GetShaderLocationAttrib_", "rl_bindings.h", [t|Ptr Shader -> CString -> IO CInt|]),        ("c'setShaderValue", "SetShaderValue_", "rl_bindings.h", [t|Ptr Shader -> CInt -> Ptr () -> CInt -> IO ()|]),@@ -637,6 +645,9 @@        ("c'decompressData", "DecompressData_", "rl_bindings.h", [t|Ptr CUChar -> CInt -> Ptr CInt -> IO (Ptr CUChar)|]),        ("c'encodeDataBase64", "EncodeDataBase64_", "rl_bindings.h", [t|Ptr CUChar -> CInt -> Ptr CInt -> IO CString|]),        ("c'decodeDataBase64", "DecodeDataBase64_", "rl_bindings.h", [t|Ptr CUChar -> Ptr CInt -> IO (Ptr CUChar)|]),+       ("c'computeCRC32", "ComputeCRC32_", "rl_bindings.h", [t|Ptr CUChar -> CInt -> IO CUInt|]),+       ("c'computeMD5", "ComputeMD5_", "rl_bindings.h", [t|Ptr CUChar -> CInt -> IO (Ptr CUInt)|]),+       ("c'computeSHA1", "ComputeSHA1_", "rl_bindings.h", [t|Ptr CUChar -> CInt -> IO (Ptr CUInt)|]),        ("c'loadAutomationEventList", "LoadAutomationEventList_", "rl_bindings.h", [t|CString -> IO (Ptr AutomationEventList)|]),        ("c'exportAutomationEventList", "ExportAutomationEventList_", "rl_bindings.h", [t|Ptr AutomationEventList -> CString -> IO CBool|]),        ("c'setAutomationEventList", "SetAutomationEventList_", "rl_bindings.h", [t|Ptr AutomationEventList -> IO ()|]),@@ -662,7 +673,7 @@        ("c'getGamepadAxisCount", "GetGamepadAxisCount_", "rl_bindings.h", [t|CInt -> IO CInt|]),        ("c'getGamepadAxisMovement", "GetGamepadAxisMovement_", "rl_bindings.h", [t|CInt -> CInt -> IO CFloat|]),        ("c'setGamepadMappings", "SetGamepadMappings_", "rl_bindings.h", [t|CString -> IO CInt|]),-       ("c'setGamepadVibration", "SetGamepadVibration_", "rl_bindings.h", [t|CInt -> CFloat -> CFloat -> IO ()|]),+       ("c'setGamepadVibration", "SetGamepadVibration_", "rl_bindings.h", [t|CInt -> CFloat -> CFloat -> CFloat -> IO ()|]),        ("c'isMouseButtonPressed", "IsMouseButtonPressed_", "rl_bindings.h", [t|CInt -> IO CBool|]),        ("c'isMouseButtonDown", "IsMouseButtonDown_", "rl_bindings.h", [t|CInt -> IO CBool|]),        ("c'isMouseButtonReleased", "IsMouseButtonReleased_", "rl_bindings.h", [t|CInt -> IO CBool|]),@@ -939,8 +950,8 @@ loadShaderFromMemory :: Maybe String -> Maybe String -> IO Shader loadShaderFromMemory vsCode fsCode = withMaybeCString vsCode (withMaybeCString fsCode . c'loadShaderFromMemory) >>= pop -isShaderReady :: Shader -> IO Bool-isShaderReady shader = toBool <$> withFreeable shader c'isShaderReady+isShaderValid :: Shader -> IO Bool+isShaderValid shader = toBool <$> withFreeable shader c'isShaderValid  getShaderLocation :: Shader -> String -> WindowResources -> IO Int getShaderLocation shader uniformName wr = do@@ -1236,6 +1247,32 @@           )     ) +computeCRC32 :: [Integer] -> IO Integer+computeCRC32 contents = do+  withFreeableArrayLen+    (map fromIntegral contents)+    (\size c -> fromIntegral <$> c'computeCRC32 c (fromIntegral $ size * sizeOf (0 :: CUChar)))++computeMD5 :: [Integer] -> IO [Integer]+computeMD5 contents = do+  withFreeableArrayLen+    (map fromIntegral contents)+    ( \size c -> do+        encoded <- c'computeMD5 c (fromIntegral $ size * sizeOf (0 :: CUChar))+        arr <- peekArray 4 encoded+        return $ map fromIntegral arr+    )++computeSHA1 :: [Integer] -> IO [Integer]+computeSHA1 contents = do+  withFreeableArrayLen+    (map fromIntegral contents)+    ( \size c -> do+        encoded <- c'computeSHA1 c (fromIntegral $ size * sizeOf (0 :: CUChar))+        arr <- peekArray 5 encoded+        return $ map fromIntegral arr+    )+ loadAutomationEventList :: String -> IO AutomationEventList loadAutomationEventList fileName = withCString fileName c'loadAutomationEventList >>= pop @@ -1325,8 +1362,8 @@ setGamepadMappings :: String -> IO Int setGamepadMappings mappings = fromIntegral <$> withCString mappings c'setGamepadMappings -setGamepadVibration :: Int -> Float -> Float -> IO ()-setGamepadVibration gamepad leftMotor rightMotor = c'setGamepadVibration (fromIntegral gamepad) (realToFrac leftMotor) (realToFrac rightMotor)+setGamepadVibration :: Int -> Float -> Float -> Float -> IO ()+setGamepadVibration gamepad leftMotor rightMotor duration = c'setGamepadVibration (fromIntegral gamepad) (realToFrac leftMotor) (realToFrac rightMotor) (realToFrac duration)  isMouseButtonPressed :: MouseButton -> IO Bool isMouseButtonPressed button = toBool <$> c'isMouseButtonPressed (fromIntegral $ fromEnum button)@@ -1432,7 +1469,7 @@ createTraceLogCallback :: TraceLogCallback -> IO C'TraceLogCallback createTraceLogCallback callback =   mk'traceLogCallback-    (\logLevel text ->+    ( \logLevel text ->         do           t <- peekCString text           callback (toEnum (fromIntegral logLevel)) t
src/Raylib/Core/Audio.hs view
@@ -17,8 +17,8 @@     unloadSoundAlias,     updateSound,     unloadSound,-    isWaveReady,-    isSoundReady,+    isWaveValid,+    isSoundValid,     exportWave,     exportWaveAsCode,     playSound,@@ -36,7 +36,7 @@     loadMusicStream,     loadMusicStreamFromMemory,     unloadMusicStream,-    isMusicReady,+    isMusicValid,     playMusicStream,     isMusicStreamPlaying,     updateMusicStream,@@ -51,7 +51,7 @@     getMusicTimePlayed,     loadAudioStream,     unloadAudioStream,-    isAudioStreamReady,+    isAudioStreamValid,     updateAudioStream,     isAudioStreamProcessed,     playAudioStream,@@ -81,9 +81,9 @@     c'loadSoundFromWave,     c'loadSoundAlias,     c'updateSound,-    c'isWaveReady,+    c'isWaveValid,     c'unloadWave,-    c'isSoundReady,+    c'isSoundValid,     c'unloadSound,     c'unloadSoundAlias,     c'exportWave,@@ -103,7 +103,7 @@     c'unloadWaveSamples,     c'loadMusicStream,     c'loadMusicStreamFromMemory,-    c'isMusicReady,+    c'isMusicValid,     c'unloadMusicStream,     c'playMusicStream,     c'isMusicStreamPlaying,@@ -118,7 +118,7 @@     c'getMusicTimeLength,     c'getMusicTimePlayed,     c'loadAudioStream,-    c'isAudioStreamReady,+    c'isAudioStreamValid,     c'unloadAudioStream,     c'updateAudioStream,     c'isAudioStreamProcessed,@@ -182,9 +182,9 @@        ("c'loadSoundFromWave", "LoadSoundFromWave_", "rl_bindings.h", [t|Ptr Wave -> IO (Ptr Sound)|]),        ("c'loadSoundAlias", "LoadSoundAlias_", "rl_bindings.h", [t|Ptr Sound -> IO (Ptr Sound)|]),        ("c'updateSound", "UpdateSound_", "rl_bindings.h", [t|Ptr Sound -> Ptr () -> CInt -> IO ()|]),-       ("c'isWaveReady", "IsWaveReady_", "rl_bindings.h", [t|Ptr Wave -> IO CBool|]),+       ("c'isWaveValid", "IsWaveValid_", "rl_bindings.h", [t|Ptr Wave -> IO CBool|]),        ("c'unloadWave", "UnloadWave_", "rl_bindings.h", [t|Ptr Wave -> IO ()|]),-       ("c'isSoundReady", "IsSoundReady_", "rl_bindings.h", [t|Ptr Sound -> IO CBool|]),+       ("c'isSoundValid", "IsSoundValid_", "rl_bindings.h", [t|Ptr Sound -> IO CBool|]),        ("c'unloadSound", "UnloadSound_", "rl_bindings.h", [t|Ptr Sound -> IO ()|]),        ("c'unloadSoundAlias", "UnloadSoundAlias_", "rl_bindings.h", [t|Ptr Sound -> IO ()|]),        ("c'exportWave", "ExportWave_", "rl_bindings.h", [t|Ptr Wave -> CString -> IO CBool|]),@@ -204,7 +204,7 @@        ("c'unloadWaveSamples", "UnloadWaveSamples_", "rl_bindings.h", [t|Ptr CFloat -> IO ()|]),        ("c'loadMusicStream", "LoadMusicStream_", "rl_bindings.h", [t|CString -> IO (Ptr Music)|]),        ("c'loadMusicStreamFromMemory", "LoadMusicStreamFromMemory_", "rl_bindings.h", [t|CString -> Ptr CUChar -> CInt -> IO (Ptr Music)|]),-       ("c'isMusicReady", "IsMusicReady_", "rl_bindings.h", [t|Ptr Music -> IO CBool|]),+       ("c'isMusicValid", "IsMusicValid_", "rl_bindings.h", [t|Ptr Music -> IO CBool|]),        ("c'unloadMusicStream", "UnloadMusicStream_", "rl_bindings.h", [t|Ptr Music -> IO ()|]),        ("c'playMusicStream", "PlayMusicStream_", "rl_bindings.h", [t|Ptr Music -> IO ()|]),        ("c'isMusicStreamPlaying", "IsMusicStreamPlaying_", "rl_bindings.h", [t|Ptr Music -> IO CBool|]),@@ -219,7 +219,7 @@        ("c'getMusicTimeLength", "GetMusicTimeLength_", "rl_bindings.h", [t|Ptr Music -> IO CFloat|]),        ("c'getMusicTimePlayed", "GetMusicTimePlayed_", "rl_bindings.h", [t|Ptr Music -> IO CFloat|]),        ("c'loadAudioStream", "LoadAudioStream_", "rl_bindings.h", [t|CUInt -> CUInt -> CUInt -> IO (Ptr AudioStream)|]),-       ("c'isAudioStreamReady", "IsAudioStreamReady_", "rl_bindings.h", [t|Ptr AudioStream -> IO CBool|]),+       ("c'isAudioStreamValid", "IsAudioStreamValid_", "rl_bindings.h", [t|Ptr AudioStream -> IO CBool|]),        ("c'unloadAudioStream", "UnloadAudioStream_", "rl_bindings.h", [t|Ptr AudioStream -> IO ()|]),        ("c'updateAudioStream", "UpdateAudioStream_", "rl_bindings.h", [t|Ptr AudioStream -> Ptr () -> CInt -> IO ()|]),        ("c'isAudioStreamProcessed", "IsAudioStreamProcessed_", "rl_bindings.h", [t|Ptr AudioStream -> IO CBool|]),@@ -283,11 +283,11 @@ unloadSound :: Sound -> WindowResources -> IO () unloadSound sound = unloadAudioStream (sound'stream sound) -isWaveReady :: Wave -> IO Bool-isWaveReady wave = toBool <$> withFreeable wave c'isWaveReady+isWaveValid :: Wave -> IO Bool+isWaveValid wave = toBool <$> withFreeable wave c'isWaveValid -isSoundReady :: Sound -> IO Bool-isSoundReady sound = toBool <$> withFreeable sound c'isSoundReady+isSoundValid :: Sound -> IO Bool+isSoundValid sound = toBool <$> withFreeable sound c'isSoundValid  exportWave :: Wave -> String -> IO Bool exportWave wave fileName = toBool <$> withFreeable wave (withCString fileName . c'exportWave)@@ -349,8 +349,8 @@ unloadMusicStream :: Music -> WindowResources -> IO () unloadMusicStream music = unloadSingleCtxDataPtr (fromEnum (music'ctxType music)) (music'ctxData music) -isMusicReady :: Music -> IO Bool-isMusicReady music = toBool <$> withFreeable music c'isMusicReady+isMusicValid :: Music -> IO Bool+isMusicValid music = toBool <$> withFreeable music c'isMusicValid  playMusicStream :: Music -> IO () playMusicStream music = withFreeable music c'playMusicStream@@ -395,8 +395,8 @@ unloadAudioStream :: AudioStream -> WindowResources -> IO () unloadAudioStream stream = unloadSingleAudioBuffer (castPtr $ audioStream'buffer stream) -isAudioStreamReady :: AudioStream -> IO Bool-isAudioStreamReady stream = toBool <$> withFreeable stream c'isAudioStreamReady+isAudioStreamValid :: AudioStream -> IO Bool+isAudioStreamValid stream = toBool <$> withFreeable stream c'isAudioStreamValid  updateAudioStream :: AudioStream -> Ptr () -> Int -> IO () updateAudioStream stream value frameCount = withFreeable stream (\s -> c'updateAudioStream s value (fromIntegral frameCount))
src/Raylib/Core/Models.hs view
@@ -28,7 +28,7 @@     loadModelFromMesh,     loadModelFromMeshManaged,     unloadModel,-    isModelReady,+    isModelValid,     getModelBoundingBox,     drawModel,     drawModelEx,@@ -63,7 +63,7 @@     loadMaterials,     unloadMaterial,     loadMaterialDefault,-    isMaterialReady,+    isMaterialValid,     setMaterialTexture,     setModelMeshMaterial,     loadModelAnimations,@@ -103,7 +103,7 @@     c'drawGrid,     c'loadModel,     c'loadModelFromMesh,-    c'isModelReady,+    c'isModelValid,     c'unloadModel,     c'getModelBoundingBox,     c'drawModel,@@ -138,7 +138,7 @@     c'genMeshCubicmap,     c'loadMaterials,     c'loadMaterialDefault,-    c'isMaterialReady,+    c'isMaterialValid,     c'unloadMaterial,     c'setMaterialTexture,     c'setModelMeshMaterial,@@ -222,7 +222,7 @@        ("c'drawGrid", "DrawGrid_", "rl_bindings.h", [t|CInt -> CFloat -> IO ()|]),        ("c'loadModel", "LoadModel_", "rl_bindings.h", [t|CString -> IO (Ptr Model)|]),        ("c'loadModelFromMesh", "LoadModelFromMesh_", "rl_bindings.h", [t|Ptr Mesh -> IO (Ptr Model)|]),-       ("c'isModelReady", "IsModelReady_", "rl_bindings.h", [t|Ptr Model -> IO CBool|]),+       ("c'isModelValid", "IsModelValid_", "rl_bindings.h", [t|Ptr Model -> IO CBool|]),        ("c'unloadModel", "UnloadModel_", "rl_bindings.h", [t|Ptr Model -> IO ()|]),        ("c'getModelBoundingBox", "GetModelBoundingBox_", "rl_bindings.h", [t|Ptr Model -> IO (Ptr BoundingBox)|]),        ("c'drawModel", "DrawModel_", "rl_bindings.h", [t|Ptr Model -> Ptr Vector3 -> CFloat -> Ptr Color -> IO ()|]),@@ -257,7 +257,7 @@        ("c'genMeshCubicmap", "GenMeshCubicmap_", "rl_bindings.h", [t|Ptr Image -> Ptr Vector3 -> IO (Ptr Mesh)|]),        ("c'loadMaterials", "LoadMaterials_", "rl_bindings.h", [t|CString -> Ptr CInt -> IO (Ptr Material)|]),        ("c'loadMaterialDefault", "LoadMaterialDefault_", "rl_bindings.h", [t|IO (Ptr Material)|]),-       ("c'isMaterialReady", "IsMaterialReady_", "rl_bindings.h", [t|Ptr Material -> IO CBool|]),+       ("c'isMaterialValid", "IsMaterialValid_", "rl_bindings.h", [t|Ptr Material -> IO CBool|]),        ("c'unloadMaterial", "UnloadMaterial_", "rl_bindings.h", [t|Ptr Material -> IO ()|]),        ("c'setMaterialTexture", "SetMaterialTexture_", "rl_bindings.h", [t|Ptr Material -> CInt -> Ptr Texture -> IO ()|]),        ("c'setModelMeshMaterial", "SetModelMeshMaterial_", "rl_bindings.h", [t|Ptr Model -> CInt -> CInt -> IO ()|]),@@ -360,8 +360,8 @@   forM_ (model'meshes model) (`unloadMesh` wr)   forM_ (model'materials model) (`unloadMaterial` wr) -isModelReady :: Model -> IO Bool-isModelReady model = toBool <$> withFreeable model c'isModelReady+isModelValid :: Model -> IO Bool+isModelValid model = toBool <$> withFreeable model c'isModelValid  getModelBoundingBox :: Model -> IO BoundingBox getModelBoundingBox model = withFreeable model c'getModelBoundingBox >>= pop@@ -485,8 +485,8 @@ loadMaterialDefault :: IO Material loadMaterialDefault = c'loadMaterialDefault >>= pop -isMaterialReady :: Material -> IO Bool-isMaterialReady material = toBool <$> withFreeable material c'isMaterialReady+isMaterialValid :: Material -> IO Bool+isMaterialValid material = toBool <$> withFreeable material c'isMaterialValid  setMaterialTexture :: Material -> MaterialMapIndex -> Texture -> IO Material setMaterialTexture material mapType texture = withFreeable material (\m -> withFreeable texture (c'setMaterialTexture m (fromIntegral (fromEnum mapType))) >> peek m)
src/Raylib/Core/Text.hs view
@@ -11,7 +11,7 @@     loadFontData,     genImageFontAtlas,     unloadFont,-    isFontReady,+    isFontValid,     exportFontAsCode,     drawFPS,     drawText,@@ -41,7 +41,7 @@     c'loadFontData,     c'genImageFontAtlas,     c'unloadFontData,-    c'isFontReady,+    c'isFontValid,     c'unloadFont,     c'exportFontAsCode,     c'drawFPS,@@ -106,7 +106,7 @@        ("c'loadFontData", "LoadFontData_", "rl_bindings.h", [t|Ptr CUChar -> CInt -> CInt -> Ptr CInt -> CInt -> CInt -> IO (Ptr GlyphInfo)|]),        ("c'genImageFontAtlas", "GenImageFontAtlas_", "rl_bindings.h", [t|Ptr GlyphInfo -> Ptr (Ptr Rectangle) -> CInt -> CInt -> CInt -> CInt -> IO (Ptr Image)|]),        ("c'unloadFontData", "UnloadFontData_", "rl_bindings.h", [t|Ptr GlyphInfo -> CInt -> IO ()|]),-       ("c'isFontReady", "IsFontReady_", "rl_bindings.h", [t|Ptr Font -> IO CBool|]),+       ("c'isFontValid", "IsFontValid_", "rl_bindings.h", [t|Ptr Font -> IO CBool|]),        ("c'unloadFont", "UnloadFont_", "rl_bindings.h", [t|Ptr Font -> IO ()|]),        ("c'exportFontAsCode", "ExportFontAsCode_", "rl_bindings.h", [t|Ptr Font -> CString -> IO CBool|]),        ("c'drawFPS", "DrawFPS_", "rl_bindings.h", [t|CInt -> CInt -> IO ()|]),@@ -187,8 +187,8 @@ unloadFont :: Font -> WindowResources -> IO () unloadFont font = unloadSingleTexture (texture'id $ font'texture font) -isFontReady :: Font -> IO Bool-isFontReady font = toBool <$> withFreeable font c'isFontReady+isFontValid :: Font -> IO Bool+isFontValid font = toBool <$> withFreeable font c'isFontValid  exportFontAsCode :: Font -> String -> IO Bool exportFontAsCode font fileName = toBool <$> withFreeable font (withCString fileName . c'exportFontAsCode)
src/Raylib/Core/Textures.hs view
@@ -10,7 +10,7 @@     loadImageFromMemory,     loadImageFromTexture,     loadImageFromScreen,-    isImageReady,+    isImageValid,     exportImage,     exportImageToMemory,     exportImageAsCode,@@ -81,8 +81,8 @@     loadTextureFromImage,     loadTextureCubemap,     loadRenderTexture,-    isTextureReady,-    isRenderTextureReady,+    isTextureValid,+    isRenderTextureValid,     unloadTexture,     unloadRenderTexture,     updateTexture,@@ -121,7 +121,7 @@     c'loadImageFromMemory,     c'loadImageFromTexture,     c'loadImageFromScreen,-    c'isImageReady,+    c'isImageValid,     c'unloadImage,     c'exportImage,     c'exportImageToMemory,@@ -194,9 +194,9 @@     c'loadTextureFromImage,     c'loadTextureCubemap,     c'loadRenderTexture,-    c'isTextureReady,+    c'isTextureValid,     c'unloadTexture,-    c'isRenderTextureReady,+    c'isRenderTextureValid,     c'unloadRenderTexture,     c'updateTexture,     c'updateTextureRec,@@ -279,7 +279,7 @@        ("c'loadImageFromMemory", "LoadImageFromMemory_", "rl_bindings.h", [t|CString -> Ptr CUChar -> CInt -> IO (Ptr Image)|]),        ("c'loadImageFromTexture", "LoadImageFromTexture_", "rl_bindings.h", [t|Ptr Texture -> IO (Ptr Image)|]),        ("c'loadImageFromScreen", "LoadImageFromScreen_", "rl_bindings.h", [t|IO (Ptr Image)|]),-       ("c'isImageReady", "IsImageReady_", "rl_bindings.h", [t|Ptr Image -> IO CBool|]),+       ("c'isImageValid", "IsImageValid_", "rl_bindings.h", [t|Ptr Image -> IO CBool|]),        ("c'unloadImage", "UnloadImage_", "rl_bindings.h", [t|Ptr Image -> IO ()|]),        ("c'exportImage", "ExportImage_", "rl_bindings.h", [t|Ptr Image -> CString -> IO CBool|]),        ("c'exportImageToMemory", "ExportImageToMemory_", "rl_bindings.h", [t|Ptr Image -> CString -> Ptr CInt -> IO (Ptr CUChar)|]),@@ -352,9 +352,9 @@        ("c'loadTextureFromImage", "LoadTextureFromImage_", "rl_bindings.h", [t|Ptr Image -> IO (Ptr Texture)|]),        ("c'loadTextureCubemap", "LoadTextureCubemap_", "rl_bindings.h", [t|Ptr Image -> CInt -> IO (Ptr Texture)|]),        ("c'loadRenderTexture", "LoadRenderTexture_", "rl_bindings.h", [t|CInt -> CInt -> IO (Ptr RenderTexture)|]),-       ("c'isTextureReady", "IsTextureReady_", "rl_bindings.h", [t|Ptr Texture -> IO CBool|]),+       ("c'isTextureValid", "IsTextureValid_", "rl_bindings.h", [t|Ptr Texture -> IO CBool|]),        ("c'unloadTexture", "UnloadTexture_", "rl_bindings.h", [t|Ptr Texture -> IO ()|]),-       ("c'isRenderTextureReady", "IsRenderTextureReady_", "rl_bindings.h", [t|Ptr RenderTexture -> IO CBool|]),+       ("c'isRenderTextureValid", "IsRenderTextureValid_", "rl_bindings.h", [t|Ptr RenderTexture -> IO CBool|]),        ("c'unloadRenderTexture", "UnloadRenderTexture_", "rl_bindings.h", [t|Ptr RenderTexture -> IO ()|]),        ("c'updateTexture", "UpdateTexture_", "rl_bindings.h", [t|Ptr Texture -> Ptr () -> IO ()|]),        ("c'updateTextureRec", "UpdateTextureRec_", "rl_bindings.h", [t|Ptr Texture -> Ptr Rectangle -> Ptr () -> IO ()|]),@@ -435,8 +435,8 @@ loadImageFromScreen :: IO Image loadImageFromScreen = c'loadImageFromScreen >>= pop -isImageReady :: Image -> IO Bool-isImageReady image = toBool <$> withFreeable image c'isImageReady+isImageValid :: Image -> IO Bool+isImageValid image = toBool <$> withFreeable image c'isImageValid  exportImage :: Image -> String -> IO Bool exportImage image fileName = toBool <$> withFreeable image (withCString fileName . c'exportImage)@@ -691,11 +691,11 @@ loadRenderTexture :: Int -> Int -> IO RenderTexture loadRenderTexture width height = c'loadRenderTexture (fromIntegral width) (fromIntegral height) >>= pop -isTextureReady :: Texture -> IO Bool-isTextureReady texture = toBool <$> withFreeable texture c'isTextureReady+isTextureValid :: Texture -> IO Bool+isTextureValid texture = toBool <$> withFreeable texture c'isTextureValid -isRenderTextureReady :: RenderTexture -> IO Bool-isRenderTextureReady renderTexture = toBool <$> withFreeable renderTexture c'isRenderTextureReady+isRenderTextureValid :: RenderTexture -> IO Bool+isRenderTextureValid renderTexture = toBool <$> withFreeable renderTexture c'isRenderTextureValid  -- | Unloads a `managed` texture from GPU memory (VRAM) unloadTexture :: Texture -> WindowResources -> IO ()