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-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 |
| [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-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 |
@ -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 |
| [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 |
| [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 |
| [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 |
@ -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) |
| [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-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-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) |

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)
[![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)
[![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})
target_compile_definitions("raylib" PRIVATE EXTERNAL_CONFIG_FLAGS)
define_if("raylib" USE_AUDIO)
foreach(FLAG IN LISTS CONFIG_HEADER_FLAGS)
string(REGEX MATCH "([^=]+)=(.+)" _ ${FLAG})

View File

@ -44,10 +44,12 @@ int main(void)
// NOTE: Billboard locked on axis-Y
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
// 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 rotateOrigin = { 0.0f };
Vector2 origin = Vector2Scale(size, 0.5f);
// Distance is needed for the correct billboard draw order
// Larger distance (further away from the camera) should be drawn prior to smaller distance.
@ -84,11 +86,11 @@ int main(void)
if (distanceStatic > distanceRotating)
{
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
{
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);
}
@ -108,4 +110,4 @@ int main(void)
//--------------------------------------------------------------------------------------
return 0;
}
}

View File

@ -30,11 +30,11 @@ int main(void)
const int screenWidth = 800;
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
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.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
camera.fovy = 45.0f; // Camera field-of-view Y
@ -42,17 +42,14 @@ int main(void)
// Load gltf model
Model model = LoadModel("resources/models/gltf/robot.glb");
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
// Load gltf model animations
int animsCount = 0;
unsigned int animIndex = 0;
unsigned int animCurrentFrame = 0;
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
//--------------------------------------------------------------------------------------
@ -61,7 +58,8 @@ int main(void)
{
// Update
//----------------------------------------------------------------------------------
UpdateCamera(&camera, CAMERA_THIRD_PERSON);
UpdateCamera(&camera, CAMERA_ORBITAL);
// Select current animation
if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)) animIndex = (animIndex + 1)%animsCount;
else if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) animIndex = (animIndex + animsCount - 1)%animsCount;
@ -79,10 +77,8 @@ int main(void)
ClearBackground(RAYWHITE);
BeginMode3D(camera);
DrawModel(model, position, 1.0f, WHITE); // Draw animated model
DrawGrid(10, 1.0f);
EndMode3D();
DrawText("Use the LEFT/RIGHT mouse buttons to switch animation", 10, 10, 20, GRAY);
@ -101,3 +97,6 @@ int main(void)
return 0;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,7 +5,7 @@
<Define name="RAYLIB_VERSION_MAJOR" 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" 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="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="" />
@ -220,7 +220,7 @@
</Struct>
<Struct name="Ray" fieldCount="2" desc="Ray, ray for raycasting">
<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 name="RayCollision" fieldCount="4" desc="RayCollision, ray hit information">
<Field type="bool" name="hit" desc="Did the ray hit something?" />
@ -2645,7 +2645,7 @@
<Param type="Camera" name="camera" desc="" />
<Param type="Texture2D" name="texture" 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="" />
</Function>
<Function name="DrawBillboardRec" retType="void" paramCount="6" desc="Draw a billboard texture defined by source">

View File

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

View File

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

View File

