diff --git a/CHANGELOG b/CHANGELOG
index b5b50e4d7..7ec73066f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -4,15 +4,430 @@ changelog
Current Release: raylib 5.0 (18 November 2023)
-------------------------------------------------------------------------
-Release: raylib 5.5 - 11th Anniversary Edition? (18 November 2024?)
+Release: raylib 5.5 (November 2024?)
-------------------------------------------------------------------------
KEY CHANGES:
- -
- -
- -
+ - New rcore backend: RGFW
+ - New raylib project creator tool
+ - New platforms supported: Dreamcast, N64, PSP, PSVita, PS4
+ - GPU Skinning (all platforms and GL versions)
+ - raymath C++ operators
Detailed changes:
-...
+
+WIP: Last update with commit from 21-Oct-2024
+
+[rcore] ADDED: Working directory info at initialization by @Ray
+[rcore] ADDED: `MakeDirectory()`, supporting recursive directory creation by @Ray
+[rcore] ADDED: `ComputeSHA1()` (#4390) by @Anthony Carbajal
+[rcore] ADDED: `ComputeCRC32()` and `ComputeMD5()` by @Ray
+[rcore] ADDED: `GetKeyName()` (#4161) by @MrScautHD
+[rcore] ADDED: `IsFileNameValid()` by @Ray
+[rcore] ADDED: `GetViewRay()`, viewport independent raycast (#3709) by @Luís Almeida
+[rcore] RENAMED: `GetMouseRay()` to `GetScreenToWorldRay()` (#3830) by @Ray
+[rcore] RENAMED: `GetViewRay()` to `GetScreenToWorldRayEx()` (#3830) by @Ray
+[rcore] REVIEWED: `GetApplicationDirectory()` for FreeBSD (#4318) by @base
+[rcore] REVIEWED: `LoadDirectoryFilesEx()`/`ScanDirectoryFiles()`, support directory on filter (#4302) by @foxblock
+[rcore] REVIEWED: Update comments on fullscreen and boderless window to describe what they do (#4280) by @Jeffery Myers
+[rcore] REVIEWED: Correct processing of mouse wheel on Automation events #4263 by @Ray
+[rcore] REVIEWED: Fix gamepad axis movement and its automation event recording (#4184) by @maxmutant
+[rcore] REVIEWED: Do not set RL_TEXTURE_FILTER_LINEAR when high dpi flag is enabled (#4189) by @Dave Green
+[rcore] REVIEWED: `GetScreenWidth()`/`GetScreenHeight()` (#4074) by @Anthony Carbajal
+[rcore] REVIEWED: Initial window dimensions checks (#3950) by @Christian Haas
+[rcore] REVIEWED: Set default init values for random #3954 by @Ray
+[rcore] REVIEWED: Window positioning, avoid out-of-screen window-bar by @Ray
+[rcore] REVIEWED: Fix framerate recording for .gif (#3894) by @Rob Loach
+[rcore] REVIEWED: Screen space related functions consistency (#3830) by @aiafrasinei
+[rcore] REVIEWED: `GetFileNameWithoutExt()` (#3771) by @oblerion
+[rcore] REVIEWED: `GetWindowScaleDPI()`, simplified (#3701) by @Karl Zylinski
+[rcore] REVIEWED: `UnloadAutomationEventList()` (#3658) by @Antonis Geralis
+[rcore] REVIEWED: Flip VR screens (#3633) by @Matthew Oros
+[rcore] REVIEWED: Remove unused vScreenCenter (#3632) by @Matthew Oros
+[rcore] REVIEWED: `LoadRandomSequence()`, issue in sequence generation #3612 by @Ray
+[rcore] REVIEWED: `IsMouseButtonUp()` (#3609) by @Kenneth M
+[rcore] REVIEWED: Fix typos in src/platforms/rcore_*.c (#3581) by @RadsammyT
+[rcore] REVIEWED: `ExportDataAsCode()`, change sanitization check (#3837) by @Laurentino Luna
+[rcore] REVIEWED: `ExportDataAsCode()`, add little sanitization to indentifier names (#3832) by @4rk
+[rcore][rlgl] REVIEWED: Fix scale issues when ending a view mode (#3746) by @Jeffery Myers
+[rcore][GLFW] REVIEWED: Keep CORE.Window.position properly in sync with glfw window position (#4190) by @Dave Green
+[rcore][GLFW] REVIEWED: Set AUTO_ICONIFY flag to false per default (#4188) by @Dave Green
+[rcore][GLFW] REVIEWED: `InitPlatform()`, add workaround for NetBSD (#4139) by @NishiOwO
+[rcore][GLFW] REVIEWED: Fix window not initializing on primary monitor (#3923) by @Rafael Bordoni
+[rcore][GLFW] REVIEWED: Set relative mouse mode when the cursor is disabled (#3874) by @Jeffery Myers
+[rcore][GLFW] REVIEWED: Remove GLFW mouse passthrough hack and increase GLFW version in CMake (#3852) by @Alexandre Almeida
+[rcore][GLFW] REVIEWED: Updated GLFW to 3.4 (#3827) by @Alexandre Almeida
+[rcore][GLFW] REVIEWED: Feature test macros before include (#3737) by @John
+[rcore][Web] ADDED: `SetWindowOpacity()` implementation (#4403) by @Asdqwe
+[rcore][Web] ADDED: `MaximizeWindow()` and `RestoreWindow()` implementations (#4397) by @Asdqwe
+[rcore][Web] ADDED: `ToggleFullscreen()` implementation (#3634) by @ubkp
+[rcore][Web] ADDED: `GetWindowPosition()` implementation (#3637) by @ubkp
+[rcore][Web] ADDED: `ToggleBorderlessWindowed()` implementation (#3622) by @ubkp
+[rcore][Web] ADDED: `GetMonitorWidth()` and `GetMonitorHeight()` implementations (#3636) by @ubkp
+[rcore][Web] REVIEWED: Update `SetWindowState()` and `ClearWindowState()` to handle `FLAG_WINDOW_MAXIMIZED` (#4402) by @Asdqwe
+[rcore][Web] REVIEWED: `WindowSizeCallback()`, do not try to handle DPI, already managed by GLFW (#4143) by @SuperUserNameMan
+[rcore][Web] REVIEWED: Relative mouse mode issues (#3940) by @Cemal Gönültaş
+[rcore][Web] REVIEWED: `ShowCursor()`, `HideCursor()` and `SetMouseCursor()` (#3647) by @ubkp
+[rcore][Web] REVIEWED: Fix CORE.Input.Mouse.cursorHidden with callbacks (#3644) by @ubkp
+[rcore][Web] REVIEWED: Fix `IsMouseButtonUp()` (#3611) by @ubkp
+[rcore][Web] REVIEWED: HighDPI support #3372 by @Ray
+[rcore][SDL] ADDED: `IsCursorOnScreen()` (#3862) by @Peter0x44
+[rcore][SDL] ADDED: Gamepad rumble/vibration support (#3819) by @GideonSerf
+[rcore][SDL] REVIEWED: Gamepad support (#3776) by @A
+[rcore][SDL] REVIEWED: `GetWorkingDirectory()`, return correct path (#4392) by @Asdqwe
+[rcore][SDL] REVIEWED: `GetClipboardText()`, fix memory leak (#4354) by @Asdqwe
+[rcore][SDL] REVIEWED: Change SDL_Joystick to SDL_GameController (#4129) by @Frank Kartheuser
+[rcore][SDL] REVIEWED: Update storage base path, use provided SDL base path by @Ray
+[rcore][SDL] REVIEWED: Call SDL_GL_SetSwapInterval() after GL context creation (#3997) by @JupiterRider
+[rcore][SDL] REVIEWED: `GetKeyPressed()` (#3869) by @Arthur
+[rcore][SDL] REVIEWED: Fix SDL multitouch tracking (#3810) by @mooff
+[rcore][SDL] REVIEWED: Fix `SUPPORT_WINMM_HIGHRES_TIMER` (#3679) by @ubkp
+[rcore][SDL] REVIEWED: SDL text input to Unicode codepoints #3650 by @Ray
+[rcore][SDL] REVIEWED: `IsMouseButtonUp()` and add touch events (#3610) by @ubkp
+[rcore][SDL] REVIEWED: Fix real touch gestures (#3614) by @ubkp
+[rcore][SDL] REVIEWED: `IsKeyPressedRepeat()` (#3605) by @ubkp
+[rcore][SDL] REVIEWED: `GetKeyPressed()` and `GetCharPressed()` for SDL (#3604) by @ubkp
+[rcore][SDL] REVIEWED: `SetMousePosition()` for SDL (#3580) by @ubkp
+[rcore][SDL] REVIEWED: `SetWindowIcon()` for SDL (#3578) by @ubkp
+[rcore][SDL][rlgl] REVIEWED: Fix for running gles2 with SDL on desktop (#3542) by @_Tradam
+[rcore][Android] REVIEWED: Issue with isGpuReady flag (#4340) by @Menno van der Graaf
+[rcore][Android] REVIEWED: Allow main() to return it its caller on configuration changes (#4288) by @Hesham Abourgheba
+[rcore][Android] REVIEWED: Replace deprecated Android function ALooper_pollAll with ALooper_pollOnce (#4275) by @Menno van der Graaf
+[rcore][Android] REVIEWED: `PollInputEvents()`, register previous gamepad events (#3910) by @Aria
+[rcore][Android] REVIEWED: Fix Android keycode translation and duplicate key constants (#3733) by @Alexandre Almeida
+[rcore][DRM] ADDED: uConsole keys mapping (#4297) by @carverdamien
+[rcore][DRM] ADDED: `GetMonitorWidth/Height()` (#3956) by @gabriel-marques
+[rcore][DRM] REVIEWED: `IsMouseButtonUp()` (#3611) by @ubkp
+[rcore][DRM] REVIEWED: Optimize gesture handling (#3616) by @ubkp
+[rcore][DRM] REVIEWED: `IsKeyPressedRepeat()` for PLATFORM_DRM direct input (#3583) by @ubkp
+[rcore][DRM] REVIEWED: Fix gamepad buttons not working in drm backend (#3888) by @MrMugame
+[rcore][DRM] REVIEWED: DRM backend to only use one api to allow for more devices (#3879) by @MrMugame
+[rcore][DRM] REVIEWED: Avoid separate thread when polling for gamepad events (#3641) by @Cinghy Creations
+[rcore][DRM] REVIEWED: Connector status reported as UNKNOWN but should be considered as CONNECTED (#4305) by @Michał Jaskólski
+[rcore][RGFW] ADDED: RGFW, new rcore backend platform (#3941) by @Colleague Riley
+[rcore][RGFW] REVIEWED: RGFW 1.0 (#4144) by @Colleague Riley
+[rcore][RGFW] REVIEWED: Fix errors when compiling with mingw (#4282) by @Colleague Riley
+[rcore][RGFW] REVIEWED: Replace long switch with a lookup table (#4108) by @Colleague Riley
+[rlgl] ADDED: More uniform data type options #4137 by @Ray
+[rlgl] ADDED: Vertex normals for RLGL immediate drawing mode (#3866) by @bohonghuang
+[rlgl] ADDED: `rlCullDistance*()` variables and getters (#3912) by @KotzaBoss
+[rlgl] ADDED: `rlSetClipPlanes()` function (#3912) by @KotzaBoss
+[rlgl] ADDED: `isGpuReady` flag, allow font loading with no GPU acceleration by @Ray -WARNING-
+[rlgl] REVIEWED: Changed RLGL_VERSION from 4.5 to 5.0 (#3914) by @Mute
+[rlgl] REVIEWED: Shader load failing returns 0, instead of fallback by @Ray -WARNING-
+[rlgl] REVIEWED: Standalone mode default flags (#4334) by @Asdqwe
+[rlgl] REVIEWED: Fix hardcoded index values in vboID array (#4312) by @Jett
+[rlgl] REVIEWED: GLint64 did not exist before OpenGL 3.2 (#4284) by @Tchan0
+[rlgl] REVIEWED: Extra warnings in case OpenGL 4.3 is not enabled (#4202) by @Maxim Knyazkin
+[rlgl] REVIEWED: Using GLint64 for glGetBufferParameteri64v() (#4197) by @Randy Palamar
+[rlgl] REVIEWED: Replace `glGetInteger64v()` with `glGetBufferParameteri64v()` (#4154) by @Kai Kitagawa-Jones
+[rlgl] REVIEWED: `rlMultMatrixf()`, fix matrix multiplication order (#3935) by @bohonghuang
+[rlgl] REVIEWED: `rlSetVertexAttribute()`, define last parameter as offset #3800 by @Ray
+[rlgl] REVIEWED: `rlDisableVertexAttribute()`, remove redundat calls for SHADER_LOC_VERTEX_COLOR (#3871) by @Kacper Zybała
+[rlgl] REVIEWED: `rlLoadFramebuffer()`, parameters not required by @Ray
+[rlgl] REVIEWED: `rlSetUniformSampler()` (#3759) by @veins1
+[rlgl] REVIEWED: Renamed near/far variables (#4039) by @jgabaut
+[rlgl] REVIEWED: Expose OpenGL symbols (#3588) by @Peter0x44
+[rlgl] REVIEWED: Fix OpenGL 1.1 build issues (#3876) by @Ray
+[rlgl] REVIEWED: Fixed compilation for OpenGL ES (#4243) by @Maxim Knyazkin
+[rlgl] REVIEWED: rlgl function description and comments by @Ray
+[rlgl] REVIEWED: Expose glad functions when building raylib as a shared lib (#3572) by @Peter0x44
+[rlgl] REVIEWED: Fix version info in rlgl.h (#3558) by @Steven Schveighoffer
+[rcamera] REVIEWED: Make camera movement independant of framerate (#4247) by @hanaxars -WARNING-
+[rcamera] REVIEWED: Updated camera speeds with GetFrameTime() (#4362) by @Anthony Carbajal
+[rcamera] REVIEWED: `UpdateCamera()`, added CAMERA_CUSTOM check (#3938) by @Tomas Fabrizio Orsi
+[rcamera] REVIEWED: Support mouse/keyboard and gamepad coexistence for input (#3579) by @ubkp
+[rcamera] REVIEWED: Cleaned away unused macros(#3762) by @Brian E
+[rcamera] REVIEWED: Fix for free camera mode (#3603) by @lesleyrs
+[rcamera] REVIEWED: `GetCameraRight()` (#3784) by @Danil
+[raymath] ADDED: C++ operator overloads for common math function (#4385) by @Jeffery Myers
+[raymath] ADDED: Vector4 math functions and Vector2 variants of some Vector3 functions (#3828) by @Bowserinator
+[raymath] REVIEWED: Fix MSVC warnings/errors in C++ (#4125) by @Jeffery Myers
+[raymath] REVIEWED: Add extern "C" to raymath header for C++ (#3978) by @Jeffery Myers
+[raymath] REVIEWED: `QuaternionFromAxisAngle()`, remove redundant axis length calculation (#3900) by @jtainer
+[raymath] REVIEWED: `Vector3Perpendicular()`, avoid implicit conversion from float to double (#3799) by @João Foscarini
+[raymath] REVIEWED: Small code refactor (#3753) by @Idir Carlos Aliane
+[rshapes] ADDED: `CheckCollisionCircleLine()` (#4018) by @kai-z99
+[rshapes] REVIEWED: Multisegment Bezier splines (#3744) by @Santiago Pelufo
+[rshapes] REVIEWED: Expose shapes drawing texture and rectangle (#3677) by @Jeffery Myers
+[rshapes] REVIEWED: `DrawLine()` #4075 by @Ray
+[rshapes] REVIEWED: `DrawPixel()` drawing by @Ray
+[rshapes] REVIEWED: `DrawLine()` to avoid pixel rounding issues #3931 by @Ray
+[rshapes] REVIEWED: `DrawRectangleLinesEx()`, make sure accounts for square tiles (#4382) by @Jojaby
+[rshapes] REVIEWED: `DrawRectangleLines()`, pixel offset when scaling (#3884) by @Ray
+[rshapes] REVIEWED: `Draw*Gradient()` color parameter names (#4270) by @Paperdomo101
+[rshapes] REVIEWED: `DrawGrid()`, remove duplicate color calls (#4148) by @Jeffery Myers
+[rshapes] REVIEWED: `DrawSplineLinear()` to `SUPPORT_SPLINE_MITERS` by @Ray
+[rshapes] REVIEWED: `DrawSplineLinear()`, implement miters (#3585) by @Toctave
+[rshapes] REVIEWED: `CheckCollisionPointRec()` by @Ray
+[rshapes] REVIEWED: `CheckCollisionPointCircle()`, new implementation (#4135) by @kai-z99
+[rshapes] REVIEWED: `CheckCollisionCircles()`, optimized (#4065) by @kai-z99
+[rshapes] REVIEWED: `CheckCollisionPointPoly()` (#3750) by @Antonio Raúl
+[rshapes] REVIEWED: `CheckCollisionCircleRec()` (#3584) by @ubkp
+[rshapes] REVIEWED: Add more detail to function comment (#4344) by @Jeffery Myers
+[rshapes] REVIEWED: Functions that draw point arrays take them as const (#4051) by @Jeffery Myers
+[rtextures] ADDED: `ColorIsEqual()` by @Ray
+[rtextures] ADDED: `ColorLerp()`, to mix 2 colors together (#4310) by @SusgUY446
+[rtextures] ADDED: `LoadImageAnimFromMemory()` (#3681) by @IoIxD
+[rtextures] ADDED: `ImageKernelConvolution()` (#3528) by @Karim
+[rtextures] ADDED: `ImageFromChannel()` (#4105) by @Bruno Cabral
+[rtextures] ADDED: `ImageDrawLineEx()` (#4097) by @Le Juez Victor
+[rtextures] ADDED: `ImageDrawTriangle()` (#4094) by @Le Juez Victor
+[rtextures] REMOVED: SVG files loading and drawing, moving it to raylib-extras by @Ray -WARNING-
+[rtextures] REVIEWED: `LoadImage()`, added support for 3-channel QOI images (#4384) by @R-YaTian
+[rtextures] REVIEWED: `LoadImageRaw()` #3926 by @Ray
+[rtextures] REVIEWED: `LoadImageColors()`, advance k in loop (#4120) by @Bruno Cabral
+[rtextures] REVIEWED: `LoadTextureCubemap()`, added `mipmaps` #3665 by @Ray
+[rtextures] REVIEWED: `LoadTextureCubemap(), assign format to cubemap (#3823) by @Gary M
+[rtextures] REVIEWED: `LoadImageFromScreen()`, fix scaling (#3881) by @proberge-dev
+[rtextures] REVIEWED: `LoadImageFromMemory()`, warnings on invalid image data (#4179) by @Jutastre
+[rtextures] REVIEWED: `LoadImageAnimFromMemory()`, added security checks (#3924) by @Ray
+[rtextures] REVIEWED: `ImageColorTint()` and `ColorTint()`, optimized (#4015) by @Le Juez Victor
+[rtextures] REVIEWED: `ImageKernelConvolution()`, formating and warnings by @Ray
+[rtextures] REVIEWED: `ImageDrawRectangleRec`, fix bounds check (#3732) by @Blockguy24
+[rtextures] REVIEWED: `ImageResizeCanvas()`, implemented fill color (#3720) by @Lieven Petersen
+[rtextures] REVIEWED: `ImageDrawRectangleRec()` (#3721) by @Le Juez Victor
+[rtextures] REVIEWED: `ImageDraw()`, don't try to blend images without alpha (#4395) by @Nikolas
+[rtextures] REVIEWED: `GenImagePerlinNoise()` being stretched (#4276) by @Bugsia
+[rtextures] REVIEWED: `DrawTexturePro()` to avoid negative dest rec #4316 by @Ray
+[rtextures] REVIEWED: `ColorToInt()`, fix undefined behaviour (#3996) by @OetkenPurveyorOfCode
+[rtextures] REVIEWED: Simplified for loop for some image manipulation functions (#3712) by @Alice Nyaa
+[rtext] ADDED: BDF fonts support (#3735) by @Stanley Fuller -WARNING-
+[rtext] ADDED: `TextToCamel()` (#4033) by @IoIxD
+[rtext] ADDED: `TextToSnake()` (#4033) by @IoIxD
+[rtext] ADDED: `TextToFloat()` (#3627) by @Benjamin Schmid Ties
+[rtext] REDESIGNED: `SetTextLineSpacing()` by @Ray -WARNING-
+[rtext] REVIEWED: `LoadFontDataBDF()` name and formating by @Ray
+[rtext] REVIEWED: `LoadFontDefault()`, initialize glyphs and recs to zero #4319 by @Ray
+[rtext] REVIEWED: `LoadFontEx()`, avoid default font fallback (#4077) by @Peter0x44 -WARNING-
+[rtext] REVIEWED: `LoadBMFont()`, extended functionality (#3536) by @Dongkun Lee
+[rtext] REVIEWED: `LoadBMFont()`, issue on not glyph data initialized by @Ray
+[rtext] REVIEWED: `LoadFontFromMemory()`, use strncpy() to fix buffer overflow (#3795) by @Mingjie Shen
+[rtext] REVIEWED: `LoadCodepoints()` returning a freed ptr when count is 0 (#4089) by @Alice Nyaa
+[rtext] REVIEWED: `LoadFontData()` avoid fallback glyphs by @Ray -WARNING-
+[rtext] REVIEWED: `LoadFontData()`, load image only if glyph has been found in font by @Ray
+[rtext] REVIEWED: `ExportFontAsCode()`, fix C++ compiler errors (#4013) by @DarkAssassin23
+[rtext] REVIEWED: `MeasureTextEx()` height calculation (#3770) by @Marrony Neris
+[rtext] REVIEWED: `CodepointToUTF8()`, clean static buffer #4379 by @Ray
+[rtext] REVIEWED: `TextToFloat()`, always multiply by sign (#4273) by @listeria
+[rtext] REVIEWED: `TextReplace()` const correctness (#3678) by @maverikou
+[rtext] REVIEWED: `TextToFloat()`, coding style (#3627) by @Benjamin Schmid Ties
+[rtext] REVIEWED: Some comments to align to style (#3756) by @Idir Carlos Aliane
+[rtext] REVIEWED: Adjust font atlas area calculation so padding area is not underestimated at small font sizes (#3719) by @Tim Romero
+[rmodels] ADDED: GPU skinning support for models animations (#4321) by @Daniel Holden -WARNING-
+[rmodels] ADDED: Support 16-bit unsigned short vec4 format for gltf joint loading (#3821) by @Gary M
+[rmodels] ADDED: Support animation names for the m3d model format (#3714) by @kolunmi
+[rmodels] ADDED: `DrawModelPoints()`, more performant point cloud rendering (#4203) by @Reese Gallagher
+[rmodels] ADDED: `ExportMeshAsCode()` by @Ray
+[rmodels] REVIEWED: Multiple updates to gltf loading, improved macro (#4373) by @Harald Scheirich
+[rmodels] REVIEWED: `LoadOBJ()`, correctly split obj meshes by material (#4285) by @Jeffery Myers
+[rmodels] REVIEWED: `LoadOBJ()`, add warning when loading an OBJ with multiple materials (#4271) by @Jeffery Myers
+[rmodels] REVIEWED: `LoadIQM()`, set model.meshMaterial[] (#4092) by @SuperUserNameMan
+[rmodels] REVIEWED: `LoadIQM()`, attempt to load texture from IQM at loadtime (#4029) by @Jett
+[rmodels] REVIEWED: `LoadM3D(), fix vertex colors for m3d files (#3859) by @Jeffery Myers
+[rmodels] REVIEWED: `LoadGLTF()`, supporting additional vertex data formats (#3546) by @MrScautHD
+[rmodels] REVIEWED: `LoadGLTF()`, correctly handle the node hierarchy in a glTF file (#4037) by @Paul Melis
+[rmodels] REVIEWED: `LoadGLTF()`, replaced SQUAD quat interpolation with cubic hermite (gltf 2.0 specs) (#3920) by @Benji
+[rmodels] REVIEWED: `LoadGLTF()`, support 2nd texture coordinates loading by @Ray
+[rmodels] REVIEWED: `LoadGLTF()`, support additional vertex attributes data formats #3890 by @Ray
+[rmodels] REVIEWED: `LoadGLTF()`, set cgltf callbacks to use `LoadFileData()` and `UnloadFileData()` (#3652) by @kolunmi
+[rmodels] REVIEWED: `LoadGLTF()`, JOINTS loading #3836 by @Ray
+[rmodels] REVIEWED: `LoadImageFromCgltfImage()`, fix base64 padding support (#4112) by @SuperUserNameMan
+[rmodels] REVIEWED: `LoadModelAnimationsIQM()`, fix corrupted animation names (#4026) by @Jett
+[rmodels] REVIEWED: `LoadModelAnimationsGLTF()`, load animations with 1 frame (#3804) by @Nikita Blizniuk
+[rmodels] REVIEWED: `LoadModelAnimationsGLTF()`, added missing interpolation types (#3919) by @Benji
+[rmodels] REVIEWED: `LoadModelAnimationsGLTF()` (#4107) by @VitoTringolo
+[rmodels] REVIEWED: `LoadBoneInfoGLTF()`, add check for animation name being NULL (#4053) by @VitoTringolo
+[rmodels] REVIEWED: `GenMeshTangents()`, read uninitialized values, fix bounding case (#4066) by @kai-z99
+[rmodels] REVIEWED: `GenMeshTangents()`, fixed out of bounds error (#3990) by @Salvador Galindo
+[rmodels] REVIEWED: `DrawCylinder()`, fix drawing due to imprecise angle (#4034) by @Paul Melis
+[rmodels] REVIEWED: `DrawMesh()`, send full matModel to shader in DrawMesh (#4005) (#4022) by @David Holland
+[rmodels] REVIEWED: `DrawMesh()`, fix material specular map retrieval (#3758) by @Victor Gallet
+[rmodels] REVIEWED: `DrawModelEx()`, simplified multiplication of colors (#4002) by @Le Juez Victor
+[rmodels] REVIEWED: `DrawBillboardPro()`, to be consistend with `DrawTexturePro()` (#4132) by @bohonghuang
+[rmodels] REVIEWED: `DrawSphereEx()` optimization (#4106) by @smalltimewizard
+[raudio] REVIEWED: `LoadMusicStreamFromMemory()`, support 24-bit FLACs (#4279) by @konstruktor227
+[raudio] REVIEWED: `LoadWaveSamples()`, fix mapping of wave data (#4062) by @listeria
+[raudio] REVIEWED: `LoadMusicStream()`, remove drwav_uninit() (#3986) by @FishingHacks
+[raudio] REVIEWED: `LoadMusicStream()` qoa and wav loading (#3966) by @veins1
+[raudio] REVIEWED: `ExportWaveAsCode()`, segfault (#3769) by @IoIxD
+[raudio] REVIEWED: `WaveCrop()`, fix issues and use frames instead of samples (#3994) by @listeria
+[raudio] REVIEWED: Crash from multithreading issues (#3907) by @Christian Haas
+[raudio] REVIEWED: Reset music.ctxType if loading wasn't succesful (#3917) by @veins1
+[raudio] REVIEWED: Added missing functions in "standalone" mode (#3760) by @Alessandro Nikolaev
+[raudio] REVIEWED: Disable unused miniaudio features (#3544) by @Alexandre Almeida
+[raudio] REVIEWED: Fix crash when switching playback device at runtime (#4102) by @jkaup
+[raudio] REVIEWED: Support 24 bits samples for FLAC format (#4058) by @Alexey Kutepov
+[examples] ADDED: `core_random_sequence` (#3846) by @Dalton Overmyer
+[examples] ADDED: `models_bone_socket` (#3833) by @iP
+[examples] ADDED: `shaders_vertex_displacement` (#4186) by @Alex ZH
+[examples] ADDED: `shaders_shadowmap` (#3653) by @TheManTheMythTheGameDev
+[examples] REVIEWED: `core_2d_camera_platformer` by @Ray
+[examples] REVIEWED: `core_2d_camera_mouse_zoom`, use logarithmic scaling for a 2d zoom functionality (#3977) by @Mike Will
+[examples] REVIEWED: `core_input_gamepad_info`, all buttons displayed within the window (#4241) by @Asdqwe
+[examples] REVIEWED: `core_input_gamepad_info`, show ps3 controller (#4040) by @Konrad Gutvik Grande
+[examples] REVIEWED: `shapes_bouncing_ball` (#4226) by @Anthony Carbajal
+[examples] REVIEWED: `shapes_following_eyes` (#3710) by @Hongyu Ouyang
+[examples] REVIEWED: `shapes_draw_rectangle_rounded` by @Ray
+[examples] REVIEWED: `shapes_draw_ring`, fix other examples (#4211) by @kai-z99
+[examples] REVIEWED: `shapes_lines_bezier` by @Ray
+[examples] REVIEWED: `textures_image_kernel` #3556 by @Ray
+[examples] REVIEWED: `text_input_box` (#4229) by @Anthony Carbajal
+[examples] REVIEWED: `text_writing_anim` (#4230) by @Anthony Carbajal
+[examples] REVIEWED: `models_billboard` by @Ray
+[examples] REVIEWED: `models_cubicmap` by @Ray
+[examples] REVIEWED: `models_point_rendering` by @Ray
+[examples] REVIEWED: `models_box_collisions` (#4224) by @Anthony Carbajal
+[examples] REVIEWED: `models_skybox`, do not use HDR by default (#4115) by @Jeffery Myers
+[examples] REVIEWED: `shaders_basic_pbr` (#4225) by @Anthony Carbajal
+[examples] REVIEWED: `shaders_palette_switch` by @Ray
+[examples] REVIEWED: `shaders_hybrid_render` (#3908) by @Yousif
+[examples] REVIEWED: `shaders_lighting_instancing`, fix vertex shader (#4056) by @Karl Zylinski
+[examples] REVIEWED: `shaders_raymarching`, add `raymarching.fs` for GLSL120 (#4183) by @CDM15y
+[examples] REVIEWED: `shaders_shadowmap`, fix shaders for GLSL 1.20 (#4167) by @CDM15y
+[examples] REVIEWED: `shaders_deferred_render` (#3655) by @Jett
+[examples] REVIEWED: `shaders_basic_pbr` (#3621) by @devdad
+[examples] REVIEWED: `shaders_basic_pbr`, remove dependencies (#3649) by @TheManTheMythTheGameDev
+[examples] REVIEWED: `shaders_basic_pbr`, added more comments by @Ray
+[examples] REVIEWED: `audio_stream_effects` (#3618) by @lipx
+[examples] REVIEWED: `audio_raw_stream` (#3624) by @riadbettole
+[examples] REVIEWED: `audio_mixed_processor` (#4214) by @Anthony Carbajal
+[examples] REVIEWED: `raylib_opengl_interop`, fix building on PLATFORM_DESKTOP_SDL (#3826) by @Peter0x44
+[examples] REVIEWED: Update examples missing UnloadTexture() calls (#4234) by @Anthony Carbajal
+[examples] REVIEWED: Added GLSL 100 and 120 shaders to lightmap example (#3543) by @Jussi Viitala
+[examples] REVIEWED: Set FPS to always 60 in all exampels (#4235) by @Anthony Carbajal
+[build] REVIEWED: Makefile by @Ray
+[build] REVIEWED: Makefile, fix wrong flag #3593 by @Ray
+[build] REVIEWED: Makefile, disable wayland by default (#4369) by @Anthony Carbajal
+[build] REVIEWED: Makefile, VSCode, fix to support multiple .c files (#4391) by @Alan Arrecis
+[build] REVIEWED: Makefile, fix -Wstringop-truncation warning (#4096) by @Peter0x44
+[build] REVIEWED: Makefile, fix issues for RGFW on Linux/macOS (#3969) by @Colleague Riley
+[build] REVIEWED: Makefile, update RAYLIB_VERSION (#3901) by @Belllg
+[build] REVIEWED: Makefile (#4054) by @Lázaro Albuquerque
+[build] REVIEWED: Makefile examples, align /usr/local with /src Makefile (#4286) by @Tchan0
+[build] REVIEWED: Makefile examples, added `textures_image_kernel` (#3555) by @Sergey Zapunidi
+[build] REVIEWED: Makefile examples (#4209) by @Anthony Carbajal
+[build] REVIEWED: build.zig, fix various issues around `-Dconfig` (#4398) by @Sage Hane
+[build] REVIEWED: build.zig, fix type mismatch (#4383) by @yuval_dev
+[build] REVIEWED: build.zig, minor fixes (#4381) by @Sage Hane
+[build] REVIEWED: build.zig, fix @src logic and a few things (#4380) by @Sage Hane
+[build] REVIEWED: build.zig, improve logic (#4375) by @Sage Hane
+[build] REVIEWED: build.zig, issues (#4374) by @William Culver
+[build] REVIEWED: build.zig, issues (#4366) by @Visen
+[build] REVIEWED: build.zig, support desktop backend change (#4358) by @Nikolas
+[build] REVIEWED: build.zig, use zig fmt (#4242) by @freakmangd
+[build] REVIEWED: build.zig, check if wayland-scanner is installed (#4217) by @lnc3l0t
+[build] REVIEWED: build.zig, override config.h definitions (#4193) by @lnc3l0t
+[build] REVIEWED: build.zig, support GLFW platform detection (#4150) by @InventorXtreme
+[build] REVIEWED: build.zig, make emscripten build compatible with Zig 0.13.0 (#4121) by @Mike Will
+[build] REVIEWED: build.zig, pass the real build.zig file (#4113) by @InKryption
+[build] REVIEWED: build.zig, leverage `dependencyFromBuildZig` (#4109) by @InKryption
+[build] REVIEWED: build.zig, run examples from their directories (#4063) by @Mike Will
+[build] REVIEWED: build.zig, fix raygui build when using addRaygui externally (#4027) by @Viktor Pocedulić
+[build] REVIEWED: build.zig, fix emscripten build (#4012) by @Dylan
+[build] REVIEWED: build.zig, update to zig 0.12.0dev while keeping 0.11.0 compatibility (#3715) by @freakmangd
+[build] REVIEWED: build.zig, drop support for 0.11.0 and use more idiomatic build script code (#3927) by @freakmangd
+[build] REVIEWED: build.zig, sdd shared library build option and update to zig 0.12.0-dev.2139 (#3727) by @Andrew Lee
+[build] REVIEWED: build.zig, add `opengl_version` option (#3979) by @Alexei Mozaidze
+[build] REVIEWED: build.zig, fix local dependency break (#3913) by @freakmangd
+[build] REVIEWED: build.zig, fix breaking builds for Zig v0.11.0 (#3896) by @iarkn
+[build] REVIEWED: build.zig, update to latest version and simplify (#3905) by @freakmangd
+[build] REVIEWED: build.zig, remove all uses of deps/mingw (#3805) by @Peter0x44
+[build] REVIEWED: build.zig, fixed illegal instruction crash (#3682) by @WisonYe
+[build] REVIEWED: build.zig, fix broken build on #3863 (#3891) by @Nikolas Mauropoulos
+[build] REVIEWED: CMake, update to raylib 5.0 (#3623) by @Peter0x44
+[build] REVIEWED: CMake, added PLATFORM option for Desktop SDL (#3809) by @mooff
+[build] REVIEWED: CMake, fix GRAPHICS_* check (#4359) by @Kacper Zybała
+[build] REVIEWED: CMake, examples projects (#4332) by @Ridge3Dproductions
+[build] REVIEWED: CMake, fix warnings in projects/CMake/CMakeLists.txt (#4278) by @Peter0x44
+[build] REVIEWED: CMake, delete BuildOptions.cmake (#4277) by @Peter0x44
+[build] REVIEWED: CMake, update version to 5.0 so libraries are correctly versioned (#3615) by @David Williams
+[build] REVIEWED: CMake, improved linkage flags to save 28KB on the final bundle (#4177) by @Lázaro Albuquerque
+[build] REVIEWED: CMake, support OpenGL ES3 in `LibraryConfigurations.cmake` (#4079) by @manuel5975p
+[build] REVIEWED: CMake, `config.h` fully available to users (#4044) by @Lázaro Albuquerque
+[build] REVIEWED: CMake, pass -sFULL_ES3 instead of -sFULL_ES3=1 (#4090) by @manuel5975p
+[build] REVIEWED: CMake, SDL build link the glfw dependency (#3860) by @Rob Loach
+[build] REVIEWED: CMake, infer CMAKE_MODULE_PATH in super-build (#4042) by @fruzitent
+[build] REVIEWED: CMake, remove USE_WAYLAND option (#3851) by @Alexandre Almeida
+[build] REVIEWED: CMake, disable SDL rlgl_standalone example (#3861) by @Rob Loach
+[build] REVIEWED: CMake, bump version required to avoid deprecated #3639 by @Ray
+[build] REVIEWED: CMake, fix examples linking -DPLATFORM=SDL (#3825) by @Peter0x44
+[build] REVIEWED: VS2022 project by @Ray
+[build] REVIEWED: VS2022, fix build warnings (#4095) by @Jeffery Myers
+[build] REVIEWED: Fix fix-build-paths (#3849) by @Caleb Barger
+[build] REVIEWED: Fix build paths (#3835) by @Steve Biedermann
+[build] REVIEWED: Fix VSCode sample project for macOS (#3666) by @Tim Romero
+[build] REVIEWED: Fix some warnings on web builds and remove some redundant flags (#4069) by @Lázaro Albuquerque
+[build] REVIEWED: Fix examples not building with gestures system disabled (#4020) by @Sprix
+[build] REVIEWED: Fix GLFW runtime platform detection (#3863) by @Alexandre Almeida
+[build] REVIEWED: Fix DRM cross-compile without sysroot (#3839) by @Christian W. Zuckschwerdt
+[build] REVIEWED: Fix cmake-built libraylib.a to properly include GLFW's object files (#3598) by @Peter0x44
+[build] REVIEWED: Hide unneeded internal symbols when building raylib as an so or dylib (#3573) by @Peter0x44
+[build] REVIEWED: Corrected the path of android ndk toolchains for OSX platforms (#3574) by @Emmanuel Méra
+[build][CI] ADDED: Automatic update for raylib_api.* (#3692) by @seiren
+[build][CI] REVIEWED: Update workflows to use latest actions/upload-artifact by @Ray
+[build][CI] REVIEWED: CodeQL minor tweaks to avoid some warnings by @Ray
+[build][CI] REVIEWED: Update linux_examples.yml by @Ray
+[build][CI] REVIEWED: Update linux.yml by @Ray
+[build][CI] REVIEWED: Update webassembly.yml by @Ray
+[build][CI] REVIEWED: Update cmake.yml by @Ray
+[build][CI] REVIEWED: Update codeql.yml, exclude src/external files by @Ray
+[bindings] ADDED: raylib-APL (#4253) by @Brian E
+[bindings] ADDED: raylib-bqn, moved rayed-bqn (#4331) by @Brian E
+[bindings] ADDED: brainfuck binding (#4169) by @_Tradam
+[bindings] ADDED: raylib-zig-bindings (#4004) by @Lionel Briand
+[bindings] ADDED: Raylib-CSharp wrapper (#3963) by @MrScautHD
+[bindings] ADDED: COBOL binding (#3661) by @glowiak
+[bindings] ADDED: raylib-beef binding (#3640) by @Braedon Lewis
+[bindings] ADDED: Raylib-CSharp-Vinculum (#3571) by @Danil
+[bindings] REVIEWED: Remove broken-link bindings #3899 by @Ray
+[bindings] REVIEWED: Updated some versions on BINDINGS.md by @Ray
+[bindings] REVIEWED: Removed umaintained repos (#3999) by @Antonis Geralis
+[bindings] REDESIGNED: Add binding link to name, instead of separate column (#3995) by @Carmine Pietroluongo
+[bindings] UPDATED: h-raylib (#4378) by @Anand Swaroop
+[bindings] UPDATED: Raylib.lean, to master version (#4337) by @Daniil Kisel
+[bindings] UPDATED: raybit, to latest master (#4311) by @Alex
+[bindings] UPDATED: dray binding (#4163) by @red thing
+[bindings] UPDATED: Julia (#4068) by @ShalokShalom
+[bindings] UPDATED: nim to latest master (#3999) by @Antonis Geralis
+[bindings] UPDATED: raylib-rs (#3991) by @IoIxD
+[bindings] UPDATED: raylib-zig version (#3902) by @Nikolas
+[bindings] UPDATED: raylib-odin (#3868) by @joyousblunder
+[bindings] UPDATED: Raylib VAPI (#3829) by @Alex Macafee
+[bindings] UPDATED: Raylib-cs (#3774) by @Brandon Baker
+[bindings] UPDATED: h-raylib (#3739) by @Anand Swaroop
+[bindings] UPDATED: OCaml bindings version (#3730) by @Tobias Mock
+[bindings] UPDATED: Raylib.c3 (#3689) by @Kenta
+[bindings] UPDATED: ray-cyber to 5.0 (#3654) by @fubark
+[bindings] UPDATED: raylib-freebasic binding (#3591) by @WIITD
+[bindings] UPDATED: SmallBASIC (#3562) by @Chris Warren-Smith
+[bindings] UPDATED: Python raylib-py v5.0.0beta1 (#3557) by @Jorge A. Gomes
+[bindings] UPDATED: raylib-d binding (#3561) by @Steven Schveighoffer
+[bindings] UPDATED: Janet (#3553) by @Dmitry Matveyev
+[bindings] UPDATED: Raylib.nelua (#3552) by @Auz
+[bindings] UPDATED: raylib-cpp to 5.0 (#3551) by @Rob Loach
+[bindings] UPDATED: Pascal binding (#3548) by @Gunko Vadim
+[external] REVIEWED: rl_gputex, correctly load mipmaps from DDS files (#4399) by @Nikolas
+[external] REVIEWED: stb_image_resize2, dix vld1q_f16 undeclared in arm (#4309) by @masnm
+[external] REVIEWED: miniaudio, fix library and Makefile for NetBSD (#4212) by @NishiOwO
+[external] REVIEWED: raygui, update to latest version 4.5-dev (#4238) by @Anthony Carbajal
+[external] REVIEWED: jar_xml, replace unicode characters by ascii characters to avoid warning in MSVC (#4196) by @Rico P
+[external] REVIEWED: vox_loader, normals and new voxels shader (#3843) by @johann nadalutti
+[parser] REVIEWED: README.md, to mirror fixed help text (#4336) by @Daniil Kisel
+[parser] REVIEWED: Fix seg fault with long comment lines (#4306) by @Chris Warren-Smith
+[parser] REVIEWED: Don't crash for files that don't end in newlines (#3981) by @Peter0x44
+[parser] REVIEWED: Issues in usage example help text (#4084) by @Peter0x44
+[parser] REVIEWED: Fix parsing of empty parentheses (#3974) by @Filyus
+[parser] REVIEWED: Address parsing issue when generating XML #3893 by @Ray
+[parser] REVIEWED: `MemoryCopy()`, prevent buffer overflow by replacing hard-coded arguments (#4011) by @avx0
+[misc] ADDED: Create logo/raylib.icns by @Ray
+[misc] ADDED: Create logo/raylib_1024x1024.png by @Ray
+[misc] ADDED: Default vertex/fragment shader for OpenGL ES 3.0 (#4178) by @Lázaro Albuquerque
+[misc] REVIEWED: README.md, fix Reddit badge (#4136) by @Ninad Sachania
+[misc] REVIEWED: .gitignore, ignore compiled dll binaries (#3628) by @2Bear
+[misc] REVIEWED: Fix undesired scrollbars on web shell files (#4104) by @jspast
+[misc] REVIEWED: Made comments on raylib.h match comments in rcamera.h (#3942) by @Tomas Fabrizio Orsi
+[misc] REVIEWED: Make raylib/raygui work better on touchscreen (#3728) by @Hongyu Ouyang
+[misc] REVIEWED: Update config.h by @Ray
-------------------------------------------------------------------------
Release: raylib 5.0 - 10th Anniversary Edition (18 November 2023)
diff --git a/CMakeOptions.txt b/CMakeOptions.txt
index ce9141e22..b387922b4 100644
--- a/CMakeOptions.txt
+++ b/CMakeOptions.txt
@@ -21,7 +21,7 @@ cmake_dependent_option(USE_AUDIO "Build raylib with audio module" ON CUSTOMIZE_B
enum_option(USE_EXTERNAL_GLFW "OFF;IF_POSSIBLE;ON" "Link raylib against system GLFW instead of embedded one")
# GLFW build options
-option(GLFW_BUILD_WAYLAND "Build the bundled GLFW with Wayland support" ON)
+option(GLFW_BUILD_WAYLAND "Build the bundled GLFW with Wayland support" OFF)
option(GLFW_BUILD_X11 "Build the bundled GLFW with X11 support" ON)
option(INCLUDE_EVERYTHING "Include everything disabled by default (for CI usage" OFF)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 78f953baf..d70617c13 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -5,7 +5,7 @@ Hello contributors! Welcome to raylib!
Do you enjoy raylib and want to contribute? Nice! You can help with the following points:
- `C programming` - Can you write/review/test/improve the code?
-- `Documentation/Tutorials/Example` - Can you write some tutorial/example?
+- `Documentation/Tutorials/Example` - Can you write some tutorials/examples?
- `Porting to other platforms` - Can you port/adapt/compile raylib on other systems?
- `Web Development` - Can you help [with the website](https://github.com/raysan5/raylib.com)?
- `Testing` - Can you find some bugs in raylib?
diff --git a/HISTORY.md b/HISTORY.md
index 035054dbe..555e81b38 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -471,3 +471,20 @@ Make sure to check raylib [CHANGELOG]([CHANGELOG](https://github.com/raysan5/ray
Undoubtedly, this is the **biggest raylib update in 10 years**. Many new features and improvements with a special focus on maintainability and long-term sustainability. **Undoubtedly, this is the raylib of the future**.
**Enjoy programming!** :)
+
+notes on raylib 5.5
+-------------------
+
+It's been **1 year** since latest raylib release and **11 years** since raylib 1.0 was officially released...
+
+Some numbers for this release:
+
+ - **+260** closed issues (for a TOTAL of **+1800**!)
+ - **+700** commits since previous RELEASE (for a TOTAL of **+7670**!)
+ - **+30** functions ADDED to raylib API (for a TOTAL of **580**!)
+ - **+110** functions REVIEWED with fixes and improvements
+ - **+135** new contributors (for a TOTAL of **+635**!)
+
+Highlights for `raylib 5.5`:
+
+TODO.
diff --git a/build.zig b/build.zig
index 56e69caf4..75a77dd51 100644
--- a/build.zig
+++ b/build.zig
@@ -116,6 +116,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
// `n` corresponds to the number of user-specified flags
outer: for (config_h_flags) |flag| {
// If a user already specified the flag, skip it
+ config_iter.reset();
while (config_iter.next()) |config_flag| {
// For a user-specified flag to match, it must share the same prefix and have the
// same length or be followed by an equals sign
@@ -186,16 +187,18 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
.linux => {
if (options.platform != .drm) {
try c_source_files.append("src/rglfw.c");
- raylib.linkSystemLibrary("GL");
- raylib.linkSystemLibrary("rt");
- raylib.linkSystemLibrary("dl");
- raylib.linkSystemLibrary("m");
- raylib.addLibraryPath(.{ .cwd_relative = "/usr/lib" });
- raylib.addIncludePath(.{ .cwd_relative = "/usr/include" });
if (options.linux_display_backend == .X11 or options.linux_display_backend == .Both) {
raylib.defineCMacro("_GLFW_X11", null);
+ raylib.linkSystemLibrary("GLX");
raylib.linkSystemLibrary("X11");
+ raylib.linkSystemLibrary("Xcursor");
+ raylib.linkSystemLibrary("Xext");
+ raylib.linkSystemLibrary("Xfixes");
+ raylib.linkSystemLibrary("Xi");
+ raylib.linkSystemLibrary("Xinerama");
+ raylib.linkSystemLibrary("Xrandr");
+ raylib.linkSystemLibrary("Xrender");
}
if (options.linux_display_backend == .Wayland or options.linux_display_backend == .Both) {
@@ -207,9 +210,8 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
@panic("`wayland-scanner` not found");
};
raylib.defineCMacro("_GLFW_WAYLAND", null);
+ raylib.linkSystemLibrary("EGL");
raylib.linkSystemLibrary("wayland-client");
- raylib.linkSystemLibrary("wayland-cursor");
- raylib.linkSystemLibrary("wayland-egl");
raylib.linkSystemLibrary("xkbcommon");
waylandGenerate(b, raylib, "wayland.xml", "wayland-client-protocol");
waylandGenerate(b, raylib, "xdg-shell.xml", "xdg-shell-client-protocol");
@@ -229,13 +231,8 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
}
raylib.linkSystemLibrary("EGL");
- raylib.linkSystemLibrary("drm");
raylib.linkSystemLibrary("gbm");
- raylib.linkSystemLibrary("pthread");
- raylib.linkSystemLibrary("rt");
- raylib.linkSystemLibrary("m");
- raylib.linkSystemLibrary("dl");
- raylib.addIncludePath(.{ .cwd_relative = "/usr/include/libdrm" });
+ raylib.linkSystemLibrary2("libdrm", .{ .use_pkg_config = .force });
raylib.defineCMacro("PLATFORM_DRM", null);
raylib.defineCMacro("EGL_NO_X11", null);
diff --git a/examples/Makefile b/examples/Makefile
index 65ee4fb80..ee3f1fc4c 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -157,8 +157,8 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
EMSDK_PATH ?= C:/emsdk
EMSCRIPTEN_PATH ?= $(EMSDK_PATH)/upstream/emscripten
CLANG_PATH = $(EMSDK_PATH)/upstream/bin
- PYTHON_PATH = $(EMSDK_PATH)/python/3.9.2-1_64bit
- NODE_PATH = $(EMSDK_PATH)/node/14.15.5_64bit/bin
+ PYTHON_PATH = $(EMSDK_PATH)/python/3.9.2-nuget_64bit
+ NODE_PATH = $(EMSDK_PATH)/node/20.18.0_64bit/bin
export PATH = $(EMSDK_PATH);$(EMSCRIPTEN_PATH);$(CLANG_PATH);$(NODE_PATH);$(PYTHON_PATH):$$(PATH)
endif
endif
@@ -197,7 +197,16 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
MAKE = mingw32-make
endif
ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
- MAKE = emmake make
+ ifeq ($(OS),Windows_NT)
+ MAKE = mingw32-make
+ else
+ EMMAKE != type emmake
+ ifneq (, $(EMMAKE))
+ MAKE = emmake make
+ else
+ MAKE = mingw32-make
+ endif
+ endif
endif
# Define compiler flags: CFLAGS
@@ -259,7 +268,7 @@ INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/src/external
# Define additional directories containing required header files
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
ifeq ($(PLATFORM_OS),BSD)
- INCLUDE_PATHS += -I$(RAYLIB_INCLUDE_PATH)
+ INCLUDE_PATHS += -I$(RAYLIB_INCLUDE_PATH) -I/usr/pkg/include -I/usr/X11R7/include
endif
ifeq ($(PLATFORM_OS),LINUX)
INCLUDE_PATHS += -I$(RAYLIB_INCLUDE_PATH)
@@ -392,6 +401,7 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
ifeq ($(PLATFORM_OS),BSD)
# Libraries for FreeBSD, OpenBSD, NetBSD, DragonFly desktop compiling
# NOTE: Required packages: mesa-libs
+ LDFLAGS += -L/usr/X11R7/lib -Wl,-R/usr/X11R7/lib
LDLIBS = -lraylib -lGL -lpthread -lm
# On XWindow requires also below libraries
@@ -451,7 +461,7 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_RGFW)
ifeq ($(PLATFORM_OS),OSX)
# Libraries for Debian GNU/Linux desktop compiling
# NOTE: Required packages: libegl1-mesa-dev
- LDLIBS = ../src/libraylib.a -lm
+ LDLIBS = ../src/libraylib.a -lm
LDLIBS += -framework Foundation -framework AppKit -framework OpenGL -framework CoreVideo
endif
endif
@@ -668,6 +678,10 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
ifeq ($(PLATFORM_OS),WINDOWS)
del *.o *.exe /s
endif
+ ifeq ($(PLATFORM_OS),BSD)
+ find . -type f -perm -ugo+x -delete
+ rm -fv *.o
+ endif
ifeq ($(PLATFORM_OS),LINUX)
find . -type f -executable -delete
rm -fv *.o
diff --git a/examples/Makefile.Web b/examples/Makefile.Web
index f6c8b785a..7e2aaacc5 100644
--- a/examples/Makefile.Web
+++ b/examples/Makefile.Web
@@ -52,6 +52,10 @@ USE_EXTERNAL_GLFW ?= FALSE
# NOTE: This variable is only used for PLATFORM_OS: LINUX
USE_WAYLAND_DISPLAY ?= FALSE
+# Use WebGL2 backend (OpenGL 3.0)
+# WARNING: Requires raylib compiled with GRAPHICS_API_OPENGL_ES3
+USE_WEBGL2 ?= FALSE
+
# Determine PLATFORM_OS in case PLATFORM_DESKTOP or PLATFORM_WEB selected
ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_DESKTOP PLATFORM_WEB))
# No uname.exe on MinGW!, but OS=Windows_NT on Windows!
@@ -110,8 +114,8 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
EMSDK_PATH ?= C:/emsdk
EMSCRIPTEN_PATH ?= $(EMSDK_PATH)/upstream/emscripten
CLANG_PATH = $(EMSDK_PATH)/upstream/bin
- PYTHON_PATH = $(EMSDK_PATH)/python/3.9.2-1_64bit
- NODE_PATH = $(EMSDK_PATH)/node/14.15.5_64bit/bin
+ PYTHON_PATH = $(EMSDK_PATH)/python/3.9.2-nuget_64bit
+ NODE_PATH = $(EMSDK_PATH)/node/20.18.0_64bit/bin
export PATH = $(EMSDK_PATH);$(EMSCRIPTEN_PATH);$(CLANG_PATH);$(NODE_PATH);$(PYTHON_PATH):$$(PATH)
endif
endif
@@ -139,7 +143,7 @@ endif
# Define default make program: MAKE
#------------------------------------------------------------------------------------------------
-MAKE ?= emmake make
+MAKE ?= make
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),WINDOWS)
@@ -149,8 +153,17 @@ endif
ifeq ($(PLATFORM),PLATFORM_ANDROID)
MAKE = mingw32-make
endif
-ifeq ($(PLATFORM),PLATFORM_WEB)
- MAKE = emmake make
+ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
+ ifeq ($(OS),Windows_NT)
+ MAKE = mingw32-make
+ else
+ EMMAKE != type emmake
+ ifneq (, $(EMMAKE))
+ MAKE = emmake make
+ else
+ MAKE = mingw32-make
+ endif
+ endif
endif
# Define compiler flags: CFLAGS
@@ -261,6 +274,12 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
# --source-map-base # allow debugging in browser with source map
LDFLAGS += -sUSE_GLFW=3 -sASYNCIFY -sEXPORTED_RUNTIME_METHODS=ccall
+ # NOTE: Flags required for WebGL 2.0 (OpenGL ES 3.0)
+ # WARNING: Requires raylib compiled with GRAPHICS_API_OPENGL_ES3
+ ifeq ($(USE_WEBGL2),TRUE)
+ LDFLAGS += -sMIN_WEBGL_VERSION=2 -sMAX_WEBGL_VERSION=2
+ endif
+
# NOTE: Simple raylib examples are compiled to be interpreter with asyncify, that way,
# we can compile same code for ALL platforms with no change required, but, working on bigger
# projects, code needs to be refactored to avoid a blocking while() loop, moving Update and Draw
@@ -434,6 +453,7 @@ TEXT = \
MODELS = \
models/models_animation \
+ models/models_gpu_skinning \
models/models_billboard \
models/models_box_collisions \
models/models_cubicmap \
@@ -540,10 +560,10 @@ core/core_3d_camera_split_screen: core/core_3d_camera_split_screen.c
core/core_3d_picking: core/core_3d_picking.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
-
+
core/core_automation_events : core/core_automation_events.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
-
+
core/core_basic_window: core/core_basic_window.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
@@ -642,7 +662,7 @@ shapes/shapes_draw_circle_sector: shapes/shapes_draw_circle_sector.c
shapes/shapes_draw_rectangle_rounded: shapes/shapes_draw_rectangle_rounded.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
-
+
shapes/shapes_draw_ring: shapes/shapes_draw_ring.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
@@ -712,7 +732,7 @@ textures/textures_image_drawing: textures/textures_image_drawing.c
textures/textures_image_generation: textures/textures_image_generation.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -sTOTAL_MEMORY=67108864
-
+
textures/textures_image_kernel: textures/textures_image_kernel.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file textures/resources/cat.png@resources/cat.png
@@ -788,7 +808,7 @@ textures/textures_to_image: textures/textures_to_image.c
text/text_codepoints_loading: text/text_codepoints_loading.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file text/resources/DotGothic16-Regular.ttf@resources/DotGothic16-Regular.ttf
-
+
text/text_draw_3d: text/text_draw_3d.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file text/resources/shaders/glsl100/alpha_discard.fs@resources/shaders/glsl100/alpha_discard.fs
@@ -854,6 +874,12 @@ models/models_animation: models/models_animation.c
--preload-file models/resources/models/iqm/guytex.png@resources/models/iqm/guytex.png \
--preload-file models/resources/models/iqm/guyanim.iqm@resources/models/iqm/guyanim.iqm
+models/models_gpu_skinning: models/models_gpu_skinning.c
+ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -sTOTAL_MEMORY=67108864 \
+ --preload-file models/resources/models/gltf/greenman.glb@resources/models/gltf/greenman.glb \
+ --preload-file models/resources/shaders/glsl100/skinning.vs@resources/shaders/glsl100/skinning.vs \
+ --preload-file models/resources/shaders/glsl100/skinning.fs@resources/shaders/glsl100/skinning.fs
+
models/models_billboard: models/models_billboard.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file models/resources/billboard.png@resources/billboard.png
@@ -877,7 +903,7 @@ models/models_first_person_maze: models/models_first_person_maze.c
models/models_geometric_shapes: models/models_geometric_shapes.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
-
+
models/models_heightmap: models/models_heightmap.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file models/resources/heightmap.png@resources/heightmap.png
@@ -886,7 +912,7 @@ models/models_loading: models/models_loading.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -sTOTAL_MEMORY=67108864 \
--preload-file models/resources/models/obj/castle.obj@resources/models/obj/castle.obj \
--preload-file models/resources/models/obj/castle_diffuse.png@resources/models/obj/castle_diffuse.png
-
+
models/models_loading_gltf: models/models_loading_gltf.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -sTOTAL_MEMORY=67108864 \
--preload-file models/resources/models/gltf/robot.glb@resources/models/gltf/robot.glb
@@ -894,12 +920,12 @@ models/models_loading_gltf: models/models_loading_gltf.c
models/models_loading_m3d: models/models_loading_m3d.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -sTOTAL_MEMORY=67108864 \
--preload-file models/resources/models/m3d/cesium_man.m3d@resources/models/m3d/cesium_man.m3d
-
+
models/models_loading_vox: models/models_loading_vox.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -sTOTAL_MEMORY=67108864 \
--preload-file models/resources/models/vox/chr_knight.vox@resources/models/vox/chr_knight.vox \
--preload-file models/resources/models/vox/chr_sword.vox@resources/models/vox/chr_sword.vox \
- --preload-file models/resources/models/vox/monu9.vox@resources/models/vox/monu9.vox
+ --preload-file models/resources/models/vox/monu9.vox@resources/models/vox/monu9.vox
models/models_mesh_generation: models/models_mesh_generation.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
@@ -925,7 +951,7 @@ models/models_skybox: models/models_skybox.c
models/models_waving_cubes: models/models_waving_cubes.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
-
+
models/models_yaw_pitch_roll: models/models_yaw_pitch_roll.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -sTOTAL_MEMORY=67108864 \
--preload-file models/resources/models/obj/plane.obj@resources/models/obj/plane.obj \
@@ -1058,7 +1084,7 @@ audio/audio_mixed_processor: audio/audio_mixed_processor.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -sTOTAL_MEMORY=67108864 \
--preload-file audio/resources/country.mp3@resources/country.mp3 \
--preload-file audio/resources/coin.wav@resources/coin.wav
-
+
audio/audio_module_playing: audio/audio_module_playing.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file audio/resources/mini1111.xm@resources/mini1111.xm
diff --git a/examples/core/core_input_gamepad.c b/examples/core/core_input_gamepad.c
index 656f7c244..538e1c389 100644
--- a/examples/core/core_input_gamepad.c
+++ b/examples/core/core_input_gamepad.c
@@ -20,9 +20,9 @@
#include "raylib.h"
// NOTE: Gamepad name ID depends on drivers and OS
-#define XBOX360_LEGACY_NAME_ID "Xbox Controller"
-#define XBOX360_NAME_ID "Xbox 360 Controller"
-#define PS3_NAME_ID "Sony PLAYSTATION(R)3 Controller"
+#define XBOX_ALIAS_1 "xbox"
+#define XBOX_ALIAS_2 "x-box"
+#define PS_ALIAS "playstation"
//------------------------------------------------------------------------------------
// Program main entry point
@@ -41,6 +41,14 @@ int main(void)
Texture2D texPs3Pad = LoadTexture("resources/ps3.png");
Texture2D texXboxPad = LoadTexture("resources/xbox.png");
+ // Set axis deadzones
+ const float leftStickDeadzoneX = 0.1f;
+ const float leftStickDeadzoneY = 0.1f;
+ const float rightStickDeadzoneX = 0.1f;
+ const float rightStickDeadzoneY = 0.1f;
+ const float leftTriggerDeadzone = -0.9f;
+ const float rightTriggerDeadzone = -0.9f;
+
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
@@ -67,7 +75,23 @@ int main(void)
{
DrawText(TextFormat("GP%d: %s", gamepad, GetGamepadName(gamepad)), 10, 10, 10, BLACK);
- if (TextIsEqual(GetGamepadName(gamepad), XBOX360_LEGACY_NAME_ID) || TextIsEqual(GetGamepadName(gamepad), XBOX360_NAME_ID))
+ // Get axis values
+ float leftStickX = GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_LEFT_X);
+ float leftStickY = GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_LEFT_Y);
+ float rightStickX = GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_RIGHT_X);
+ float rightStickY = GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_RIGHT_Y);
+ float leftTrigger = GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_LEFT_TRIGGER);
+ float rightTrigger = GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_RIGHT_TRIGGER);
+
+ // Calculate deadzones
+ if (leftStickX > -leftStickDeadzoneX && leftStickX < leftStickDeadzoneX) leftStickX = 0.0f;
+ if (leftStickY > -leftStickDeadzoneY && leftStickY < leftStickDeadzoneY) leftStickY = 0.0f;
+ if (rightStickX > -rightStickDeadzoneX && rightStickX < rightStickDeadzoneX) rightStickX = 0.0f;
+ if (rightStickY > -rightStickDeadzoneY && rightStickY < rightStickDeadzoneY) rightStickY = 0.0f;
+ if (leftTrigger < leftTriggerDeadzone) leftTrigger = -1.0f;
+ if (rightTrigger < rightTriggerDeadzone) rightTrigger = -1.0f;
+
+ if (TextFindIndex(TextToLower(GetGamepadName(gamepad)), XBOX_ALIAS_1) > -1 || TextFindIndex(TextToLower(GetGamepadName(gamepad)), XBOX_ALIAS_2) > -1)
{
DrawTexture(texXboxPad, 0, 0, DARKGRAY);
@@ -95,32 +119,31 @@ int main(void)
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_TRIGGER_1)) DrawCircle(536, 61, 20, RED);
// Draw axis: left joystick
-
Color leftGamepadColor = BLACK;
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_THUMB)) leftGamepadColor = RED;
DrawCircle(259, 152, 39, BLACK);
DrawCircle(259, 152, 34, LIGHTGRAY);
- DrawCircle(259 + (int)(GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_LEFT_X)*20),
- 152 + (int)(GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_LEFT_Y)*20), 25, leftGamepadColor);
+ DrawCircle(259 + (int)(leftStickX*20),
+ 152 + (int)(leftStickY*20), 25, leftGamepadColor);
// Draw axis: right joystick
Color rightGamepadColor = BLACK;
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_THUMB)) rightGamepadColor = RED;
DrawCircle(461, 237, 38, BLACK);
DrawCircle(461, 237, 33, LIGHTGRAY);
- DrawCircle(461 + (int)(GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_RIGHT_X)*20),
- 237 + (int)(GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_RIGHT_Y)*20), 25, rightGamepadColor);
+ DrawCircle(461 + (int)(rightStickX*20),
+ 237 + (int)(rightStickY*20), 25, rightGamepadColor);
// Draw axis: left-right triggers
DrawRectangle(170, 30, 15, 70, GRAY);
DrawRectangle(604, 30, 15, 70, GRAY);
- DrawRectangle(170, 30, 15, (int)(((1 + GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_LEFT_TRIGGER))/2)*70), RED);
- DrawRectangle(604, 30, 15, (int)(((1 + GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_RIGHT_TRIGGER))/2)*70), RED);
+ DrawRectangle(170, 30, 15, (int)(((1 + leftTrigger)/2)*70), RED);
+ DrawRectangle(604, 30, 15, (int)(((1 + rightTrigger)/2)*70), RED);
//DrawText(TextFormat("Xbox axis LT: %02.02f", GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_LEFT_TRIGGER)), 10, 40, 10, BLACK);
//DrawText(TextFormat("Xbox axis RT: %02.02f", GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_RIGHT_TRIGGER)), 10, 60, 10, BLACK);
}
- else if (TextIsEqual(GetGamepadName(gamepad), PS3_NAME_ID))
+ else if (TextFindIndex(TextToLower(GetGamepadName(gamepad)), PS_ALIAS) > -1)
{
DrawTexture(texPs3Pad, 0, 0, DARKGRAY);
@@ -150,30 +173,85 @@ int main(void)
// Draw axis: left joystick
Color leftGamepadColor = BLACK;
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_THUMB)) leftGamepadColor = RED;
- DrawCircle(319, 255, 35, leftGamepadColor);
+ DrawCircle(319, 255, 35, BLACK);
DrawCircle(319, 255, 31, LIGHTGRAY);
- DrawCircle(319 + (int)(GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_LEFT_X) * 20),
- 255 + (int)(GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_LEFT_Y) * 20), 25, leftGamepadColor);
+ DrawCircle(319 + (int)(leftStickX*20),
+ 255 + (int)(leftStickY*20), 25, leftGamepadColor);
// Draw axis: right joystick
Color rightGamepadColor = BLACK;
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_THUMB)) rightGamepadColor = RED;
DrawCircle(475, 255, 35, BLACK);
DrawCircle(475, 255, 31, LIGHTGRAY);
- DrawCircle(475 + (int)(GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_RIGHT_X) * 20),
- 255 + (int)(GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_RIGHT_Y) * 20), 25, rightGamepadColor);
+ DrawCircle(475 + (int)(rightStickX*20),
+ 255 + (int)(rightStickY*20), 25, rightGamepadColor);
// Draw axis: left-right triggers
DrawRectangle(169, 48, 15, 70, GRAY);
DrawRectangle(611, 48, 15, 70, GRAY);
- DrawRectangle(169, 48, 15, (int)(((1 - GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_LEFT_TRIGGER)) / 2) * 70), RED);
- DrawRectangle(611, 48, 15, (int)(((1 - GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_RIGHT_TRIGGER)) / 2) * 70), RED);
+ DrawRectangle(169, 48, 15, (int)(((1 + leftTrigger)/2)*70), RED);
+ DrawRectangle(611, 48, 15, (int)(((1 + rightTrigger)/2)*70), RED);
}
else
{
- DrawText("- GENERIC GAMEPAD -", 280, 180, 20, GRAY);
- // TODO: Draw generic gamepad
+ // Draw background: generic
+ DrawRectangleRounded((Rectangle){ 175, 110, 460, 220}, 0.3f, 0.0f, DARKGRAY);
+
+ // Draw buttons: basic
+ DrawCircle(365, 170, 12, RAYWHITE);
+ DrawCircle(405, 170, 12, RAYWHITE);
+ DrawCircle(445, 170, 12, RAYWHITE);
+ DrawCircle(516, 191, 17, RAYWHITE);
+ DrawCircle(551, 227, 17, RAYWHITE);
+ DrawCircle(587, 191, 17, RAYWHITE);
+ DrawCircle(551, 155, 17, RAYWHITE);
+ if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_MIDDLE_LEFT)) DrawCircle(365, 170, 10, RED);
+ if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_MIDDLE)) DrawCircle(405, 170, 10, GREEN);
+ if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_MIDDLE_RIGHT)) DrawCircle(445, 170, 10, BLUE);
+ if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_FACE_LEFT)) DrawCircle(516, 191, 15, GOLD);
+ if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_FACE_DOWN)) DrawCircle(551, 227, 15, BLUE);
+ if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_FACE_RIGHT)) DrawCircle(587, 191, 15, GREEN);
+ if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_FACE_UP)) DrawCircle(551, 155, 15, RED);
+
+ // Draw buttons: d-pad
+ DrawRectangle(245, 145, 28, 88, RAYWHITE);
+ DrawRectangle(215, 174, 88, 29, RAYWHITE);
+ DrawRectangle(247, 147, 24, 84, BLACK);
+ DrawRectangle(217, 176, 84, 25, BLACK);
+ if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_FACE_UP)) DrawRectangle(247, 147, 24, 29, RED);
+ if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_FACE_DOWN)) DrawRectangle(247, 147 + 54, 24, 30, RED);
+ if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_FACE_LEFT)) DrawRectangle(217, 176, 30, 25, RED);
+ if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_FACE_RIGHT)) DrawRectangle(217 + 54, 176, 30, 25, RED);
+
+ // Draw buttons: left-right back
+ DrawRectangleRounded((Rectangle){ 215, 98, 100, 10}, 0.5f, 0.0f, DARKGRAY);
+ DrawRectangleRounded((Rectangle){ 495, 98, 100, 10}, 0.5f, 0.0f, DARKGRAY);
+ if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_TRIGGER_1)) DrawRectangleRounded((Rectangle){ 215, 98, 100, 10}, 0.5f, 0.0f, RED);
+ if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_TRIGGER_1)) DrawRectangleRounded((Rectangle){ 495, 98, 100, 10}, 0.5f, 0.0f, RED);
+
+ // Draw axis: left joystick
+ Color leftGamepadColor = BLACK;
+ if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_THUMB)) leftGamepadColor = RED;
+ DrawCircle(345, 260, 40, BLACK);
+ DrawCircle(345, 260, 35, LIGHTGRAY);
+ DrawCircle(345 + (int)(leftStickX*20),
+ 260 + (int)(leftStickY*20), 25, leftGamepadColor);
+
+ // Draw axis: right joystick
+ Color rightGamepadColor = BLACK;
+ if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_THUMB)) rightGamepadColor = RED;
+ DrawCircle(465, 260, 40, BLACK);
+ DrawCircle(465, 260, 35, LIGHTGRAY);
+ DrawCircle(465 + (int)(rightStickX*20),
+ 260 + (int)(rightStickY*20), 25, rightGamepadColor);
+
+ // Draw axis: left-right triggers
+ DrawRectangle(151, 110, 15, 70, GRAY);
+ DrawRectangle(644, 110, 15, 70, GRAY);
+ DrawRectangle(151, 110, 15, (int)(((1 + leftTrigger)/2)*70), RED);
+ DrawRectangle(644, 110, 15, (int)(((1 + rightTrigger)/2)*70), RED);
+
}
DrawText(TextFormat("DETECTED AXIS [%i]:", GetGamepadAxisCount(0)), 10, 50, 10, MAROON);
diff --git a/examples/core/core_input_virtual_controls.c b/examples/core/core_input_virtual_controls.c
index ae7f770aa..2d2b91e67 100644
--- a/examples/core/core_input_virtual_controls.c
+++ b/examples/core/core_input_virtual_controls.c
@@ -54,8 +54,8 @@ int main(void)
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
- // Update
- //--------------------------------------------------------------------------
+ // Update
+ //--------------------------------------------------------------------------
dpadKeydown = -1; //reset
float inputX=0;
float inputY=0;
@@ -89,10 +89,9 @@ int main(void)
case 3: playerY += 50*GetFrameTime();
default:;
};
- //--------------------------------------------------------------------------
-
- // Draw
- //--------------------------------------------------------------------------
+ //--------------------------------------------------------------------------
+ // Draw
+ //--------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
for(int i=0;i<4;i++)
@@ -103,14 +102,15 @@ int main(void)
{
//draw label
DrawText(TextSubtext(dpadLabel,i,1),
- dpadCollider[i][0]-5,
- dpadCollider[i][1]-5,16,BLACK);
+ dpadCollider[i][0]-7,
+ dpadCollider[i][1]-8,20,BLACK);
}
-
}
- DrawText("Player",playerX,playerY,16,BLACK);
+
+ DrawRectangle(playerX-4,playerY-4,75,28,RED);
+ DrawText("Player",playerX,playerY,20,WHITE);
EndDrawing();
- //--------------------------------------------------------------------------
+ //--------------------------------------------------------------------------
}
// De-Initialization
diff --git a/examples/core/core_input_virtual_controls.png b/examples/core/core_input_virtual_controls.png
index a9776e68a..cb1444598 100644
Binary files a/examples/core/core_input_virtual_controls.png and b/examples/core/core_input_virtual_controls.png differ
diff --git a/examples/models/models_gpu_skinning.c b/examples/models/models_gpu_skinning.c
index b6296c96a..7e81b0d82 100644
--- a/examples/models/models_gpu_skinning.c
+++ b/examples/models/models_gpu_skinning.c
@@ -81,6 +81,8 @@ int main(void)
// Update model animation
ModelAnimation anim = modelAnimations[animIndex];
animCurrentFrame = (animCurrentFrame + 1)%anim.frameCount;
+ characterModel.transform = MatrixTranslate(position.x, position.y, position.z);
+ UpdateModelAnimationBoneMatrices(characterModel, anim, animCurrentFrame);
//----------------------------------------------------------------------------------
// Draw
@@ -91,12 +93,11 @@ int main(void)
BeginMode3D(camera);
- // Draw character
- characterModel.transform = MatrixTranslate(position.x, position.y, position.z);
- UpdateModelAnimationBoneMatrices(characterModel, anim, animCurrentFrame);
+ // Draw character mesh, pose calculation is done in shader (GPU skinning)
DrawMesh(characterModel.meshes[0], characterModel.materials[1], characterModel.transform);
DrawGrid(10, 1.0f);
+
EndMode3D();
DrawText("Use the T/G to switch animation", 10, 10, 20, GRAY);
@@ -107,11 +108,11 @@ int main(void)
// De-Initialization
//--------------------------------------------------------------------------------------
- UnloadModelAnimations(modelAnimations, animsCount);
- UnloadModel(characterModel); // Unload character model and meshes/material
- UnloadShader(skinningShader);
+ UnloadModelAnimations(modelAnimations, animsCount); // Unload model animation
+ UnloadModel(characterModel); // Unload model and meshes/material
+ UnloadShader(skinningShader); // Unload GPU skinning shader
- CloseWindow(); // Close window and OpenGL context
+ CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
diff --git a/examples/models/models_skybox.c b/examples/models/models_skybox.c
index fc9627b42..4689acd77 100644
--- a/examples/models/models_skybox.c
+++ b/examples/models/models_skybox.c
@@ -191,7 +191,7 @@ static TextureCubemap GenTextureCubemap(Shader shader, Texture2D panorama, int s
// STEP 1: Setup framebuffer
//------------------------------------------------------------------------------------------
unsigned int rbo = rlLoadTextureDepth(size, size, true);
- cubemap.id = rlLoadTextureCubemap(0, size, format);
+ cubemap.id = rlLoadTextureCubemap(0, size, format, 1);
unsigned int fbo = rlLoadFramebuffer();
rlFramebufferAttach(fbo, rbo, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_RENDERBUFFER, 0);
diff --git a/examples/models/resources/shaders/glsl100/skinning.fs b/examples/models/resources/shaders/glsl100/skinning.fs
index ef6568036..96bcabe01 100644
--- a/examples/models/resources/shaders/glsl100/skinning.fs
+++ b/examples/models/resources/shaders/glsl100/skinning.fs
@@ -1,17 +1,20 @@
#version 100
+precision mediump float;
+
// Input vertex attributes (from vertex shader)
-in vec2 fragTexCoord;
-in vec4 fragColor;
-
-// Output fragment color
-out vec4 finalColor;
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+// Input uniform values
uniform sampler2D texture0;
uniform vec4 colDiffuse;
void main()
{
- vec4 texelColor = texture(texture0, fragTexCoord);
- finalColor = texelColor*colDiffuse*fragColor;
+ // Fetch color from texture sampler
+ vec4 texelColor = texture2D(texture0, fragTexCoord);
+
+ // Calculate final fragment color
+ gl_FragColor = texelColor*colDiffuse*fragColor;
}
diff --git a/examples/models/resources/shaders/glsl100/skinning.vs b/examples/models/resources/shaders/glsl100/skinning.vs
index 9c92e2a8c..627a7dda4 100644
--- a/examples/models/resources/shaders/glsl100/skinning.vs
+++ b/examples/models/resources/shaders/glsl100/skinning.vs
@@ -1,18 +1,21 @@
#version 100
-in vec3 vertexPosition;
-in vec2 vertexTexCoord;
-in vec4 vertexColor;
-in vec4 vertexBoneIds;
-in vec4 vertexBoneWeights;
+#define MAX_BONE_NUM 64
-#define MAX_BONE_NUM 128
+// Input vertex attributes
+attribute vec3 vertexPosition;
+attribute vec2 vertexTexCoord;
+attribute vec4 vertexColor;
+attribute vec4 vertexBoneIds;
+attribute vec4 vertexBoneWeights;
+
+// Input uniform values
+uniform mat4 mvp;
uniform mat4 boneMatrices[MAX_BONE_NUM];
-uniform mat4 mvp;
-
-out vec2 fragTexCoord;
-out vec4 fragColor;
+// Output vertex attributes (to fragment shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
void main()
{
@@ -21,14 +24,36 @@ void main()
int boneIndex2 = int(vertexBoneIds.z);
int boneIndex3 = int(vertexBoneIds.w);
+ // WARNING: OpenGL ES 2.0 does not support automatic matrix transposing, neither transpose() function
+ mat4 boneMatrixTransposed0 = mat4(
+ vec4(boneMatrices[boneIndex0][0].x, boneMatrices[boneIndex0][1].x, boneMatrices[boneIndex0][2].x, boneMatrices[boneIndex0][3].x),
+ vec4(boneMatrices[boneIndex0][0].y, boneMatrices[boneIndex0][1].y, boneMatrices[boneIndex0][2].y, boneMatrices[boneIndex0][3].y),
+ vec4(boneMatrices[boneIndex0][0].z, boneMatrices[boneIndex0][1].z, boneMatrices[boneIndex0][2].z, boneMatrices[boneIndex0][3].z),
+ vec4(boneMatrices[boneIndex0][0].w, boneMatrices[boneIndex0][1].w, boneMatrices[boneIndex0][2].w, boneMatrices[boneIndex0][3].w));
+ mat4 boneMatrixTransposed1 = mat4(
+ vec4(boneMatrices[boneIndex1][0].x, boneMatrices[boneIndex1][1].x, boneMatrices[boneIndex1][2].x, boneMatrices[boneIndex1][3].x),
+ vec4(boneMatrices[boneIndex1][0].y, boneMatrices[boneIndex1][1].y, boneMatrices[boneIndex1][2].y, boneMatrices[boneIndex1][3].y),
+ vec4(boneMatrices[boneIndex1][0].z, boneMatrices[boneIndex1][1].z, boneMatrices[boneIndex1][2].z, boneMatrices[boneIndex1][3].z),
+ vec4(boneMatrices[boneIndex1][0].w, boneMatrices[boneIndex1][1].w, boneMatrices[boneIndex1][2].w, boneMatrices[boneIndex1][3].w));
+ mat4 boneMatrixTransposed2 = mat4(
+ vec4(boneMatrices[boneIndex2][0].x, boneMatrices[boneIndex2][1].x, boneMatrices[boneIndex2][2].x, boneMatrices[boneIndex2][3].x),
+ vec4(boneMatrices[boneIndex2][0].y, boneMatrices[boneIndex2][1].y, boneMatrices[boneIndex2][2].y, boneMatrices[boneIndex2][3].y),
+ vec4(boneMatrices[boneIndex2][0].z, boneMatrices[boneIndex2][1].z, boneMatrices[boneIndex2][2].z, boneMatrices[boneIndex2][3].z),
+ vec4(boneMatrices[boneIndex2][0].w, boneMatrices[boneIndex2][1].w, boneMatrices[boneIndex2][2].w, boneMatrices[boneIndex2][3].w));
+ mat4 boneMatrixTransposed3 = mat4(
+ vec4(boneMatrices[boneIndex3][0].x, boneMatrices[boneIndex3][1].x, boneMatrices[boneIndex3][2].x, boneMatrices[boneIndex3][3].x),
+ vec4(boneMatrices[boneIndex3][0].y, boneMatrices[boneIndex3][1].y, boneMatrices[boneIndex3][2].y, boneMatrices[boneIndex3][3].y),
+ vec4(boneMatrices[boneIndex3][0].z, boneMatrices[boneIndex3][1].z, boneMatrices[boneIndex3][2].z, boneMatrices[boneIndex3][3].z),
+ vec4(boneMatrices[boneIndex3][0].w, boneMatrices[boneIndex3][1].w, boneMatrices[boneIndex3][2].w, boneMatrices[boneIndex3][3].w));
+
vec4 skinnedPosition =
- vertexBoneWeights.x * (boneMatrices[boneIndex0] * vec4(vertexPosition, 1.0f)) +
- vertexBoneWeights.y * (boneMatrices[boneIndex1] * vec4(vertexPosition, 1.0f)) +
- vertexBoneWeights.z * (boneMatrices[boneIndex2] * vec4(vertexPosition, 1.0f)) +
- vertexBoneWeights.w * (boneMatrices[boneIndex3] * vec4(vertexPosition, 1.0f));
+ vertexBoneWeights.x*(boneMatrixTransposed0*vec4(vertexPosition, 1.0)) +
+ vertexBoneWeights.y*(boneMatrixTransposed1*vec4(vertexPosition, 1.0)) +
+ vertexBoneWeights.z*(boneMatrixTransposed2*vec4(vertexPosition, 1.0)) +
+ vertexBoneWeights.w*(boneMatrixTransposed3*vec4(vertexPosition, 1.0));
fragTexCoord = vertexTexCoord;
fragColor = vertexColor;
- gl_Position = mvp * skinnedPosition;
+ gl_Position = mvp*skinnedPosition;
}
\ No newline at end of file
diff --git a/examples/models/resources/shaders/glsl330/skinning.vs b/examples/models/resources/shaders/glsl330/skinning.vs
index 2dc976c48..73ecca51e 100644
--- a/examples/models/resources/shaders/glsl330/skinning.vs
+++ b/examples/models/resources/shaders/glsl330/skinning.vs
@@ -1,16 +1,19 @@
#version 330
+#define MAX_BONE_NUM 128
+
+// Input vertex attributes
in vec3 vertexPosition;
in vec2 vertexTexCoord;
in vec4 vertexColor;
in vec4 vertexBoneIds;
in vec4 vertexBoneWeights;
-#define MAX_BONE_NUM 128
+// Input uniform values
+uniform mat4 mvp;
uniform mat4 boneMatrices[MAX_BONE_NUM];
-uniform mat4 mvp;
-
+// Output vertex attributes (to fragment shader)
out vec2 fragTexCoord;
out vec4 fragColor;
@@ -22,13 +25,13 @@ void main()
int boneIndex3 = int(vertexBoneIds.w);
vec4 skinnedPosition =
- vertexBoneWeights.x * (boneMatrices[boneIndex0] * vec4(vertexPosition, 1.0f)) +
- vertexBoneWeights.y * (boneMatrices[boneIndex1] * vec4(vertexPosition, 1.0f)) +
- vertexBoneWeights.z * (boneMatrices[boneIndex2] * vec4(vertexPosition, 1.0f)) +
- vertexBoneWeights.w * (boneMatrices[boneIndex3] * vec4(vertexPosition, 1.0f));
+ vertexBoneWeights.x*(boneMatrices[boneIndex0]*vec4(vertexPosition, 1.0)) +
+ vertexBoneWeights.y*(boneMatrices[boneIndex1]*vec4(vertexPosition, 1.0)) +
+ vertexBoneWeights.z*(boneMatrices[boneIndex2]*vec4(vertexPosition, 1.0)) +
+ vertexBoneWeights.w*(boneMatrices[boneIndex3]*vec4(vertexPosition, 1.0));
fragTexCoord = vertexTexCoord;
fragColor = vertexColor;
- gl_Position = mvp * skinnedPosition;
+ gl_Position = mvp*skinnedPosition;
}
\ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl330/base.fs b/examples/shaders/resources/shaders/glsl330/base.fs
index 6b5006224..813f32b1d 100644
--- a/examples/shaders/resources/shaders/glsl330/base.fs
+++ b/examples/shaders/resources/shaders/glsl330/base.fs
@@ -20,6 +20,9 @@ void main()
// NOTE: Implement here your fragment shader code
- finalColor = texelColor*colDiffuse;
+ // final color is the color from the texture
+ // times the tint color (colDiffuse)
+ // times the fragment color (interpolated vertex color)
+ finalColor = texelColor*colDiffuse*fragColor;
}
diff --git a/examples/shaders/shaders_model_shader.c b/examples/shaders/shaders_model_shader.c
index bf2c112be..9faa2d589 100644
--- a/examples/shaders/shaders_model_shader.c
+++ b/examples/shaders/shaders_model_shader.c
@@ -69,7 +69,7 @@ int main(void)
{
// Update
//----------------------------------------------------------------------------------
- UpdateCamera(&camera, CAMERA_FIRST_PERSON);
+ UpdateCamera(&camera, CAMERA_FREE);
//----------------------------------------------------------------------------------
// Draw
diff --git a/parser/output/raylib_api.json b/parser/output/raylib_api.json
index 591fef737..37b0a16a6 100644
--- a/parser/output/raylib_api.json
+++ b/parser/output/raylib_api.json
@@ -27,7 +27,7 @@
{
"name": "RAYLIB_VERSION",
"type": "STRING",
- "value": "5.5-dev",
+ "value": "5.5",
"description": ""
},
{
@@ -2839,11 +2839,6 @@
"name": "CUBEMAP_LAYOUT_CROSS_FOUR_BY_THREE",
"value": 4,
"description": "Layout is defined by a 4x3 cross with cubemap faces"
- },
- {
- "name": "CUBEMAP_LAYOUT_PANORAMA",
- "value": 5,
- "description": "Layout is defined by a panorama image (equirrectangular map)"
}
]
},
@@ -3182,22 +3177,22 @@
},
{
"name": "IsWindowHidden",
- "description": "Check if window is currently hidden (only PLATFORM_DESKTOP)",
+ "description": "Check if window is currently hidden",
"returnType": "bool"
},
{
"name": "IsWindowMinimized",
- "description": "Check if window is currently minimized (only PLATFORM_DESKTOP)",
+ "description": "Check if window is currently minimized",
"returnType": "bool"
},
{
"name": "IsWindowMaximized",
- "description": "Check if window is currently maximized (only PLATFORM_DESKTOP)",
+ "description": "Check if window is currently maximized",
"returnType": "bool"
},
{
"name": "IsWindowFocused",
- "description": "Check if window is currently focused (only PLATFORM_DESKTOP)",
+ "description": "Check if window is currently focused",
"returnType": "bool"
},
{
@@ -3218,7 +3213,7 @@
},
{
"name": "SetWindowState",
- "description": "Set window configuration state using flags (only PLATFORM_DESKTOP)",
+ "description": "Set window configuration state using flags",
"returnType": "void",
"params": [
{
@@ -3240,32 +3235,32 @@
},
{
"name": "ToggleFullscreen",
- "description": "Toggle window state: fullscreen/windowed [resizes monitor to match window resolution] (only PLATFORM_DESKTOP)",
+ "description": "Toggle window state: fullscreen/windowed, resizes monitor to match window resolution",
"returnType": "void"
},
{
"name": "ToggleBorderlessWindowed",
- "description": "Toggle window state: borderless windowed [resizes window to match monitor resolution] (only PLATFORM_DESKTOP)",
+ "description": "Toggle window state: borderless windowed, resizes window to match monitor resolution",
"returnType": "void"
},
{
"name": "MaximizeWindow",
- "description": "Set window state: maximized, if resizable (only PLATFORM_DESKTOP)",
+ "description": "Set window state: maximized, if resizable",
"returnType": "void"
},
{
"name": "MinimizeWindow",
- "description": "Set window state: minimized, if resizable (only PLATFORM_DESKTOP)",
+ "description": "Set window state: minimized, if resizable",
"returnType": "void"
},
{
"name": "RestoreWindow",
- "description": "Set window state: not minimized/maximized (only PLATFORM_DESKTOP)",
+ "description": "Set window state: not minimized/maximized",
"returnType": "void"
},
{
"name": "SetWindowIcon",
- "description": "Set icon for window (single image, RGBA 32bit, only PLATFORM_DESKTOP)",
+ "description": "Set icon for window (single image, RGBA 32bit)",
"returnType": "void",
"params": [
{
@@ -3276,7 +3271,7 @@
},
{
"name": "SetWindowIcons",
- "description": "Set icon for window (multiple images, RGBA 32bit, only PLATFORM_DESKTOP)",
+ "description": "Set icon for window (multiple images, RGBA 32bit)",
"returnType": "void",
"params": [
{
@@ -3291,7 +3286,7 @@
},
{
"name": "SetWindowTitle",
- "description": "Set title for window (only PLATFORM_DESKTOP and PLATFORM_WEB)",
+ "description": "Set title for window",
"returnType": "void",
"params": [
{
@@ -3302,7 +3297,7 @@
},
{
"name": "SetWindowPosition",
- "description": "Set window position on screen (only PLATFORM_DESKTOP)",
+ "description": "Set window position on screen",
"returnType": "void",
"params": [
{
@@ -3373,7 +3368,7 @@
},
{
"name": "SetWindowOpacity",
- "description": "Set window opacity [0.0f..1.0f] (only PLATFORM_DESKTOP)",
+ "description": "Set window opacity [0.0f..1.0f]",
"returnType": "void",
"params": [
{
@@ -3384,7 +3379,7 @@
},
{
"name": "SetWindowFocused",
- "description": "Set window focused (only PLATFORM_DESKTOP)",
+ "description": "Set window focused",
"returnType": "void"
},
{
@@ -3419,7 +3414,7 @@
},
{
"name": "GetCurrentMonitor",
- "description": "Get current connected monitor",
+ "description": "Get current monitor where window is placed",
"returnType": "int"
},
{
@@ -4829,7 +4824,7 @@
},
{
"name": "IsKeyPressedRepeat",
- "description": "Check if a key has been pressed again (Only PLATFORM_DESKTOP)",
+ "description": "Check if a key has been pressed again",
"returnType": "bool",
"params": [
{
@@ -5018,7 +5013,7 @@
},
{
"name": "SetGamepadVibration",
- "description": "Set gamepad vibration for both motors",
+ "description": "Set gamepad vibration for both motors (duration in seconds)",
"returnType": "void",
"params": [
{
@@ -5032,6 +5027,10 @@
{
"type": "float",
"name": "rightMotor"
+ },
+ {
+ "type": "float",
+ "name": "duration"
}
]
},
@@ -6658,6 +6657,29 @@
}
]
},
+ {
+ "name": "CheckCollisionCircleLine",
+ "description": "Check if circle collides with a line created betweeen two points [p1] and [p2]",
+ "returnType": "bool",
+ "params": [
+ {
+ "type": "Vector2",
+ "name": "center"
+ },
+ {
+ "type": "float",
+ "name": "radius"
+ },
+ {
+ "type": "Vector2",
+ "name": "p1"
+ },
+ {
+ "type": "Vector2",
+ "name": "p2"
+ }
+ ]
+ },
{
"name": "CheckCollisionPointRec",
"description": "Check if point is inside rectangle",
@@ -6715,6 +6737,29 @@
}
]
},
+ {
+ "name": "CheckCollisionPointLine",
+ "description": "Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold]",
+ "returnType": "bool",
+ "params": [
+ {
+ "type": "Vector2",
+ "name": "point"
+ },
+ {
+ "type": "Vector2",
+ "name": "p1"
+ },
+ {
+ "type": "Vector2",
+ "name": "p2"
+ },
+ {
+ "type": "int",
+ "name": "threshold"
+ }
+ ]
+ },
{
"name": "CheckCollisionPointPoly",
"description": "Check if point is within a polygon described by array of vertices",
@@ -6761,52 +6806,6 @@
}
]
},
- {
- "name": "CheckCollisionPointLine",
- "description": "Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold]",
- "returnType": "bool",
- "params": [
- {
- "type": "Vector2",
- "name": "point"
- },
- {
- "type": "Vector2",
- "name": "p1"
- },
- {
- "type": "Vector2",
- "name": "p2"
- },
- {
- "type": "int",
- "name": "threshold"
- }
- ]
- },
- {
- "name": "CheckCollisionCircleLine",
- "description": "Check if circle collides with a line created betweeen two points [p1] and [p2]",
- "returnType": "bool",
- "params": [
- {
- "type": "Vector2",
- "name": "center"
- },
- {
- "type": "float",
- "name": "radius"
- },
- {
- "type": "Vector2",
- "name": "p1"
- },
- {
- "type": "Vector2",
- "name": "p2"
- }
- ]
- },
{
"name": "GetCollisionRec",
"description": "Get collision rectangle for two rectangles collision",
@@ -11070,7 +11069,26 @@
},
{
"name": "UpdateModelAnimation",
- "description": "Update model animation pose",
+ "description": "Update model animation pose (CPU)",
+ "returnType": "void",
+ "params": [
+ {
+ "type": "Model",
+ "name": "model"
+ },
+ {
+ "type": "ModelAnimation",
+ "name": "anim"
+ },
+ {
+ "type": "int",
+ "name": "frame"
+ }
+ ]
+ },
+ {
+ "name": "UpdateModelAnimationBoneMatrices",
+ "description": "Update model animation mesh bone matrices (GPU skinning)",
"returnType": "void",
"params": [
{
@@ -11128,25 +11146,6 @@
}
]
},
- {
- "name": "UpdateModelAnimationBoneMatrices",
- "description": "Update model animation mesh bone matrices (Note GPU skinning does not work on Mac)",
- "returnType": "void",
- "params": [
- {
- "type": "Model",
- "name": "model"
- },
- {
- "type": "ModelAnimation",
- "name": "anim"
- },
- {
- "type": "int",
- "name": "frame"
- }
- ]
- },
{
"name": "CheckCollisionSpheres",
"description": "Check collision between two spheres",
diff --git a/parser/output/raylib_api.lua b/parser/output/raylib_api.lua
index b84e3c08c..934c08eb7 100644
--- a/parser/output/raylib_api.lua
+++ b/parser/output/raylib_api.lua
@@ -27,7 +27,7 @@ return {
{
name = "RAYLIB_VERSION",
type = "STRING",
- value = "5.5-dev",
+ value = "5.5",
description = ""
},
{
@@ -2839,11 +2839,6 @@ return {
name = "CUBEMAP_LAYOUT_CROSS_FOUR_BY_THREE",
value = 4,
description = "Layout is defined by a 4x3 cross with cubemap faces"
- },
- {
- name = "CUBEMAP_LAYOUT_PANORAMA",
- value = 5,
- description = "Layout is defined by a panorama image (equirrectangular map)"
}
}
},
@@ -3134,22 +3129,22 @@ return {
},
{
name = "IsWindowHidden",
- description = "Check if window is currently hidden (only PLATFORM_DESKTOP)",
+ description = "Check if window is currently hidden",
returnType = "bool"
},
{
name = "IsWindowMinimized",
- description = "Check if window is currently minimized (only PLATFORM_DESKTOP)",
+ description = "Check if window is currently minimized",
returnType = "bool"
},
{
name = "IsWindowMaximized",
- description = "Check if window is currently maximized (only PLATFORM_DESKTOP)",
+ description = "Check if window is currently maximized",
returnType = "bool"
},
{
name = "IsWindowFocused",
- description = "Check if window is currently focused (only PLATFORM_DESKTOP)",
+ description = "Check if window is currently focused",
returnType = "bool"
},
{
@@ -3167,7 +3162,7 @@ return {
},
{
name = "SetWindowState",
- description = "Set window configuration state using flags (only PLATFORM_DESKTOP)",
+ description = "Set window configuration state using flags",
returnType = "void",
params = {
{type = "unsigned int", name = "flags"}
@@ -3183,32 +3178,32 @@ return {
},
{
name = "ToggleFullscreen",
- description = "Toggle window state: fullscreen/windowed [resizes monitor to match window resolution] (only PLATFORM_DESKTOP)",
+ description = "Toggle window state: fullscreen/windowed, resizes monitor to match window resolution",
returnType = "void"
},
{
name = "ToggleBorderlessWindowed",
- description = "Toggle window state: borderless windowed [resizes window to match monitor resolution] (only PLATFORM_DESKTOP)",
+ description = "Toggle window state: borderless windowed, resizes window to match monitor resolution",
returnType = "void"
},
{
name = "MaximizeWindow",
- description = "Set window state: maximized, if resizable (only PLATFORM_DESKTOP)",
+ description = "Set window state: maximized, if resizable",
returnType = "void"
},
{
name = "MinimizeWindow",
- description = "Set window state: minimized, if resizable (only PLATFORM_DESKTOP)",
+ description = "Set window state: minimized, if resizable",
returnType = "void"
},
{
name = "RestoreWindow",
- description = "Set window state: not minimized/maximized (only PLATFORM_DESKTOP)",
+ description = "Set window state: not minimized/maximized",
returnType = "void"
},
{
name = "SetWindowIcon",
- description = "Set icon for window (single image, RGBA 32bit, only PLATFORM_DESKTOP)",
+ description = "Set icon for window (single image, RGBA 32bit)",
returnType = "void",
params = {
{type = "Image", name = "image"}
@@ -3216,7 +3211,7 @@ return {
},
{
name = "SetWindowIcons",
- description = "Set icon for window (multiple images, RGBA 32bit, only PLATFORM_DESKTOP)",
+ description = "Set icon for window (multiple images, RGBA 32bit)",
returnType = "void",
params = {
{type = "Image *", name = "images"},
@@ -3225,7 +3220,7 @@ return {
},
{
name = "SetWindowTitle",
- description = "Set title for window (only PLATFORM_DESKTOP and PLATFORM_WEB)",
+ description = "Set title for window",
returnType = "void",
params = {
{type = "const char *", name = "title"}
@@ -3233,7 +3228,7 @@ return {
},
{
name = "SetWindowPosition",
- description = "Set window position on screen (only PLATFORM_DESKTOP)",
+ description = "Set window position on screen",
returnType = "void",
params = {
{type = "int", name = "x"},
@@ -3277,7 +3272,7 @@ return {
},
{
name = "SetWindowOpacity",
- description = "Set window opacity [0.0f..1.0f] (only PLATFORM_DESKTOP)",
+ description = "Set window opacity [0.0f..1.0f]",
returnType = "void",
params = {
{type = "float", name = "opacity"}
@@ -3285,7 +3280,7 @@ return {
},
{
name = "SetWindowFocused",
- description = "Set window focused (only PLATFORM_DESKTOP)",
+ description = "Set window focused",
returnType = "void"
},
{
@@ -3320,7 +3315,7 @@ return {
},
{
name = "GetCurrentMonitor",
- description = "Get current connected monitor",
+ description = "Get current monitor where window is placed",
returnType = "int"
},
{
@@ -4286,7 +4281,7 @@ return {
},
{
name = "IsKeyPressedRepeat",
- description = "Check if a key has been pressed again (Only PLATFORM_DESKTOP)",
+ description = "Check if a key has been pressed again",
returnType = "bool",
params = {
{type = "int", name = "key"}
@@ -4418,12 +4413,13 @@ return {
},
{
name = "SetGamepadVibration",
- description = "Set gamepad vibration for both motors",
+ description = "Set gamepad vibration for both motors (duration in seconds)",
returnType = "void",
params = {
{type = "int", name = "gamepad"},
{type = "float", name = "leftMotor"},
- {type = "float", name = "rightMotor"}
+ {type = "float", name = "rightMotor"},
+ {type = "float", name = "duration"}
}
},
{
@@ -5263,6 +5259,17 @@ return {
{type = "Rectangle", name = "rec"}
}
},
+ {
+ name = "CheckCollisionCircleLine",
+ description = "Check if circle collides with a line created betweeen two points [p1] and [p2]",
+ returnType = "bool",
+ params = {
+ {type = "Vector2", name = "center"},
+ {type = "float", name = "radius"},
+ {type = "Vector2", name = "p1"},
+ {type = "Vector2", name = "p2"}
+ }
+ },
{
name = "CheckCollisionPointRec",
description = "Check if point is inside rectangle",
@@ -5293,6 +5300,17 @@ return {
{type = "Vector2", name = "p3"}
}
},
+ {
+ name = "CheckCollisionPointLine",
+ description = "Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold]",
+ returnType = "bool",
+ params = {
+ {type = "Vector2", name = "point"},
+ {type = "Vector2", name = "p1"},
+ {type = "Vector2", name = "p2"},
+ {type = "int", name = "threshold"}
+ }
+ },
{
name = "CheckCollisionPointPoly",
description = "Check if point is within a polygon described by array of vertices",
@@ -5315,28 +5333,6 @@ return {
{type = "Vector2 *", name = "collisionPoint"}
}
},
- {
- name = "CheckCollisionPointLine",
- description = "Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold]",
- returnType = "bool",
- params = {
- {type = "Vector2", name = "point"},
- {type = "Vector2", name = "p1"},
- {type = "Vector2", name = "p2"},
- {type = "int", name = "threshold"}
- }
- },
- {
- name = "CheckCollisionCircleLine",
- description = "Check if circle collides with a line created betweeen two points [p1] and [p2]",
- returnType = "bool",
- params = {
- {type = "Vector2", name = "center"},
- {type = "float", name = "radius"},
- {type = "Vector2", name = "p1"},
- {type = "Vector2", name = "p2"}
- }
- },
{
name = "GetCollisionRec",
description = "Get collision rectangle for two rectangles collision",
@@ -7602,7 +7598,17 @@ return {
},
{
name = "UpdateModelAnimation",
- description = "Update model animation pose",
+ description = "Update model animation pose (CPU)",
+ returnType = "void",
+ params = {
+ {type = "Model", name = "model"},
+ {type = "ModelAnimation", name = "anim"},
+ {type = "int", name = "frame"}
+ }
+ },
+ {
+ name = "UpdateModelAnimationBoneMatrices",
+ description = "Update model animation mesh bone matrices (GPU skinning)",
returnType = "void",
params = {
{type = "Model", name = "model"},
@@ -7636,16 +7642,6 @@ return {
{type = "ModelAnimation", name = "anim"}
}
},
- {
- name = "UpdateModelAnimationBoneMatrices",
- description = "Update model animation mesh bone matrices (Note GPU skinning does not work on Mac)",
- returnType = "void",
- params = {
- {type = "Model", name = "model"},
- {type = "ModelAnimation", name = "anim"},
- {type = "int", name = "frame"}
- }
- },
{
name = "CheckCollisionSpheres",
description = "Check collision between two spheres",
diff --git a/parser/output/raylib_api.txt b/parser/output/raylib_api.txt
index e0d5f36b4..541b5caf3 100644
--- a/parser/output/raylib_api.txt
+++ b/parser/output/raylib_api.txt
@@ -24,7 +24,7 @@ Define 004: RAYLIB_VERSION_PATCH
Define 005: RAYLIB_VERSION
Name: RAYLIB_VERSION
Type: STRING
- Value: "5.5-dev"
+ Value: "5.5"
Description:
Define 006: __declspec(x)
Name: __declspec(x)
@@ -889,7 +889,7 @@ Enum 14: TextureWrap (4 values)
Value[TEXTURE_WRAP_CLAMP]: 1
Value[TEXTURE_WRAP_MIRROR_REPEAT]: 2
Value[TEXTURE_WRAP_MIRROR_CLAMP]: 3
-Enum 15: CubemapLayout (6 values)
+Enum 15: CubemapLayout (5 values)
Name: CubemapLayout
Description: Cubemap layouts
Value[CUBEMAP_LAYOUT_AUTO_DETECT]: 0
@@ -897,7 +897,6 @@ Enum 15: CubemapLayout (6 values)
Value[CUBEMAP_LAYOUT_LINE_HORIZONTAL]: 2
Value[CUBEMAP_LAYOUT_CROSS_THREE_BY_FOUR]: 3
Value[CUBEMAP_LAYOUT_CROSS_FOUR_BY_THREE]: 4
- Value[CUBEMAP_LAYOUT_PANORAMA]: 5
Enum 16: FontType (3 values)
Name: FontType
Description: Font type, defines generation method
@@ -1021,22 +1020,22 @@ Function 005: IsWindowFullscreen() (0 input parameters)
Function 006: IsWindowHidden() (0 input parameters)
Name: IsWindowHidden
Return type: bool
- Description: Check if window is currently hidden (only PLATFORM_DESKTOP)
+ Description: Check if window is currently hidden
No input parameters
Function 007: IsWindowMinimized() (0 input parameters)
Name: IsWindowMinimized
Return type: bool
- Description: Check if window is currently minimized (only PLATFORM_DESKTOP)
+ Description: Check if window is currently minimized
No input parameters
Function 008: IsWindowMaximized() (0 input parameters)
Name: IsWindowMaximized
Return type: bool
- Description: Check if window is currently maximized (only PLATFORM_DESKTOP)
+ Description: Check if window is currently maximized
No input parameters
Function 009: IsWindowFocused() (0 input parameters)
Name: IsWindowFocused
Return type: bool
- Description: Check if window is currently focused (only PLATFORM_DESKTOP)
+ Description: Check if window is currently focused
No input parameters
Function 010: IsWindowResized() (0 input parameters)
Name: IsWindowResized
@@ -1051,7 +1050,7 @@ Function 011: IsWindowState() (1 input parameters)
Function 012: SetWindowState() (1 input parameters)
Name: SetWindowState
Return type: void
- Description: Set window configuration state using flags (only PLATFORM_DESKTOP)
+ Description: Set window configuration state using flags
Param[1]: flags (type: unsigned int)
Function 013: ClearWindowState() (1 input parameters)
Name: ClearWindowState
@@ -1061,48 +1060,48 @@ Function 013: ClearWindowState() (1 input parameters)
Function 014: ToggleFullscreen() (0 input parameters)
Name: ToggleFullscreen
Return type: void
- Description: Toggle window state: fullscreen/windowed [resizes monitor to match window resolution] (only PLATFORM_DESKTOP)
+ Description: Toggle window state: fullscreen/windowed, resizes monitor to match window resolution
No input parameters
Function 015: ToggleBorderlessWindowed() (0 input parameters)
Name: ToggleBorderlessWindowed
Return type: void
- Description: Toggle window state: borderless windowed [resizes window to match monitor resolution] (only PLATFORM_DESKTOP)
+ Description: Toggle window state: borderless windowed, resizes window to match monitor resolution
No input parameters
Function 016: MaximizeWindow() (0 input parameters)
Name: MaximizeWindow
Return type: void
- Description: Set window state: maximized, if resizable (only PLATFORM_DESKTOP)
+ Description: Set window state: maximized, if resizable
No input parameters
Function 017: MinimizeWindow() (0 input parameters)
Name: MinimizeWindow
Return type: void
- Description: Set window state: minimized, if resizable (only PLATFORM_DESKTOP)
+ Description: Set window state: minimized, if resizable
No input parameters
Function 018: RestoreWindow() (0 input parameters)
Name: RestoreWindow
Return type: void
- Description: Set window state: not minimized/maximized (only PLATFORM_DESKTOP)
+ Description: Set window state: not minimized/maximized
No input parameters
Function 019: SetWindowIcon() (1 input parameters)
Name: SetWindowIcon
Return type: void
- Description: Set icon for window (single image, RGBA 32bit, only PLATFORM_DESKTOP)
+ Description: Set icon for window (single image, RGBA 32bit)
Param[1]: image (type: Image)
Function 020: SetWindowIcons() (2 input parameters)
Name: SetWindowIcons
Return type: void
- Description: Set icon for window (multiple images, RGBA 32bit, only PLATFORM_DESKTOP)
+ Description: Set icon for window (multiple images, RGBA 32bit)
Param[1]: images (type: Image *)
Param[2]: count (type: int)
Function 021: SetWindowTitle() (1 input parameters)
Name: SetWindowTitle
Return type: void
- Description: Set title for window (only PLATFORM_DESKTOP and PLATFORM_WEB)
+ Description: Set title for window
Param[1]: title (type: const char *)
Function 022: SetWindowPosition() (2 input parameters)
Name: SetWindowPosition
Return type: void
- Description: Set window position on screen (only PLATFORM_DESKTOP)
+ Description: Set window position on screen
Param[1]: x (type: int)
Param[2]: y (type: int)
Function 023: SetWindowMonitor() (1 input parameters)
@@ -1131,12 +1130,12 @@ Function 026: SetWindowSize() (2 input parameters)
Function 027: SetWindowOpacity() (1 input parameters)
Name: SetWindowOpacity
Return type: void
- Description: Set window opacity [0.0f..1.0f] (only PLATFORM_DESKTOP)
+ Description: Set window opacity [0.0f..1.0f]
Param[1]: opacity (type: float)
Function 028: SetWindowFocused() (0 input parameters)
Name: SetWindowFocused
Return type: void
- Description: Set window focused (only PLATFORM_DESKTOP)
+ Description: Set window focused
No input parameters
Function 029: GetWindowHandle() (0 input parameters)
Name: GetWindowHandle
@@ -1171,7 +1170,7 @@ Function 034: GetMonitorCount() (0 input parameters)
Function 035: GetCurrentMonitor() (0 input parameters)
Name: GetCurrentMonitor
Return type: int
- Description: Get current connected monitor
+ Description: Get current monitor where window is placed
No input parameters
Function 036: GetMonitorPosition() (1 input parameters)
Name: GetMonitorPosition
@@ -1855,7 +1854,7 @@ Function 160: IsKeyPressed() (1 input parameters)
Function 161: IsKeyPressedRepeat() (1 input parameters)
Name: IsKeyPressedRepeat
Return type: bool
- Description: Check if a key has been pressed again (Only PLATFORM_DESKTOP)
+ Description: Check if a key has been pressed again
Param[1]: key (type: int)
Function 162: IsKeyDown() (1 input parameters)
Name: IsKeyDown
@@ -1942,13 +1941,14 @@ Function 177: SetGamepadMappings() (1 input parameters)
Return type: int
Description: Set internal gamepad mappings (SDL_GameControllerDB)
Param[1]: mappings (type: const char *)
-Function 178: SetGamepadVibration() (3 input parameters)
+Function 178: SetGamepadVibration() (4 input parameters)
Name: SetGamepadVibration
Return type: void
- Description: Set gamepad vibration for both motors
+ Description: Set gamepad vibration for both motors (duration in seconds)
Param[1]: gamepad (type: int)
Param[2]: leftMotor (type: float)
Param[3]: rightMotor (type: float)
+ Param[4]: duration (type: float)
Function 179: IsMouseButtonPressed() (1 input parameters)
Name: IsMouseButtonPressed
Return type: bool
@@ -2576,20 +2576,28 @@ Function 265: CheckCollisionCircleRec() (3 input parameters)
Param[1]: center (type: Vector2)
Param[2]: radius (type: float)
Param[3]: rec (type: Rectangle)
-Function 266: CheckCollisionPointRec() (2 input parameters)
+Function 266: CheckCollisionCircleLine() (4 input parameters)
+ Name: CheckCollisionCircleLine
+ Return type: bool
+ Description: Check if circle collides with a line created betweeen two points [p1] and [p2]
+ Param[1]: center (type: Vector2)
+ Param[2]: radius (type: float)
+ Param[3]: p1 (type: Vector2)
+ Param[4]: p2 (type: Vector2)
+Function 267: CheckCollisionPointRec() (2 input parameters)
Name: CheckCollisionPointRec
Return type: bool
Description: Check if point is inside rectangle
Param[1]: point (type: Vector2)
Param[2]: rec (type: Rectangle)
-Function 267: CheckCollisionPointCircle() (3 input parameters)
+Function 268: CheckCollisionPointCircle() (3 input parameters)
Name: CheckCollisionPointCircle
Return type: bool
Description: Check if point is inside circle
Param[1]: point (type: Vector2)
Param[2]: center (type: Vector2)
Param[3]: radius (type: float)
-Function 268: CheckCollisionPointTriangle() (4 input parameters)
+Function 269: CheckCollisionPointTriangle() (4 input parameters)
Name: CheckCollisionPointTriangle
Return type: bool
Description: Check if point is inside a triangle
@@ -2597,14 +2605,22 @@ Function 268: CheckCollisionPointTriangle() (4 input parameters)
Param[2]: p1 (type: Vector2)
Param[3]: p2 (type: Vector2)
Param[4]: p3 (type: Vector2)
-Function 269: CheckCollisionPointPoly() (3 input parameters)
+Function 270: CheckCollisionPointLine() (4 input parameters)
+ Name: CheckCollisionPointLine
+ Return type: bool
+ Description: Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold]
+ Param[1]: point (type: Vector2)
+ Param[2]: p1 (type: Vector2)
+ Param[3]: p2 (type: Vector2)
+ Param[4]: threshold (type: int)
+Function 271: CheckCollisionPointPoly() (3 input parameters)
Name: CheckCollisionPointPoly
Return type: bool
Description: Check if point is within a polygon described by array of vertices
Param[1]: point (type: Vector2)
Param[2]: points (type: const Vector2 *)
Param[3]: pointCount (type: int)
-Function 270: CheckCollisionLines() (5 input parameters)
+Function 272: CheckCollisionLines() (5 input parameters)
Name: CheckCollisionLines
Return type: bool
Description: Check the collision between two lines defined by two points each, returns collision point by reference
@@ -2613,22 +2629,6 @@ Function 270: CheckCollisionLines() (5 input parameters)
Param[3]: startPos2 (type: Vector2)
Param[4]: endPos2 (type: Vector2)
Param[5]: collisionPoint (type: Vector2 *)
-Function 271: CheckCollisionPointLine() (4 input parameters)
- Name: CheckCollisionPointLine
- Return type: bool
- Description: Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold]
- Param[1]: point (type: Vector2)
- Param[2]: p1 (type: Vector2)
- Param[3]: p2 (type: Vector2)
- Param[4]: threshold (type: int)
-Function 272: CheckCollisionCircleLine() (4 input parameters)
- Name: CheckCollisionCircleLine
- Return type: bool
- Description: Check if circle collides with a line created betweeen two points [p1] and [p2]
- Param[1]: center (type: Vector2)
- Param[2]: radius (type: float)
- Param[3]: p1 (type: Vector2)
- Param[4]: p2 (type: Vector2)
Function 273: GetCollisionRec() (2 input parameters)
Name: GetCollisionRec
Return type: Rectangle
@@ -4217,34 +4217,34 @@ Function 501: LoadModelAnimations() (2 input parameters)
Function 502: UpdateModelAnimation() (3 input parameters)
Name: UpdateModelAnimation
Return type: void
- Description: Update model animation pose
+ Description: Update model animation pose (CPU)
Param[1]: model (type: Model)
Param[2]: anim (type: ModelAnimation)
Param[3]: frame (type: int)
-Function 503: UnloadModelAnimation() (1 input parameters)
+Function 503: UpdateModelAnimationBoneMatrices() (3 input parameters)
+ Name: UpdateModelAnimationBoneMatrices
+ Return type: void
+ Description: Update model animation mesh bone matrices (GPU skinning)
+ Param[1]: model (type: Model)
+ Param[2]: anim (type: ModelAnimation)
+ Param[3]: frame (type: int)
+Function 504: UnloadModelAnimation() (1 input parameters)
Name: UnloadModelAnimation
Return type: void
Description: Unload animation data
Param[1]: anim (type: ModelAnimation)
-Function 504: UnloadModelAnimations() (2 input parameters)
+Function 505: UnloadModelAnimations() (2 input parameters)
Name: UnloadModelAnimations
Return type: void
Description: Unload animation array data
Param[1]: animations (type: ModelAnimation *)
Param[2]: animCount (type: int)
-Function 505: IsModelAnimationValid() (2 input parameters)
+Function 506: IsModelAnimationValid() (2 input parameters)
Name: IsModelAnimationValid
Return type: bool
Description: Check model animation skeleton match
Param[1]: model (type: Model)
Param[2]: anim (type: ModelAnimation)
-Function 506: UpdateModelAnimationBoneMatrices() (3 input parameters)
- Name: UpdateModelAnimationBoneMatrices
- Return type: void
- Description: Update model animation mesh bone matrices (Note GPU skinning does not work on Mac)
- Param[1]: model (type: Model)
- Param[2]: anim (type: ModelAnimation)
- Param[3]: frame (type: int)
Function 507: CheckCollisionSpheres() (4 input parameters)
Name: CheckCollisionSpheres
Return type: bool
diff --git a/parser/output/raylib_api.xml b/parser/output/raylib_api.xml
index f59faf754..58794b4eb 100644
--- a/parser/output/raylib_api.xml
+++ b/parser/output/raylib_api.xml
@@ -5,7 +5,7 @@
-
+
@@ -595,13 +595,12 @@
-
+
-
@@ -689,46 +688,46 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -747,10 +746,10 @@
-
+
-
+
@@ -764,7 +763,7 @@
-
+
@@ -1164,7 +1163,7 @@
-
+
@@ -1217,10 +1216,11 @@
-
+
+
@@ -1658,6 +1658,12 @@
+
+
+
+
+
+
@@ -1673,6 +1679,12 @@
+
+
+
+
+
+
@@ -1685,18 +1697,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
@@ -2821,7 +2821,12 @@
-
+
+
+
+
+
+
@@ -2837,11 +2842,6 @@
-
-
-
-
-
diff --git a/projects/4coder/Makefile b/projects/4coder/Makefile
index f2091f0e3..8e64702a6 100644
--- a/projects/4coder/Makefile
+++ b/projects/4coder/Makefile
@@ -117,8 +117,8 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
EMSDK_PATH ?= C:/emsdk
EMSCRIPTEN_PATH ?= $(EMSDK_PATH)/upstream/emscripten
CLANG_PATH = $(EMSDK_PATH)/upstream/bin
- PYTHON_PATH = $(EMSDK_PATH)/python/3.9.2-1_64bit
- NODE_PATH = $(EMSDK_PATH)/node/14.15.5_64bit/bin
+ PYTHON_PATH = $(EMSDK_PATH)/python/3.9.2-nuget_64bit
+ NODE_PATH = $(EMSDK_PATH)/node/20.18.0_64bit/bin
export PATH = $(EMSDK_PATH);$(EMSCRIPTEN_PATH);$(CLANG_PATH);$(NODE_PATH);$(PYTHON_PATH);C:\raylib\MinGW\bin:$$(PATH)
endif
diff --git a/projects/VS2022/examples/shaders_shadowmap.vcxproj b/projects/VS2022/examples/shaders_shadowmap.vcxproj
new file mode 100644
index 000000000..d1ec9b23a
--- /dev/null
+++ b/projects/VS2022/examples/shaders_shadowmap.vcxproj
@@ -0,0 +1,387 @@
+
+
+
+
+ Debug.DLL
+ Win32
+
+
+ Debug.DLL
+ x64
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release.DLL
+ Win32
+
+
+ Release.DLL
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}
+ Win32Proj
+ shaders_shadowmap
+ 10.0
+ shaders_shadowmap
+
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ $(SolutionDir)..\..\examples\shaders
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shaders
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shaders
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shaders
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shaders
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shaders
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shaders
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shaders
+ WindowsLocalDebugger
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ /FS %(AdditionalOptions)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+
+
+
+ {e89d61ac-55de-4482-afd4-df7242ebc859}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/VS2022/raylib.sln b/projects/VS2022/raylib.sln
index 1dbd38984..acda9e25a 100644
--- a/projects/VS2022/raylib.sln
+++ b/projects/VS2022/raylib.sln
@@ -299,6 +299,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_top_down_lights", "e
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_gpu_skinning", "examples\models_gpu_skinning.vcxproj", "{8245DAD9-D402-4D5C-8F45-32229CD3B263}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_shadowmap", "examples\shaders_shadowmap.vcxproj", "{41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_input_virtual_controls", "examples\core_input_virtual_controls.vcxproj", "{92B64AE7-D773-6F03-89F1-CE59BBF4F053}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug.DLL|x64 = Debug.DLL|x64
@@ -2483,22 +2487,6 @@ Global
{EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release|x64.Build.0 = Release|x64
{EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release|x86.ActiveCfg = Release|Win32
{EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release|x86.Build.0 = Release|Win32
- {D8026C60-CCBC-45DF-9085-BF21569EB414}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
- {D8026C60-CCBC-45DF-9085-BF21569EB414}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
- {D8026C60-CCBC-45DF-9085-BF21569EB414}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
- {D8026C60-CCBC-45DF-9085-BF21569EB414}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
- {D8026C60-CCBC-45DF-9085-BF21569EB414}.Debug|x64.ActiveCfg = Debug|x64
- {D8026C60-CCBC-45DF-9085-BF21569EB414}.Debug|x64.Build.0 = Debug|x64
- {D8026C60-CCBC-45DF-9085-BF21569EB414}.Debug|x86.ActiveCfg = Debug|Win32
- {D8026C60-CCBC-45DF-9085-BF21569EB414}.Debug|x86.Build.0 = Debug|Win32
- {D8026C60-CCBC-45DF-9085-BF21569EB414}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
- {D8026C60-CCBC-45DF-9085-BF21569EB414}.Release.DLL|x64.Build.0 = Release.DLL|x64
- {D8026C60-CCBC-45DF-9085-BF21569EB414}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
- {D8026C60-CCBC-45DF-9085-BF21569EB414}.Release.DLL|x86.Build.0 = Release.DLL|Win32
- {D8026C60-CCBC-45DF-9085-BF21569EB414}.Release|x64.ActiveCfg = Release|x64
- {D8026C60-CCBC-45DF-9085-BF21569EB414}.Release|x64.Build.0 = Release|x64
- {D8026C60-CCBC-45DF-9085-BF21569EB414}.Release|x86.ActiveCfg = Release|Win32
- {D8026C60-CCBC-45DF-9085-BF21569EB414}.Release|x86.Build.0 = Release|Win32
{DF25E545-00FF-4E64-844C-7DF98991F901}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
{DF25E545-00FF-4E64-844C-7DF98991F901}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
{DF25E545-00FF-4E64-844C-7DF98991F901}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
@@ -2547,6 +2535,38 @@ Global
{8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release|x64.Build.0 = Release|x64
{8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release|x86.ActiveCfg = Release|Win32
{8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release|x86.Build.0 = Release|Win32
+ {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug|x64.ActiveCfg = Debug|x64
+ {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug|x64.Build.0 = Debug|x64
+ {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug|x86.ActiveCfg = Debug|Win32
+ {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug|x86.Build.0 = Debug|Win32
+ {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release|x64.ActiveCfg = Release|x64
+ {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release|x64.Build.0 = Release|x64
+ {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release|x86.ActiveCfg = Release|Win32
+ {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release|x86.Build.0 = Release|Win32
+ {92B64AE7-D773-6F03-89F1-CE59BBF4F053}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {92B64AE7-D773-6F03-89F1-CE59BBF4F053}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {92B64AE7-D773-6F03-89F1-CE59BBF4F053}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {92B64AE7-D773-6F03-89F1-CE59BBF4F053}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {92B64AE7-D773-6F03-89F1-CE59BBF4F053}.Debug|x64.ActiveCfg = Debug|x64
+ {92B64AE7-D773-6F03-89F1-CE59BBF4F053}.Debug|x64.Build.0 = Debug|x64
+ {92B64AE7-D773-6F03-89F1-CE59BBF4F053}.Debug|x86.ActiveCfg = Debug|Win32
+ {92B64AE7-D773-6F03-89F1-CE59BBF4F053}.Debug|x86.Build.0 = Debug|Win32
+ {92B64AE7-D773-6F03-89F1-CE59BBF4F053}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {92B64AE7-D773-6F03-89F1-CE59BBF4F053}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {92B64AE7-D773-6F03-89F1-CE59BBF4F053}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {92B64AE7-D773-6F03-89F1-CE59BBF4F053}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {92B64AE7-D773-6F03-89F1-CE59BBF4F053}.Release|x64.ActiveCfg = Release|x64
+ {92B64AE7-D773-6F03-89F1-CE59BBF4F053}.Release|x64.Build.0 = Release|x64
+ {92B64AE7-D773-6F03-89F1-CE59BBF4F053}.Release|x86.ActiveCfg = Release|Win32
+ {92B64AE7-D773-6F03-89F1-CE59BBF4F053}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -2695,10 +2715,11 @@ Global
{88DE5AD6-0074-4A5A-BE22-C840153E35D5} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9}
{A546E75A-5242-46E6-9A9E-6C91554EAB84} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9}
{EFA150D4-F93B-4D7D-A69C-9E8B4663BECD} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9}
- {D8026C60-CCBC-45DF-9085-BF21569EB414} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE}
{DF25E545-00FF-4E64-844C-7DF98991F901} = {278D8859-20B1-428F-8448-064F46E1F021}
{703BE7BA-5B99-4F70-806D-3A259F6A991E} = {278D8859-20B1-428F-8448-064F46E1F021}
{8245DAD9-D402-4D5C-8F45-32229CD3B263} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}
+ {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9}
+ {92B64AE7-D773-6F03-89F1-CE59BBF4F053} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29}
diff --git a/projects/VSCode/Makefile b/projects/VSCode/Makefile
index 86febfba0..65a6f9544 100644
--- a/projects/VSCode/Makefile
+++ b/projects/VSCode/Makefile
@@ -120,8 +120,8 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
EMSDK_PATH ?= C:/emsdk
EMSCRIPTEN_PATH ?= $(EMSDK_PATH)/upstream/emscripten
CLANG_PATH = $(EMSDK_PATH)/upstream/bin
- PYTHON_PATH = $(EMSDK_PATH)/python/3.9.2-1_64bit
- NODE_PATH = $(EMSDK_PATH)/node/14.18.2_64bit/bin
+ PYTHON_PATH = $(EMSDK_PATH)/python/3.9.2-nuget_64bit
+ NODE_PATH = $(EMSDK_PATH)/node/20.18.0_64bit/bin
export PATH = $(EMSDK_PATH);$(EMSCRIPTEN_PATH);$(CLANG_PATH);$(NODE_PATH);$(PYTHON_PATH):$$(PATH)
endif
diff --git a/src/Makefile b/src/Makefile
index 137c28b53..1f0b730c6 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -184,8 +184,8 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
EMSDK_PATH ?= C:/emsdk
EMSCRIPTEN_PATH ?= $(EMSDK_PATH)/upstream/emscripten
CLANG_PATH := $(EMSDK_PATH)/upstream/bin
- PYTHON_PATH := $(EMSDK_PATH)/python/3.9.2-1_64bit
- NODE_PATH := $(EMSDK_PATH)/node/14.15.5_64bit/bin
+ PYTHON_PATH := $(EMSDK_PATH)/python/3.9.2-nuget_64bit
+ NODE_PATH := $(EMSDK_PATH)/node/20.18.0_64bit/bin
export PATH := $(EMSDK_PATH);$(EMSCRIPTEN_PATH);$(CLANG_PATH);$(NODE_PATH);$(PYTHON_PATH);C:/raylib/MinGW/bin;$(PATH)
endif
endif
@@ -230,8 +230,8 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
endif
# Define raylib graphics api depending on selected platform
+# NOTE: By default use OpenGL 3.3 on desktop platforms
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
- # By default use OpenGL 3.3 on desktop platforms
GRAPHICS ?= GRAPHICS_API_OPENGL_33
#GRAPHICS = GRAPHICS_API_OPENGL_11 # Uncomment to use OpenGL 1.1
#GRAPHICS = GRAPHICS_API_OPENGL_21 # Uncomment to use OpenGL 2.1
@@ -239,11 +239,9 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
#GRAPHICS = GRAPHICS_API_OPENGL_ES2 # Uncomment to use OpenGL ES 2.0 (ANGLE)
endif
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_SDL)
- # By default use OpenGL 3.3 on desktop platform with SDL backend
GRAPHICS ?= GRAPHICS_API_OPENGL_33
endif
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_RGFW)
- # By default use OpenGL 3.3 on desktop platforms
GRAPHICS ?= GRAPHICS_API_OPENGL_33
#GRAPHICS = GRAPHICS_API_OPENGL_11 # Uncomment to use OpenGL 1.1
#GRAPHICS = GRAPHICS_API_OPENGL_21 # Uncomment to use OpenGL 2.1
@@ -257,7 +255,7 @@ endif
ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
# On HTML5 OpenGL ES 2.0 is used, emscripten translates it to WebGL 1.0
GRAPHICS = GRAPHICS_API_OPENGL_ES2
- #GRAPHICS = GRAPHICS_API_OPENGL_ES3 # Uncomment to use ES3/WebGL2 (preliminary support).
+ #GRAPHICS = GRAPHICS_API_OPENGL_ES3
endif
ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
# By default use OpenGL ES 2.0 on Android
diff --git a/src/config.h b/src/config.h
index 9123a2291..f37a9de3e 100644
--- a/src/config.h
+++ b/src/config.h
@@ -100,6 +100,8 @@
// Show OpenGL extensions and capabilities detailed logs on init
//#define RLGL_SHOW_GL_DETAILS_INFO 1
+#define RL_SUPPORT_MESH_GPU_SKINNING 1 // GPU skinning, comment if your GPU does not support more than 8 VBOs
+
//#define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 4096 // Default internal render batch elements limits
#define RL_DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering)
#define RL_DEFAULT_BATCH_DRAWCALLS 256 // Default number of batch draw calls (by state changes: mode, texture)
@@ -120,16 +122,11 @@
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT 4
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2 5
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES 6
-
-
-#define RL_SUPPORT_MESH_GPU_SKINNING // Remove this if your GPU does not support more than 8 VBOs
-
-#ifdef RL_SUPPORT_MESH_GPU_SKINNING
-#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS 7
-#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS 8
+#if defined(RL_SUPPORT_MESH_GPU_SKINNING)
+ #define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS 7
+ #define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS 8
#endif
-
// Default shader vertex attribute names to set location points
// NOTE: When a new shader is loaded, the following locations are tried to be set for convenience
#define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION
diff --git a/src/external/cgltf.h b/src/external/cgltf.h
index 323120145..36fd644e1 100644
--- a/src/external/cgltf.h
+++ b/src/external/cgltf.h
@@ -1,7 +1,7 @@
/**
* cgltf - a single-file glTF 2.0 parser written in C99.
*
- * Version: 1.13
+ * Version: 1.14
*
* Website: https://github.com/jkuhlmann/cgltf
*
@@ -395,6 +395,8 @@ typedef struct cgltf_texture
cgltf_sampler* sampler;
cgltf_bool has_basisu;
cgltf_image* basisu_image;
+ cgltf_bool has_webp;
+ cgltf_image* webp_image;
cgltf_extras extras;
cgltf_size extensions_count;
cgltf_extension* extensions;
@@ -1697,7 +1699,20 @@ cgltf_result cgltf_validate(cgltf_data* data)
{
if (data->nodes[i].weights && data->nodes[i].mesh)
{
- CGLTF_ASSERT_IF (data->nodes[i].mesh->primitives_count && data->nodes[i].mesh->primitives[0].targets_count != data->nodes[i].weights_count, cgltf_result_invalid_gltf);
+ CGLTF_ASSERT_IF(data->nodes[i].mesh->primitives_count && data->nodes[i].mesh->primitives[0].targets_count != data->nodes[i].weights_count, cgltf_result_invalid_gltf);
+ }
+
+ if (data->nodes[i].has_mesh_gpu_instancing)
+ {
+ CGLTF_ASSERT_IF(data->nodes[i].mesh == NULL, cgltf_result_invalid_gltf);
+ CGLTF_ASSERT_IF(data->nodes[i].mesh_gpu_instancing.attributes_count == 0, cgltf_result_invalid_gltf);
+
+ cgltf_accessor* first = data->nodes[i].mesh_gpu_instancing.attributes[0].data;
+
+ for (cgltf_size k = 0; k < data->nodes[i].mesh_gpu_instancing.attributes_count; ++k)
+ {
+ CGLTF_ASSERT_IF(data->nodes[i].mesh_gpu_instancing.attributes[k].data->count != first->count, cgltf_result_invalid_gltf);
+ }
}
}
@@ -4538,6 +4553,34 @@ static int cgltf_parse_json_texture(cgltf_options* options, jsmntok_t const* tok
}
}
}
+ else if (cgltf_json_strcmp(tokens + i, json_chunk, "EXT_texture_webp") == 0)
+ {
+ out_texture->has_webp = 1;
+ ++i;
+ CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
+ int num_properties = tokens[i].size;
+ ++i;
+
+ for (int t = 0; t < num_properties; ++t)
+ {
+ CGLTF_CHECK_KEY(tokens[i]);
+
+ if (cgltf_json_strcmp(tokens + i, json_chunk, "source") == 0)
+ {
+ ++i;
+ out_texture->webp_image = CGLTF_PTRINDEX(cgltf_image, cgltf_json_to_int(tokens + i, json_chunk));
+ ++i;
+ }
+ else
+ {
+ i = cgltf_skip_json(tokens, i + 1);
+ }
+ if (i < 0)
+ {
+ return i;
+ }
+ }
+ }
else
{
i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_texture->extensions[out_texture->extensions_count++]));
@@ -6548,6 +6591,7 @@ static int cgltf_fixup_pointers(cgltf_data* data)
{
CGLTF_PTRFIXUP(data->textures[i].image, data->images, data->images_count);
CGLTF_PTRFIXUP(data->textures[i].basisu_image, data->images, data->images_count);
+ CGLTF_PTRFIXUP(data->textures[i].webp_image, data->images, data->images_count);
CGLTF_PTRFIXUP(data->textures[i].sampler, data->samplers, data->samplers_count);
}
diff --git a/src/external/dr_mp3.h b/src/external/dr_mp3.h
index 84849ee4c..e1a66d99c 100644
--- a/src/external/dr_mp3.h
+++ b/src/external/dr_mp3.h
@@ -1,6 +1,6 @@
/*
MP3 audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file.
-dr_mp3 - v0.6.38 - 2023-11-02
+dr_mp3 - v0.6.39 - 2024-02-27
David Reid - mackron@gmail.com
@@ -95,7 +95,7 @@ extern "C" {
#define DRMP3_VERSION_MAJOR 0
#define DRMP3_VERSION_MINOR 6
-#define DRMP3_VERSION_REVISION 38
+#define DRMP3_VERSION_REVISION 39
#define DRMP3_VERSION_STRING DRMP3_XSTRINGIFY(DRMP3_VERSION_MAJOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_MINOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_REVISION)
#include /* For size_t. */
@@ -1985,8 +1985,8 @@ static drmp3_int16 drmp3d_scale_pcm(float sample)
s32 -= (s32 < 0);
s = (drmp3_int16)drmp3_clip_int16_arm(s32);
#else
- if (sample >= 32766.5) return (drmp3_int16) 32767;
- if (sample <= -32767.5) return (drmp3_int16)-32768;
+ if (sample >= 32766.5f) return (drmp3_int16) 32767;
+ if (sample <= -32767.5f) return (drmp3_int16)-32768;
s = (drmp3_int16)(sample + .5f);
s -= (s < 0); /* away from zero, to be compliant */
#endif
@@ -2404,9 +2404,9 @@ DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num
for(; i < num_samples; i++)
{
float sample = in[i] * 32768.0f;
- if (sample >= 32766.5)
+ if (sample >= 32766.5f)
out[i] = (drmp3_int16) 32767;
- else if (sample <= -32767.5)
+ else if (sample <= -32767.5f)
out[i] = (drmp3_int16)-32768;
else
{
@@ -4495,6 +4495,9 @@ counts rather than sample counts.
/*
REVISION HISTORY
================
+v0.6.39 - 2024-02-27
+ - Fix a Wdouble-promotion warning.
+
v0.6.38 - 2023-11-02
- Fix build for ARMv6-M.
diff --git a/src/external/dr_wav.h b/src/external/dr_wav.h
index 36451b589..a8207ab90 100644
--- a/src/external/dr_wav.h
+++ b/src/external/dr_wav.h
@@ -1,6 +1,6 @@
/*
WAV audio loader and writer. Choice of public domain or MIT-0. See license statements at the end of this file.
-dr_wav - v0.13.13 - 2023-11-02
+dr_wav - v0.13.16 - 2024-02-27
David Reid - mackron@gmail.com
@@ -147,7 +147,7 @@ extern "C" {
#define DRWAV_VERSION_MAJOR 0
#define DRWAV_VERSION_MINOR 13
-#define DRWAV_VERSION_REVISION 13
+#define DRWAV_VERSION_REVISION 16
#define DRWAV_VERSION_STRING DRWAV_XSTRINGIFY(DRWAV_VERSION_MAJOR) "." DRWAV_XSTRINGIFY(DRWAV_VERSION_MINOR) "." DRWAV_XSTRINGIFY(DRWAV_VERSION_REVISION)
#include /* For size_t. */
@@ -3075,7 +3075,13 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on
if (pWav->container == drwav_container_riff || pWav->container == drwav_container_rifx) {
if (drwav_bytes_to_u32_ex(chunkSizeBytes, pWav->container) < 36) {
- return DRWAV_FALSE; /* Chunk size should always be at least 36 bytes. */
+ /*
+ I've had a report of a WAV file failing to load when the size of the WAVE chunk is not encoded
+ and is instead just set to 0. I'm going to relax the validation here to allow these files to
+ load. Considering the chunk size isn't actually used this should be safe. With this change my
+ test suite still passes.
+ */
+ /*return DRWAV_FALSE;*/ /* Chunk size should always be at least 36 bytes. */
}
} else if (pWav->container == drwav_container_rf64) {
if (drwav_bytes_to_u32_le(chunkSizeBytes) != 0xFFFFFFFF) {
@@ -3554,10 +3560,7 @@ DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc on
/* Getting here means it's not a chunk that we care about internally, but might need to be handled as metadata by the caller. */
if (isProcessingMetadata) {
- drwav_uint64 metadataBytesRead;
-
- metadataBytesRead = drwav__metadata_process_chunk(&metadataParser, &header, drwav_metadata_type_all_including_unknown);
- DRWAV_ASSERT(metadataBytesRead <= header.sizeInBytes);
+ drwav__metadata_process_chunk(&metadataParser, &header, drwav_metadata_type_all_including_unknown);
/* Go back to the start of the chunk so we can normalize the position of the cursor. */
if (drwav__seek_from_start(pWav->onSeek, cursor, pWav->pUserData) == DRWAV_FALSE) {
@@ -7830,7 +7833,7 @@ DRWAV_API void drwav_f32_to_s32(drwav_int32* pOut, const float* pIn, size_t samp
}
for (i = 0; i < sampleCount; ++i) {
- *pOut++ = (drwav_int32)(2147483648.0 * pIn[i]);
+ *pOut++ = (drwav_int32)(2147483648.0f * pIn[i]);
}
}
@@ -8347,6 +8350,15 @@ DRWAV_API drwav_bool32 drwav_fourcc_equal(const drwav_uint8* a, const char* b)
/*
REVISION HISTORY
================
+v0.13.16 - 2024-02-27
+ - Fix a Wdouble-promotion warning.
+
+v0.13.15 - 2024-01-23
+ - Relax some unnecessary validation that prevented some files from loading.
+
+v0.13.14 - 2023-12-02
+ - Fix a warning about an unused variable.
+
v0.13.13 - 2023-11-02
- Fix a warning when compiling with Clang.
diff --git a/src/external/qoa.h b/src/external/qoa.h
index fc62f4765..f0f44214d 100644
--- a/src/external/qoa.h
+++ b/src/external/qoa.h
@@ -366,22 +366,7 @@ unsigned int qoa_encode_frame(const short *sample_data, qoa_desc *qoa, unsigned
), bytes, &p);
- for (int c = 0; c < channels; c++) {
- /* If the weights have grown too large, reset them to 0. This may happen
- with certain high-frequency sounds. This is a last resort and will
- introduce quite a bit of noise, but should at least prevent pops/clicks */
- int weights_sum =
- qoa->lms[c].weights[0] * qoa->lms[c].weights[0] +
- qoa->lms[c].weights[1] * qoa->lms[c].weights[1] +
- qoa->lms[c].weights[2] * qoa->lms[c].weights[2] +
- qoa->lms[c].weights[3] * qoa->lms[c].weights[3];
- if (weights_sum > 0x2fffffff) {
- qoa->lms[c].weights[0] = 0;
- qoa->lms[c].weights[1] = 0;
- qoa->lms[c].weights[2] = 0;
- qoa->lms[c].weights[3] = 0;
- }
-
+ for (unsigned int c = 0; c < channels; c++) {
/* Write the current LMS state */
qoa_uint64_t weights = 0;
qoa_uint64_t history = 0;
@@ -395,9 +380,9 @@ unsigned int qoa_encode_frame(const short *sample_data, qoa_desc *qoa, unsigned
/* We encode all samples with the channels interleaved on a slice level.
E.g. for stereo: (ch-0, slice 0), (ch 1, slice 0), (ch 0, slice 1), ...*/
- for (int sample_index = 0; sample_index < frame_len; sample_index += QOA_SLICE_LEN) {
+ for (unsigned int sample_index = 0; sample_index < frame_len; sample_index += QOA_SLICE_LEN) {
- for (int c = 0; c < channels; c++) {
+ for (unsigned int c = 0; c < channels; c++) {
int slice_len = qoa_clamp(QOA_SLICE_LEN, 0, frame_len - sample_index);
int slice_start = sample_index * channels + c;
int slice_end = (sample_index + slice_len) * channels + c;
@@ -405,10 +390,13 @@ unsigned int qoa_encode_frame(const short *sample_data, qoa_desc *qoa, unsigned
/* Brute for search for the best scalefactor. Just go through all
16 scalefactors, encode all samples for the current slice and
meassure the total squared error. */
- qoa_uint64_t best_error = -1;
- qoa_uint64_t best_slice;
+ qoa_uint64_t best_rank = -1;
+ #ifdef QOA_RECORD_TOTAL_ERROR
+ qoa_uint64_t best_error = -1;
+ #endif
+ qoa_uint64_t best_slice = 0;
qoa_lms_t best_lms;
- int best_scalefactor;
+ int best_scalefactor = 0;
for (int sfi = 0; sfi < 16; sfi++) {
/* There is a strong correlation between the scalefactors of
@@ -421,7 +409,10 @@ unsigned int qoa_encode_frame(const short *sample_data, qoa_desc *qoa, unsigned
state when encoding. */
qoa_lms_t lms = qoa->lms[c];
qoa_uint64_t slice = scalefactor;
- qoa_uint64_t current_error = 0;
+ qoa_uint64_t current_rank = 0;
+ #ifdef QOA_RECORD_TOTAL_ERROR
+ qoa_uint64_t current_error = 0;
+ #endif
for (int si = slice_start; si < slice_end; si += channels) {
int sample = sample_data[si];
@@ -434,9 +425,27 @@ unsigned int qoa_encode_frame(const short *sample_data, qoa_desc *qoa, unsigned
int dequantized = qoa_dequant_tab[scalefactor][quantized];
int reconstructed = qoa_clamp_s16(predicted + dequantized);
+
+ /* If the weights have grown too large, we introduce a penalty
+ here. This prevents pops/clicks in certain problem cases */
+ int weights_penalty = ((
+ lms.weights[0] * lms.weights[0] +
+ lms.weights[1] * lms.weights[1] +
+ lms.weights[2] * lms.weights[2] +
+ lms.weights[3] * lms.weights[3]
+ ) >> 18) - 0x8ff;
+ if (weights_penalty < 0) {
+ weights_penalty = 0;
+ }
+
long long error = (sample - reconstructed);
- current_error += error * error;
- if (current_error > best_error) {
+ qoa_uint64_t error_sq = error * error;
+
+ current_rank += error_sq + weights_penalty * weights_penalty;
+ #ifdef QOA_RECORD_TOTAL_ERROR
+ current_error += error_sq;
+ #endif
+ if (current_rank > best_rank) {
break;
}
@@ -444,8 +453,11 @@ unsigned int qoa_encode_frame(const short *sample_data, qoa_desc *qoa, unsigned
slice = (slice << 3) | quantized;
}
- if (current_error < best_error) {
- best_error = current_error;
+ if (current_rank < best_rank) {
+ best_rank = current_rank;
+ #ifdef QOA_RECORD_TOTAL_ERROR
+ best_error = current_error;
+ #endif
best_slice = slice;
best_lms = lms;
best_scalefactor = scalefactor;
@@ -490,7 +502,7 @@ void *qoa_encode(const short *sample_data, qoa_desc *qoa, unsigned int *out_len)
unsigned char *bytes = QOA_MALLOC(encoded_size);
- for (int c = 0; c < qoa->channels; c++) {
+ for (unsigned int c = 0; c < qoa->channels; c++) {
/* Set the initial LMS weights to {0, 0, -1, 2}. This helps with the
prediction of the first few ms of a file. */
qoa->lms[c].weights[0] = 0;
@@ -513,7 +525,7 @@ void *qoa_encode(const short *sample_data, qoa_desc *qoa, unsigned int *out_len)
#endif
int frame_len = QOA_FRAME_LEN;
- for (int sample_index = 0; sample_index < qoa->samples; sample_index += frame_len) {
+ for (unsigned int sample_index = 0; sample_index < qoa->samples; sample_index += frame_len) {
frame_len = qoa_clamp(QOA_FRAME_LEN, 0, qoa->samples - sample_index);
const short *frame_samples = sample_data + sample_index * qoa->channels;
unsigned int frame_size = qoa_encode_frame(frame_samples, qoa, frame_len, bytes + p);
@@ -576,14 +588,14 @@ unsigned int qoa_decode_frame(const unsigned char *bytes, unsigned int size, qoa
/* Read and verify the frame header */
qoa_uint64_t frame_header = qoa_read_u64(bytes, &p);
- int channels = (frame_header >> 56) & 0x0000ff;
- int samplerate = (frame_header >> 32) & 0xffffff;
- int samples = (frame_header >> 16) & 0x00ffff;
- int frame_size = (frame_header ) & 0x00ffff;
+ unsigned int channels = (frame_header >> 56) & 0x0000ff;
+ unsigned int samplerate = (frame_header >> 32) & 0xffffff;
+ unsigned int samples = (frame_header >> 16) & 0x00ffff;
+ unsigned int frame_size = (frame_header ) & 0x00ffff;
- int data_size = frame_size - 8 - QOA_LMS_LEN * 4 * channels;
- int num_slices = data_size / 8;
- int max_total_samples = num_slices * QOA_SLICE_LEN;
+ unsigned int data_size = frame_size - 8 - QOA_LMS_LEN * 4 * channels;
+ unsigned int num_slices = data_size / 8;
+ unsigned int max_total_samples = num_slices * QOA_SLICE_LEN;
if (
channels != qoa->channels ||
@@ -596,7 +608,7 @@ unsigned int qoa_decode_frame(const unsigned char *bytes, unsigned int size, qoa
/* Read the LMS state: 4 x 2 bytes history, 4 x 2 bytes weights per channel */
- for (int c = 0; c < channels; c++) {
+ for (unsigned int c = 0; c < channels; c++) {
qoa_uint64_t history = qoa_read_u64(bytes, &p);
qoa_uint64_t weights = qoa_read_u64(bytes, &p);
for (int i = 0; i < QOA_LMS_LEN; i++) {
@@ -609,17 +621,19 @@ unsigned int qoa_decode_frame(const unsigned char *bytes, unsigned int size, qoa
/* Decode all slices for all channels in this frame */
- for (int sample_index = 0; sample_index < samples; sample_index += QOA_SLICE_LEN) {
- for (int c = 0; c < channels; c++) {
+ for (unsigned int sample_index = 0; sample_index < samples; sample_index += QOA_SLICE_LEN) {
+ for (unsigned int c = 0; c < channels; c++) {
qoa_uint64_t slice = qoa_read_u64(bytes, &p);
int scalefactor = (slice >> 60) & 0xf;
+ slice <<= 4;
+
int slice_start = sample_index * channels + c;
int slice_end = qoa_clamp(sample_index + QOA_SLICE_LEN, 0, samples) * channels + c;
for (int si = slice_start; si < slice_end; si += channels) {
int predicted = qoa_lms_predict(&qoa->lms[c]);
- int quantized = (slice >> 57) & 0x7;
+ int quantized = (slice >> 61) & 0x7;
int dequantized = qoa_dequant_tab[scalefactor][quantized];
int reconstructed = qoa_clamp_s16(predicted + dequantized);
diff --git a/src/external/stb_image.h b/src/external/stb_image.h
index 5e807a0a6..9eedabedc 100644
--- a/src/external/stb_image.h
+++ b/src/external/stb_image.h
@@ -1,4 +1,4 @@
-/* stb_image - v2.28 - public domain image loader - http://nothings.org/stb
+/* stb_image - v2.30 - public domain image loader - http://nothings.org/stb
no warranty implied; use at your own risk
Do this:
@@ -48,6 +48,8 @@ LICENSE
RECENT REVISION HISTORY:
+ 2.30 (2024-05-31) avoid erroneous gcc warning
+ 2.29 (2023-05-xx) optimizations
2.28 (2023-01-29) many error fixes, security errors, just tons of stuff
2.27 (2021-07-11) document stbi_info better, 16-bit PNM support, bug fixes
2.26 (2020-07-13) many minor fixes
@@ -1072,8 +1074,8 @@ static int stbi__addints_valid(int a, int b)
return a <= INT_MAX - b;
}
-// returns 1 if the product of two signed shorts is valid, 0 on overflow.
-static int stbi__mul2shorts_valid(short a, short b)
+// returns 1 if the product of two ints fits in a signed short, 0 on overflow.
+static int stbi__mul2shorts_valid(int a, int b)
{
if (b == 0 || b == -1) return 1; // multiplication by 0 is always 0; check for -1 so SHRT_MIN/b doesn't overflow
if ((a >= 0) == (b >= 0)) return a <= SHRT_MAX/b; // product is positive, so similar to mul2sizes_valid
@@ -3384,13 +3386,13 @@ static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan)
return 1;
}
-static int stbi__skip_jpeg_junk_at_end(stbi__jpeg *j)
+static stbi_uc stbi__skip_jpeg_junk_at_end(stbi__jpeg *j)
{
// some JPEGs have junk at end, skip over it but if we find what looks
// like a valid marker, resume there
while (!stbi__at_eof(j->s)) {
- int x = stbi__get8(j->s);
- while (x == 255) { // might be a marker
+ stbi_uc x = stbi__get8(j->s);
+ while (x == 0xff) { // might be a marker
if (stbi__at_eof(j->s)) return STBI__MARKER_none;
x = stbi__get8(j->s);
if (x != 0x00 && x != 0xff) {
@@ -4176,6 +4178,7 @@ typedef struct
{
stbi_uc *zbuffer, *zbuffer_end;
int num_bits;
+ int hit_zeof_once;
stbi__uint32 code_buffer;
char *zout;
@@ -4242,9 +4245,20 @@ stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z)
int b,s;
if (a->num_bits < 16) {
if (stbi__zeof(a)) {
- return -1; /* report error for unexpected end of data. */
+ if (!a->hit_zeof_once) {
+ // This is the first time we hit eof, insert 16 extra padding btis
+ // to allow us to keep going; if we actually consume any of them
+ // though, that is invalid data. This is caught later.
+ a->hit_zeof_once = 1;
+ a->num_bits += 16; // add 16 implicit zero bits
+ } else {
+ // We already inserted our extra 16 padding bits and are again
+ // out, this stream is actually prematurely terminated.
+ return -1;
+ }
+ } else {
+ stbi__fill_bits(a);
}
- stbi__fill_bits(a);
}
b = z->fast[a->code_buffer & STBI__ZFAST_MASK];
if (b) {
@@ -4309,6 +4323,13 @@ static int stbi__parse_huffman_block(stbi__zbuf *a)
int len,dist;
if (z == 256) {
a->zout = zout;
+ if (a->hit_zeof_once && a->num_bits < 16) {
+ // The first time we hit zeof, we inserted 16 extra zero bits into our bit
+ // buffer so the decoder can just do its speculative decoding. But if we
+ // actually consumed any of those bits (which is the case when num_bits < 16),
+ // the stream actually read past the end so it is malformed.
+ return stbi__err("unexpected end","Corrupt PNG");
+ }
return 1;
}
if (z >= 286) return stbi__err("bad huffman code","Corrupt PNG"); // per DEFLATE, length codes 286 and 287 must not appear in compressed data
@@ -4320,7 +4341,7 @@ static int stbi__parse_huffman_block(stbi__zbuf *a)
dist = stbi__zdist_base[z];
if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]);
if (zout - a->zout_start < dist) return stbi__err("bad dist","Corrupt PNG");
- if (zout + len > a->zout_end) {
+ if (len > a->zout_end - zout) {
if (!stbi__zexpand(a, zout, len)) return 0;
zout = a->zout;
}
@@ -4464,6 +4485,7 @@ static int stbi__parse_zlib(stbi__zbuf *a, int parse_header)
if (!stbi__parse_zlib_header(a)) return 0;
a->num_bits = 0;
a->code_buffer = 0;
+ a->hit_zeof_once = 0;
do {
final = stbi__zreceive(a,1);
type = stbi__zreceive(a,2);
@@ -4619,9 +4641,8 @@ enum {
STBI__F_up=2,
STBI__F_avg=3,
STBI__F_paeth=4,
- // synthetic filters used for first scanline to avoid needing a dummy row of 0s
- STBI__F_avg_first,
- STBI__F_paeth_first
+ // synthetic filter used for first scanline to avoid needing a dummy row of 0s
+ STBI__F_avg_first
};
static stbi_uc first_row_filter[5] =
@@ -4630,29 +4651,56 @@ static stbi_uc first_row_filter[5] =
STBI__F_sub,
STBI__F_none,
STBI__F_avg_first,
- STBI__F_paeth_first
+ STBI__F_sub // Paeth with b=c=0 turns out to be equivalent to sub
};
static int stbi__paeth(int a, int b, int c)
{
- int p = a + b - c;
- int pa = abs(p-a);
- int pb = abs(p-b);
- int pc = abs(p-c);
- if (pa <= pb && pa <= pc) return a;
- if (pb <= pc) return b;
- return c;
+ // This formulation looks very different from the reference in the PNG spec, but is
+ // actually equivalent and has favorable data dependencies and admits straightforward
+ // generation of branch-free code, which helps performance significantly.
+ int thresh = c*3 - (a + b);
+ int lo = a < b ? a : b;
+ int hi = a < b ? b : a;
+ int t0 = (hi <= thresh) ? lo : c;
+ int t1 = (thresh <= lo) ? hi : t0;
+ return t1;
}
static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 };
+// adds an extra all-255 alpha channel
+// dest == src is legal
+// img_n must be 1 or 3
+static void stbi__create_png_alpha_expand8(stbi_uc *dest, stbi_uc *src, stbi__uint32 x, int img_n)
+{
+ int i;
+ // must process data backwards since we allow dest==src
+ if (img_n == 1) {
+ for (i=x-1; i >= 0; --i) {
+ dest[i*2+1] = 255;
+ dest[i*2+0] = src[i];
+ }
+ } else {
+ STBI_ASSERT(img_n == 3);
+ for (i=x-1; i >= 0; --i) {
+ dest[i*4+3] = 255;
+ dest[i*4+2] = src[i*3+2];
+ dest[i*4+1] = src[i*3+1];
+ dest[i*4+0] = src[i*3+0];
+ }
+ }
+}
+
// create the png data from post-deflated data
static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color)
{
- int bytes = (depth == 16? 2 : 1);
+ int bytes = (depth == 16 ? 2 : 1);
stbi__context *s = a->s;
stbi__uint32 i,j,stride = x*out_n*bytes;
stbi__uint32 img_len, img_width_bytes;
+ stbi_uc *filter_buf;
+ int all_ok = 1;
int k;
int img_n = s->img_n; // copy it into a local for later
@@ -4664,8 +4712,11 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
a->out = (stbi_uc *) stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into
if (!a->out) return stbi__err("outofmem", "Out of memory");
+ // note: error exits here don't need to clean up a->out individually,
+ // stbi__do_png always does on error.
if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG");
img_width_bytes = (((img_n * x * depth) + 7) >> 3);
+ if (!stbi__mad2sizes_valid(img_width_bytes, y, img_width_bytes)) return stbi__err("too large", "Corrupt PNG");
img_len = (img_width_bytes + 1) * y;
// we used to check for exact match between raw_len and img_len on non-interlaced PNGs,
@@ -4673,189 +4724,137 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
// so just check for raw_len < img_len always.
if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG");
+ // Allocate two scan lines worth of filter workspace buffer.
+ filter_buf = (stbi_uc *) stbi__malloc_mad2(img_width_bytes, 2, 0);
+ if (!filter_buf) return stbi__err("outofmem", "Out of memory");
+
+ // Filtering for low-bit-depth images
+ if (depth < 8) {
+ filter_bytes = 1;
+ width = img_width_bytes;
+ }
+
for (j=0; j < y; ++j) {
- stbi_uc *cur = a->out + stride*j;
- stbi_uc *prior;
+ // cur/prior filter buffers alternate
+ stbi_uc *cur = filter_buf + (j & 1)*img_width_bytes;
+ stbi_uc *prior = filter_buf + (~j & 1)*img_width_bytes;
+ stbi_uc *dest = a->out + stride*j;
+ int nk = width * filter_bytes;
int filter = *raw++;
- if (filter > 4)
- return stbi__err("invalid filter","Corrupt PNG");
-
- if (depth < 8) {
- if (img_width_bytes > x) return stbi__err("invalid width","Corrupt PNG");
- cur += x*out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place
- filter_bytes = 1;
- width = img_width_bytes;
+ // check filter type
+ if (filter > 4) {
+ all_ok = stbi__err("invalid filter","Corrupt PNG");
+ break;
}
- prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above
// if first row, use special filter that doesn't sample previous row
if (j == 0) filter = first_row_filter[filter];
- // handle first byte explicitly
- for (k=0; k < filter_bytes; ++k) {
- switch (filter) {
- case STBI__F_none : cur[k] = raw[k]; break;
- case STBI__F_sub : cur[k] = raw[k]; break;
- case STBI__F_up : cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break;
- case STBI__F_avg : cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1)); break;
- case STBI__F_paeth : cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0,prior[k],0)); break;
- case STBI__F_avg_first : cur[k] = raw[k]; break;
- case STBI__F_paeth_first: cur[k] = raw[k]; break;
- }
+ // perform actual filtering
+ switch (filter) {
+ case STBI__F_none:
+ memcpy(cur, raw, nk);
+ break;
+ case STBI__F_sub:
+ memcpy(cur, raw, filter_bytes);
+ for (k = filter_bytes; k < nk; ++k)
+ cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]);
+ break;
+ case STBI__F_up:
+ for (k = 0; k < nk; ++k)
+ cur[k] = STBI__BYTECAST(raw[k] + prior[k]);
+ break;
+ case STBI__F_avg:
+ for (k = 0; k < filter_bytes; ++k)
+ cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1));
+ for (k = filter_bytes; k < nk; ++k)
+ cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1));
+ break;
+ case STBI__F_paeth:
+ for (k = 0; k < filter_bytes; ++k)
+ cur[k] = STBI__BYTECAST(raw[k] + prior[k]); // prior[k] == stbi__paeth(0,prior[k],0)
+ for (k = filter_bytes; k < nk; ++k)
+ cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes], prior[k], prior[k-filter_bytes]));
+ break;
+ case STBI__F_avg_first:
+ memcpy(cur, raw, filter_bytes);
+ for (k = filter_bytes; k < nk; ++k)
+ cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1));
+ break;
}
- if (depth == 8) {
- if (img_n != out_n)
- cur[img_n] = 255; // first pixel
- raw += img_n;
- cur += out_n;
- prior += out_n;
- } else if (depth == 16) {
- if (img_n != out_n) {
- cur[filter_bytes] = 255; // first pixel top byte
- cur[filter_bytes+1] = 255; // first pixel bottom byte
- }
- raw += filter_bytes;
- cur += output_bytes;
- prior += output_bytes;
- } else {
- raw += 1;
- cur += 1;
- prior += 1;
- }
+ raw += nk;
- // this is a little gross, so that we don't switch per-pixel or per-component
- if (depth < 8 || img_n == out_n) {
- int nk = (width - 1)*filter_bytes;
- #define STBI__CASE(f) \
- case f: \
- for (k=0; k < nk; ++k)
- switch (filter) {
- // "none" filter turns into a memcpy here; make that explicit.
- case STBI__F_none: memcpy(cur, raw, nk); break;
- STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); } break;
- STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break;
- STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); } break;
- STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],prior[k],prior[k-filter_bytes])); } break;
- STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); } break;
- STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],0,0)); } break;
- }
- #undef STBI__CASE
- raw += nk;
- } else {
- STBI_ASSERT(img_n+1 == out_n);
- #define STBI__CASE(f) \
- case f: \
- for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \
- for (k=0; k < filter_bytes; ++k)
- switch (filter) {
- STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break;
- STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k- output_bytes]); } break;
- STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break;
- STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k- output_bytes])>>1)); } break;
- STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],prior[k],prior[k- output_bytes])); } break;
- STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k- output_bytes] >> 1)); } break;
- STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); } break;
- }
- #undef STBI__CASE
-
- // the loop above sets the high byte of the pixels' alpha, but for
- // 16 bit png files we also need the low byte set. we'll do that here.
- if (depth == 16) {
- cur = a->out + stride*j; // start at the beginning of the row again
- for (i=0; i < x; ++i,cur+=output_bytes) {
- cur[filter_bytes+1] = 255;
- }
- }
- }
- }
-
- // we make a separate pass to expand bits to pixels; for performance,
- // this could run two scanlines behind the above code, so it won't
- // intefere with filtering but will still be in the cache.
- if (depth < 8) {
- for (j=0; j < y; ++j) {
- stbi_uc *cur = a->out + stride*j;
- stbi_uc *in = a->out + stride*j + x*out_n - img_width_bytes;
- // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit
- // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop
+ // expand decoded bits in cur to dest, also adding an extra alpha channel if desired
+ if (depth < 8) {
stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range
+ stbi_uc *in = cur;
+ stbi_uc *out = dest;
+ stbi_uc inb = 0;
+ stbi__uint32 nsmp = x*img_n;
- // note that the final byte might overshoot and write more data than desired.
- // we can allocate enough data that this never writes out of memory, but it
- // could also overwrite the next scanline. can it overwrite non-empty data
- // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel.
- // so we need to explicitly clamp the final ones
-
+ // expand bits to bytes first
if (depth == 4) {
- for (k=x*img_n; k >= 2; k-=2, ++in) {
- *cur++ = scale * ((*in >> 4) );
- *cur++ = scale * ((*in ) & 0x0f);
+ for (i=0; i < nsmp; ++i) {
+ if ((i & 1) == 0) inb = *in++;
+ *out++ = scale * (inb >> 4);
+ inb <<= 4;
}
- if (k > 0) *cur++ = scale * ((*in >> 4) );
} else if (depth == 2) {
- for (k=x*img_n; k >= 4; k-=4, ++in) {
- *cur++ = scale * ((*in >> 6) );
- *cur++ = scale * ((*in >> 4) & 0x03);
- *cur++ = scale * ((*in >> 2) & 0x03);
- *cur++ = scale * ((*in ) & 0x03);
+ for (i=0; i < nsmp; ++i) {
+ if ((i & 3) == 0) inb = *in++;
+ *out++ = scale * (inb >> 6);
+ inb <<= 2;
}
- if (k > 0) *cur++ = scale * ((*in >> 6) );
- if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03);
- if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03);
- } else if (depth == 1) {
- for (k=x*img_n; k >= 8; k-=8, ++in) {
- *cur++ = scale * ((*in >> 7) );
- *cur++ = scale * ((*in >> 6) & 0x01);
- *cur++ = scale * ((*in >> 5) & 0x01);
- *cur++ = scale * ((*in >> 4) & 0x01);
- *cur++ = scale * ((*in >> 3) & 0x01);
- *cur++ = scale * ((*in >> 2) & 0x01);
- *cur++ = scale * ((*in >> 1) & 0x01);
- *cur++ = scale * ((*in ) & 0x01);
+ } else {
+ STBI_ASSERT(depth == 1);
+ for (i=0; i < nsmp; ++i) {
+ if ((i & 7) == 0) inb = *in++;
+ *out++ = scale * (inb >> 7);
+ inb <<= 1;
}
- if (k > 0) *cur++ = scale * ((*in >> 7) );
- if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01);
- if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01);
- if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01);
- if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01);
- if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01);
- if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01);
}
- if (img_n != out_n) {
- int q;
- // insert alpha = 255
- cur = a->out + stride*j;
+
+ // insert alpha=255 values if desired
+ if (img_n != out_n)
+ stbi__create_png_alpha_expand8(dest, dest, x, img_n);
+ } else if (depth == 8) {
+ if (img_n == out_n)
+ memcpy(dest, cur, x*img_n);
+ else
+ stbi__create_png_alpha_expand8(dest, cur, x, img_n);
+ } else if (depth == 16) {
+ // convert the image data from big-endian to platform-native
+ stbi__uint16 *dest16 = (stbi__uint16*)dest;
+ stbi__uint32 nsmp = x*img_n;
+
+ if (img_n == out_n) {
+ for (i = 0; i < nsmp; ++i, ++dest16, cur += 2)
+ *dest16 = (cur[0] << 8) | cur[1];
+ } else {
+ STBI_ASSERT(img_n+1 == out_n);
if (img_n == 1) {
- for (q=x-1; q >= 0; --q) {
- cur[q*2+1] = 255;
- cur[q*2+0] = cur[q];
+ for (i = 0; i < x; ++i, dest16 += 2, cur += 2) {
+ dest16[0] = (cur[0] << 8) | cur[1];
+ dest16[1] = 0xffff;
}
} else {
STBI_ASSERT(img_n == 3);
- for (q=x-1; q >= 0; --q) {
- cur[q*4+3] = 255;
- cur[q*4+2] = cur[q*3+2];
- cur[q*4+1] = cur[q*3+1];
- cur[q*4+0] = cur[q*3+0];
+ for (i = 0; i < x; ++i, dest16 += 4, cur += 6) {
+ dest16[0] = (cur[0] << 8) | cur[1];
+ dest16[1] = (cur[2] << 8) | cur[3];
+ dest16[2] = (cur[4] << 8) | cur[5];
+ dest16[3] = 0xffff;
}
}
}
}
- } else if (depth == 16) {
- // force the image data from big-endian to platform-native.
- // this is done in a separate pass due to the decoding relying
- // on the data being untouched, but could probably be done
- // per-line during decode if care is taken.
- stbi_uc *cur = a->out;
- stbi__uint16 *cur16 = (stbi__uint16*)cur;
-
- for(i=0; i < x*y*out_n; ++i,cur16++,cur+=2) {
- *cur16 = (cur[0] << 8) | cur[1];
- }
}
+ STBI_FREE(filter_buf);
+ if (!all_ok) return 0;
+
return 1;
}
@@ -5161,9 +5160,11 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
// non-paletted with tRNS = constant alpha. if header-scanning, we can stop now.
if (scan == STBI__SCAN_header) { ++s->img_n; return 1; }
if (z->depth == 16) {
- for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is
+ for (k = 0; k < s->img_n && k < 3; ++k) // extra loop test to suppress false GCC warning
+ tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is
} else {
- for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger
+ for (k = 0; k < s->img_n && k < 3; ++k)
+ tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger
}
}
break;
diff --git a/src/external/stb_image_resize2.h b/src/external/stb_image_resize2.h
index ae8d730bf..2f2627463 100644
--- a/src/external/stb_image_resize2.h
+++ b/src/external/stb_image_resize2.h
@@ -1,4 +1,4 @@
-/* stb_image_resize2 - v2.10 - public domain image resizing
+/* stb_image_resize2 - v2.12 - public domain image resizing
by Jeff Roberts (v2) and Jorge L Rodriguez
http://github.com/nothings/stb
@@ -11,35 +11,6 @@
#define STB_IMAGE_RESIZE_IMPLEMENTATION
before the #include. That will create the implementation in that file.
- PORTING FROM VERSION 1
-
- The API has changed. You can continue to use the old version of stb_image_resize.h,
- which is available in the "deprecated/" directory.
-
- If you're using the old simple-to-use API, porting is straightforward.
- (For more advanced APIs, read the documentation.)
-
- stbir_resize_uint8():
- - call `stbir_resize_uint8_linear`, cast channel count to `stbir_pixel_layout`
-
- stbir_resize_float():
- - call `stbir_resize_float_linear`, cast channel count to `stbir_pixel_layout`
-
- stbir_resize_uint8_srgb():
- - function name is unchanged
- - cast channel count to `stbir_pixel_layout`
- - above is sufficient unless your image has alpha and it's not RGBA/BGRA
- - in that case, follow the below instructions for stbir_resize_uint8_srgb_edgemode
-
- stbir_resize_uint8_srgb_edgemode()
- - switch to the "medium complexity" API
- - stbir_resize(), very similar API but a few more parameters:
- - pixel_layout: cast channel count to `stbir_pixel_layout`
- - data_type: STBIR_TYPE_UINT8_SRGB
- - edge: unchanged (STBIR_EDGE_WRAP, etc.)
- - filter: STBIR_FILTER_DEFAULT
- - which channel is alpha is specified in stbir_pixel_layout, see enum for details
-
EASY API CALLS:
Easy API downsamples w/Mitchell filter, upsamples w/cubic interpolation, clamps to edge.
@@ -296,6 +267,34 @@
ASSERT
Define STBIR_ASSERT(boolval) to override assert() and not use assert.h
+ PORTING FROM VERSION 1
+ The API has changed. You can continue to use the old version of stb_image_resize.h,
+ which is available in the "deprecated/" directory.
+
+ If you're using the old simple-to-use API, porting is straightforward.
+ (For more advanced APIs, read the documentation.)
+
+ stbir_resize_uint8():
+ - call `stbir_resize_uint8_linear`, cast channel count to `stbir_pixel_layout`
+
+ stbir_resize_float():
+ - call `stbir_resize_float_linear`, cast channel count to `stbir_pixel_layout`
+
+ stbir_resize_uint8_srgb():
+ - function name is unchanged
+ - cast channel count to `stbir_pixel_layout`
+ - above is sufficient unless your image has alpha and it's not RGBA/BGRA
+ - in that case, follow the below instructions for stbir_resize_uint8_srgb_edgemode
+
+ stbir_resize_uint8_srgb_edgemode()
+ - switch to the "medium complexity" API
+ - stbir_resize(), very similar API but a few more parameters:
+ - pixel_layout: cast channel count to `stbir_pixel_layout`
+ - data_type: STBIR_TYPE_UINT8_SRGB
+ - edge: unchanged (STBIR_EDGE_WRAP, etc.)
+ - filter: STBIR_FILTER_DEFAULT
+ - which channel is alpha is specified in stbir_pixel_layout, see enum for details
+
FUTURE TODOS
* For polyphase integral filters, we just memcpy the coeffs to dupe
them, but we should indirect and use the same coeff memory.
@@ -328,6 +327,10 @@
Nathan Reed: warning fixes for 1.0
REVISIONS
+ 2.12 (2024-10-18) fix incorrect use of user_data with STBIR_FREE
+ 2.11 (2024-09-08) fix harmless asan warnings in 2-channel and 3-channel mode
+ with AVX-2, fix some weird scaling edge conditions with
+ point sample mode.
2.10 (2024-07-27) fix the defines GCC and mingw for loop unroll control,
fix MSVC 32-bit arm half float routines.
2.09 (2024-06-19) fix the defines for 32-bit ARM GCC builds (was selecting
@@ -3247,6 +3250,7 @@ static void stbir__calculate_in_pixel_range( int * first_pixel, int * last_pixel
first = (int)(STBIR_FLOORF(in_pixel_influence_lowerbound + 0.5f));
last = (int)(STBIR_FLOORF(in_pixel_influence_upperbound - 0.5f));
+ if ( last < first ) last = first; // point sample mode can span a value *right* at 0.5, and cause these to cross
if ( edge == STBIR_EDGE_WRAP )
{
@@ -3282,6 +3286,11 @@ static void stbir__calculate_coefficients_for_gather_upsample( float out_filter_
stbir__calculate_in_pixel_range( &in_first_pixel, &in_last_pixel, out_pixel_center, out_filter_radius, inv_scale, out_shift, input_size, edge );
+ // make sure we never generate a range larger than our precalculated coeff width
+ // this only happens in point sample mode, but it's a good safe thing to do anyway
+ if ( ( in_last_pixel - in_first_pixel + 1 ) > coefficient_width )
+ in_last_pixel = in_first_pixel + coefficient_width - 1;
+
last_non_zero = -1;
for (i = 0; i <= in_last_pixel - in_first_pixel; i++)
{
@@ -3317,19 +3326,22 @@ static void stbir__calculate_coefficients_for_gather_upsample( float out_filter_
}
}
-static void stbir__insert_coeff( stbir__contributors * contribs, float * coeffs, int new_pixel, float new_coeff )
+static void stbir__insert_coeff( stbir__contributors * contribs, float * coeffs, int new_pixel, float new_coeff, int max_width )
{
if ( new_pixel <= contribs->n1 ) // before the end
{
if ( new_pixel < contribs->n0 ) // before the front?
{
- int j, o = contribs->n0 - new_pixel;
- for ( j = contribs->n1 - contribs->n0 ; j <= 0 ; j-- )
- coeffs[ j + o ] = coeffs[ j ];
- for ( j = 1 ; j < o ; j-- )
- coeffs[ j ] = coeffs[ 0 ];
- coeffs[ 0 ] = new_coeff;
- contribs->n0 = new_pixel;
+ if ( ( contribs->n1 - new_pixel + 1 ) <= max_width )
+ {
+ int j, o = contribs->n0 - new_pixel;
+ for ( j = contribs->n1 - contribs->n0 ; j <= 0 ; j-- )
+ coeffs[ j + o ] = coeffs[ j ];
+ for ( j = 1 ; j < o ; j-- )
+ coeffs[ j ] = coeffs[ 0 ];
+ coeffs[ 0 ] = new_coeff;
+ contribs->n0 = new_pixel;
+ }
}
else
{
@@ -3338,12 +3350,15 @@ static void stbir__insert_coeff( stbir__contributors * contribs, float * coeffs,
}
else
{
- int j, e = new_pixel - contribs->n0;
- for( j = ( contribs->n1 - contribs->n0 ) + 1 ; j < e ; j++ ) // clear in-betweens coeffs if there are any
- coeffs[j] = 0;
+ if ( ( new_pixel - contribs->n0 + 1 ) <= max_width )
+ {
+ int j, e = new_pixel - contribs->n0;
+ for( j = ( contribs->n1 - contribs->n0 ) + 1 ; j < e ; j++ ) // clear in-betweens coeffs if there are any
+ coeffs[j] = 0;
- coeffs[ e ] = new_coeff;
- contribs->n1 = new_pixel;
+ coeffs[ e ] = new_coeff;
+ contribs->n1 = new_pixel;
+ }
}
}
@@ -3522,6 +3537,7 @@ static void stbir__cleanup_gathered_coefficients( stbir_edge edge, stbir__filter
coeffs = coefficient_group;
contribs = contributors;
+
for (n = 0; n < num_contributors; n++)
{
int i;
@@ -3561,7 +3577,7 @@ static void stbir__cleanup_gathered_coefficients( stbir_edge edge, stbir__filter
int endi = contribs->n1;
contribs->n1 = input_last_n1;
for( i = input_size; i <= endi; i++ )
- stbir__insert_coeff( contribs, coeffs, stbir__edge_wrap_slow[edge]( i, input_size ), coeffs[i-start] );
+ stbir__insert_coeff( contribs, coeffs, stbir__edge_wrap_slow[edge]( i, input_size ), coeffs[i-start], coefficient_width );
}
// now check left hand edge
@@ -3573,7 +3589,7 @@ static void stbir__cleanup_gathered_coefficients( stbir_edge edge, stbir__filter
// reinsert the coeffs with it reflected or clamped (insert accumulates, if the coeffs exist)
for( i = -1 ; i > contribs->n0 ; i-- )
- stbir__insert_coeff( contribs, coeffs, stbir__edge_wrap_slow[edge]( i, input_size ), *c-- );
+ stbir__insert_coeff( contribs, coeffs, stbir__edge_wrap_slow[edge]( i, input_size ), *c--, coefficient_width );
save_n0 = contribs->n0;
save_n0_coeff = c[0]; // save it, since we didn't do the final one (i==n0), because there might be too many coeffs to hold (before we resize)!
@@ -3583,7 +3599,7 @@ static void stbir__cleanup_gathered_coefficients( stbir_edge edge, stbir__filter
coeffs[i] = coeffs[i-save_n0];
// now that we have shrunk down the contribs, we insert the first one safely
- stbir__insert_coeff( contribs, coeffs, stbir__edge_wrap_slow[edge]( save_n0, input_size ), save_n0_coeff );
+ stbir__insert_coeff( contribs, coeffs, stbir__edge_wrap_slow[edge]( save_n0, input_size ), save_n0_coeff, coefficient_width );
}
}
@@ -3592,6 +3608,7 @@ static void stbir__cleanup_gathered_coefficients( stbir_edge edge, stbir__filter
int diff = contribs->n1 - contribs->n0 + 1;
while ( diff && ( coeffs[ diff-1 ] == 0.0f ) )
--diff;
+
contribs->n1 = contribs->n0 + diff - 1;
if ( contribs->n0 <= contribs->n1 )
@@ -3964,7 +3981,7 @@ static void stbir__calculate_filters( stbir__sampler * samp, stbir__sampler * ot
}
else
{
- stbir__insert_coeff( scatter_contributors, scatter_coeffs, n, gc );
+ stbir__insert_coeff( scatter_contributors, scatter_coeffs, n, gc, scatter_coefficient_width );
}
STBIR_ASSERT( ( scatter_contributors->n1 - scatter_contributors->n0 + 1 ) <= scatter_coefficient_width );
}
@@ -4810,12 +4827,13 @@ static void stbir__decode_scanline(stbir__info const * stbir_info, int n, float
stbir__simdf8_madd_mem( tot0, tot0, c, decode+(ofs)*2 );
#define stbir__1_coeff_remnant( ofs ) \
- { stbir__simdf t; \
+ { stbir__simdf t,d; \
stbir__simdf_load1z( t, hc + (ofs) ); \
+ stbir__simdf_load2( d, decode + (ofs) * 2 ); \
stbir__simdf_0123to0011( t, t ); \
- stbir__simdf_mult_mem( t, t, decode+(ofs)*2 ); \
+ stbir__simdf_mult( t, t, d ); \
stbir__simdf8_add4( tot0, tot0, t ); }
-
+
#define stbir__2_coeff_remnant( ofs ) \
{ stbir__simdf t; \
stbir__simdf_load2( t, hc + (ofs) ); \
@@ -6714,7 +6732,7 @@ static void stbir__free_internal_mem( stbir__info *info )
STBIR__FREE_AND_CLEAR( info->horizontal.coefficients );
STBIR__FREE_AND_CLEAR( info->horizontal.contributors );
STBIR__FREE_AND_CLEAR( info->alloced_mem );
- STBIR__FREE_AND_CLEAR( info );
+ STBIR_FREE( info, info->user_data );
#endif
}
@@ -7112,6 +7130,11 @@ static stbir__info * stbir__alloc_internal_mem_and_build_samplers( stbir__sample
#ifdef STBIR__SEPARATE_ALLOCATIONS
temp_mem_amt = decode_buffer_size;
+
+ #ifdef STBIR_SIMD8
+ if ( effective_channels == 3 )
+ --temp_mem_amt; // avx in 3 channel mode needs one float at the start of the buffer
+ #endif
#else
temp_mem_amt = ( decode_buffer_size + ring_buffer_size + vertical_buffer_size ) * splits;
#endif
@@ -7217,6 +7240,12 @@ static stbir__info * stbir__alloc_internal_mem_and_build_samplers( stbir__sample
int t, ofs, start;
ofs = decode_buffer_size / 4;
+
+ #if defined( STBIR__SEPARATE_ALLOCATIONS ) && defined(STBIR_SIMD8)
+ if ( effective_channels == 3 )
+ --ofs; // avx in 3 channel mode needs one float at the start of the buffer, so we snap back for clearing
+ #endif
+
start = ofs - 4;
if ( start < 0 ) start = 0;
diff --git a/src/external/stb_truetype.h b/src/external/stb_truetype.h
index bbf2284b1..90a5c2e2b 100644
--- a/src/external/stb_truetype.h
+++ b/src/external/stb_truetype.h
@@ -54,7 +54,7 @@
// Hou Qiming Derek Vinyard
// Rob Loach Cort Stratton
// Kenney Phillis Jr. Brian Costabile
-// Ken Voskuil (kaesve)
+// Ken Voskuil (kaesve) Yakov Galka
//
// VERSION HISTORY
//
@@ -4604,6 +4604,8 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc
scale_y = -scale_y;
{
+ // distance from singular values (in the same units as the pixel grid)
+ const float eps = 1./1024, eps2 = eps*eps;
int x,y,i,j;
float *precompute;
stbtt_vertex *verts;
@@ -4616,15 +4618,15 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc
float x0 = verts[i].x*scale_x, y0 = verts[i].y*scale_y;
float x1 = verts[j].x*scale_x, y1 = verts[j].y*scale_y;
float dist = (float) STBTT_sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0));
- precompute[i] = (dist == 0) ? 0.0f : 1.0f / dist;
+ precompute[i] = (dist < eps) ? 0.0f : 1.0f / dist;
} else if (verts[i].type == STBTT_vcurve) {
float x2 = verts[j].x *scale_x, y2 = verts[j].y *scale_y;
float x1 = verts[i].cx*scale_x, y1 = verts[i].cy*scale_y;
float x0 = verts[i].x *scale_x, y0 = verts[i].y *scale_y;
float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2;
float len2 = bx*bx + by*by;
- if (len2 != 0.0f)
- precompute[i] = 1.0f / (bx*bx + by*by);
+ if (len2 >= eps2)
+ precompute[i] = 1.0f / len2;
else
precompute[i] = 0.0f;
} else
@@ -4689,8 +4691,8 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc
float a = 3*(ax*bx + ay*by);
float b = 2*(ax*ax + ay*ay) + (mx*bx+my*by);
float c = mx*ax+my*ay;
- if (a == 0.0) { // if a is 0, it's linear
- if (b != 0.0) {
+ if (STBTT_fabs(a) < eps2) { // if a is 0, it's linear
+ if (STBTT_fabs(b) >= eps2) {
res[num++] = -c/b;
}
} else {
diff --git a/src/platforms/rcore_android.c b/src/platforms/rcore_android.c
index 88438c9b0..85ce82a3a 100644
--- a/src/platforms/rcore_android.c
+++ b/src/platforms/rcore_android.c
@@ -615,7 +615,7 @@ int SetGamepadMappings(const char *mappings)
}
// 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");
}
diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c
index 0bc52ac9e..41f7fac39 100644
--- a/src/platforms/rcore_desktop_glfw.c
+++ b/src/platforms/rcore_desktop_glfw.c
@@ -1060,7 +1060,7 @@ int SetGamepadMappings(const char *mappings)
}
// 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");
}
diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c
index b4ceb78eb..7cbe0354e 100644
--- a/src/platforms/rcore_desktop_sdl.c
+++ b/src/platforms/rcore_desktop_sdl.c
@@ -953,17 +953,17 @@ int SetGamepadMappings(const char *mappings)
}
// 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));
}
}
diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c
index e77457b1b..eb8ef0103 100644
--- a/src/platforms/rcore_drm.c
+++ b/src/platforms/rcore_drm.c
@@ -610,7 +610,7 @@ int SetGamepadMappings(const char *mappings)
}
// 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 @@ int InitPlatform(void)
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))
diff --git a/src/platforms/rcore_web.c b/src/platforms/rcore_web.c
index 36af66a47..e15d3f5bf 100644
--- a/src/platforms/rcore_web.c
+++ b/src/platforms/rcore_web.c
@@ -324,8 +324,8 @@ void MaximizeWindow(void)
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);
+ const int tabWidth = EM_ASM_INT( return window.innerWidth; );
+ const int tabHeight = EM_ASM_INT( return window.innerHeight; );
if (tabWidth && tabHeight) glfwSetWindowSize(platform.handle, tabWidth, tabHeight);
@@ -423,8 +423,8 @@ void SetWindowState(unsigned int flags)
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);
+ const int tabWidth = EM_ASM_INT( return window.innerWidth; );
+ const int tabHeight = EM_ASM_INT( return window.innerHeight; );
if (tabWidth && tabHeight) glfwSetWindowSize(platform.handle, tabWidth, tabHeight);
@@ -892,9 +892,34 @@ int SetGamepadMappings(const char *mappings)
}
// 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
@@ -1614,9 +1639,6 @@ static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const Emscripte
// return 1; // The event was consumed by the callback handler
// }
-EM_JS(int, GetWindowInnerWidth, (), { return window.innerWidth; });
-EM_JS(int, GetWindowInnerHeight, (), { return window.innerHeight; });
-
// Register DOM element resize event
static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent *event, void *userData)
{
@@ -1625,8 +1647,8 @@ static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent *
// This event is called whenever the window changes sizes,
// so the size of the canvas object is explicitly retrieved below
- int width = GetWindowInnerWidth();
- int height = GetWindowInnerHeight();
+ int width = EM_ASM_INT( return window.innerWidth; );
+ int height = EM_ASM_INT( return window.innerHeight; );
if (width < (int)CORE.Window.screenMin.width) width = CORE.Window.screenMin.width;
else if (width > (int)CORE.Window.screenMax.width && CORE.Window.screenMax.width > 0) width = CORE.Window.screenMax.width;
diff --git a/src/raylib.h b/src/raylib.h
index 25ee6943f..c9d9f6e54 100644
--- a/src/raylib.h
+++ b/src/raylib.h
@@ -1,22 +1,22 @@
/**********************************************************************************************
*
-* raylib v5.5-dev - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com)
+* raylib v5.5 - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com)
*
* FEATURES:
* - NO external dependencies, all required libraries included with raylib
* - Multiplatform: Windows, Linux, FreeBSD, OpenBSD, NetBSD, DragonFly,
* MacOS, Haiku, Android, Raspberry Pi, DRM native, HTML5.
* - Written in plain C code (C99) in PascalCase/camelCase notation
-* - Hardware accelerated with OpenGL (1.1, 2.1, 3.3, 4.3 or ES2 - choose at compile)
+* - Hardware accelerated with OpenGL (1.1, 2.1, 3.3, 4.3, ES2, ES3 - choose at compile)
* - Unique OpenGL abstraction layer (usable as standalone module): [rlgl]
-* - Multiple Fonts formats supported (TTF, XNA fonts, AngelCode fonts)
+* - Multiple Fonts formats supported (TTF, OTF, FNT, BDF, Sprite fonts)
* - Outstanding texture formats support, including compressed formats (DXT, ETC, ASTC)
* - Full 3d support for 3d Shapes, Models, Billboards, Heightmaps and more!
* - Flexible Materials system, supporting classic maps and PBR maps
-* - Animated 3D models supported (skeletal bones animation) (IQM)
+* - Animated 3D models supported (skeletal bones animation) (IQM, M3D, GLTF)
* - Shaders support, including Model shaders and Postprocessing shaders
* - Powerful math module for Vector, Matrix and Quaternion operations: [raymath]
-* - Audio loading and playing with streaming support (WAV, OGG, MP3, FLAC, XM, MOD)
+* - Audio loading and playing with streaming support (WAV, OGG, MP3, FLAC, QOA, XM, MOD)
* - VR stereo rendering with configurable HMD device parameters
* - Bindings to multiple programming languages available!
*
@@ -27,29 +27,35 @@
* - One default RenderBatch is loaded on rlglInit()->rlLoadRenderBatch() [rlgl] (OpenGL 3.3 or ES2)
*
* DEPENDENCIES (included):
-* [rcore] rglfw (Camilla Löwy - github.com/glfw/glfw) for window/context management and input (PLATFORM_DESKTOP)
-* [rlgl] glad (David Herberth - github.com/Dav1dde/glad) for OpenGL 3.3 extensions loading (PLATFORM_DESKTOP)
+* [rcore][GLFW] rglfw (Camilla Löwy - github.com/glfw/glfw) for window/context management and input
+* [rcore][RGFW] rgfw (ColleagueRiley - github.com/ColleagueRiley/RGFW) for window/context management and input
+* [rlgl] glad/glad_gles2 (David Herberth - github.com/Dav1dde/glad) for OpenGL 3.3 extensions loading
* [raudio] miniaudio (David Reid - github.com/mackron/miniaudio) for audio device/context management
*
* OPTIONAL DEPENDENCIES (included):
* [rcore] msf_gif (Miles Fogle) for GIF recording
* [rcore] sinfl (Micha Mettke) for DEFLATE decompression algorithm
* [rcore] sdefl (Micha Mettke) for DEFLATE compression algorithm
+* [rcore] rprand (Ramon Snatamaria) for pseudo-random numbers generation
+* [rtextures] qoi (Dominic Szablewski - https://phoboslab.org) for QOI image manage
* [rtextures] stb_image (Sean Barret) for images loading (BMP, TGA, PNG, JPEG, HDR...)
* [rtextures] stb_image_write (Sean Barret) for image writing (BMP, TGA, PNG, JPG)
-* [rtextures] stb_image_resize (Sean Barret) for image resizing algorithms
+* [rtextures] stb_image_resize2 (Sean Barret) for image resizing algorithms
+* [rtextures] stb_perlin (Sean Barret) for Perlin Noise image generation
* [rtext] stb_truetype (Sean Barret) for ttf fonts loading
* [rtext] stb_rect_pack (Sean Barret) for rectangles packing
* [rmodels] par_shapes (Philip Rideout) for parametric 3d shapes generation
* [rmodels] tinyobj_loader_c (Syoyo Fujita) for models loading (OBJ, MTL)
* [rmodels] cgltf (Johannes Kuhlmann) for models loading (glTF)
-* [rmodels] Model3D (bzt) for models loading (M3D, https://bztsrc.gitlab.io/model3d)
+* [rmodels] m3d (bzt) for models loading (M3D, https://bztsrc.gitlab.io/model3d)
+* [rmodels] vox_loader (Johann Nadalutti) for models loading (VOX)
* [raudio] dr_wav (David Reid) for WAV audio file loading
* [raudio] dr_flac (David Reid) for FLAC audio file loading
* [raudio] dr_mp3 (David Reid) for MP3 audio file loading
* [raudio] stb_vorbis (Sean Barret) for OGG audio loading
* [raudio] jar_xm (Joshua Reisenauer) for XM audio module loading
* [raudio] jar_mod (Joshua Reisenauer) for MOD audio module loading
+* [raudio] qoa (Dominic Szablewski - https://phoboslab.org) for QOA audio manage
*
*
* LICENSE: zlib/libpng
@@ -84,7 +90,7 @@
#define RAYLIB_VERSION_MAJOR 5
#define RAYLIB_VERSION_MINOR 5
#define RAYLIB_VERSION_PATCH 0
-#define RAYLIB_VERSION "5.5-dev"
+#define RAYLIB_VERSION "5.5"
// Function specifiers in case library is build/used as a shared library
// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
@@ -877,8 +883,7 @@ typedef enum {
CUBEMAP_LAYOUT_LINE_VERTICAL, // Layout is defined by a vertical line with faces
CUBEMAP_LAYOUT_LINE_HORIZONTAL, // Layout is defined by a horizontal line with faces
CUBEMAP_LAYOUT_CROSS_THREE_BY_FOUR, // Layout is defined by a 3x4 cross with cubemap faces
- CUBEMAP_LAYOUT_CROSS_FOUR_BY_THREE, // Layout is defined by a 4x3 cross with cubemap faces
- CUBEMAP_LAYOUT_PANORAMA // Layout is defined by a panorama image (equirrectangular map)
+ CUBEMAP_LAYOUT_CROSS_FOUR_BY_THREE // Layout is defined by a 4x3 cross with cubemap faces
} CubemapLayout;
// Font type, defines generation method
@@ -965,36 +970,36 @@ RLAPI void CloseWindow(void); // Close windo
RLAPI bool WindowShouldClose(void); // Check if application should close (KEY_ESCAPE pressed or windows close icon clicked)
RLAPI bool IsWindowReady(void); // Check if window has been initialized successfully
RLAPI bool IsWindowFullscreen(void); // Check if window is currently fullscreen
-RLAPI bool IsWindowHidden(void); // Check if window is currently hidden (only PLATFORM_DESKTOP)
-RLAPI bool IsWindowMinimized(void); // Check if window is currently minimized (only PLATFORM_DESKTOP)
-RLAPI bool IsWindowMaximized(void); // Check if window is currently maximized (only PLATFORM_DESKTOP)
-RLAPI bool IsWindowFocused(void); // Check if window is currently focused (only PLATFORM_DESKTOP)
+RLAPI bool IsWindowHidden(void); // Check if window is currently hidden
+RLAPI bool IsWindowMinimized(void); // Check if window is currently minimized
+RLAPI bool IsWindowMaximized(void); // Check if window is currently maximized
+RLAPI bool IsWindowFocused(void); // Check if window is currently focused
RLAPI bool IsWindowResized(void); // Check if window has been resized last frame
RLAPI bool IsWindowState(unsigned int flag); // Check if one specific window flag is enabled
-RLAPI void SetWindowState(unsigned int flags); // Set window configuration state using flags (only PLATFORM_DESKTOP)
+RLAPI void SetWindowState(unsigned int flags); // Set window configuration state using flags
RLAPI void ClearWindowState(unsigned int flags); // Clear window configuration state flags
-RLAPI void ToggleFullscreen(void); // Toggle window state: fullscreen/windowed [resizes monitor to match window resolution] (only PLATFORM_DESKTOP)
-RLAPI void ToggleBorderlessWindowed(void); // Toggle window state: borderless windowed [resizes window to match monitor resolution] (only PLATFORM_DESKTOP)
-RLAPI void MaximizeWindow(void); // Set window state: maximized, if resizable (only PLATFORM_DESKTOP)
-RLAPI void MinimizeWindow(void); // Set window state: minimized, if resizable (only PLATFORM_DESKTOP)
-RLAPI void RestoreWindow(void); // Set window state: not minimized/maximized (only PLATFORM_DESKTOP)
-RLAPI void SetWindowIcon(Image image); // Set icon for window (single image, RGBA 32bit, only PLATFORM_DESKTOP)
-RLAPI void SetWindowIcons(Image *images, int count); // Set icon for window (multiple images, RGBA 32bit, only PLATFORM_DESKTOP)
-RLAPI void SetWindowTitle(const char *title); // Set title for window (only PLATFORM_DESKTOP and PLATFORM_WEB)
-RLAPI void SetWindowPosition(int x, int y); // Set window position on screen (only PLATFORM_DESKTOP)
+RLAPI void ToggleFullscreen(void); // Toggle window state: fullscreen/windowed, resizes monitor to match window resolution
+RLAPI void ToggleBorderlessWindowed(void); // Toggle window state: borderless windowed, resizes window to match monitor resolution
+RLAPI void MaximizeWindow(void); // Set window state: maximized, if resizable
+RLAPI void MinimizeWindow(void); // Set window state: minimized, if resizable
+RLAPI void RestoreWindow(void); // Set window state: not minimized/maximized
+RLAPI void SetWindowIcon(Image image); // Set icon for window (single image, RGBA 32bit)
+RLAPI void SetWindowIcons(Image *images, int count); // Set icon for window (multiple images, RGBA 32bit)
+RLAPI void SetWindowTitle(const char *title); // Set title for window
+RLAPI void SetWindowPosition(int x, int y); // Set window position on screen
RLAPI void SetWindowMonitor(int monitor); // Set monitor for the current window
RLAPI void SetWindowMinSize(int width, int height); // Set window minimum dimensions (for FLAG_WINDOW_RESIZABLE)
RLAPI void SetWindowMaxSize(int width, int height); // Set window maximum dimensions (for FLAG_WINDOW_RESIZABLE)
RLAPI void SetWindowSize(int width, int height); // Set window dimensions
-RLAPI void SetWindowOpacity(float opacity); // Set window opacity [0.0f..1.0f] (only PLATFORM_DESKTOP)
-RLAPI void SetWindowFocused(void); // Set window focused (only PLATFORM_DESKTOP)
+RLAPI void SetWindowOpacity(float opacity); // Set window opacity [0.0f..1.0f]
+RLAPI void SetWindowFocused(void); // Set window focused
RLAPI void *GetWindowHandle(void); // Get native window handle
RLAPI int GetScreenWidth(void); // Get current screen width
RLAPI int GetScreenHeight(void); // Get current screen height
RLAPI int GetRenderWidth(void); // Get current render width (it considers HiDPI)
RLAPI int GetRenderHeight(void); // Get current render height (it considers HiDPI)
RLAPI int GetMonitorCount(void); // Get number of connected monitors
-RLAPI int GetCurrentMonitor(void); // Get current connected monitor
+RLAPI int GetCurrentMonitor(void); // Get current monitor where window is placed
RLAPI Vector2 GetMonitorPosition(int monitor); // Get specified monitor position
RLAPI int GetMonitorWidth(int monitor); // Get specified monitor width (current video mode used by monitor)
RLAPI int GetMonitorHeight(int monitor); // Get specified monitor height (current video mode used by monitor)
@@ -1165,7 +1170,7 @@ RLAPI void PlayAutomationEvent(AutomationEvent event);
// Input-related functions: keyboard
RLAPI bool IsKeyPressed(int key); // Check if a key has been pressed once
-RLAPI bool IsKeyPressedRepeat(int key); // Check if a key has been pressed again (Only PLATFORM_DESKTOP)
+RLAPI bool IsKeyPressedRepeat(int key); // Check if a key has been pressed again
RLAPI bool IsKeyDown(int key); // Check if a key is being pressed
RLAPI bool IsKeyReleased(int key); // Check if a key has been released once
RLAPI bool IsKeyUp(int key); // Check if a key is NOT being pressed
@@ -1184,7 +1189,7 @@ RLAPI int GetGamepadButtonPressed(void);
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
@@ -1299,13 +1304,13 @@ RLAPI Vector2 GetSplinePointBezierCubic(Vector2 p1, Vector2 c2, Vector2 c3, Vect
RLAPI bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles
RLAPI bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles
RLAPI bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec); // Check collision between circle and rectangle
+RLAPI bool CheckCollisionCircleLine(Vector2 center, float radius, Vector2 p1, Vector2 p2); // Check if circle collides with a line created betweeen two points [p1] and [p2]
RLAPI bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
RLAPI bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius); // Check if point is inside circle
RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3); // Check if point is inside a triangle
+RLAPI bool CheckCollisionPointLine(Vector2 point, Vector2 p1, Vector2 p2, int threshold); // Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold]
RLAPI bool CheckCollisionPointPoly(Vector2 point, const Vector2 *points, int pointCount); // Check if point is within a polygon described by array of vertices
RLAPI bool CheckCollisionLines(Vector2 startPos1, Vector2 endPos1, Vector2 startPos2, Vector2 endPos2, Vector2 *collisionPoint); // Check the collision between two lines defined by two points each, returns collision point by reference
-RLAPI bool CheckCollisionPointLine(Vector2 point, Vector2 p1, Vector2 p2, int threshold); // Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold]
-RLAPI bool CheckCollisionCircleLine(Vector2 center, float radius, Vector2 p1, Vector2 p2); // Check if circle collides with a line created betweeen two points [p1] and [p2]
RLAPI Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2); // Get collision rectangle for two rectangles collision
//------------------------------------------------------------------------------------
@@ -1596,11 +1601,11 @@ RLAPI void SetModelMeshMaterial(Model *model, int meshId, int materialId);
// Model animations loading/unloading functions
RLAPI ModelAnimation *LoadModelAnimations(const char *fileName, int *animCount); // Load model animations from file
-RLAPI void UpdateModelAnimation(Model model, ModelAnimation anim, int frame); // Update model animation pose
+RLAPI void UpdateModelAnimation(Model model, ModelAnimation anim, int frame); // Update model animation pose (CPU)
+RLAPI void UpdateModelAnimationBoneMatrices(Model model, ModelAnimation anim, int frame); // Update model animation mesh bone matrices (GPU skinning)
RLAPI void UnloadModelAnimation(ModelAnimation anim); // Unload animation data
RLAPI void UnloadModelAnimations(ModelAnimation *animations, int animCount); // Unload animation array data
RLAPI bool IsModelAnimationValid(Model model, ModelAnimation anim); // Check model animation skeleton match
-RLAPI void UpdateModelAnimationBoneMatrices(Model model, ModelAnimation anim, int frame); // Update model animation mesh bone matrices (Note GPU skinning does not work on Mac)
// Collision detection functions
RLAPI bool CheckCollisionSpheres(Vector3 center1, float radius1, Vector3 center2, float radius2); // Check collision between two spheres
diff --git a/src/rcore.c b/src/rcore.c
index a1771d18e..9734972cf 100644
--- a/src/rcore.c
+++ b/src/rcore.c
@@ -3295,8 +3295,7 @@ float GetGamepadAxisMovement(int gamepad, int axis)
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (axis < MAX_GAMEPAD_AXIS)) {
float movement = value < 0.0f ? CORE.Input.Gamepad.axisState[gamepad][axis] : fabsf(CORE.Input.Gamepad.axisState[gamepad][axis]);
- // 0.1f = GAMEPAD_AXIS_MINIMUM_DRIFT/DELTA
- if (movement > value + 0.1f) value = CORE.Input.Gamepad.axisState[gamepad][axis];
+ if (movement > value) value = CORE.Input.Gamepad.axisState[gamepad][axis];
}
return value;
diff --git a/src/rlgl.h b/src/rlgl.h
index 6cfc2dcfb..34cae97e8 100644
--- a/src/rlgl.h
+++ b/src/rlgl.h
@@ -8,17 +8,17 @@
*
* ADDITIONAL NOTES:
* When choosing an OpenGL backend different than OpenGL 1.1, some internal buffer are
-* initialized on rlglInit() to accumulate vertex data.
+* initialized on rlglInit() to accumulate vertex data
*
* When an internal state change is required all the stored vertex data is renderer in batch,
-* additionally, rlDrawRenderBatchActive() could be called to force flushing of the batch.
+* additionally, rlDrawRenderBatchActive() could be called to force flushing of the batch
*
* Some resources are also loaded for convenience, here the complete list:
* - Default batch (RLGL.defaultBatch): RenderBatch system to accumulate vertex data
* - Default texture (RLGL.defaultTextureId): 1x1 white pixel R8G8B8A8
* - Default shader (RLGL.State.defaultShaderId, RLGL.State.defaultShaderLocs)
*
-* Internal buffer (and resources) must be manually unloaded calling rlglClose().
+* Internal buffer (and resources) must be manually unloaded calling rlglClose()
*
* CONFIGURATION:
* #define GRAPHICS_API_OPENGL_11
@@ -32,9 +32,9 @@
* required by any other module, use rlGetVersion() to check it
*
* #define RLGL_IMPLEMENTATION
-* Generates the implementation of the library into the included file.
+* Generates the implementation of the library into the included file
* If not defined, the library is in header only mode and can be included in other headers
-* or source files without problems. But only ONE file should hold the implementation.
+* or source files without problems. But only ONE file should hold the implementation
*
* #define RLGL_RENDER_TEXTURES_HINT
* Enable framebuffer objects (fbo) support (enabled by default)
@@ -749,7 +749,7 @@ RLAPI void rlDrawVertexArrayElementsInstanced(int offset, int count, const void
// Textures management
RLAPI unsigned int rlLoadTexture(const void *data, int width, int height, int format, int mipmapCount); // Load texture data
RLAPI unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer); // Load depth texture/renderbuffer (to be attached to fbo)
-RLAPI unsigned int rlLoadTextureCubemap(const void *data, int size, int format); // Load texture cubemap data
+RLAPI unsigned int rlLoadTextureCubemap(const void *data, int size, int format, int mipmapCount); // Load texture cubemap data
RLAPI void rlUpdateTexture(unsigned int id, int offsetX, int offsetY, int width, int height, int format, const void *data); // Update texture with new data on GPU
RLAPI void rlGetGlTextureFormats(int format, unsigned int *glInternalFormat, unsigned int *glFormat, unsigned int *glType); // Get OpenGL internal formats
RLAPI const char *rlGetPixelFormatName(unsigned int format); // Get name string for pixel format
@@ -1503,8 +1503,8 @@ void rlVertex3f(float x, float y, float z)
tz = RLGL.State.transform.m2*x + RLGL.State.transform.m6*y + RLGL.State.transform.m10*z + RLGL.State.transform.m14;
}
- // WARNING: We can't break primitives when launching a new batch.
- // RL_LINES comes in pairs, RL_TRIANGLES come in groups of 3 vertices and RL_QUADS come in groups of 4 vertices.
+ // WARNING: We can't break primitives when launching a new batch
+ // RL_LINES comes in pairs, RL_TRIANGLES come in groups of 3 vertices and RL_QUADS come in groups of 4 vertices
// We must check current draw.mode when a new vertex is required and finish the batch only if the draw.mode draw.vertexCount is %2, %3 or %4
if (RLGL.State.vertexCounter > (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4 - 4))
{
@@ -2933,11 +2933,11 @@ void rlDrawRenderBatch(rlRenderBatch *batch)
glBufferSubData(GL_ARRAY_BUFFER, 0, RLGL.State.vertexCounter*4*sizeof(unsigned char), batch->vertexBuffer[batch->currentBuffer].colors);
//glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*4*batch->vertexBuffer[batch->currentBuffer].elementCount, batch->vertexBuffer[batch->currentBuffer].colors, GL_DYNAMIC_DRAW); // Update all buffer
- // NOTE: glMapBuffer() causes sync issue.
- // If GPU is working with this buffer, glMapBuffer() will wait(stall) until GPU to finish its job.
- // To avoid waiting (idle), you can call first glBufferData() with NULL pointer before glMapBuffer().
+ // NOTE: glMapBuffer() causes sync issue
+ // If GPU is working with this buffer, glMapBuffer() will wait(stall) until GPU to finish its job
+ // To avoid waiting (idle), you can call first glBufferData() with NULL pointer before glMapBuffer()
// If you do that, the previous data in PBO will be discarded and glMapBuffer() returns a new
- // allocated pointer immediately even if GPU is still working with the previous data.
+ // allocated pointer immediately even if GPU is still working with the previous data
// Another option: map the buffer object into client's memory
// Probably this code could be moved somewhere else...
@@ -2990,7 +2990,7 @@ void rlDrawRenderBatch(rlRenderBatch *batch)
}
// WARNING: For the following setup of the view, model, and normal matrices, it is expected that
- // transformations and rendering occur between rlPushMatrix and rlPopMatrix.
+ // transformations and rendering occur between rlPushMatrix() and rlPopMatrix()
if (RLGL.State.currentShaderLocs[RL_SHADER_LOC_MATRIX_VIEW] != -1)
{
@@ -3060,15 +3060,15 @@ void rlDrawRenderBatch(rlRenderBatch *batch)
if ((batch->draws[i].mode == RL_LINES) || (batch->draws[i].mode == RL_TRIANGLES)) glDrawArrays(batch->draws[i].mode, vertexOffset, batch->draws[i].vertexCount);
else
{
-#if defined(GRAPHICS_API_OPENGL_33)
+ #if defined(GRAPHICS_API_OPENGL_33)
// We need to define the number of indices to be processed: elementCount*6
// NOTE: The final parameter tells the GPU the offset in bytes from the
// start of the index buffer to the location of the first index to process
glDrawElements(GL_TRIANGLES, batch->draws[i].vertexCount/4*6, GL_UNSIGNED_INT, (GLvoid *)(vertexOffset/4*6*sizeof(GLuint)));
-#endif
-#if defined(GRAPHICS_API_OPENGL_ES2)
+ #endif
+ #if defined(GRAPHICS_API_OPENGL_ES2)
glDrawElements(GL_TRIANGLES, batch->draws[i].vertexCount/4*6, GL_UNSIGNED_SHORT, (GLvoid *)(vertexOffset/4*6*sizeof(GLushort)));
-#endif
+ #endif
}
vertexOffset += (batch->draws[i].vertexCount + batch->draws[i].vertexAlignment);
@@ -3386,11 +3386,17 @@ unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer)
// Load texture cubemap
// NOTE: Cubemap data is expected to be 6 images in a single data array (one after the other),
// expected the following convention: +X, -X, +Y, -Y, +Z, -Z
-unsigned int rlLoadTextureCubemap(const void *data, int size, int format)
+unsigned int rlLoadTextureCubemap(const void *data, int size, int format, int mipmapCount)
{
unsigned int id = 0;
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
+ int mipSize = size;
+
+ // NOTE: Added pointer math separately from function to avoid UBSAN complaining
+ unsigned char *dataPtr = NULL;
+ if (data != NULL) dataPtr = (unsigned char *)data;
+
unsigned int dataSize = rlGetPixelDataSize(size, size, format);
glGenTextures(1, &id);
@@ -3401,24 +3407,28 @@ unsigned int rlLoadTextureCubemap(const void *data, int size, int format)
if (glInternalFormat != 0)
{
- // Load cubemap faces
- for (unsigned int i = 0; i < 6; i++)
+ // Load cubemap faces/mipmaps
+ for (unsigned int i = 0; i < 6*mipmapCount; i++)
{
+ int mipmapLevel = i/6;
+ int face = i%6;
+
if (data == NULL)
{
if (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB)
{
- if ((format == RL_PIXELFORMAT_UNCOMPRESSED_R32) || (format == RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32)
- || (format == RL_PIXELFORMAT_UNCOMPRESSED_R16) || (format == RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16))
- TRACELOG(RL_LOG_WARNING, "TEXTURES: Cubemap requested format not supported");
- else glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, size, size, 0, glFormat, glType, NULL);
+ if ((format == RL_PIXELFORMAT_UNCOMPRESSED_R32) ||
+ (format == RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32) ||
+ (format == RL_PIXELFORMAT_UNCOMPRESSED_R16) ||
+ (format == RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16)) TRACELOG(RL_LOG_WARNING, "TEXTURES: Cubemap requested format not supported");
+ else glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mipmapLevel, glInternalFormat, mipSize, mipSize, 0, glFormat, glType, NULL);
}
else TRACELOG(RL_LOG_WARNING, "TEXTURES: Empty cubemap creation does not support compressed format");
}
else
{
- if (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, size, size, 0, glFormat, glType, (unsigned char *)data + i*dataSize);
- else glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, size, size, 0, dataSize, (unsigned char *)data + i*dataSize);
+ if (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mipmapLevel, glInternalFormat, mipSize, mipSize, 0, glFormat, glType, (unsigned char *)dataPtr + face*dataSize);
+ else glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mipmapLevel, glInternalFormat, mipSize, mipSize, 0, dataSize, (unsigned char *)dataPtr + face*dataSize);
}
#if defined(GRAPHICS_API_OPENGL_33)
@@ -3437,11 +3447,23 @@ unsigned int rlLoadTextureCubemap(const void *data, int size, int format)
glTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
}
#endif
+ if (face == 5)
+ {
+ mipSize /= 2;
+ if (data != NULL) dataPtr += dataSize*6; // Increment data pointer to next mipmap
+
+ // Security check for NPOT textures
+ if (mipSize < 1) mipSize = 1;
+
+ dataSize = rlGetPixelDataSize(mipSize, mipSize, format);
+ }
}
}
// Set cubemap texture sampling parameters
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ if (mipmapCount > 1) glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ else glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
@@ -3600,8 +3622,8 @@ void *rlReadTexturePixels(unsigned int id, int width, int height, int format)
//glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
//glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format);
- // NOTE: Each row written to or read from by OpenGL pixel operations like glGetTexImage are aligned to a 4 byte boundary by default, which may add some padding.
- // Use glPixelStorei to modify padding with the GL_[UN]PACK_ALIGNMENT setting.
+ // NOTE: Each row written to or read from by OpenGL pixel operations like glGetTexImage are aligned to a 4 byte boundary by default, which may add some padding
+ // Use glPixelStorei to modify padding with the GL_[UN]PACK_ALIGNMENT setting
// GL_PACK_ALIGNMENT affects operations that read from OpenGL memory (glReadPixels, glGetTexImage, etc.)
// GL_UNPACK_ALIGNMENT affects operations that write to OpenGL memory (glTexImage, etc.)
glPixelStorei(GL_PACK_ALIGNMENT, 1);
@@ -3622,7 +3644,7 @@ void *rlReadTexturePixels(unsigned int id, int width, int height, int format)
#if defined(GRAPHICS_API_OPENGL_ES2)
// glGetTexImage() is not available on OpenGL ES 2.0
- // Texture width and height are required on OpenGL ES 2.0. There is no way to get it from texture id.
+ // Texture width and height are required on OpenGL ES 2.0, there is no way to get it from texture id
// Two possible Options:
// 1 - Bind texture to color fbo attachment and glReadPixels()
// 2 - Create an fbo, activate it, render quad with texture, glReadPixels()
@@ -3788,7 +3810,7 @@ void rlUnloadFramebuffer(unsigned int id)
else if (depthType == GL_TEXTURE) glDeleteTextures(1, &depthIdU);
// NOTE: If a texture object is deleted while its image is attached to the *currently bound* framebuffer,
- // the texture image is automatically detached from the currently bound framebuffer.
+ // the texture image is automatically detached from the currently bound framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &id);
@@ -4231,7 +4253,7 @@ unsigned int rlLoadShaderProgram(unsigned int vShaderId, unsigned int fShaderId)
else
{
// Get the size of compiled shader program (not available on OpenGL ES 2.0)
- // NOTE: If GL_LINK_STATUS is GL_FALSE, program binary length is zero.
+ // NOTE: If GL_LINK_STATUS is GL_FALSE, program binary length is zero
//GLint binarySize = 0;
//glGetProgramiv(id, GL_PROGRAM_BINARY_LENGTH, &binarySize);
@@ -4337,8 +4359,12 @@ void rlSetUniformMatrix(int locIndex, Matrix mat)
// Set shader value uniform matrix
void rlSetUniformMatrices(int locIndex, const Matrix *matrices, int count)
{
-#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- glUniformMatrix4fv(locIndex, count, true, (const float*)matrices);
+#if defined(GRAPHICS_API_OPENGL_33)
+ glUniformMatrix4fv(locIndex, count, true, (const float *)matrices);
+#elif defined(GRAPHICS_API_OPENGL_ES2)
+ // WARNING: WebGL does not support Matrix transpose ("true" parameter)
+ // REF: https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/uniformMatrix
+ glUniformMatrix4fv(locIndex, count, false, (const float *)matrices);
#endif
}
@@ -4421,7 +4447,7 @@ unsigned int rlLoadComputeShaderProgram(unsigned int shaderId)
else
{
// Get the size of compiled shader program (not available on OpenGL ES 2.0)
- // NOTE: If GL_LINK_STATUS is GL_FALSE, program binary length is zero.
+ // NOTE: If GL_LINK_STATUS is GL_FALSE, program binary length is zero
//GLint binarySize = 0;
//glGetProgramiv(id, GL_PROGRAM_BINARY_LENGTH, &binarySize);
@@ -4942,7 +4968,7 @@ static void rlLoadShaderDefault(void)
RLGL.State.defaultShaderLocs[RL_SHADER_LOC_VERTEX_COLOR] = glGetAttribLocation(RLGL.State.defaultShaderId, RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR);
// Set default shader locations: uniform locations
- RLGL.State.defaultShaderLocs[RL_SHADER_LOC_MATRIX_MVP] = glGetUniformLocation(RLGL.State.defaultShaderId, RL_DEFAULT_SHADER_UNIFORM_NAME_MVP);
+ RLGL.State.defaultShaderLocs[RL_SHADER_LOC_MATRIX_MVP] = glGetUniformLocation(RLGL.State.defaultShaderId, RL_DEFAULT_SHADER_UNIFORM_NAME_MVP);
RLGL.State.defaultShaderLocs[RL_SHADER_LOC_COLOR_DIFFUSE] = glGetUniformLocation(RLGL.State.defaultShaderId, RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR);
RLGL.State.defaultShaderLocs[RL_SHADER_LOC_MAP_DIFFUSE] = glGetUniformLocation(RLGL.State.defaultShaderId, RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0);
}
diff --git a/src/rmodels.c b/src/rmodels.c
index 30130d9e0..ed15d9658 100644
--- a/src/rmodels.c
+++ b/src/rmodels.c
@@ -2364,6 +2364,9 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, int frame)
}
}
+// Update model animated bones transform matrices for a given frame
+// NOTE: Updated data is not uploaded to GPU but kept at model.meshes[i].boneMatrices[boneId],
+// to be uploaded to shader at drawing, in case GPU skinning is enabled
void UpdateModelAnimationBoneMatrices(Model model, ModelAnimation anim, int frame)
{
if ((anim.frameCount > 0) && (anim.bones != NULL) && (anim.framePoses != NULL))
diff --git a/src/rshapes.c b/src/rshapes.c
index e9b5ca87b..ece5513b3 100644
--- a/src/rshapes.c
+++ b/src/rshapes.c
@@ -807,6 +807,30 @@ void DrawRectangleGradientEx(Rectangle rec, Color topLeft, Color bottomLeft, Col
// but it solves another issue: https://github.com/raysan5/raylib/issues/3884
void DrawRectangleLines(int posX, int posY, int width, int height, Color color)
{
+ Matrix mat = rlGetMatrixModelview();
+ float zoomFactor = 0.5f/mat.m0;
+ rlBegin(RL_LINES);
+ rlColor4ub(color.r, color.g, color.b, color.a);
+ rlVertex2f((float)posX - zoomFactor, (float)posY);
+ rlVertex2f((float)posX + (float)width + zoomFactor, (float)posY);
+
+ rlVertex2f((float)posX + (float)width, (float)posY - zoomFactor);
+ rlVertex2f((float)posX + (float)width, (float)posY + (float)height + zoomFactor);
+
+ rlVertex2f((float)posX + (float)width + zoomFactor, (float)posY + (float)height);
+ rlVertex2f((float)posX - zoomFactor, (float)posY + (float)height);
+
+ rlVertex2f((float)posX, (float)posY + (float)height + zoomFactor);
+ rlVertex2f((float)posX, (float)posY - zoomFactor);
+ rlEnd();
+/*
+// Previous implementation, it has issues... but it does not require view matrix...
+#if defined(SUPPORT_QUADS_DRAW_MODE)
+ DrawRectangle(posX, posY, width, 1, color);
+ DrawRectangle(posX + width - 1, posY + 1, 1, height - 2, color);
+ DrawRectangle(posX, posY + height - 1, width, 1, color);
+ DrawRectangle(posX, posY + 1, 1, height - 2, color);
+#else
rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f((float)posX, (float)posY);
@@ -821,6 +845,8 @@ void DrawRectangleLines(int posX, int posY, int width, int height, Color color)
rlVertex2f((float)posX + 1, (float)posY + (float)height);
rlVertex2f((float)posX + 1, (float)posY + 1);
rlEnd();
+//#endif
+*/
}
// Draw rectangle outline with extended parameters
@@ -1650,7 +1676,7 @@ void DrawSplineLinear(const Vector2 *points, int pointCount, float thick, Color
prevNormal = normal;
}
-#else // !SUPPORT_SPLINE_MITTERS
+#else // !SUPPORT_SPLINE_MITERS
Vector2 delta = { 0 };
float length = 0.0f;
diff --git a/src/rtextures.c b/src/rtextures.c
index a4534a7a2..84144068d 100644
--- a/src/rtextures.c
+++ b/src/rtextures.c
@@ -1111,8 +1111,7 @@ Image GenImageText(int width, int height, const char *text)
{
Image image = { 0 };
-#if defined(SUPPORT_MODULE_RTEXT)
- int textLength = TextLength(text);
+ int textLength = (int)strlen(text);
int imageViewSize = width*height;
image.width = width;
@@ -1122,10 +1121,6 @@ Image GenImageText(int width, int height, const char *text)
image.mipmaps = 1;
memcpy(image.data, text, (textLength > imageViewSize)? imageViewSize : textLength);
-#else
- TRACELOG(LOG_WARNING, "IMAGE: GenImageText() requires module: rtext");
- image = GenImageColor(width, height, BLACK); // Generating placeholder black image rectangle
-#endif
return image;
}
@@ -2395,22 +2390,16 @@ void ImageMipmaps(Image *image)
else TRACELOG(LOG_WARNING, "IMAGE: Mipmaps required memory could not be allocated");
// Pointer to allocated memory point where store next mipmap level data
- unsigned char *nextmip = (unsigned char *)image->data + GetPixelDataSize(image->width, image->height, image->format);
+ unsigned char *nextmip = image->data;
- mipWidth = image->width/2;
- mipHeight = image->height/2;
+ mipWidth = image->width;
+ mipHeight = image->height;
mipSize = GetPixelDataSize(mipWidth, mipHeight, image->format);
Image imCopy = ImageCopy(*image);
for (int i = 1; i < mipCount; i++)
{
- TRACELOGD("IMAGE: Generating mipmap level: %i (%i x %i) - size: %i - offset: 0x%x", i, mipWidth, mipHeight, mipSize, nextmip);
-
- ImageResize(&imCopy, mipWidth, mipHeight); // Uses internally Mitchell cubic downscale filter
-
- memcpy(nextmip, imCopy.data, mipSize);
nextmip += mipSize;
- image->mipmaps++;
mipWidth /= 2;
mipHeight /= 2;
@@ -2420,9 +2409,19 @@ void ImageMipmaps(Image *image)
if (mipHeight < 1) mipHeight = 1;
mipSize = GetPixelDataSize(mipWidth, mipHeight, image->format);
+
+ if (i < image->mipmaps) continue;
+
+ TRACELOGD("IMAGE: Generating mipmap level: %i (%i x %i) - size: %i - offset: 0x%x", i, mipWidth, mipHeight, mipSize, nextmip);
+
+ ImageResize(&imCopy, mipWidth, mipHeight); // Uses internally Mitchell cubic downscale filter
+
+ memcpy(nextmip, imCopy.data, mipSize);
}
UnloadImage(imCopy);
+
+ image->mipmaps = mipCount;
}
else TRACELOG(LOG_WARNING, "IMAGE: Mipmaps already available");
}
@@ -3911,7 +3910,6 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color
if ((dst->data == NULL) || (dst->width == 0) || (dst->height == 0) ||
(src.data == NULL) || (src.width == 0) || (src.height == 0)) return;
- if (dst->mipmaps > 1) TRACELOG(LOG_WARNING, "Image drawing only applied to base mipmap level");
if (dst->format >= PIXELFORMAT_COMPRESSED_DXT1_RGB) TRACELOG(LOG_WARNING, "Image drawing not supported for compressed formats");
else
{
@@ -4024,6 +4022,35 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color
}
if (useSrcMod) UnloadImage(srcMod); // Unload source modified image
+
+ if ((dst->mipmaps > 1) && (src.mipmaps > 1))
+ {
+ Image mipmapDst = *dst;
+ mipmapDst.data = (char *)mipmapDst.data + GetPixelDataSize(mipmapDst.width, mipmapDst.height, mipmapDst.format);
+ mipmapDst.width /= 2;
+ mipmapDst.height /= 2;
+ mipmapDst.mipmaps--;
+
+ Image mipmapSrc = src;
+ mipmapSrc.data = (char *)mipmapSrc.data + GetPixelDataSize(mipmapSrc.width, mipmapSrc.height, mipmapSrc.format);
+ mipmapSrc.width /= 2;
+ mipmapSrc.height /= 2;
+ mipmapSrc.mipmaps--;
+
+ Rectangle mipmapSrcRec = srcRec;
+ mipmapSrcRec.width /= 2;
+ mipmapSrcRec.height /= 2;
+ mipmapSrcRec.x /= 2;
+ mipmapSrcRec.y /= 2;
+
+ Rectangle mipmapDstRec = dstRec;
+ mipmapDstRec.width /= 2;
+ mipmapDstRec.height /= 2;
+ mipmapDstRec.x /= 2;
+ mipmapDstRec.y /= 2;
+
+ ImageDraw(&mipmapDst, mipmapSrc, mipmapSrcRec, mipmapDstRec, tint);
+ }
}
}
@@ -4105,7 +4132,6 @@ TextureCubemap LoadTextureCubemap(Image image, int layout)
{
if ((image.width/6) == image.height) { layout = CUBEMAP_LAYOUT_LINE_HORIZONTAL; cubemap.width = image.width/6; }
else if ((image.width/4) == (image.height/3)) { layout = CUBEMAP_LAYOUT_CROSS_FOUR_BY_THREE; cubemap.width = image.width/4; }
- else if (image.width >= (int)((float)image.height*1.85f)) { layout = CUBEMAP_LAYOUT_PANORAMA; cubemap.width = image.width/4; }
}
else if (image.height > image.width)
{
@@ -4119,7 +4145,6 @@ TextureCubemap LoadTextureCubemap(Image image, int layout)
if (layout == CUBEMAP_LAYOUT_LINE_HORIZONTAL) cubemap.width = image.width/6;
if (layout == CUBEMAP_LAYOUT_CROSS_THREE_BY_FOUR) cubemap.width = image.width/3;
if (layout == CUBEMAP_LAYOUT_CROSS_FOUR_BY_THREE) cubemap.width = image.width/4;
- if (layout == CUBEMAP_LAYOUT_PANORAMA) cubemap.width = image.width/4;
}
cubemap.height = cubemap.width;
@@ -4138,11 +4163,11 @@ TextureCubemap LoadTextureCubemap(Image image, int layout)
{
faces = ImageCopy(image); // Image data already follows expected convention
}
- else if (layout == CUBEMAP_LAYOUT_PANORAMA)
+ /*else if (layout == CUBEMAP_LAYOUT_PANORAMA)
{
- // TODO: Convert panorama image to square faces...
+ // TODO: implement panorama by converting image to square faces...
// Ref: https://github.com/denivip/panorama/blob/master/panorama.cpp
- }
+ } */
else
{
if (layout == CUBEMAP_LAYOUT_LINE_HORIZONTAL) for (int i = 0; i < 6; i++) faceRecs[i].x = (float)size*i;
@@ -4169,6 +4194,9 @@ TextureCubemap LoadTextureCubemap(Image image, int layout)
faces = GenImageColor(size, size*6, MAGENTA);
ImageFormat(&faces, image.format);
+ //ImageMipmaps(&image); // WARNING: image is a copy, it can't be done here, no intention to pass image by reference...
+ ImageMipmaps(&faces);
+
// NOTE: Image formatting does not work with compressed textures
for (int i = 0; i < 6; i++) ImageDraw(&faces, image, faceRecs[i], (Rectangle){ 0, (float)size*i, (float)size, (float)size }, WHITE);
@@ -4176,7 +4204,7 @@ TextureCubemap LoadTextureCubemap(Image image, int layout)
// NOTE: Cubemap data is expected to be provided as 6 images in a single data array,
// one after the other (that's a vertical image), following convention: +X, -X, +Y, -Y, +Z, -Z
- cubemap.id = rlLoadTextureCubemap(faces.data, size, faces.format);
+ cubemap.id = rlLoadTextureCubemap(faces.data, size, faces.format, faces.mipmaps);
if (cubemap.id != 0)
{