Merge branch 'master' of github.com:raysan5/raylib

This commit is contained in:
Jeffery Myers 2024-07-28 15:32:58 -07:00
commit 72296664d2
32 changed files with 4173 additions and 3199 deletions

View File

@ -9,6 +9,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| [raylib](https://github.com/raysan5/raylib) | **5.0** | [C/C++](https://en.wikipedia.org/wiki/C_(programming_language)) | Zlib | | [raylib](https://github.com/raysan5/raylib) | **5.0** | [C/C++](https://en.wikipedia.org/wiki/C_(programming_language)) | Zlib |
| [raylib-beef](https://github.com/Starpelly/raylib-beef) | **5.0** | [Beef](https://www.beeflang.org) | MIT | | [raylib-beef](https://github.com/Starpelly/raylib-beef) | **5.0** | [Beef](https://www.beeflang.org) | MIT |
| [raylib-boo](https://github.com/Rabios/raylib-boo) | 3.7 | [Boo](http://boo-language.github.io) | MIT | | [raylib-boo](https://github.com/Rabios/raylib-boo) | 3.7 | [Boo](http://boo-language.github.io) | MIT |
| [raybit](https://github.com/Alex-Velez/raybit) | 3.7 | [Brainfuck](https://en.wikipedia.org/wiki/Brainfuck) | MIT |
| [Raylib-cs](https://github.com/ChrisDill/Raylib-cs) | **5.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | Zlib | | [Raylib-cs](https://github.com/ChrisDill/Raylib-cs) | **5.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | Zlib |
| [Raylib-CsLo](https://github.com/NotNotTech/Raylib-CsLo) | 4.2 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 | | [Raylib-CsLo](https://github.com/NotNotTech/Raylib-CsLo) | 4.2 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 |
| [Raylib-CSharp-Vinculum](https://github.com/ZeroElectric/Raylib-CSharp-Vinculum) | **5.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 | | [Raylib-CSharp-Vinculum](https://github.com/ZeroElectric/Raylib-CSharp-Vinculum) | **5.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 |
@ -21,7 +22,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| [ray-cyber](https://github.com/fubark/ray-cyber) | **5.0** | [Cyber](https://cyberscript.dev) | MIT | | [ray-cyber](https://github.com/fubark/ray-cyber) | **5.0** | [Cyber](https://cyberscript.dev) | MIT |
| [dart-raylib](https://gitlab.com/wolfenrain/dart-raylib) | 4.0 | [Dart](https://dart.dev) | MIT | | [dart-raylib](https://gitlab.com/wolfenrain/dart-raylib) | 4.0 | [Dart](https://dart.dev) | MIT |
| [bindbc-raylib3](https://github.com/o3o/bindbc-raylib3) | **5.0** | [D](https://dlang.org) | BSL-1.0 | | [bindbc-raylib3](https://github.com/o3o/bindbc-raylib3) | **5.0** | [D](https://dlang.org) | BSL-1.0 |
| [dray](https://github.com/redthing1/dray) | 4.2 | [D](https://dlang.org) | Apache-2.0 | | [dray](https://github.com/redthing1/dray) | **5.0** | [D](https://dlang.org) | Apache-2.0 |
| [raylib-d](https://github.com/schveiguy/raylib-d) | **5.0** | [D](https://dlang.org) | Zlib | | [raylib-d](https://github.com/schveiguy/raylib-d) | **5.0** | [D](https://dlang.org) | Zlib |
| [rayex](https://github.com/shiryel/rayex) | 3.7 | [elixir](https://elixir-lang.org) | Apache-2.0 | | [rayex](https://github.com/shiryel/rayex) | 3.7 | [elixir](https://elixir-lang.org) | Apache-2.0 |
| [raylib-factor](https://github.com/factor/factor/blob/master/extra/raylib/raylib.factor) | 4.5 | [Factor](https://factorcode.org) | BSD | | [raylib-factor](https://github.com/factor/factor/blob/master/extra/raylib/raylib.factor) | 4.5 | [Factor](https://factorcode.org) | BSD |
@ -149,7 +150,7 @@ These are older raylib bindings that are more than 2 versions old or have not be
| [ray.mod](https://github.com/bmx-ng/ray.mod) | 3.0 | [BlitzMax](https://blitzmax.org) | | [ray.mod](https://github.com/bmx-ng/ray.mod) | 3.0 | [BlitzMax](https://blitzmax.org) |
| [raylib-mosaic](https://github.com/pluckyporcupine/raylib-mosaic) | 3.0 | [Mosaic](https://github.com/sal55/langs/tree/master/Mosaic) | | [raylib-mosaic](https://github.com/pluckyporcupine/raylib-mosaic) | 3.0 | [Mosaic](https://github.com/sal55/langs/tree/master/Mosaic) |
| [raylib-xdpw](https://github.com/vtereshkov/raylib-xdpw) | 2.6 | [XD Pascal](https://github.com/vtereshkov/xdpw) | | [raylib-xdpw](https://github.com/vtereshkov/raylib-xdpw) | 2.6 | [XD Pascal](https://github.com/vtereshkov/xdpw) |
| [raylib-carp](https://github.com/pluckyporcupine/raylib-carp) | 3.0 | [Carp](https://github.com/carp-lang/Carp) | | [raylib-carp](https://github.com/sacredbirdman/raylib-carp) | 3.0 | [Carp](https://github.com/carp-lang/Carp) |
| [raylib-fb](https://github.com/IchMagBier/raylib-fb) | 3.0 | [FreeBasic](https://www.freebasic.net) | | [raylib-fb](https://github.com/IchMagBier/raylib-fb) | 3.0 | [FreeBasic](https://www.freebasic.net) |
| [raylib-purebasic](https://github.com/D-a-n-i-l-o/raylib-purebasic) | 3.0 | [PureBasic](https://www.purebasic.com) | | [raylib-purebasic](https://github.com/D-a-n-i-l-o/raylib-purebasic) | 3.0 | [PureBasic](https://www.purebasic.com) |
| [raylib-ats2](https://github.com/mephistopheles-8/raylib-ats2) | 3.0 | [ATS2](http://www.ats-lang.org) | | [raylib-ats2](https://github.com/mephistopheles-8/raylib-ats2) | 3.0 | [ATS2](http://www.ats-lang.org) |

View File

@ -20,7 +20,7 @@ Ready to learn? Jump to [code examples!](https://www.raylib.com/examples.html)
[![License](https://img.shields.io/badge/license-zlib%2Flibpng-blue.svg)](LICENSE) [![License](https://img.shields.io/badge/license-zlib%2Flibpng-blue.svg)](LICENSE)
[![Discord Members](https://img.shields.io/discord/426912293134270465.svg?label=Discord&logo=discord)](https://discord.gg/raylib) [![Discord Members](https://img.shields.io/discord/426912293134270465.svg?label=Discord&logo=discord)](https://discord.gg/raylib)
[![Subreddit Subscribers](https://img.shields.io/reddit/subreddit-subscribers/raylib?label=reddit%20r%2Fraylib&logo=reddit)](https://www.reddit.com/r/raylib/) [![Reddit Static Badge](https://img.shields.io/badge/-r%2Fraylib-red?style=flat&logo=reddit&label=reddit)](https://www.reddit.com/r/raylib/)
[![Youtube Subscribers](https://img.shields.io/youtube/channel/subscribers/UC8WIBkhYb5sBNqXO1mZ7WSQ?style=flat&label=Youtube&logo=youtube)](https://www.youtube.com/c/raylib) [![Youtube Subscribers](https://img.shields.io/youtube/channel/subscribers/UC8WIBkhYb5sBNqXO1mZ7WSQ?style=flat&label=Youtube&logo=youtube)](https://www.youtube.com/c/raylib)
[![Twitch Status](https://img.shields.io/twitch/status/raysan5?style=flat&label=Twitch&logo=twitch)](https://www.twitch.tv/raysan5) [![Twitch Status](https://img.shields.io/twitch/status/raysan5?style=flat&label=Twitch&logo=twitch)](https://www.twitch.tv/raysan5)

View File

@ -11,7 +11,6 @@ endfunction()
if(${CUSTOMIZE_BUILD}) if(${CUSTOMIZE_BUILD})
target_compile_definitions("raylib" PRIVATE EXTERNAL_CONFIG_FLAGS) target_compile_definitions("raylib" PRIVATE EXTERNAL_CONFIG_FLAGS)
define_if("raylib" USE_AUDIO)
foreach(FLAG IN LISTS CONFIG_HEADER_FLAGS) foreach(FLAG IN LISTS CONFIG_HEADER_FLAGS)
string(REGEX MATCH "([^=]+)=(.+)" _ ${FLAG}) string(REGEX MATCH "([^=]+)=(.+)" _ ${FLAG})

View File

@ -44,10 +44,12 @@ int main(void)
// NOTE: Billboard locked on axis-Y // NOTE: Billboard locked on axis-Y
Vector3 billUp = { 0.0f, 1.0f, 0.0f }; Vector3 billUp = { 0.0f, 1.0f, 0.0f };
// Set the height of the rotating billboard to 1.0 with the aspect ratio fixed
Vector2 size = { source.width/source.height, 1.0f };
// Rotate around origin // Rotate around origin
// Here we choose to rotate around the image center // Here we choose to rotate around the image center
// NOTE: (-1, 1) is the range where origin.x, origin.y is inside the texture Vector2 origin = Vector2Scale(size, 0.5f);
Vector2 rotateOrigin = { 0.0f };
// Distance is needed for the correct billboard draw order // Distance is needed for the correct billboard draw order
// Larger distance (further away from the camera) should be drawn prior to smaller distance. // Larger distance (further away from the camera) should be drawn prior to smaller distance.
@ -84,11 +86,11 @@ int main(void)
if (distanceStatic > distanceRotating) if (distanceStatic > distanceRotating)
{ {
DrawBillboard(camera, bill, billPositionStatic, 2.0f, WHITE); DrawBillboard(camera, bill, billPositionStatic, 2.0f, WHITE);
DrawBillboardPro(camera, bill, source, billPositionRotating, billUp, (Vector2) {1.0f, 1.0f}, rotateOrigin, rotation, WHITE); DrawBillboardPro(camera, bill, source, billPositionRotating, billUp, size, origin, rotation, WHITE);
} }
else else
{ {
DrawBillboardPro(camera, bill, source, billPositionRotating, billUp, (Vector2) {1.0f, 1.0f}, rotateOrigin, rotation, WHITE); DrawBillboardPro(camera, bill, source, billPositionRotating, billUp, size, origin, rotation, WHITE);
DrawBillboard(camera, bill, billPositionStatic, 2.0f, WHITE); DrawBillboard(camera, bill, billPositionStatic, 2.0f, WHITE);
} }

View File

@ -30,11 +30,11 @@ int main(void)
const int screenWidth = 800; const int screenWidth = 800;
const int screenHeight = 450; const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [models] example - loading gltf"); InitWindow(screenWidth, screenHeight, "raylib [models] example - loading gltf animations");
// Define the camera to look into our 3d world // Define the camera to look into our 3d world
Camera camera = { 0 }; Camera camera = { 0 };
camera.position = (Vector3){ 5.0f, 5.0f, 5.0f }; // Camera position camera.position = (Vector3){ 6.0f, 6.0f, 6.0f }; // Camera position
camera.target = (Vector3){ 0.0f, 2.0f, 0.0f }; // Camera looking at point camera.target = (Vector3){ 0.0f, 2.0f, 0.0f }; // Camera looking at point
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target) camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
camera.fovy = 45.0f; // Camera field-of-view Y camera.fovy = 45.0f; // Camera field-of-view Y
@ -42,6 +42,7 @@ int main(void)
// Load gltf model // Load gltf model
Model model = LoadModel("resources/models/gltf/robot.glb"); Model model = LoadModel("resources/models/gltf/robot.glb");
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
// Load gltf model animations // Load gltf model animations
int animsCount = 0; int animsCount = 0;
@ -49,10 +50,6 @@ int main(void)
unsigned int animCurrentFrame = 0; unsigned int animCurrentFrame = 0;
ModelAnimation *modelAnimations = LoadModelAnimations("resources/models/gltf/robot.glb", &animsCount); ModelAnimation *modelAnimations = LoadModelAnimations("resources/models/gltf/robot.glb", &animsCount);
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
DisableCursor(); // Limit cursor to relative movement inside the window
SetTargetFPS(60); // Set our game to run at 60 frames-per-second SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
@ -61,7 +58,8 @@ int main(void)
{ {
// Update // Update
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
UpdateCamera(&camera, CAMERA_THIRD_PERSON); UpdateCamera(&camera, CAMERA_ORBITAL);
// Select current animation // Select current animation
if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)) animIndex = (animIndex + 1)%animsCount; if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)) animIndex = (animIndex + 1)%animsCount;
else if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) animIndex = (animIndex + animsCount - 1)%animsCount; else if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) animIndex = (animIndex + animsCount - 1)%animsCount;
@ -79,10 +77,8 @@ int main(void)
ClearBackground(RAYWHITE); ClearBackground(RAYWHITE);
BeginMode3D(camera); BeginMode3D(camera);
DrawModel(model, position, 1.0f, WHITE); // Draw animated model DrawModel(model, position, 1.0f, WHITE); // Draw animated model
DrawGrid(10, 1.0f); DrawGrid(10, 1.0f);
EndMode3D(); EndMode3D();
DrawText("Use the LEFT/RIGHT mouse buttons to switch animation", 10, 10, 20, GRAY); DrawText("Use the LEFT/RIGHT mouse buttons to switch animation", 10, 10, 20, GRAY);
@ -101,3 +97,6 @@ int main(void)
return 0; return 0;
} }

View File

@ -1,7 +1,5 @@
#version 120 #version 120
precision mediump float;
#define MAX_LIGHTS 4 #define MAX_LIGHTS 4
#define LIGHT_DIRECTIONAL 0 #define LIGHT_DIRECTIONAL 0
#define LIGHT_POINT 1 #define LIGHT_POINT 1
@ -17,12 +15,12 @@ struct Light {
}; };
// Input vertex attributes (from vertex shader) // Input vertex attributes (from vertex shader)
varying in vec3 fragPosition; varying vec3 fragPosition;
varying in vec2 fragTexCoord; varying vec2 fragTexCoord;
varying in vec4 fragColor; varying vec4 fragColor;
varying in vec3 fragNormal; varying vec3 fragNormal;
varying in vec4 shadowPos; varying vec4 shadowPos;
varying in mat3 TBN; varying mat3 TBN;
// Input uniform values // Input uniform values

View File

@ -1,15 +1,13 @@
#version 120 #version 120
precision mediump float;
// This shader is based on the basic lighting shader // This shader is based on the basic lighting shader
// This only supports one light, which is directional, and it (of course) supports shadows // This only supports one light, which is directional, and it (of course) supports shadows
// Input vertex attributes (from vertex shader) // Input vertex attributes (from vertex shader)
varying in vec3 fragPosition; varying vec3 fragPosition;
varying in vec2 fragTexCoord; varying vec2 fragTexCoord;
//varying in vec4 fragColor; //varying in vec4 fragColor;
varying in vec3 fragNormal; varying vec3 fragNormal;
// Input uniform values // Input uniform values
uniform sampler2D texture0; uniform sampler2D texture0;

View File

@ -27,7 +27,7 @@
{ {
"name": "RAYLIB_VERSION", "name": "RAYLIB_VERSION",
"type": "STRING", "type": "STRING",
"value": "5.5", "value": "5.5-dev",
"description": "" "description": ""
}, },
{ {
@ -1058,7 +1058,7 @@
{ {
"type": "Vector3", "type": "Vector3",
"name": "direction", "name": "direction",
"description": "Ray direction" "description": "Ray direction (normalized)"
} }
] ]
}, },
@ -10400,7 +10400,7 @@
}, },
{ {
"type": "float", "type": "float",
"name": "size" "name": "scale"
}, },
{ {
"type": "Color", "type": "Color",

View File

@ -27,7 +27,7 @@ return {
{ {
name = "RAYLIB_VERSION", name = "RAYLIB_VERSION",
type = "STRING", type = "STRING",
value = "5.5", value = "5.5-dev",
description = "" description = ""
}, },
{ {
@ -1058,7 +1058,7 @@ return {
{ {
type = "Vector3", type = "Vector3",
name = "direction", name = "direction",
description = "Ray direction" description = "Ray direction (normalized)"
} }
} }
}, },
@ -7230,7 +7230,7 @@ return {
{type = "Camera", name = "camera"}, {type = "Camera", name = "camera"},
{type = "Texture2D", name = "texture"}, {type = "Texture2D", name = "texture"},
{type = "Vector3", name = "position"}, {type = "Vector3", name = "position"},
{type = "float", name = "size"}, {type = "float", name = "scale"},
{type = "Color", name = "tint"} {type = "Color", name = "tint"}
} }
}, },

View File

@ -24,7 +24,7 @@ Define 004: RAYLIB_VERSION_PATCH
Define 005: RAYLIB_VERSION Define 005: RAYLIB_VERSION
Name: RAYLIB_VERSION Name: RAYLIB_VERSION
Type: STRING Type: STRING
Value: "5.5" Value: "5.5-dev"
Description: Description:
Define 006: __declspec(x) Define 006: __declspec(x)
Name: __declspec(x) Name: __declspec(x)
@ -473,7 +473,7 @@ Struct 23: Ray (2 fields)
Name: Ray Name: Ray
Description: Ray, ray for raycasting Description: Ray, ray for raycasting
Field[1]: Vector3 position // Ray position (origin) Field[1]: Vector3 position // Ray position (origin)
Field[2]: Vector3 direction // Ray direction Field[2]: Vector3 direction // Ray direction (normalized)
Struct 24: RayCollision (4 fields) Struct 24: RayCollision (4 fields)
Name: RayCollision Name: RayCollision
Description: RayCollision, ray hit information Description: RayCollision, ray hit information
@ -3968,7 +3968,7 @@ Function 466: DrawBillboard() (5 input parameters)
Param[1]: camera (type: Camera) Param[1]: camera (type: Camera)
Param[2]: texture (type: Texture2D) Param[2]: texture (type: Texture2D)
Param[3]: position (type: Vector3) Param[3]: position (type: Vector3)
Param[4]: size (type: float) Param[4]: scale (type: float)
Param[5]: tint (type: Color) Param[5]: tint (type: Color)
Function 467: DrawBillboardRec() (6 input parameters) Function 467: DrawBillboardRec() (6 input parameters)
Name: DrawBillboardRec Name: DrawBillboardRec

View File

@ -5,7 +5,7 @@
<Define name="RAYLIB_VERSION_MAJOR" type="INT" value="5" desc="" /> <Define name="RAYLIB_VERSION_MAJOR" type="INT" value="5" desc="" />
<Define name="RAYLIB_VERSION_MINOR" type="INT" value="5" desc="" /> <Define name="RAYLIB_VERSION_MINOR" type="INT" value="5" desc="" />
<Define name="RAYLIB_VERSION_PATCH" type="INT" value="0" desc="" /> <Define name="RAYLIB_VERSION_PATCH" type="INT" value="0" desc="" />
<Define name="RAYLIB_VERSION" type="STRING" value="5.5" desc="" /> <Define name="RAYLIB_VERSION" type="STRING" value="5.5-dev" desc="" />
<Define name="__declspec(x)" type="MACRO" value="__attribute__((x))" desc="" /> <Define name="__declspec(x)" type="MACRO" value="__attribute__((x))" desc="" />
<Define name="RLAPI" type="UNKNOWN" value="__declspec(dllexport)" desc="We are building the library as a Win32 shared library (.dll)" /> <Define name="RLAPI" type="UNKNOWN" value="__declspec(dllexport)" desc="We are building the library as a Win32 shared library (.dll)" />
<Define name="PI" type="FLOAT" value="3.14159265358979323846" desc="" /> <Define name="PI" type="FLOAT" value="3.14159265358979323846" desc="" />
@ -220,7 +220,7 @@
</Struct> </Struct>
<Struct name="Ray" fieldCount="2" desc="Ray, ray for raycasting"> <Struct name="Ray" fieldCount="2" desc="Ray, ray for raycasting">
<Field type="Vector3" name="position" desc="Ray position (origin)" /> <Field type="Vector3" name="position" desc="Ray position (origin)" />
<Field type="Vector3" name="direction" desc="Ray direction" /> <Field type="Vector3" name="direction" desc="Ray direction (normalized)" />
</Struct> </Struct>
<Struct name="RayCollision" fieldCount="4" desc="RayCollision, ray hit information"> <Struct name="RayCollision" fieldCount="4" desc="RayCollision, ray hit information">
<Field type="bool" name="hit" desc="Did the ray hit something?" /> <Field type="bool" name="hit" desc="Did the ray hit something?" />
@ -2645,7 +2645,7 @@
<Param type="Camera" name="camera" desc="" /> <Param type="Camera" name="camera" desc="" />
<Param type="Texture2D" name="texture" desc="" /> <Param type="Texture2D" name="texture" desc="" />
<Param type="Vector3" name="position" desc="" /> <Param type="Vector3" name="position" desc="" />
<Param type="float" name="size" desc="" /> <Param type="float" name="scale" desc="" />
<Param type="Color" name="tint" desc="" /> <Param type="Color" name="tint" desc="" />
</Function> </Function>
<Function name="DrawBillboardRec" retType="void" paramCount="6" desc="Draw a billboard texture defined by source"> <Function name="DrawBillboardRec" retType="void" paramCount="6" desc="Draw a billboard texture defined by source">

View File

@ -376,6 +376,9 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\..\examples\models\models_loading_gltf.c" /> <ClCompile Include="..\..\..\examples\models\models_loading_gltf.c" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\..\examples\examples.rc" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\raylib\raylib.vcxproj"> <ProjectReference Include="..\raylib\raylib.vcxproj">
<Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project> <Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project>

View File

@ -29,6 +29,7 @@ set(raylib_public_headers
# Sources to be compiled # Sources to be compiled
set(raylib_sources set(raylib_sources
raudio.c
rcore.c rcore.c
rmodels.c rmodels.c
rshapes.c rshapes.c
@ -47,14 +48,12 @@ endif ()
# Produces a variable LIBS_PRIVATE that will be used later # Produces a variable LIBS_PRIVATE that will be used later
include(LibraryConfigurations) include(LibraryConfigurations)
if (USE_AUDIO) if (SUPPORT_MODULE_RAUDIO)
MESSAGE(STATUS "Audio Backend: miniaudio") MESSAGE(STATUS "Audio Backend: miniaudio")
list(APPEND raylib_sources raudio.c)
else () else ()
MESSAGE(STATUS "Audio Backend: None (-DUSE_AUDIO=OFF)") MESSAGE(STATUS "Audio Backend: None (-DCUSTOMIZE_BUILD=ON -DSUPPORT_MODULE_RAUDIO=OFF)")
endif () endif ()
add_library(raylib ${raylib_sources} ${raylib_public_headers}) add_library(raylib ${raylib_sources} ${raylib_public_headers})
if (NOT BUILD_SHARED_LIBS) if (NOT BUILD_SHARED_LIBS)
@ -71,7 +70,8 @@ endif()
if (${PLATFORM} MATCHES "Web") if (${PLATFORM} MATCHES "Web")
target_link_options(raylib PUBLIC "-sUSE_GLFW=3") target_link_options(raylib PUBLIC "-sUSE_GLFW=3")
if(${GRAPHICS} MATCHES "GRAPHICS_API_OPENGL_ES3") if(${GRAPHICS} MATCHES "GRAPHICS_API_OPENGL_ES3")
target_link_options(raylib PUBLIC "-sFULL_ES3") target_link_options(raylib PUBLIC "-sMIN_WEBGL_VERSION=2")
target_link_options(raylib PUBLIC "-sMAX_WEBGL_VERSION=2")
endif() endif()
endif() endif()

View File

@ -117,13 +117,13 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
raylib.addLibraryPath(.{ .cwd_relative = "/usr/lib" }); raylib.addLibraryPath(.{ .cwd_relative = "/usr/lib" });
raylib.addIncludePath(.{ .cwd_relative = "/usr/include" }); raylib.addIncludePath(.{ .cwd_relative = "/usr/include" });
if (options.linux_display_backend == .X11 or options.linux_display_backend == .Both) {
switch (options.linux_display_backend) {
.X11 => {
raylib.defineCMacro("_GLFW_X11", null); raylib.defineCMacro("_GLFW_X11", null);
raylib.linkSystemLibrary("X11"); raylib.linkSystemLibrary("X11");
}, }
.Wayland => {
if (options.linux_display_backend == .Wayland or options.linux_display_backend == .Both) {
raylib.defineCMacro("_GLFW_WAYLAND", null); raylib.defineCMacro("_GLFW_WAYLAND", null);
raylib.linkSystemLibrary("wayland-client"); raylib.linkSystemLibrary("wayland-client");
raylib.linkSystemLibrary("wayland-cursor"); raylib.linkSystemLibrary("wayland-cursor");
@ -139,9 +139,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
waylandGenerate(b, raylib, "fractional-scale-v1.xml", "fractional-scale-v1-client-protocol"); waylandGenerate(b, raylib, "fractional-scale-v1.xml", "fractional-scale-v1-client-protocol");
waylandGenerate(b, raylib, "xdg-activation-v1.xml", "xdg-activation-v1-client-protocol"); waylandGenerate(b, raylib, "xdg-activation-v1.xml", "xdg-activation-v1-client-protocol");
waylandGenerate(b, raylib, "idle-inhibit-unstable-v1.xml", "idle-inhibit-unstable-v1-client-protocol"); waylandGenerate(b, raylib, "idle-inhibit-unstable-v1.xml", "idle-inhibit-unstable-v1-client-protocol");
},
} }
raylib.defineCMacro("PLATFORM_DESKTOP", null); raylib.defineCMacro("PLATFORM_DESKTOP", null);
} else { } else {
if (options.opengl_version == .auto) { if (options.opengl_version == .auto) {
@ -253,7 +251,7 @@ pub const Options = struct {
raygui: bool = false, raygui: bool = false,
platform_drm: bool = false, platform_drm: bool = false,
shared: bool = false, shared: bool = false,
linux_display_backend: LinuxDisplayBackend = .X11, linux_display_backend: LinuxDisplayBackend = .Both,
opengl_version: OpenglVersion = .auto, opengl_version: OpenglVersion = .auto,
raygui_dependency_name: []const u8 = "raygui", raygui_dependency_name: []const u8 = "raygui",
@ -284,6 +282,7 @@ pub const OpenglVersion = enum {
pub const LinuxDisplayBackend = enum { pub const LinuxDisplayBackend = enum {
X11, X11,
Wayland, Wayland,
Both,
}; };
pub fn build(b: *std.Build) !void { pub fn build(b: *std.Build) !void {

6141
src/external/RGFW.h vendored

File diff suppressed because it is too large Load Diff

View File

@ -21473,7 +21473,9 @@ static ma_result ma_context_get_MMDevice__wasapi(ma_context* pContext, ma_device
MA_ASSERT(pContext != NULL); MA_ASSERT(pContext != NULL);
MA_ASSERT(ppMMDevice != NULL); MA_ASSERT(ppMMDevice != NULL);
ma_CoInitializeEx(pContext, NULL, MA_COINIT_VALUE);
hr = ma_CoCreateInstance(pContext, &MA_CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, &MA_IID_IMMDeviceEnumerator, (void**)&pDeviceEnumerator); hr = ma_CoCreateInstance(pContext, &MA_CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, &MA_IID_IMMDeviceEnumerator, (void**)&pDeviceEnumerator);
ma_CoUninitialize(pContext);
if (FAILED(hr)) { if (FAILED(hr)) {
ma_log_postf(ma_context_get_log(pContext), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to create IMMDeviceEnumerator.\n"); ma_log_postf(ma_context_get_log(pContext), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to create IMMDeviceEnumerator.\n");
return ma_result_from_HRESULT(hr); return ma_result_from_HRESULT(hr);

View File

@ -632,6 +632,13 @@ void SetMouseCursor(int cursor)
TRACELOG(LOG_WARNING, "SetMouseCursor() not implemented on target platform"); TRACELOG(LOG_WARNING, "SetMouseCursor() not implemented on target platform");
} }
// Get physical key name.
const char *GetKeyName(int key)
{
TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform");
return "";
}
// Register all input events // Register all input events
void PollInputEvents(void) void PollInputEvents(void)
{ {

View File

@ -1075,6 +1075,12 @@ void SetMouseCursor(int cursor)
} }
} }
// Get physical key name.
const char *GetKeyName(int key)
{
return glfwGetKeyName(key, glfwGetKeyScancode(key));
}
// Register all input events // Register all input events
void PollInputEvents(void) void PollInputEvents(void)
{ {
@ -1617,7 +1623,11 @@ int InitPlatform(void)
CORE.Storage.basePath = GetWorkingDirectory(); CORE.Storage.basePath = GetWorkingDirectory();
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
char* glfwPlatform = ""; #if defined(__NetBSD__)
// Workaround for NetBSD
char *glfwPlatform = "X11";
#else
char *glfwPlatform = "";
switch (glfwGetPlatform()) switch (glfwGetPlatform())
{ {
case GLFW_PLATFORM_WIN32: glfwPlatform = "Win32"; break; case GLFW_PLATFORM_WIN32: glfwPlatform = "Win32"; break;
@ -1625,10 +1635,11 @@ int InitPlatform(void)
case GLFW_PLATFORM_WAYLAND: glfwPlatform = "Wayland"; break; case GLFW_PLATFORM_WAYLAND: glfwPlatform = "Wayland"; break;
case GLFW_PLATFORM_X11: glfwPlatform = "X11"; break; case GLFW_PLATFORM_X11: glfwPlatform = "X11"; break;
case GLFW_PLATFORM_NULL: glfwPlatform = "Null"; break; case GLFW_PLATFORM_NULL: glfwPlatform = "Null"; break;
default: break;
} }
#endif
TRACELOG(LOG_INFO, "GLFW platform: %s", glfwPlatform); TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (GLFW - %s): Initialized successfully", glfwPlatform);
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (GLFW): Initialized successfully");
return 0; return 0;
} }
@ -1664,23 +1675,9 @@ static void WindowSizeCallback(GLFWwindow *window, int width, int height)
if (IsWindowFullscreen()) return; if (IsWindowFullscreen()) return;
// Set current screen size // Set current screen size
#if defined(__APPLE__)
CORE.Window.screen.width = width;
CORE.Window.screen.height = height;
#else
if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0)
{
Vector2 windowScaleDPI = GetWindowScaleDPI();
CORE.Window.screen.width = (unsigned int)(width/windowScaleDPI.x);
CORE.Window.screen.height = (unsigned int)(height/windowScaleDPI.y);
}
else
{
CORE.Window.screen.width = width; CORE.Window.screen.width = width;
CORE.Window.screen.height = height; CORE.Window.screen.height = height;
}
#endif
// NOTE: Postprocessing texture is not scaled to new size // NOTE: Postprocessing texture is not scaled to new size
} }

View File

@ -8,19 +8,17 @@
* - MacOS (Cocoa) * - MacOS (Cocoa)
* *
* LIMITATIONS: * LIMITATIONS:
* - Limitation 01 * - TODO
* - Limitation 02
* *
* POSSIBLE IMPROVEMENTS: * POSSIBLE IMPROVEMENTS:
* - Improvement 01 * - TODO
* - Improvement 02
* *
* ADDITIONAL NOTES: * ADDITIONAL NOTES:
* - TRACELOG() function is located in raylib [utils] module * - TRACELOG() function is located in raylib [utils] module
* *
* CONFIGURATION: * CONFIGURATION:
* #define RCORE_PLATFORM_CUSTOM_FLAG * #define RCORE_PLATFORM_RGFW
* Custom flag for rcore on target platform -not used- * Custom flag for rcore on target platform RGFW
* *
* DEPENDENCIES: * DEPENDENCIES:
* - RGFW.h (main library): Windowing and inputs management * - RGFW.h (main library): Windowing and inputs management
@ -48,57 +46,56 @@
* *
**********************************************************************************************/ **********************************************************************************************/
#ifdef GRAPHICS_API_OPENGL_ES2 #if defined(GRAPHICS_API_OPENGL_ES2)
#define RGFW_OPENGL_ES2 #define RGFW_OPENGL_ES2
#endif #endif
void ShowCursor(void); void ShowCursor(void);
void CloseWindow(void); void CloseWindow(void);
#ifdef __linux__ #if defined(__linux__)
#define _INPUT_EVENT_CODES_H #define _INPUT_EVENT_CODES_H
#endif #endif
#if defined(__unix__) || defined(__linux__) #if defined(__unix__) || defined(__linux__)
#define _XTYPEDEF_FONT #define _XTYPEDEF_FONT
#endif #endif
#define RGFW_IMPLEMENTATION #define RGFW_IMPLEMENTATION
#if defined(__WIN32) || defined(__WIN64) #if defined(__WIN32) || defined(__WIN64)
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#define Rectangle rectangle_win32 #define Rectangle rectangle_win32
#define CloseWindow CloseWindow_win32 #define CloseWindow CloseWindow_win32
#define ShowCursor __imp_ShowCursor #define ShowCursor __imp_ShowCursor
#define _APISETSTRING_ #define _APISETSTRING_
#endif #endif
#ifdef __APPLE__ #if defined(__APPLE__)
#define Point NSPOINT #define Point NSPOINT
#define Size NSSIZE #define Size NSSIZE
#endif #endif
#ifdef _MSC_VER #if defined(_MSC_VER)
__declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int CodePage, unsigned long dwFlags, const char* lpMultiByteStr, int cbMultiByte, wchar_t* lpWideCharStr, int cchWideChar); __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int CodePage, unsigned long dwFlags, const char *lpMultiByteStr, int cbMultiByte, wchar_t *lpWideCharStr, int cchWideChar);
#endif #endif
#include "../external/RGFW.h" #include "../external/RGFW.h"
#if defined(__WIN32) || defined(__WIN64) #if defined(__WIN32) || defined(__WIN64)
#undef DrawText #undef DrawText
#undef ShowCursor #undef ShowCursor
#undef CloseWindow #undef CloseWindow
#undef Rectangle #undef Rectangle
#endif #endif
#ifdef __APPLE__ #if defined(__APPLE__)
#undef Point #undef Point
#undef Size #undef Size
#endif #endif
#include <stdbool.h> #include <stdbool.h>
#include <string.h> // Required for: strcmp()
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Types and Structures Definition // Types and Structures Definition
@ -114,6 +111,8 @@ extern CoreData CORE; // Global CORE state context
static PlatformData platform = { NULL }; // Platform specific static PlatformData platform = { NULL }; // Platform specific
static bool RGFW_disableCursor = false;
static const unsigned short keyMappingRGFW[] = { static const unsigned short keyMappingRGFW[] = {
[RGFW_KEY_NULL] = KEY_NULL, [RGFW_KEY_NULL] = KEY_NULL,
[RGFW_Quote] = KEY_APOSTROPHE, [RGFW_Quote] = KEY_APOSTROPHE,
@ -183,7 +182,7 @@ static const unsigned short keyMappingRGFW[] = {
[RGFW_u] = KEY_U, [RGFW_u] = KEY_U,
[RGFW_v] = KEY_V, [RGFW_v] = KEY_V,
[RGFW_w] = KEY_W, [RGFW_w] = KEY_W,
[RGFW_x] KEY_X, [RGFW_x] = KEY_X,
[RGFW_y] = KEY_Y, [RGFW_y] = KEY_Y,
[RGFW_z] = KEY_Z, [RGFW_z] = KEY_Z,
[RGFW_Bracket] = KEY_LEFT_BRACKET, [RGFW_Bracket] = KEY_LEFT_BRACKET,
@ -252,10 +251,10 @@ void ToggleFullscreen(void)
// Toggle borderless windowed mode // Toggle borderless windowed mode
void ToggleBorderlessWindowed(void) void ToggleBorderlessWindowed(void)
{ {
CORE.Window.flags & FLAG_WINDOW_UNDECORATED;
if (platform.window != NULL) if (platform.window != NULL)
TRACELOG(LOG_WARNING, "ToggleBorderlessWindowed() after window creation not available on target platform"); {
RGFW_window_setBorder(platform.window, CORE.Window.flags & FLAG_WINDOW_UNDECORATED);
}
} }
// Set window state: maximized, if resizable // Set window state: maximized, if resizable
@ -292,6 +291,7 @@ void SetWindowState(unsigned int flags)
} }
if (flags & FLAG_WINDOW_RESIZABLE) if (flags & FLAG_WINDOW_RESIZABLE)
{ {
printf("%i %i\n", platform.window->r.w, platform.window->r.h);
RGFW_window_setMaxSize(platform.window, RGFW_AREA(platform.window->r.w, platform.window->r.h)); RGFW_window_setMaxSize(platform.window, RGFW_AREA(platform.window->r.w, platform.window->r.h));
RGFW_window_setMinSize(platform.window, RGFW_AREA(platform.window->r.w, platform.window->r.h)); RGFW_window_setMinSize(platform.window, RGFW_AREA(platform.window->r.w, platform.window->r.h));
} }
@ -313,7 +313,7 @@ void SetWindowState(unsigned int flags)
} }
if (flags & FLAG_WINDOW_UNFOCUSED) if (flags & FLAG_WINDOW_UNFOCUSED)
{ {
TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_UNFOCUSED is not supported on PLATFORM_DESKTOP_SDL"); TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_UNFOCUSED is not supported on PLATFORM_DESKTOP_RGFW");
} }
if (flags & FLAG_WINDOW_TOPMOST) if (flags & FLAG_WINDOW_TOPMOST)
{ {
@ -325,7 +325,7 @@ void SetWindowState(unsigned int flags)
} }
if (flags & FLAG_WINDOW_TRANSPARENT) if (flags & FLAG_WINDOW_TRANSPARENT)
{ {
TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_TRANSPARENT is not supported on PLATFORM_DESKTOP_RGFW"); TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_TRANSPARENT post window creation post window creation is not supported on PLATFORM_DESKTOP_RGFW");
} }
if (flags & FLAG_WINDOW_HIGHDPI) if (flags & FLAG_WINDOW_HIGHDPI)
{ {
@ -333,7 +333,7 @@ void SetWindowState(unsigned int flags)
} }
if (flags & FLAG_WINDOW_MOUSE_PASSTHROUGH) if (flags & FLAG_WINDOW_MOUSE_PASSTHROUGH)
{ {
TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_MOUSE_PASSTHROUGH is not supported on PLATFORM_DESKTOP_RGFW"); RGFW_window_setMousePassthrough(platform.window, flags & FLAG_WINDOW_MOUSE_PASSTHROUGH);
} }
if (flags & FLAG_BORDERLESS_WINDOWED_MODE) if (flags & FLAG_BORDERLESS_WINDOWED_MODE)
{ {
@ -408,7 +408,7 @@ void ClearWindowState(unsigned int flags)
} }
if (flags & FLAG_WINDOW_MOUSE_PASSTHROUGH) if (flags & FLAG_WINDOW_MOUSE_PASSTHROUGH)
{ {
//SDL_SetWindowGrab(platform.window, SDL_TRUE); RGFW_window_setMousePassthrough(platform.window, flags & FLAG_WINDOW_MOUSE_PASSTHROUGH);
TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_MOUSE_PASSTHROUGH is not supported on PLATFORM_DESKTOP_RGFW"); TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_MOUSE_PASSTHROUGH is not supported on PLATFORM_DESKTOP_RGFW");
} }
if (flags & FLAG_BORDERLESS_WINDOWED_MODE) if (flags & FLAG_BORDERLESS_WINDOWED_MODE)
@ -483,14 +483,14 @@ void SetWindowIcons(Image *images, int count)
// Set title for window // Set title for window
void SetWindowTitle(const char *title) void SetWindowTitle(const char *title)
{ {
RGFW_window_setName(platform.window, title); RGFW_window_setName(platform.window, (char*)title);
CORE.Window.title = title; CORE.Window.title = title;
} }
// Set window position on screen (windowed mode) // Set window position on screen (windowed mode)
void SetWindowPosition(int x, int y) void SetWindowPosition(int x, int y)
{ {
RGFW_window_move(platform.window, RGFW_VECTOR(x, y)); RGFW_window_move(platform.window, RGFW_POINT(x, y));
} }
// Set monitor for the current window // Set monitor for the current window
@ -536,7 +536,9 @@ void SetWindowFocused(void)
// Get native window handle // Get native window handle
void *GetWindowHandle(void) void *GetWindowHandle(void)
{ {
#ifndef RGFW_WINDOWS #ifdef RGFW_WEBASM
return (void*)platform.window->src.ctx;
#elif !defined(RGFW_WINDOWS)
return (void *)platform.window->src.window; return (void *)platform.window->src.window;
#else #else
return platform.window->src.hwnd; return platform.window->src.hwnd;
@ -566,16 +568,15 @@ int GetMonitorCount(void)
// Get number of monitors // Get number of monitors
int GetCurrentMonitor(void) int GetCurrentMonitor(void)
{ {
int current = 0;
RGFW_monitor *mons = RGFW_getMonitors(); RGFW_monitor *mons = RGFW_getMonitors();
RGFW_monitor mon = RGFW_window_getMonitor(platform.window); RGFW_monitor mon = RGFW_window_getMonitor(platform.window);
for (int i = 0; i < 6; i++) for (int i = 0; i < 6; i++)
{ {
if ((mons[i].rect.x == mon.rect.x) && (mons[i].rect.y == mon.rect.y)) current = i; if ((mons[i].rect.x == mon.rect.x) && (mons[i].rect.y == mon.rect.y)) return i;
} }
return current; return 0;
} }
// Get selected monitor position // Get selected monitor position
@ -644,7 +645,7 @@ Vector2 GetWindowScaleDPI(void)
{ {
RGFW_monitor monitor = RGFW_window_getMonitor(platform.window); RGFW_monitor monitor = RGFW_window_getMonitor(platform.window);
return (Vector2){((u32)monitor.scaleX)*platform.window->r.w, ((u32) monitor.scaleX)*platform.window->r.h}; return (Vector2){monitor.scaleX, monitor.scaleX};
} }
// Set clipboard text content // Set clipboard text content
@ -674,8 +675,6 @@ void HideCursor(void)
CORE.Input.Mouse.cursorHidden = true; CORE.Input.Mouse.cursorHidden = true;
} }
bool RGFW_disableCursor = false;
// Enables cursor (unlock cursor) // Enables cursor (unlock cursor)
void EnableCursor(void) void EnableCursor(void)
{ {
@ -692,8 +691,8 @@ void EnableCursor(void)
void DisableCursor(void) void DisableCursor(void)
{ {
RGFW_disableCursor = true; RGFW_disableCursor = true;
// Set cursor position in the middle
SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2); RGFW_window_mouseHold(platform.window, RGFW_AREA(CORE.Window.screen.width / 2, CORE.Window.screen.height / 2));
HideCursor(); HideCursor();
} }
@ -729,7 +728,7 @@ void OpenURL(const char *url)
if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character"); if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character");
else else
{ {
// TODO: // TODO: Open URL implementation
} }
} }
@ -747,7 +746,7 @@ int SetGamepadMappings(const char *mappings)
// Set mouse position XY // Set mouse position XY
void SetMousePosition(int x, int y) void SetMousePosition(int x, int y)
{ {
RGFW_window_moveMouse(platform.window, RGFW_VECTOR(x, y)); RGFW_window_moveMouse(platform.window, RGFW_POINT(x, y));
CORE.Input.Mouse.currentPosition = (Vector2){ (float)x, (float)y }; CORE.Input.Mouse.currentPosition = (Vector2){ (float)x, (float)y };
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition; CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
} }
@ -758,8 +757,67 @@ void SetMouseCursor(int cursor)
RGFW_window_setMouseStandard(platform.window, cursor); RGFW_window_setMouseStandard(platform.window, cursor);
} }
// Get physical key name.
const char *GetKeyName(int key)
{
TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform");
return "";
}
static KeyboardKey ConvertScancodeToKey(u32 keycode); static KeyboardKey ConvertScancodeToKey(u32 keycode);
// TODO: Review function to avoid duplicate with RSGL
char RSGL_keystrToChar(const char *str)
{
if (str[1] == 0) return str[0];
static const char *map[] = {
"asciitilde", "`",
"grave", "~",
"exclam", "!",
"at", "@",
"numbersign", "#",
"dollar", "$",
"percent", "%%",
"asciicircum", "^",
"ampersand", "&",
"asterisk", "*",
"parenleft", "(",
"parenright", ")",
"underscore", "_",
"minus", "-",
"plus", "+",
"equal", "=",
"braceleft", "{",
"bracketleft", "[",
"bracketright", "]",
"braceright", "}",
"colon", ":",
"semicolon", ";",
"quotedbl", "\"",
"apostrophe", "'",
"bar", "|",
"backslash", "\'",
"less", "<",
"comma", ",",
"greater", ">",
"period", ".",
"question", "?",
"slash", "/",
"space", " ",
"Return", "\n",
"Enter", "\n",
"enter", "\n",
};
for (unsigned char i = 0; i < (sizeof(map)/sizeof(char *)); i += 2)
{
if (strcmp(map[i], str) == 0) return *map[i + 1];
}
return '\0';
}
// Register all input events // Register all input events
void PollInputEvents(void) void PollInputEvents(void)
{ {
@ -812,8 +870,7 @@ void PollInputEvents(void)
} }
// Register previous mouse states // Register previous mouse states
for (int i = 0; i < MAX_MOUSE_BUTTONS; i++) for (int i = 0; i < MAX_MOUSE_BUTTONS; i++) CORE.Input.Mouse.previousButtonState[i] = CORE.Input.Mouse.currentButtonState[i];
CORE.Input.Mouse.previousButtonState[i] = CORE.Input.Mouse.currentButtonState[i];
// Poll input events for current platform // Poll input events for current platform
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -822,15 +879,16 @@ void PollInputEvents(void)
#define RGFW_HOLD_MOUSE (1L<<2) #define RGFW_HOLD_MOUSE (1L<<2)
#if defined(RGFW_X11) //|| defined(RGFW_MACOS) #if defined(RGFW_X11) //|| defined(RGFW_MACOS)
if (platform.window->src.winArgs & RGFW_HOLD_MOUSE) if (platform.window->_winArgs & RGFW_HOLD_MOUSE)
{ {
CORE.Input.Mouse.previousPosition = (Vector2){ 0.0f, 0.0f }; CORE.Input.Mouse.previousPosition = (Vector2){ 0.0f, 0.0f };
CORE.Input.Mouse.currentPosition = (Vector2){ 0.0f, 0.0f }; CORE.Input.Mouse.currentPosition = (Vector2){ 0.0f, 0.0f };
} }
else { else
{
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition; CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
} }
#endif #endif
while (RGFW_window_checkEvent(platform.window)) while (RGFW_window_checkEvent(platform.window))
{ {
@ -847,7 +905,7 @@ void PollInputEvents(void)
} }
} }
RGFW_Event* event = &platform.window->event; RGFW_Event *event = &platform.window->event;
// All input events can be processed after polling // All input events can be processed after polling
switch (event->type) switch (event->type)
@ -924,7 +982,7 @@ void PollInputEvents(void)
if (CORE.Input.Keyboard.charPressedQueueCount < MAX_CHAR_PRESSED_QUEUE) if (CORE.Input.Keyboard.charPressedQueueCount < MAX_CHAR_PRESSED_QUEUE)
{ {
// Add character (codepoint) to the queue // Add character (codepoint) to the queue
CORE.Input.Keyboard.charPressedQueue[CORE.Input.Keyboard.charPressedQueueCount] = RGFW_keystrToChar(event->keyName); CORE.Input.Keyboard.charPressedQueue[CORE.Input.Keyboard.charPressedQueueCount] = RSGL_keystrToChar(event->keyName);
CORE.Input.Keyboard.charPressedQueueCount++; CORE.Input.Keyboard.charPressedQueueCount++;
} }
} break; } break;
@ -974,17 +1032,17 @@ void PollInputEvents(void)
} break; } break;
case RGFW_mousePosChanged: case RGFW_mousePosChanged:
{ {
if (platform.window->src.winArgs & RGFW_HOLD_MOUSE) if (platform.window->_winArgs & RGFW_HOLD_MOUSE)
{ {
CORE.Input.Mouse.previousPosition = (Vector2){ 0.0f, 0.0f }; CORE.Input.Mouse.previousPosition = (Vector2){ 0.0f, 0.0f };
if ((event->point.x - (platform.window->r.w/2))*2) if (event->point.x)
CORE.Input.Mouse.previousPosition.x = CORE.Input.Mouse.currentPosition.x; CORE.Input.Mouse.previousPosition.x = CORE.Input.Mouse.currentPosition.x;
if ((event->point.y - (platform.window->r.h/2))*2) if (event->point.y)
CORE.Input.Mouse.previousPosition.y = CORE.Input.Mouse.currentPosition.y; CORE.Input.Mouse.previousPosition.y = CORE.Input.Mouse.currentPosition.y;
CORE.Input.Mouse.currentPosition.x = (event->point.x - (platform.window->r.w/2))*2; CORE.Input.Mouse.currentPosition.x = (float)event->point.x;
CORE.Input.Mouse.currentPosition.y = (event->point.y - (platform.window->r.h/2))*2; CORE.Input.Mouse.currentPosition.y = (float)event->point.y;
} }
else else
{ {
@ -1109,6 +1167,7 @@ void PollInputEvents(void)
int button = (axis == GAMEPAD_AXIS_LEFT_TRIGGER)? GAMEPAD_BUTTON_LEFT_TRIGGER_2 : GAMEPAD_BUTTON_RIGHT_TRIGGER_2; int button = (axis == GAMEPAD_AXIS_LEFT_TRIGGER)? GAMEPAD_BUTTON_LEFT_TRIGGER_2 : GAMEPAD_BUTTON_RIGHT_TRIGGER_2;
int pressed = (value > 0.1f); int pressed = (value > 0.1f);
CORE.Input.Gamepad.currentButtonState[event->joystick][button] = pressed; CORE.Input.Gamepad.currentButtonState[event->joystick][button] = pressed;
if (pressed) CORE.Input.Gamepad.lastButtonPressed = button; if (pressed) CORE.Input.Gamepad.lastButtonPressed = button;
else if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0; else if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0;
} }
@ -1147,8 +1206,6 @@ void PollInputEvents(void)
} }
#endif #endif
} }
if (RGFW_disableCursor && platform.window->event.inFocus) RGFW_window_mouseHold(platform.window, RGFW_AREA(0, 0));
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
} }
@ -1200,8 +1257,17 @@ int InitPlatform(void)
platform.window = RGFW_createWindow(CORE.Window.title, RGFW_RECT(0, 0, CORE.Window.screen.width, CORE.Window.screen.height), flags); platform.window = RGFW_createWindow(CORE.Window.title, RGFW_RECT(0, 0, CORE.Window.screen.width, CORE.Window.screen.height), flags);
if (CORE.Window.flags & FLAG_VSYNC_HINT) RGFW_area screenSize = RGFW_getScreenSize();
RGFW_window_swapInterval(platform.window, 1); CORE.Window.display.width = screenSize.w;
CORE.Window.display.height = screenSize.h;
/*
I think this is needed by Raylib now ?
If so, rcore_destkop_sdl should be updated too
*/
SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);
if (CORE.Window.flags & FLAG_VSYNC_HINT) RGFW_window_swapInterval(platform.window, 1);
RGFW_window_makeCurrent(platform.window); RGFW_window_makeCurrent(platform.window);
@ -1266,12 +1332,12 @@ int InitPlatform(void)
CORE.Storage.basePath = GetWorkingDirectory(); CORE.Storage.basePath = GetWorkingDirectory();
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
#ifdef RGFW_X11 #ifdef RGFW_X11
for (int i = 0; (i < 4) && (i < MAX_GAMEPADS); i++) for (int i = 0; (i < 4) && (i < MAX_GAMEPADS); i++)
{ {
RGFW_registerJoystick(platform.window, i); RGFW_registerJoystick(platform.window, i);
} }
#endif #endif
TRACELOG(LOG_INFO, "PLATFORM: CUSTOM: Initialized successfully"); TRACELOG(LOG_INFO, "PLATFORM: CUSTOM: Initialized successfully");

View File

@ -64,7 +64,7 @@ typedef struct {
SDL_Window *window; SDL_Window *window;
SDL_GLContext glContext; SDL_GLContext glContext;
SDL_Joystick *gamepad[MAX_GAMEPADS]; SDL_GameController *gamepad[MAX_GAMEPADS];
SDL_Cursor *cursor; SDL_Cursor *cursor;
bool cursorRelative; bool cursorRelative;
} PlatformData; } PlatformData;
@ -944,7 +944,7 @@ void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor)
if (IsGamepadAvailable(gamepad)) if (IsGamepadAvailable(gamepad))
{ {
SDL_JoystickRumble(platform.gamepad[gamepad], (Uint16)(leftMotor*65535.0f), (Uint16)(rightMotor*65535.0f), (Uint32)(MAX_GAMEPAD_VIBRATION_TIME*1000.0f)); SDL_GameControllerRumble(platform.gamepad[gamepad], (Uint16)(leftMotor*65535.0f), (Uint16)(rightMotor*65535.0f), (Uint32)(MAX_GAMEPAD_VIBRATION_TIME*1000.0f));
} }
} }
@ -966,6 +966,12 @@ void SetMouseCursor(int cursor)
CORE.Input.Mouse.cursor = cursor; CORE.Input.Mouse.cursor = cursor;
} }
// Get physical key name.
const char *GetKeyName(int key)
{
return SDL_GetKeyName(key);
}
static void UpdateTouchPointsSDL(SDL_TouchFingerEvent event) static void UpdateTouchPointsSDL(SDL_TouchFingerEvent event)
{ {
CORE.Input.Touch.pointCount = SDL_GetNumTouchFingers(event.touchId); CORE.Input.Touch.pointCount = SDL_GetNumTouchFingers(event.touchId);
@ -1245,15 +1251,15 @@ void PollInputEvents(void)
if (!CORE.Input.Gamepad.ready[jid] && (jid < MAX_GAMEPADS)) if (!CORE.Input.Gamepad.ready[jid] && (jid < MAX_GAMEPADS))
{ {
platform.gamepad[jid] = SDL_JoystickOpen(jid); platform.gamepad[jid] = SDL_GameControllerOpen(jid);
if (platform.gamepad[jid]) if (platform.gamepad[jid])
{ {
CORE.Input.Gamepad.ready[jid] = true; CORE.Input.Gamepad.ready[jid] = true;
CORE.Input.Gamepad.axisCount[jid] = SDL_JoystickNumAxes(platform.gamepad[jid]); CORE.Input.Gamepad.axisCount[jid] = SDL_JoystickNumAxes(SDL_GameControllerGetJoystick(platform.gamepad[jid]));
CORE.Input.Gamepad.axisState[jid][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f; CORE.Input.Gamepad.axisState[jid][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f;
CORE.Input.Gamepad.axisState[jid][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f; CORE.Input.Gamepad.axisState[jid][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f;
strncpy(CORE.Input.Gamepad.name[jid], SDL_JoystickName(platform.gamepad[jid]), 63); strncpy(CORE.Input.Gamepad.name[jid], SDL_GameControllerNameForIndex(jid), 63);
CORE.Input.Gamepad.name[jid][63] = '\0'; CORE.Input.Gamepad.name[jid][63] = '\0';
} }
else else
@ -1266,15 +1272,15 @@ void PollInputEvents(void)
{ {
int jid = event.jdevice.which; int jid = event.jdevice.which;
if (jid == SDL_JoystickInstanceID(platform.gamepad[jid])) if (jid == SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(platform.gamepad[jid])))
{ {
SDL_JoystickClose(platform.gamepad[jid]); SDL_GameControllerClose(platform.gamepad[jid]);
platform.gamepad[jid] = SDL_JoystickOpen(0); platform.gamepad[jid] = SDL_GameControllerOpen(0);
CORE.Input.Gamepad.ready[jid] = false; CORE.Input.Gamepad.ready[jid] = false;
memset(CORE.Input.Gamepad.name[jid], 0, 64); memset(CORE.Input.Gamepad.name[jid], 0, 64);
} }
} break; } break;
case SDL_JOYBUTTONDOWN: case SDL_CONTROLLERBUTTONDOWN:
{ {
int button = -1; int button = -1;
@ -1308,7 +1314,7 @@ void PollInputEvents(void)
CORE.Input.Gamepad.lastButtonPressed = button; CORE.Input.Gamepad.lastButtonPressed = button;
} }
} break; } break;
case SDL_JOYBUTTONUP: case SDL_CONTROLLERBUTTONUP:
{ {
int button = -1; int button = -1;
@ -1342,7 +1348,7 @@ void PollInputEvents(void)
if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0; if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0;
} }
} break; } break;
case SDL_JOYAXISMOTION: case SDL_CONTROLLERAXISMOTION:
{ {
int axis = -1; int axis = -1;
@ -1548,15 +1554,15 @@ int InitPlatform(void)
// Initialize gamepads // Initialize gamepads
for (int i = 0; (i < SDL_NumJoysticks()) && (i < MAX_GAMEPADS); i++) for (int i = 0; (i < SDL_NumJoysticks()) && (i < MAX_GAMEPADS); i++)
{ {
platform.gamepad[i] = SDL_JoystickOpen(i); platform.gamepad[i] = SDL_GameControllerOpen(i);
if (platform.gamepad[i]) if (platform.gamepad[i])
{ {
CORE.Input.Gamepad.ready[i] = true; CORE.Input.Gamepad.ready[i] = true;
CORE.Input.Gamepad.axisCount[i] = SDL_JoystickNumAxes(platform.gamepad[i]); CORE.Input.Gamepad.axisCount[i] = SDL_JoystickNumAxes(SDL_GameControllerGetJoystick(platform.gamepad[i]));
CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f; CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f;
CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f; CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f;
strncpy(CORE.Input.Gamepad.name[i], SDL_JoystickName(platform.gamepad[i]), 63); strncpy(CORE.Input.Gamepad.name[i], SDL_GameControllerNameForIndex(i), 63);
CORE.Input.Gamepad.name[i][63] = '\0'; CORE.Input.Gamepad.name[i][63] = '\0';
} }
else TRACELOG(LOG_WARNING, "PLATFORM: Unable to open game controller [ERROR: %s]", SDL_GetError()); else TRACELOG(LOG_WARNING, "PLATFORM: Unable to open game controller [ERROR: %s]", SDL_GetError());

View File

@ -628,6 +628,13 @@ void SetMouseCursor(int cursor)
TRACELOG(LOG_WARNING, "SetMouseCursor() not implemented on target platform"); TRACELOG(LOG_WARNING, "SetMouseCursor() not implemented on target platform");
} }
// Get physical key name.
const char *GetKeyName(int key)
{
TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform");
return "";
}
// Register all input events // Register all input events
void PollInputEvents(void) void PollInputEvents(void)
{ {

View File

@ -384,6 +384,13 @@ void SetMouseCursor(int cursor)
TRACELOG(LOG_WARNING, "SetMouseCursor() not implemented on target platform"); TRACELOG(LOG_WARNING, "SetMouseCursor() not implemented on target platform");
} }
// Get physical key name.
const char *GetKeyName(int key)
{
TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform");
return "";
}
// Register all input events // Register all input events
void PollInputEvents(void) void PollInputEvents(void)
{ {

View File

@ -884,6 +884,13 @@ void SetMouseCursor(int cursor)
} }
} }
// Get physical key name.
const char *GetKeyName(int key)
{
TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform");
return "";
}
// Register all input events // Register all input events
void PollInputEvents(void) void PollInputEvents(void)
{ {

View File

@ -1550,7 +1550,7 @@ Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data,
else if ((strcmp(fileType, ".ogg") == 0) || (strcmp(fileType, ".OGG") == 0)) else if ((strcmp(fileType, ".ogg") == 0) || (strcmp(fileType, ".OGG") == 0))
{ {
// Open ogg audio stream // Open ogg audio stream
stb_vorbis* ctxOgg = stb_vorbis_open_memory((const unsigned char*)data, dataSize, NULL, NULL); stb_vorbis* ctxOgg = stb_vorbis_open_memory((const unsigned char *)data, dataSize, NULL, NULL);
if (ctxOgg != NULL) if (ctxOgg != NULL)
{ {

View File

@ -1,6 +1,6 @@
/********************************************************************************************** /**********************************************************************************************
* *
* raylib v5.5 - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com) * raylib v5.5-dev - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com)
* *
* FEATURES: * FEATURES:
* - NO external dependencies, all required libraries included with raylib * - NO external dependencies, all required libraries included with raylib
@ -84,7 +84,7 @@
#define RAYLIB_VERSION_MAJOR 5 #define RAYLIB_VERSION_MAJOR 5
#define RAYLIB_VERSION_MINOR 5 #define RAYLIB_VERSION_MINOR 5
#define RAYLIB_VERSION_PATCH 0 #define RAYLIB_VERSION_PATCH 0
#define RAYLIB_VERSION "5.5" #define RAYLIB_VERSION "5.5-dev"
// Function specifiers in case library is build/used as a shared library // 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 // NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
@ -421,7 +421,7 @@ typedef struct ModelAnimation {
// Ray, ray for raycasting // Ray, ray for raycasting
typedef struct Ray { typedef struct Ray {
Vector3 position; // Ray position (origin) Vector3 position; // Ray position (origin)
Vector3 direction; // Ray direction Vector3 direction; // Ray direction (normalized)
} Ray; } Ray;
// RayCollision, ray hit information // RayCollision, ray hit information
@ -1546,7 +1546,7 @@ RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, floa
RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set) RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set)
RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters
RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires) RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires)
RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float size, Color tint); // Draw a billboard texture RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float scale, Color tint); // Draw a billboard texture
RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint); // Draw a billboard texture defined by source RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint); // Draw a billboard texture defined by source
RLAPI void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint); // Draw a billboard texture defined by source and rotation RLAPI void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint); // Draw a billboard texture defined by source and rotation

View File

@ -2549,9 +2549,13 @@ RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotatio
// Extract scale // Extract scale
const float det = a*A + b*B + c*C; const float det = a*A + b*B + c*C;
float scalex = Vector3Length((Vector3){ a, b, c }); Vector3 abc = { a, b, c };
float scaley = Vector3Length((Vector3){ d, e, f }); Vector3 def = { d, e, f };
float scalez = Vector3Length((Vector3){ g, h, i }); Vector3 ghi = { g, h, i };
float scalex = Vector3Length(abc);
float scaley = Vector3Length(def);
float scalez = Vector3Length(ghi);
Vector3 s = { scalex, scaley, scalez }; Vector3 s = { scalex, scaley, scalez };
if (det < 0) s = Vector3Negate(s); if (det < 0) s = Vector3Negate(s);

View File

@ -668,21 +668,15 @@ void InitWindow(int width, int height, const char *title)
SetShapesTexture(texture, (Rectangle){ 0.0f, 0.0f, 1.0f, 1.0f }); // WARNING: Module required: rshapes SetShapesTexture(texture, (Rectangle){ 0.0f, 0.0f, 1.0f, 1.0f }); // WARNING: Module required: rshapes
#endif #endif
#endif #endif
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0)
{
// Set default font texture filter for HighDPI (blurry)
// RL_TEXTURE_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps
rlTextureParameters(GetFontDefault().texture.id, RL_TEXTURE_MIN_FILTER, RL_TEXTURE_FILTER_LINEAR);
rlTextureParameters(GetFontDefault().texture.id, RL_TEXTURE_MAG_FILTER, RL_TEXTURE_FILTER_LINEAR);
}
#endif
CORE.Time.frameCounter = 0; CORE.Time.frameCounter = 0;
CORE.Window.shouldClose = false; CORE.Window.shouldClose = false;
// Initialize random seed // Initialize random seed
SetRandomSeed((unsigned int)time(NULL)); SetRandomSeed((unsigned int)time(NULL));
TRACELOG(LOG_INFO, "SYSTEM: Working Directory: %s", GetWorkingDirectory());
} }
// Close window and unload OpenGL context // Close window and unload OpenGL context
@ -2958,10 +2952,14 @@ int GetGamepadAxisCount(int gamepad)
// Get axis movement vector for a gamepad // Get axis movement vector for a gamepad
float GetGamepadAxisMovement(int gamepad, int axis) float GetGamepadAxisMovement(int gamepad, int axis)
{ {
float value = 0; float value = (axis == GAMEPAD_AXIS_LEFT_TRIGGER || axis == GAMEPAD_AXIS_RIGHT_TRIGGER)? -1.0f : 0.0f;
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (axis < MAX_GAMEPAD_AXIS) && if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (axis < MAX_GAMEPAD_AXIS)) {
(fabsf(CORE.Input.Gamepad.axisState[gamepad][axis]) > 0.1f)) value = CORE.Input.Gamepad.axisState[gamepad][axis]; // 0.1f = GAMEPAD_AXIS_MINIMUM_DRIFT/DELTA float movement = value < 0.0f ? CORE.Input.Gamepad.axisState[gamepad][axis] : fabs(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];
}
return value; return value;
} }
@ -3482,7 +3480,7 @@ static void RecordAutomationEvent(void)
currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter; currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter;
currentEventList->events[currentEventList->count].type = INPUT_MOUSE_WHEEL_MOTION; currentEventList->events[currentEventList->count].type = INPUT_MOUSE_WHEEL_MOTION;
currentEventList->events[currentEventList->count].params[0] = (int)CORE.Input.Mouse.currentWheelMove.x; currentEventList->events[currentEventList->count].params[0] = (int)CORE.Input.Mouse.currentWheelMove.x;
currentEventList->events[currentEventList->count].params[1] = (int)CORE.Input.Mouse.currentWheelMove.y;; currentEventList->events[currentEventList->count].params[1] = (int)CORE.Input.Mouse.currentWheelMove.y;
currentEventList->events[currentEventList->count].params[2] = 0; currentEventList->events[currentEventList->count].params[2] = 0;
TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_MOUSE_WHEEL_MOTION | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]); TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_MOUSE_WHEEL_MOTION | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]);
@ -3605,7 +3603,8 @@ static void RecordAutomationEvent(void)
for (int axis = 0; axis < MAX_GAMEPAD_AXIS; axis++) for (int axis = 0; axis < MAX_GAMEPAD_AXIS; axis++)
{ {
// Event type: INPUT_GAMEPAD_AXIS_MOTION // Event type: INPUT_GAMEPAD_AXIS_MOTION
if (CORE.Input.Gamepad.axisState[gamepad][axis] > 0.1f) float defaultMovement = (axis == GAMEPAD_AXIS_LEFT_TRIGGER || axis == GAMEPAD_AXIS_RIGHT_TRIGGER)? -1.0f : 0.0f;
if (GetGamepadAxisMovement(gamepad, axis) != defaultMovement)
{ {
currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter; currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter;
currentEventList->events[currentEventList->count].type = INPUT_GAMEPAD_AXIS_MOTION; currentEventList->events[currentEventList->count].type = INPUT_GAMEPAD_AXIS_MOTION;

View File

@ -844,9 +844,9 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
#define GL_GLEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES
#include <GLES2/gl2ext.h> // OpenGL ES 2.0 extensions library #include <GLES2/gl2ext.h> // OpenGL ES 2.0 extensions library
#elif defined(GRAPHICS_API_OPENGL_ES2) #elif defined(GRAPHICS_API_OPENGL_ES2)
// NOTE: OpenGL ES 2.0 can be enabled on PLATFORM_DESKTOP, // NOTE: OpenGL ES 2.0 can be enabled on Desktop platforms,
// in that case, functions are loaded from a custom glad for OpenGL ES 2.0 // in that case, functions are loaded from a custom glad for OpenGL ES 2.0
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_DESKTOP_SDL) #if defined(PLATFORM_DESKTOP_GLFW) || defined(PLATFORM_DESKTOP_SDL)
#define GLAD_GLES2_IMPLEMENTATION #define GLAD_GLES2_IMPLEMENTATION
#include "external/glad_gles2.h" #include "external/glad_gles2.h"
#else #else
@ -2390,7 +2390,7 @@ void rlLoadExtensions(void *loader)
#elif defined(GRAPHICS_API_OPENGL_ES2) #elif defined(GRAPHICS_API_OPENGL_ES2)
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_DESKTOP_SDL) #if defined(PLATFORM_DESKTOP_GLFW) || defined(PLATFORM_DESKTOP_SDL)
// TODO: Support GLAD loader for OpenGL ES 3.0 // TODO: Support GLAD loader for OpenGL ES 3.0
if (gladLoadGLES2((GLADloadfunc)loader) == 0) TRACELOG(RL_LOG_WARNING, "GLAD: Cannot load OpenGL ES2.0 functions"); if (gladLoadGLES2((GLADloadfunc)loader) == 0) TRACELOG(RL_LOG_WARNING, "GLAD: Cannot load OpenGL ES2.0 functions");
else TRACELOG(RL_LOG_INFO, "GLAD: OpenGL ES 2.0 loaded successfully"); else TRACELOG(RL_LOG_INFO, "GLAD: OpenGL ES 2.0 loaded successfully");
@ -4401,7 +4401,7 @@ unsigned int rlGetShaderBufferSize(unsigned int id)
#if defined(GRAPHICS_API_OPENGL_43) #if defined(GRAPHICS_API_OPENGL_43)
glBindBuffer(GL_SHADER_STORAGE_BUFFER, id); glBindBuffer(GL_SHADER_STORAGE_BUFFER, id);
glGetInteger64v(GL_SHADER_STORAGE_BUFFER_SIZE, &size); glGetBufferParameteri64v(GL_SHADER_STORAGE_BUFFER, GL_BUFFER_SIZE, &size);
#endif #endif
return (size > 0)? (unsigned int)size : 0; return (size > 0)? (unsigned int)size : 0;
@ -4756,7 +4756,16 @@ static void rlLoadShaderDefault(void)
"out vec2 fragTexCoord; \n" "out vec2 fragTexCoord; \n"
"out vec4 fragColor; \n" "out vec4 fragColor; \n"
#endif #endif
#if defined(GRAPHICS_API_OPENGL_ES2)
#if defined(GRAPHICS_API_OPENGL_ES3)
"#version 300 es \n"
"precision mediump float; \n" // Precision required for OpenGL ES3 (WebGL 2) (on some browsers)
"in vec3 vertexPosition; \n"
"in vec2 vertexTexCoord; \n"
"in vec4 vertexColor; \n"
"out vec2 fragTexCoord; \n"
"out vec4 fragColor; \n"
#elif defined(GRAPHICS_API_OPENGL_ES2)
"#version 100 \n" "#version 100 \n"
"precision mediump float; \n" // Precision required for OpenGL ES2 (WebGL) (on some browsers) "precision mediump float; \n" // Precision required for OpenGL ES2 (WebGL) (on some browsers)
"attribute vec3 vertexPosition; \n" "attribute vec3 vertexPosition; \n"
@ -4765,6 +4774,7 @@ static void rlLoadShaderDefault(void)
"varying vec2 fragTexCoord; \n" "varying vec2 fragTexCoord; \n"
"varying vec4 fragColor; \n" "varying vec4 fragColor; \n"
#endif #endif
"uniform mat4 mvp; \n" "uniform mat4 mvp; \n"
"void main() \n" "void main() \n"
"{ \n" "{ \n"
@ -4799,7 +4809,21 @@ static void rlLoadShaderDefault(void)
" finalColor = texelColor*colDiffuse*fragColor; \n" " finalColor = texelColor*colDiffuse*fragColor; \n"
"} \n"; "} \n";
#endif #endif
#if defined(GRAPHICS_API_OPENGL_ES2)
#if defined(GRAPHICS_API_OPENGL_ES3)
"#version 300 es \n"
"precision mediump float; \n" // Precision required for OpenGL ES3 (WebGL 2)
"in vec2 fragTexCoord; \n"
"in vec4 fragColor; \n"
"out vec4 finalColor; \n"
"uniform sampler2D texture0; \n"
"uniform vec4 colDiffuse; \n"
"void main() \n"
"{ \n"
" vec4 texelColor = texture(texture0, fragTexCoord); \n"
" finalColor = texelColor*colDiffuse*fragColor; \n"
"} \n";
#elif defined(GRAPHICS_API_OPENGL_ES2)
"#version 100 \n" "#version 100 \n"
"precision mediump float; \n" // Precision required for OpenGL ES2 (WebGL) "precision mediump float; \n" // Precision required for OpenGL ES2 (WebGL)
"varying vec2 fragTexCoord; \n" "varying vec2 fragTexCoord; \n"

View File

@ -1072,16 +1072,10 @@ void DrawGrid(int slices, float spacing)
if (i == 0) if (i == 0)
{ {
rlColor3f(0.5f, 0.5f, 0.5f); rlColor3f(0.5f, 0.5f, 0.5f);
rlColor3f(0.5f, 0.5f, 0.5f);
rlColor3f(0.5f, 0.5f, 0.5f);
rlColor3f(0.5f, 0.5f, 0.5f);
} }
else else
{ {
rlColor3f(0.75f, 0.75f, 0.75f); rlColor3f(0.75f, 0.75f, 0.75f);
rlColor3f(0.75f, 0.75f, 0.75f);
rlColor3f(0.75f, 0.75f, 0.75f);
rlColor3f(0.75f, 0.75f, 0.75f);
} }
rlVertex3f((float)i*spacing, 0.0f, (float)-halfSlices*spacing); rlVertex3f((float)i*spacing, 0.0f, (float)-halfSlices*spacing);
@ -3638,11 +3632,11 @@ void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float
} }
// Draw a billboard // Draw a billboard
void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float size, Color tint) void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float scale, Color tint)
{ {
Rectangle source = { 0.0f, 0.0f, (float)texture.width, (float)texture.height }; Rectangle source = { 0.0f, 0.0f, (float)texture.width, (float)texture.height };
DrawBillboardRec(camera, texture, source, position, (Vector2){ size, size }, tint); DrawBillboardRec(camera, texture, source, position, (Vector2) { scale*fabsf((float)source.width/source.height), scale }, tint);
} }
// Draw a billboard (part of a texture defined by a rectangle) // Draw a billboard (part of a texture defined by a rectangle)
@ -3651,116 +3645,82 @@ void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector
// NOTE: Billboard locked on axis-Y // NOTE: Billboard locked on axis-Y
Vector3 up = { 0.0f, 1.0f, 0.0f }; Vector3 up = { 0.0f, 1.0f, 0.0f };
DrawBillboardPro(camera, texture, source, position, up, size, Vector2Zero(), 0.0f, tint); DrawBillboardPro(camera, texture, source, position, up, size, Vector2Scale(size, 0.5), 0.0f, tint);
} }
// Draw a billboard with additional parameters // Draw a billboard with additional parameters
// NOTE: Size defines the destination rectangle size, stretching the source texture as required
void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint) void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint)
{ {
// NOTE: Billboard size will maintain source rectangle aspect ratio, size will represent billboard width // Compute the up vector and the right vector
Vector2 sizeRatio = { size.x*fabsf((float)source.width/source.height), size.y };
Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up); Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
Vector3 right = { matView.m0, matView.m4, matView.m8 }; Vector3 right = { matView.m0, matView.m4, matView.m8 };
//Vector3 up = { matView.m1, matView.m5, matView.m9 }; right = Vector3Scale(right, size.x);
up = Vector3Scale(up, size.y);
Vector3 rightScaled = Vector3Scale(right, sizeRatio.x/2); // Flip the content of the billboard while maintaining the counterclockwise edge rendering order
Vector3 upScaled = Vector3Scale(up, sizeRatio.y/2); if (size.x < 0.0f)
Vector3 p1 = Vector3Add(rightScaled, upScaled);
Vector3 p2 = Vector3Subtract(rightScaled, upScaled);
Vector3 topLeft = Vector3Scale(p2, -1);
Vector3 topRight = p1;
Vector3 bottomRight = p2;
Vector3 bottomLeft = Vector3Scale(p1, -1);
if (rotation != 0.0f)
{ {
float sinRotation = sinf(rotation*DEG2RAD); source.x += size.x;
float cosRotation = cosf(rotation*DEG2RAD); source.width *= -1.0;
right = Vector3Negate(right);
// NOTE: (-1, 1) is the range where origin.x, origin.y is inside the texture origin.x *= -1.0f;
float rotateAboutX = sizeRatio.x*origin.x/2; }
float rotateAboutY = sizeRatio.y*origin.y/2; if (size.y < 0.0f)
{
float xtvalue, ytvalue; source.y += size.y;
float rotatedX, rotatedY; source.height *= -1.0;
up = Vector3Negate(up);
xtvalue = Vector3DotProduct(right, topLeft) - rotateAboutX; // Project points to x and y coordinates on the billboard plane origin.y *= -1.0f;
ytvalue = Vector3DotProduct(up, topLeft) - rotateAboutY;
rotatedX = xtvalue*cosRotation - ytvalue*sinRotation + rotateAboutX; // Rotate about the point origin
rotatedY = xtvalue*sinRotation + ytvalue*cosRotation + rotateAboutY;
topLeft = Vector3Add(Vector3Scale(up, rotatedY), Vector3Scale(right, rotatedX)); // Translate back to cartesian coordinates
xtvalue = Vector3DotProduct(right, topRight) - rotateAboutX;
ytvalue = Vector3DotProduct(up, topRight) - rotateAboutY;
rotatedX = xtvalue*cosRotation - ytvalue*sinRotation + rotateAboutX;
rotatedY = xtvalue*sinRotation + ytvalue*cosRotation + rotateAboutY;
topRight = Vector3Add(Vector3Scale(up, rotatedY), Vector3Scale(right, rotatedX));
xtvalue = Vector3DotProduct(right, bottomRight) - rotateAboutX;
ytvalue = Vector3DotProduct(up, bottomRight) - rotateAboutY;
rotatedX = xtvalue*cosRotation - ytvalue*sinRotation + rotateAboutX;
rotatedY = xtvalue*sinRotation + ytvalue*cosRotation + rotateAboutY;
bottomRight = Vector3Add(Vector3Scale(up, rotatedY), Vector3Scale(right, rotatedX));
xtvalue = Vector3DotProduct(right, bottomLeft)-rotateAboutX;
ytvalue = Vector3DotProduct(up, bottomLeft)-rotateAboutY;
rotatedX = xtvalue*cosRotation - ytvalue*sinRotation + rotateAboutX;
rotatedY = xtvalue*sinRotation + ytvalue*cosRotation + rotateAboutY;
bottomLeft = Vector3Add(Vector3Scale(up, rotatedY), Vector3Scale(right, rotatedX));
} }
// Translate points to the draw center (position) // Draw the texture region described by source on the following rectangle in 3D space:
topLeft = Vector3Add(topLeft, position); //
topRight = Vector3Add(topRight, position); // size.x <--.
bottomRight = Vector3Add(bottomRight, position); // 3 ^---------------------------+ 2 \ rotation
bottomLeft = Vector3Add(bottomLeft, position); // | | /
// | |
// | origin.x position |
// up |.............. | size.y
// | . |
// | . origin.y |
// | . |
// 0 +---------------------------> 1
// right
Vector3 forward;
if (rotation != 0.0) forward = Vector3CrossProduct(right, up);
Vector3 origin3D = Vector3Add(Vector3Scale(Vector3Normalize(right), origin.x), Vector3Scale(Vector3Normalize(up), origin.y));
Vector3 points[4];
points[0] = Vector3Zero();
points[1] = right;
points[2] = Vector3Add(up, right);
points[3] = up;
for (int i = 0; i < 4; i++)
{
points[i] = Vector3Subtract(points[i], origin3D);
if (rotation != 0.0) points[i] = Vector3RotateByAxisAngle(points[i], forward, rotation * DEG2RAD);
points[i] = Vector3Add(points[i], position);
}
Vector2 texcoords[4];
texcoords[0] = (Vector2) { (float)source.x/texture.width, (float)(source.y + source.height)/texture.height };
texcoords[1] = (Vector2) { (float)(source.x + source.width)/texture.width, (float)(source.y + source.height)/texture.height };
texcoords[2] = (Vector2) { (float)(source.x + source.width)/texture.width, (float)source.y/texture.height };
texcoords[3] = (Vector2) { (float)source.x/texture.width, (float)source.y/texture.height };
rlSetTexture(texture.id); rlSetTexture(texture.id);
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
rlColor4ub(tint.r, tint.g, tint.b, tint.a); rlColor4ub(tint.r, tint.g, tint.b, tint.a);
for (int i = 0; i < 4; i++)
if (sizeRatio.x*sizeRatio.y >= 0.0f)
{ {
// Bottom-left corner for texture and quad rlTexCoord2f(texcoords[i].x, texcoords[i].y);
rlTexCoord2f((float)source.x/texture.width, (float)source.y/texture.height); rlVertex3f(points[i].x, points[i].y, points[i].z);
rlVertex3f(topLeft.x, topLeft.y, topLeft.z);
// Top-left corner for texture and quad
rlTexCoord2f((float)source.x/texture.width, (float)(source.y + source.height)/texture.height);
rlVertex3f(bottomLeft.x, bottomLeft.y, bottomLeft.z);
// Top-right corner for texture and quad
rlTexCoord2f((float)(source.x + source.width)/texture.width, (float)(source.y + source.height)/texture.height);
rlVertex3f(bottomRight.x, bottomRight.y, bottomRight.z);
// Bottom-right corner for texture and quad
rlTexCoord2f((float)(source.x + source.width)/texture.width, (float)source.y/texture.height);
rlVertex3f(topRight.x, topRight.y, topRight.z);
}
else
{
// Reverse vertex order if the size has only one negative dimension
rlTexCoord2f((float)(source.x + source.width)/texture.width, (float)source.y/texture.height);
rlVertex3f(topRight.x, topRight.y, topRight.z);
rlTexCoord2f((float)(source.x + source.width)/texture.width, (float)(source.y + source.height)/texture.height);
rlVertex3f(bottomRight.x, bottomRight.y, bottomRight.z);
rlTexCoord2f((float)source.x/texture.width, (float)(source.y + source.height)/texture.height);
rlVertex3f(bottomLeft.x, bottomLeft.y, bottomLeft.z);
rlTexCoord2f((float)source.x/texture.width, (float)source.y/texture.height);
rlVertex3f(topLeft.x, topLeft.y, topLeft.z);
} }
rlEnd(); rlEnd();
rlSetTexture(0); rlSetTexture(0);
} }
@ -4328,7 +4288,7 @@ static Model LoadIQM(const char *fileName)
// In case file can not be read, return an empty model // In case file can not be read, return an empty model
if (fileDataPtr == NULL) return model; if (fileDataPtr == NULL) return model;
const char* basePath = GetDirectoryPath(fileName); const char *basePath = GetDirectoryPath(fileName);
// Read IQM header // Read IQM header
IQMHeader *iqmHeader = (IQMHeader *)fileDataPtr; IQMHeader *iqmHeader = (IQMHeader *)fileDataPtr;
@ -5206,7 +5166,7 @@ static Model LoadGLTF(const char *fileName)
// Transform the vertices // Transform the vertices
float *vertices = model.meshes[meshIndex].vertices; float *vertices = model.meshes[meshIndex].vertices;
for (int k = 0; k < attribute->count; k++) for (unsigned int k = 0; k < attribute->count; k++)
{ {
Vector3 vt = Vector3Transform((Vector3){ vertices[3*k], vertices[3*k+1], vertices[3*k+2] }, worldMatrix); Vector3 vt = Vector3Transform((Vector3){ vertices[3*k], vertices[3*k+1], vertices[3*k+2] }, worldMatrix);
vertices[3*k] = vt.x; vertices[3*k] = vt.x;
@ -5230,7 +5190,7 @@ static Model LoadGLTF(const char *fileName)
// Transform the normals // Transform the normals
float *normals = model.meshes[meshIndex].normals; float *normals = model.meshes[meshIndex].normals;
for (int k = 0; k < attribute->count; k++) for (unsigned int k = 0; k < attribute->count; k++)
{ {
Vector3 nt = Vector3Transform((Vector3){ normals[3*k], normals[3*k+1], normals[3*k+2] }, worldMatrixNormals); Vector3 nt = Vector3Transform((Vector3){ normals[3*k], normals[3*k+1], normals[3*k+2] }, worldMatrixNormals);
normals[3*k] = nt.x; normals[3*k] = nt.x;
@ -5254,7 +5214,7 @@ static Model LoadGLTF(const char *fileName)
// Transform the tangents // Transform the tangents
float *tangents = model.meshes[meshIndex].tangents; float *tangents = model.meshes[meshIndex].tangents;
for (int k = 0; k < attribute->count; k++) for (unsigned int k = 0; k < attribute->count; k++)
{ {
Vector3 tt = Vector3Transform((Vector3){ tangents[3*k], tangents[3*k+1], tangents[3*k+2] }, worldMatrix); Vector3 tt = Vector3Transform((Vector3){ tangents[3*k], tangents[3*k+1], tangents[3*k+2] }, worldMatrix);
tangents[3*k] = tt.x; tangents[3*k] = tt.x;

View File

@ -2172,7 +2172,9 @@ bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius)
{ {
bool collision = false; bool collision = false;
collision = CheckCollisionCircles(point, 0, center, radius); float distanceSquared = (point.x - center.x)*(point.x - center.x) + (point.y - center.y)*(point.y - center.y);
if (distanceSquared <= radius*radius) collision = true;
return collision; return collision;
} }

View File

@ -1572,7 +1572,7 @@ char *TextReplace(const char *text, const char *replace, const char *by)
byLen = TextLength(by); byLen = TextLength(by);
// Count the number of replacements needed // Count the number of replacements needed
insertPoint = (char*)text; insertPoint = (char *)text;
for (count = 0; (temp = strstr(insertPoint, replace)); count++) insertPoint = temp + replaceLen; for (count = 0; (temp = strstr(insertPoint, replace)); count++) insertPoint = temp + replaceLen;
// Allocate returning string and point temp to it // Allocate returning string and point temp to it
@ -2339,7 +2339,7 @@ static GlyphInfo *LoadFontDataBDF(const unsigned char *fileData, int dataSize, i
int readBytes = 0; // Data bytes read (line) int readBytes = 0; // Data bytes read (line)
int readVars = 0; // Variables filled by sscanf() int readVars = 0; // Variables filled by sscanf()
const char *fileText = (const char*)fileData; const char *fileText = (const char *)fileData;
const char *fileTextPtr = fileText; const char *fileTextPtr = fileText;
bool fontMalformed = false; // Is the font malformed bool fontMalformed = false; // Is the font malformed

View File

@ -503,7 +503,16 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i
Image image = { 0 }; Image image = { 0 };
// Security check for input data // Security check for input data
if ((fileType == NULL) || (fileData == NULL) || (dataSize == 0)) return image; if ((fileData == NULL) || (dataSize == 0))
{
TRACELOG(LOG_WARNING, "IMAGE: Invalid file data");
return image;
}
if (fileType == NULL)
{
TRACELOG(LOG_WARNING, "IMAGE: Missing file extension");
return image;
}
if ((false) if ((false)
#if defined(SUPPORT_FILEFORMAT_PNG) #if defined(SUPPORT_FILEFORMAT_PNG)
@ -1213,6 +1222,7 @@ Image GenImageText(int width, int height, const char *text)
{ {
Image image = { 0 }; Image image = { 0 };
#if defined(SUPPORT_MODULE_RTEXT)
int textLength = TextLength(text); int textLength = TextLength(text);
int imageViewSize = width*height; int imageViewSize = width*height;
@ -1223,6 +1233,10 @@ Image GenImageText(int width, int height, const char *text)
image.mipmaps = 1; image.mipmaps = 1;
memcpy(image.data, text, (textLength > imageViewSize)? imageViewSize : textLength); 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; return image;
} }
@ -3658,7 +3672,7 @@ void ImageDrawLineEx(Image *dst, Vector2 start, Vector2 end, int thick, Color co
{ {
// Line is more horizontal // Line is more horizontal
// Calculate half the width of the line // Calculate half the width of the line
int wy = (thick - 1)*sqrtf(dx*dx + dy*dy)/(2*abs(dx)); int wy = (thick - 1)*(int)sqrtf((float)(dx*dx + dy*dy))/(2*abs(dx));
// Draw additional lines above and below the main line // Draw additional lines above and below the main line
for (int i = 1; i <= wy; i++) for (int i = 1; i <= wy; i++)
@ -3671,7 +3685,7 @@ void ImageDrawLineEx(Image *dst, Vector2 start, Vector2 end, int thick, Color co
{ {
// Line is more vertical or perfectly horizontal // Line is more vertical or perfectly horizontal
// Calculate half the width of the line // Calculate half the width of the line
int wx = (thick - 1)*sqrtf(dx*dx + dy*dy)/(2*abs(dy)); int wx = (thick - 1)*(int)sqrtf((float)(dx*dx + dy*dy))/(2*abs(dy));
// Draw additional lines to the left and right of the main line // Draw additional lines to the left and right of the main line
for (int i = 1; i <= wx; i++) for (int i = 1; i <= wx; i++)