@ -117,31 +117,29 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
raylib.addLibraryPath(.{ .cwd_relative = "/usr/lib" });
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.linkSystemLibrary("X11");
},
.Wayland => {
raylib.defineCMacro("_GLFW_WAYLAND", null);
raylib.linkSystemLibrary("wayland-client");
raylib.linkSystemLibrary("wayland-cursor");
raylib.linkSystemLibrary("wayland-egl");
raylib.linkSystemLibrary("xkbcommon");
raylib.addIncludePath(b.path("src"));
waylandGenerate(b, raylib, "wayland.xml", "wayland-client-protocol");
waylandGenerate(b, raylib, "xdg-shell.xml", "xdg-shell-client-protocol");
waylandGenerate(b, raylib, "xdg-decoration-unstable-v1.xml", "xdg-decoration-unstable-v1-client-protocol");
waylandGenerate(b, raylib, "viewporter.xml", "viewporter-client-protocol");
waylandGenerate(b, raylib, "relative-pointer-unstable-v1.xml", "relative-pointer-unstable-v1-client-protocol");
waylandGenerate(b, raylib, "pointer-constraints-unstable-v1.xml", "pointer-constraints-unstable-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, "idle-inhibit-unstable-v1.xml", "idle-inhibit-unstable-v1-client-protocol");
},
}
if (options.linux_display_backend == .Wayland or options.linux_display_backend == .Both) {
raylib.defineCMacro("_GLFW_WAYLAND", null);
raylib.linkSystemLibrary("wayland-client");
raylib.linkSystemLibrary("wayland-cursor");
raylib.linkSystemLibrary("wayland-egl");
raylib.linkSystemLibrary("xkbcommon");
raylib.addIncludePath(b.path("src"));
waylandGenerate(b, raylib, "wayland.xml", "wayland-client-protocol");
waylandGenerate(b, raylib, "xdg-shell.xml", "xdg-shell-client-protocol");
waylandGenerate(b, raylib, "xdg-decoration-unstable-v1.xml", "xdg-decoration-unstable-v1-client-protocol");
waylandGenerate(b, raylib, "viewporter.xml", "viewporter-client-protocol");
waylandGenerate(b, raylib, "relative-pointer-unstable-v1.xml", "relative-pointer-unstable-v1-client-protocol");
waylandGenerate(b, raylib, "pointer-constraints-unstable-v1.xml", "pointer-constraints-unstable-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, "idle-inhibit-unstable-v1.xml", "idle-inhibit-unstable-v1-client-protocol");
}
raylib.defineCMacro("PLATFORM_DESKTOP", null);
} else {
if (options.opengl_version == .auto) {
@ -253,7 +251,7 @@ pub const Options = struct {
raygui: bool = false,
platform_drm: bool = false,
shared: bool = false,
linux_display_backend: LinuxDisplayBackend = .X11,
linux_display_backend: LinuxDisplayBackend = .Both,
opengl_version: OpenglVersion = .auto,
raygui_dependency_name: []const u8 = "raygui",
@ -284,6 +282,7 @@ pub const OpenglVersion = enum {
pub const LinuxDisplayBackend = enum {
X11,
Wayland,
Both,
};
pub fn build(b: *std.Build) !void {

6641
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(ppMMDevice != NULL);
ma_CoInitializeEx(pContext, NULL, MA_COINIT_VALUE);
hr = ma_CoCreateInstance(pContext, &MA_CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, &MA_IID_IMMDeviceEnumerator, (void**)&pDeviceEnumerator);
ma_CoUninitialize(pContext);
if (FAILED(hr)) {
ma_log_postf(ma_context_get_log(pContext), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to create IMMDeviceEnumerator.\n");
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");
}
// Get physical key name.
const char *GetKeyName(int key)
{
TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform");
return "";
}
// Register all input events
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
void PollInputEvents(void)
{
@ -1617,18 +1623,23 @@ int InitPlatform(void)
CORE.Storage.basePath = GetWorkingDirectory();
//----------------------------------------------------------------------------
char* glfwPlatform = "";
#if defined(__NetBSD__)
// Workaround for NetBSD
char *glfwPlatform = "X11";
#else
char *glfwPlatform = "";
switch (glfwGetPlatform())
{
case GLFW_PLATFORM_WIN32: glfwPlatform = "Win32"; break;
case GLFW_PLATFORM_COCOA: glfwPlatform = "Cocoa"; break;
case GLFW_PLATFORM_WIN32: glfwPlatform = "Win32"; break;
case GLFW_PLATFORM_COCOA: glfwPlatform = "Cocoa"; break;
case GLFW_PLATFORM_WAYLAND: glfwPlatform = "Wayland"; break;
case GLFW_PLATFORM_X11: glfwPlatform = "X11"; break;
case GLFW_PLATFORM_NULL: glfwPlatform = "Null"; break;
case GLFW_PLATFORM_X11: glfwPlatform = "X11"; break;
case GLFW_PLATFORM_NULL: glfwPlatform = "Null"; break;
default: break;
}
#endif
TRACELOG(LOG_INFO, "GLFW platform: %s", glfwPlatform);
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (GLFW): Initialized successfully");
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (GLFW - %s): Initialized successfully", glfwPlatform);
return 0;
}
@ -1664,23 +1675,9 @@ static void WindowSizeCallback(GLFWwindow *window, int width, int height)
if (IsWindowFullscreen()) return;
// 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.height = height;
}
#endif
// NOTE: Postprocessing texture is not scaled to new size
}

View File

@ -8,19 +8,17 @@
* - MacOS (Cocoa)
*
* LIMITATIONS:
* - Limitation 01
* - Limitation 02
* - TODO
*
* POSSIBLE IMPROVEMENTS:
* - Improvement 01
* - Improvement 02
* - TODO
*
* ADDITIONAL NOTES:
* - TRACELOG() function is located in raylib [utils] module
*
* CONFIGURATION:
* #define RCORE_PLATFORM_CUSTOM_FLAG
* Custom flag for rcore on target platform -not used-
* #define RCORE_PLATFORM_RGFW
* Custom flag for rcore on target platform RGFW
*
* DEPENDENCIES:
* - RGFW.h (main library): Windowing and inputs management
@ -48,57 +46,56 @@
*
**********************************************************************************************/
#ifdef GRAPHICS_API_OPENGL_ES2
#define RGFW_OPENGL_ES2
#if defined(GRAPHICS_API_OPENGL_ES2)
#define RGFW_OPENGL_ES2
#endif
void ShowCursor(void);
void CloseWindow(void);
#ifdef __linux__
#define _INPUT_EVENT_CODES_H
#if defined(__linux__)
#define _INPUT_EVENT_CODES_H
#endif
#if defined(__unix__) || defined(__linux__)
#define _XTYPEDEF_FONT
#define _XTYPEDEF_FONT
#endif
#define RGFW_IMPLEMENTATION
#if defined(__WIN32) || defined(__WIN64)
#define WIN32_LEAN_AND_MEAN
#define Rectangle rectangle_win32
#define CloseWindow CloseWindow_win32
#define ShowCursor __imp_ShowCursor
#define _APISETSTRING_
#define WIN32_LEAN_AND_MEAN
#define Rectangle rectangle_win32
#define CloseWindow CloseWindow_win32
#define ShowCursor __imp_ShowCursor
#define _APISETSTRING_
#endif
#ifdef __APPLE__
#define Point NSPOINT
#define Size NSSIZE
#if defined(__APPLE__)
#define Point NSPOINT
#define Size NSSIZE
#endif
#ifdef _MSC_VER
__declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int CodePage, unsigned long dwFlags, const char* lpMultiByteStr, int cbMultiByte, wchar_t* lpWideCharStr, int cchWideChar);
#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);
#endif
#include "../external/RGFW.h"
#if defined(__WIN32) || defined(__WIN64)
#undef DrawText
#undef ShowCursor
#undef CloseWindow
#undef Rectangle
#undef DrawText
#undef ShowCursor
#undef CloseWindow
#undef Rectangle
#endif
#ifdef __APPLE__
#undef Point
#undef Size
#if defined(__APPLE__)
#undef Point
#undef Size
#endif
#include <stdbool.h>
#include <string.h> // Required for: strcmp()
//----------------------------------------------------------------------------------
// Types and Structures Definition
@ -112,7 +109,9 @@ typedef struct {
//----------------------------------------------------------------------------------
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[] = {
[RGFW_KEY_NULL] = KEY_NULL,
@ -183,7 +182,7 @@ static const unsigned short keyMappingRGFW[] = {
[RGFW_u] = KEY_U,
[RGFW_v] = KEY_V,
[RGFW_w] = KEY_W,
[RGFW_x] KEY_X,
[RGFW_x] = KEY_X,
[RGFW_y] = KEY_Y,
[RGFW_z] = KEY_Z,
[RGFW_Bracket] = KEY_LEFT_BRACKET,
@ -244,7 +243,7 @@ bool WindowShouldClose(void)
// Toggle fullscreen mode
void ToggleFullscreen(void)
{
{
RGFW_window_maximize(platform.window);
ToggleBorderlessWindowed();
}
@ -252,10 +251,10 @@ void ToggleFullscreen(void)
// Toggle borderless windowed mode
void ToggleBorderlessWindowed(void)
{
CORE.Window.flags & FLAG_WINDOW_UNDECORATED;
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
@ -292,6 +291,7 @@ void SetWindowState(unsigned int flags)
}
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_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)
{
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)
{
@ -325,7 +325,7 @@ void SetWindowState(unsigned int flags)
}
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)
{
@ -333,7 +333,7 @@ void SetWindowState(unsigned int flags)
}
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)
{
@ -408,7 +408,7 @@ void ClearWindowState(unsigned int flags)
}
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");
}
if (flags & FLAG_BORDERLESS_WINDOWED_MODE)
@ -483,14 +483,14 @@ void SetWindowIcons(Image *images, int count)
// Set title for window
void SetWindowTitle(const char *title)
{
RGFW_window_setName(platform.window, title);
RGFW_window_setName(platform.window, (char*)title);
CORE.Window.title = title;
}
// Set window position on screen (windowed mode)
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
@ -536,7 +536,9 @@ void SetWindowFocused(void)
// Get native window handle
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;
#else
return platform.window->src.hwnd;
@ -566,16 +568,15 @@ int GetMonitorCount(void)
// Get number of monitors
int GetCurrentMonitor(void)
{
int current = 0;
RGFW_monitor *mons = RGFW_getMonitors();
RGFW_monitor mon = RGFW_window_getMonitor(platform.window);
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
@ -644,7 +645,7 @@ Vector2 GetWindowScaleDPI(void)
{
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
@ -674,8 +675,6 @@ void HideCursor(void)
CORE.Input.Mouse.cursorHidden = true;
}
bool RGFW_disableCursor = false;
// Enables cursor (unlock cursor)
void EnableCursor(void)
{
@ -692,8 +691,8 @@ void EnableCursor(void)
void DisableCursor(void)
{
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();
}
@ -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");
else
{
// TODO:
// TODO: Open URL implementation
}
}
@ -747,7 +746,7 @@ int SetGamepadMappings(const char *mappings)
// Set mouse position XY
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.previousPosition = CORE.Input.Mouse.currentPosition;
}
@ -758,8 +757,67 @@ void SetMouseCursor(int 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);
// 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
void PollInputEvents(void)
{
@ -812,8 +870,7 @@ void PollInputEvents(void)
}
// Register previous mouse states
for (int i = 0; i < MAX_MOUSE_BUTTONS; i++)
CORE.Input.Mouse.previousButtonState[i] = CORE.Input.Mouse.currentButtonState[i];
for (int i = 0; i < MAX_MOUSE_BUTTONS; i++) CORE.Input.Mouse.previousButtonState[i] = CORE.Input.Mouse.currentButtonState[i];
// Poll input events for current platform
//-----------------------------------------------------------------------------
@ -822,15 +879,16 @@ void PollInputEvents(void)
#define RGFW_HOLD_MOUSE (1L<<2)
#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.currentPosition = (Vector2){ 0.0f, 0.0f };
}
else {
else
{
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
}
#endif
#endif
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
switch (event->type)
@ -924,7 +982,7 @@ void PollInputEvents(void)
if (CORE.Input.Keyboard.charPressedQueueCount < MAX_CHAR_PRESSED_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++;
}
} break;
@ -974,17 +1032,17 @@ void PollInputEvents(void)
} break;
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 };
if ((event->point.x - (platform.window->r.w/2))*2)
if (event->point.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.currentPosition.x = (event->point.x - (platform.window->r.w/2))*2;
CORE.Input.Mouse.currentPosition.y = (event->point.y - (platform.window->r.h/2))*2;
CORE.Input.Mouse.currentPosition.x = (float)event->point.x;
CORE.Input.Mouse.currentPosition.y = (float)event->point.y;
}
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 pressed = (value > 0.1f);
CORE.Input.Gamepad.currentButtonState[event->joystick][button] = pressed;
if (pressed) CORE.Input.Gamepad.lastButtonPressed = button;
else if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0;
}
@ -1147,8 +1206,6 @@ void PollInputEvents(void)
}
#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);
if (CORE.Window.flags & FLAG_VSYNC_HINT)
RGFW_window_swapInterval(platform.window, 1);
RGFW_area screenSize = RGFW_getScreenSize();
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);
@ -1266,12 +1332,12 @@ int InitPlatform(void)
CORE.Storage.basePath = GetWorkingDirectory();
//----------------------------------------------------------------------------
#ifdef RGFW_X11
#ifdef RGFW_X11
for (int i = 0; (i < 4) && (i < MAX_GAMEPADS); i++)
{
RGFW_registerJoystick(platform.window, i);
}
#endif
#endif
TRACELOG(LOG_INFO, "PLATFORM: CUSTOM: Initialized successfully");

View File

@ -64,7 +64,7 @@ typedef struct {
SDL_Window *window;
SDL_GLContext glContext;
SDL_Joystick *gamepad[MAX_GAMEPADS];
SDL_GameController *gamepad[MAX_GAMEPADS];
SDL_Cursor *cursor;
bool cursorRelative;
} PlatformData;
@ -944,7 +944,7 @@ void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor)
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;
}
// Get physical key name.
const char *GetKeyName(int key)
{
return SDL_GetKeyName(key);
}
static void UpdateTouchPointsSDL(SDL_TouchFingerEvent event)
{
CORE.Input.Touch.pointCount = SDL_GetNumTouchFingers(event.touchId);
@ -1245,15 +1251,15 @@ void PollInputEvents(void)
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])
{
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_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';
}
else
@ -1266,15 +1272,15 @@ void PollInputEvents(void)
{
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]);
platform.gamepad[jid] = SDL_JoystickOpen(0);
SDL_GameControllerClose(platform.gamepad[jid]);
platform.gamepad[jid] = SDL_GameControllerOpen(0);
CORE.Input.Gamepad.ready[jid] = false;
memset(CORE.Input.Gamepad.name[jid], 0, 64);
}
} break;
case SDL_JOYBUTTONDOWN:
case SDL_CONTROLLERBUTTONDOWN:
{
int button = -1;
@ -1308,7 +1314,7 @@ void PollInputEvents(void)
CORE.Input.Gamepad.lastButtonPressed = button;
}
} break;
case SDL_JOYBUTTONUP:
case SDL_CONTROLLERBUTTONUP:
{
int button = -1;
@ -1342,7 +1348,7 @@ void PollInputEvents(void)
if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0;
}
} break;
case SDL_JOYAXISMOTION:
case SDL_CONTROLLERAXISMOTION:
{
int axis = -1;
@ -1548,15 +1554,15 @@ int InitPlatform(void)
// Initialize gamepads
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])
{
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_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';
}
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");
}
// Get physical key name.
const char *GetKeyName(int key)
{
TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform");
return "";
}
// Register all input events
void PollInputEvents(void)
{

View File

@ -384,6 +384,13 @@ void SetMouseCursor(int cursor)
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
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
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))
{
// 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)
{

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:
* - NO external dependencies, all required libraries included with raylib
@ -84,7 +84,7 @@
#define RAYLIB_VERSION_MAJOR 5
#define RAYLIB_VERSION_MINOR 5
#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
// 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
typedef struct Ray {
Vector3 position; // Ray position (origin)
Vector3 direction; // Ray direction
Vector3 direction; // Ray direction (normalized)
} Ray;
// 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 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 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 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
const float det = a*A + b*B + c*C;
float scalex = Vector3Length((Vector3){ a, b, c });
float scaley = Vector3Length((Vector3){ d, e, f });
float scalez = Vector3Length((Vector3){ g, h, i });
Vector3 abc = { a, b, c };
Vector3 def = { d, e, f };
Vector3 ghi = { g, h, i };
float scalex = Vector3Length(abc);
float scaley = Vector3Length(def);
float scalez = Vector3Length(ghi);
Vector3 s = { scalex, scaley, scalez };
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
#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.Window.shouldClose = false;
// Initialize random seed
SetRandomSeed((unsigned int)time(NULL));
TRACELOG(LOG_INFO, "SYSTEM: Working Directory: %s", GetWorkingDirectory());
}
// Close window and unload OpenGL context
@ -2958,10 +2952,14 @@ int GetGamepadAxisCount(int gamepad)
// Get axis movement vector for a gamepad
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) &&
(fabsf(CORE.Input.Gamepad.axisState[gamepad][axis]) > 0.1f)) value = CORE.Input.Gamepad.axisState[gamepad][axis]; // 0.1f = GAMEPAD_AXIS_MINIMUM_DRIFT/DELTA
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (axis < MAX_GAMEPAD_AXIS)) {
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;
}
@ -3482,7 +3480,7 @@ static void RecordAutomationEvent(void)
currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter;
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[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;
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++)
{
// 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].type = INPUT_GAMEPAD_AXIS_MOTION;

View File

@ -844,9 +844,9 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
#define GL_GLEXT_PROTOTYPES
#include <GLES2/gl2ext.h> // OpenGL ES 2.0 extensions library
#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
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_DESKTOP_SDL)
#if defined(PLATFORM_DESKTOP_GLFW) || defined(PLATFORM_DESKTOP_SDL)
#define GLAD_GLES2_IMPLEMENTATION
#include "external/glad_gles2.h"
#else
@ -2390,7 +2390,7 @@ void rlLoadExtensions(void *loader)
#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
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");
@ -4401,7 +4401,7 @@ unsigned int rlGetShaderBufferSize(unsigned int id)
#if defined(GRAPHICS_API_OPENGL_43)
glBindBuffer(GL_SHADER_STORAGE_BUFFER, id);
glGetInteger64v(GL_SHADER_STORAGE_BUFFER_SIZE, &size);
glGetBufferParameteri64v(GL_SHADER_STORAGE_BUFFER, GL_BUFFER_SIZE, &size);
#endif
return (size > 0)? (unsigned int)size : 0;
@ -4756,7 +4756,16 @@ static void rlLoadShaderDefault(void)
"out vec2 fragTexCoord; \n"
"out vec4 fragColor; \n"
#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"
"precision mediump float; \n" // Precision required for OpenGL ES2 (WebGL) (on some browsers)
"attribute vec3 vertexPosition; \n"
@ -4765,6 +4774,7 @@ static void rlLoadShaderDefault(void)
"varying vec2 fragTexCoord; \n"
"varying vec4 fragColor; \n"
#endif
"uniform mat4 mvp; \n"
"void main() \n"
"{ \n"
@ -4799,7 +4809,21 @@ static void rlLoadShaderDefault(void)
" finalColor = texelColor*colDiffuse*fragColor; \n"
"} \n";
#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"
"precision mediump float; \n" // Precision required for OpenGL ES2 (WebGL)
"varying vec2 fragTexCoord; \n"

View File

@ -1072,16 +1072,10 @@ void DrawGrid(int slices, float spacing)
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);
}
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);
}
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
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 };
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)
@ -3651,116 +3645,82 @@ void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector
// NOTE: Billboard locked on axis-Y
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
// 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)
{
// NOTE: Billboard size will maintain source rectangle aspect ratio, size will represent billboard width
Vector2 sizeRatio = { size.x*fabsf((float)source.width/source.height), size.y };
// Compute the up vector and the right vector
Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
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);
Vector3 upScaled = Vector3Scale(up, sizeRatio.y/2);
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)
// Flip the content of the billboard while maintaining the counterclockwise edge rendering order
if (size.x < 0.0f)
{
float sinRotation = sinf(rotation*DEG2RAD);
float cosRotation = cosf(rotation*DEG2RAD);
// NOTE: (-1, 1) is the range where origin.x, origin.y is inside the texture
float rotateAboutX = sizeRatio.x*origin.x/2;
float rotateAboutY = sizeRatio.y*origin.y/2;
float xtvalue, ytvalue;
float rotatedX, rotatedY;
xtvalue = Vector3DotProduct(right, topLeft) - rotateAboutX; // Project points to x and y coordinates on the billboard plane
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));
source.x += size.x;
source.width *= -1.0;
right = Vector3Negate(right);
origin.x *= -1.0f;
}
if (size.y < 0.0f)
{
source.y += size.y;
source.height *= -1.0;
up = Vector3Negate(up);
origin.y *= -1.0f;
}
// Translate points to the draw center (position)
topLeft = Vector3Add(topLeft, position);
topRight = Vector3Add(topRight, position);
bottomRight = Vector3Add(bottomRight, position);
bottomLeft = Vector3Add(bottomLeft, position);
// Draw the texture region described by source on the following rectangle in 3D space:
//
// size.x <--.
// 3 ^---------------------------+ 2 \ rotation
// | | /
// | |
// | 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);
rlBegin(RL_QUADS);
rlColor4ub(tint.r, tint.g, tint.b, tint.a);
if (sizeRatio.x*sizeRatio.y >= 0.0f)
for (int i = 0; i < 4; i++)
{
// Bottom-left corner for texture and quad
rlTexCoord2f((float)source.x/texture.width, (float)source.y/texture.height);
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);
rlTexCoord2f(texcoords[i].x, texcoords[i].y);
rlVertex3f(points[i].x, points[i].y, points[i].z);
}
rlEnd();
rlSetTexture(0);
}
@ -4328,7 +4288,7 @@ static Model LoadIQM(const char *fileName)
// In case file can not be read, return an empty model
if (fileDataPtr == NULL) return model;
const char* basePath = GetDirectoryPath(fileName);
const char *basePath = GetDirectoryPath(fileName);
// Read IQM header
IQMHeader *iqmHeader = (IQMHeader *)fileDataPtr;
@ -5206,7 +5166,7 @@ static Model LoadGLTF(const char *fileName)
// Transform the 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);
vertices[3*k] = vt.x;
@ -5230,7 +5190,7 @@ static Model LoadGLTF(const char *fileName)
// Transform the 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);
normals[3*k] = nt.x;
@ -5254,7 +5214,7 @@ static Model LoadGLTF(const char *fileName)
// Transform the 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);
tangents[3*k] = tt.x;

View File

@ -2172,7 +2172,9 @@ bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius)
{
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;
}

View File

@ -1572,7 +1572,7 @@ char *TextReplace(const char *text, const char *replace, const char *by)
byLen = TextLength(by);
// Count the number of replacements needed
insertPoint = (char*)text;
insertPoint = (char *)text;
for (count = 0; (temp = strstr(insertPoint, replace)); count++) insertPoint = temp + replaceLen;
// 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 readVars = 0; // Variables filled by sscanf()
const char *fileText = (const char*)fileData;
const char *fileText = (const char *)fileData;
const char *fileTextPtr = fileText;
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 };
// 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 defined(SUPPORT_FILEFORMAT_PNG)
@ -1213,6 +1222,7 @@ Image GenImageText(int width, int height, const char *text)
{
Image image = { 0 };
#if defined(SUPPORT_MODULE_RTEXT)
int textLength = TextLength(text);
int imageViewSize = width*height;
@ -1223,6 +1233,10 @@ 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;
}
@ -3658,7 +3672,7 @@ void ImageDrawLineEx(Image *dst, Vector2 start, Vector2 end, int thick, Color co
{
// Line is more horizontal
// 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
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
// 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
for (int i = 1; i <= wx; i++)