Merge branch 'raysan5:master' into master

This commit is contained in:
Colleague Riley 2024-07-09 17:20:33 -04:00 committed by GitHub
commit c5c0aeb4cb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
39 changed files with 3335 additions and 2998 deletions

1
.gitignore vendored
View File

@ -104,6 +104,7 @@ GRTAGS
GTAGS GTAGS
# Zig programming language # Zig programming language
.zig-cache/
zig-cache/ zig-cache/
zig-out/ zig-out/
build/ build/

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

@ -4,7 +4,9 @@
# #
# This file supports building raylib examples for the following platforms: # This file supports building raylib examples for the following platforms:
# #
# > PLATFORM_DESKTOP (GLFW backend): # > PLATFORM_DESKTOP
# - Defaults to PLATFORM_DESKTOP_GLFW
# > PLATFORM_DESKTOP_GFLW (GLFW backend):
# - Windows (Win32, Win64) # - Windows (Win32, Win64)
# - Linux (X11/Wayland desktop mode) # - Linux (X11/Wayland desktop mode)
# - macOS/OSX (x64, arm64) # - macOS/OSX (x64, arm64)
@ -52,9 +54,15 @@
# Define target platform: PLATFORM_DESKTOP, PLATFORM_DESKTOP_SDL, PLATFORM_DRM, PLATFORM_ANDROID, PLATFORM_WEB # Define target platform: PLATFORM_DESKTOP, PLATFORM_DESKTOP_SDL, PLATFORM_DRM, PLATFORM_ANDROID, PLATFORM_WEB
PLATFORM ?= PLATFORM_DESKTOP PLATFORM ?= PLATFORM_DESKTOP
ifeq ($(PLATFORM), PLATFORM_DESKTOP)
TARGET_PLATFORM = PLATFORM_DESKTOP_GLFW
else
TARGET_PLATFORM = $(PLATFORM)
endif
# Define required raylib variables # Define required raylib variables
PROJECT_NAME ?= raylib_examples PROJECT_NAME ?= raylib_examples
RAYLIB_VERSION ?= 5.0.0 RAYLIB_VERSION ?= 5.5.0
RAYLIB_PATH ?= .. RAYLIB_PATH ?= ..
# Define raylib source code path # Define raylib source code path
@ -91,7 +99,7 @@ BUILD_WEB_RESOURCES ?= TRUE
BUILD_WEB_RESOURCES_PATH ?= $(dir $<)resources@resources BUILD_WEB_RESOURCES_PATH ?= $(dir $<)resources@resources
# Determine PLATFORM_OS when required # Determine PLATFORM_OS when required
ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_DESKTOP PLATFORM_DESKTOP_SDL PLATFORM_WEB PLATFORM_DESKTOP_RGFW)) ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW PLATFORM_DESKTOP_SDL PLATFORM_DESKTOP_RGFW PLATFORM_WEB))
# No uname.exe on MinGW!, but OS=Windows_NT on Windows! # No uname.exe on MinGW!, but OS=Windows_NT on Windows!
# ifeq ($(UNAME),Msys) -> Windows # ifeq ($(UNAME),Msys) -> Windows
ifeq ($(OS),Windows_NT) ifeq ($(OS),Windows_NT)
@ -118,7 +126,7 @@ ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_DESKTOP PLATFORM_DESKTOP_SDL PLA
endif endif
endif endif
endif endif
ifeq ($(PLATFORM),PLATFORM_DRM) ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
UNAMEOS = $(shell uname) UNAMEOS = $(shell uname)
ifeq ($(UNAMEOS),Linux) ifeq ($(UNAMEOS),Linux)
PLATFORM_OS = LINUX PLATFORM_OS = LINUX
@ -127,7 +135,7 @@ endif
# RAYLIB_PATH adjustment for LINUX platform # RAYLIB_PATH adjustment for LINUX platform
# TODO: Do we really need this? # TODO: Do we really need this?
ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
ifeq ($(PLATFORM_OS),LINUX) ifeq ($(PLATFORM_OS),LINUX)
RAYLIB_PREFIX ?= .. RAYLIB_PREFIX ?= ..
RAYLIB_PATH = $(realpath $(RAYLIB_PREFIX)) RAYLIB_PATH = $(realpath $(RAYLIB_PREFIX))
@ -135,14 +143,14 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
endif endif
# Default path for raylib on Raspberry Pi # Default path for raylib on Raspberry Pi
ifeq ($(PLATFORM),PLATFORM_DRM) ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
RAYLIB_PATH ?= /home/pi/raylib RAYLIB_PATH ?= /home/pi/raylib
endif endif
# Define raylib release directory for compiled library # Define raylib release directory for compiled library
RAYLIB_RELEASE_PATH ?= $(RAYLIB_PATH)/src RAYLIB_RELEASE_PATH ?= $(RAYLIB_PATH)/src
ifeq ($(PLATFORM),PLATFORM_WEB) ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
ifeq ($(PLATFORM_OS),WINDOWS) ifeq ($(PLATFORM_OS),WINDOWS)
# Emscripten required variables # Emscripten required variables
EMSDK_PATH ?= C:/emsdk EMSDK_PATH ?= C:/emsdk
@ -158,7 +166,7 @@ endif
#------------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------------------
CC = gcc CC = gcc
ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
ifeq ($(PLATFORM_OS),OSX) ifeq ($(PLATFORM_OS),OSX)
# OSX default compiler # OSX default compiler
CC = clang CC = clang
@ -168,7 +176,7 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
CC = clang CC = clang
endif endif
endif endif
ifeq ($(PLATFORM),PLATFORM_WEB) ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
# HTML5 emscripten compiler # HTML5 emscripten compiler
# WARNING: To compile to HTML5, code must be redesigned # WARNING: To compile to HTML5, code must be redesigned
# to use emscripten.h and emscripten_set_main_loop() # to use emscripten.h and emscripten_set_main_loop()
@ -179,15 +187,15 @@ endif
#------------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------------------
MAKE ?= make MAKE ?= make
ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
ifeq ($(PLATFORM_OS),WINDOWS) ifeq ($(PLATFORM_OS),WINDOWS)
MAKE = mingw32-make MAKE = mingw32-make
endif endif
endif endif
ifeq ($(PLATFORM),PLATFORM_ANDROID) ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
MAKE = mingw32-make MAKE = mingw32-make
endif endif
ifeq ($(PLATFORM),PLATFORM_WEB) ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
MAKE = emmake make MAKE = emmake make
endif endif
@ -206,11 +214,11 @@ CFLAGS = -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces -Wunused-result
ifeq ($(BUILD_MODE),DEBUG) ifeq ($(BUILD_MODE),DEBUG)
CFLAGS += -g -D_DEBUG CFLAGS += -g -D_DEBUG
ifeq ($(PLATFORM),PLATFORM_WEB) ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
CFLAGS += -sASSERTIONS=1 --profiling CFLAGS += -sASSERTIONS=1 --profiling
endif endif
else else
ifeq ($(PLATFORM),PLATFORM_WEB) ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
ifeq ($(BUILD_WEB_ASYNCIFY),TRUE) ifeq ($(BUILD_WEB_ASYNCIFY),TRUE)
CFLAGS += -O3 CFLAGS += -O3
else else
@ -227,7 +235,7 @@ endif
# -Wstrict-prototypes warn if a function is declared or defined without specifying the argument types # -Wstrict-prototypes warn if a function is declared or defined without specifying the argument types
# -Werror=implicit-function-declaration catch function calls without prior declaration # -Werror=implicit-function-declaration catch function calls without prior declaration
#CFLAGS += -Wextra -Wmissing-prototypes -Wstrict-prototypes #CFLAGS += -Wextra -Wmissing-prototypes -Wstrict-prototypes
ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
ifeq ($(PLATFORM_OS),LINUX) ifeq ($(PLATFORM_OS),LINUX)
ifeq ($(RAYLIB_LIBTYPE),STATIC) ifeq ($(RAYLIB_LIBTYPE),STATIC)
CFLAGS += -D_DEFAULT_SOURCE CFLAGS += -D_DEFAULT_SOURCE
@ -238,7 +246,7 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
endif endif
endif endif
endif endif
ifeq ($(PLATFORM),PLATFORM_DRM) ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
CFLAGS += -std=gnu99 -DEGL_NO_X11 CFLAGS += -std=gnu99 -DEGL_NO_X11
endif endif
@ -248,7 +256,7 @@ endif
INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/src/external INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/src/external
# Define additional directories containing required header files # Define additional directories containing required header files
ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
ifeq ($(PLATFORM_OS),BSD) ifeq ($(PLATFORM_OS),BSD)
INCLUDE_PATHS += -I$(RAYLIB_INCLUDE_PATH) INCLUDE_PATHS += -I$(RAYLIB_INCLUDE_PATH)
endif endif
@ -256,10 +264,10 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
INCLUDE_PATHS += -I$(RAYLIB_INCLUDE_PATH) INCLUDE_PATHS += -I$(RAYLIB_INCLUDE_PATH)
endif endif
endif endif
ifeq ($(PLATFORM),PLATFORM_DESKTOP_SDL) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_SDL)
INCLUDE_PATHS += -I$(SDL_INCLUDE_PATH) INCLUDE_PATHS += -I$(SDL_INCLUDE_PATH)
endif endif
ifeq ($(PLATFORM),PLATFORM_DRM) ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
INCLUDE_PATHS += -I$(RAYLIB_INCLUDE_PATH) INCLUDE_PATHS += -I$(RAYLIB_INCLUDE_PATH)
INCLUDE_PATHS += -I/usr/include/libdrm INCLUDE_PATHS += -I/usr/include/libdrm
endif endif
@ -273,7 +281,7 @@ endif
#------------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------------------
LDFLAGS = -L. -L$(RAYLIB_RELEASE_PATH) -L$(RAYLIB_PATH)/src LDFLAGS = -L. -L$(RAYLIB_RELEASE_PATH) -L$(RAYLIB_PATH)/src
ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
ifeq ($(PLATFORM_OS),WINDOWS) ifeq ($(PLATFORM_OS),WINDOWS)
# NOTE: The resource .rc file contains windows executable icon and properties # NOTE: The resource .rc file contains windows executable icon and properties
LDFLAGS += $(RAYLIB_PATH)/src/raylib.rc.data LDFLAGS += $(RAYLIB_PATH)/src/raylib.rc.data
@ -289,7 +297,7 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
LDFLAGS += -Lsrc -L$(RAYLIB_LIB_PATH) LDFLAGS += -Lsrc -L$(RAYLIB_LIB_PATH)
endif endif
endif endif
ifeq ($(PLATFORM),PLATFORM_DESKTOP_SDL) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_SDL)
ifeq ($(PLATFORM_OS),WINDOWS) ifeq ($(PLATFORM_OS),WINDOWS)
# NOTE: The resource .rc file contains windows executable icon and properties # NOTE: The resource .rc file contains windows executable icon and properties
LDFLAGS += $(RAYLIB_PATH)/src/raylib.rc.data LDFLAGS += $(RAYLIB_PATH)/src/raylib.rc.data
@ -300,7 +308,7 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP_SDL)
endif endif
LDFLAGS += -L$(SDL_LIBRARY_PATH) LDFLAGS += -L$(SDL_LIBRARY_PATH)
endif endif
ifeq ($(PLATFORM),PLATFORM_WEB) ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
# -Os # size optimization # -Os # size optimization
# -O2 # optimization level 2, if used, also set --memory-init-file 0 # -O2 # optimization level 2, if used, also set --memory-init-file 0
# -sUSE_GLFW=3 # Use glfw3 library (context/input management) # -sUSE_GLFW=3 # Use glfw3 library (context/input management)
@ -347,7 +355,7 @@ endif
# Define libraries required on linking: LDLIBS # Define libraries required on linking: LDLIBS
# NOTE: To link libraries (lib<name>.so or lib<name>.a), use -l<name> # NOTE: To link libraries (lib<name>.so or lib<name>.a), use -l<name>
#------------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------------------
ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
ifeq ($(PLATFORM_OS),WINDOWS) ifeq ($(PLATFORM_OS),WINDOWS)
# Libraries for Windows desktop compilation # Libraries for Windows desktop compilation
# NOTE: WinMM library required to set high-res timer resolution # NOTE: WinMM library required to set high-res timer resolution
@ -393,7 +401,7 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
LDLIBS += -lglfw LDLIBS += -lglfw
endif endif
endif endif
ifeq ($(PLATFORM),PLATFORM_DESKTOP_SDL) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_SDL)
ifeq ($(PLATFORM_OS),WINDOWS) ifeq ($(PLATFORM_OS),WINDOWS)
# Libraries for Windows desktop compilation # Libraries for Windows desktop compilation
LDLIBS = -lraylib -lSDL2 -lSDL2main -lopengl32 -lgdi32 LDLIBS = -lraylib -lSDL2 -lSDL2main -lopengl32 -lgdi32
@ -421,7 +429,7 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP_SDL)
LDLIBS += -latomic LDLIBS += -latomic
endif endif
endif endif
ifeq ($(PLATFORM),PLATFORM_DESKTOP_RGFW) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_RGFW)
ifeq ($(PLATFORM_OS),WINDOWS) ifeq ($(PLATFORM_OS),WINDOWS)
# Libraries for Windows desktop compilation # Libraries for Windows desktop compilation
LDLIBS = ..\src\libraylib.a -lgdi32 -lwinmm -lopengl32 LDLIBS = ..\src\libraylib.a -lgdi32 -lwinmm -lopengl32
@ -446,12 +454,12 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP_RGFW)
LDLIBS += -framework Foundation -framework AppKit -framework OpenGL -framework CoreVideo LDLIBS += -framework Foundation -framework AppKit -framework OpenGL -framework CoreVideo
endif endif
endif endif
ifeq ($(PLATFORM),PLATFORM_DRM) ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
# Libraries for DRM compiling # Libraries for DRM compiling
# NOTE: Required packages: libasound2-dev (ALSA) # NOTE: Required packages: libasound2-dev (ALSA)
LDLIBS = -lraylib -lGLESv2 -lEGL -lpthread -lrt -lm -lgbm -ldrm -ldl -latomic LDLIBS = -lraylib -lGLESv2 -lEGL -lpthread -lrt -lm -lgbm -ldrm -ldl -latomic
endif endif
ifeq ($(PLATFORM),PLATFORM_WEB) ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
# Libraries for web (HTML5) compiling # Libraries for web (HTML5) compiling
LDLIBS = $(RAYLIB_RELEASE_PATH)/libraylib.a LDLIBS = $(RAYLIB_RELEASE_PATH)/libraylib.a
endif endif
@ -638,17 +646,17 @@ others: $(OTHERS)
# Generic compilation pattern # Generic compilation pattern
# NOTE: Examples must be ready for Android compilation! # NOTE: Examples must be ready for Android compilation!
%: %.c %: %.c
ifeq ($(PLATFORM),PLATFORM_ANDROID) ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
$(MAKE) -f Makefile.Android PROJECT_NAME=$@ PROJECT_SOURCE_FILES=$< $(MAKE) -f Makefile.Android PROJECT_NAME=$@ PROJECT_SOURCE_FILES=$<
else ifeq ($(PLATFORM),PLATFORM_WEB) else ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
$(MAKE) -f Makefile.Web $@ $(MAKE) -f Makefile.Web $@
else else
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -D$(TARGET_PLATFORM)
endif endif
# Clean everything # Clean everything
clean: clean:
ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
ifeq ($(PLATFORM_OS),WINDOWS) ifeq ($(PLATFORM_OS),WINDOWS)
del *.o *.exe /s del *.o *.exe /s
endif endif
@ -661,11 +669,11 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
rm -f *.o rm -f *.o
endif endif
endif endif
ifeq ($(PLATFORM),PLATFORM_DRM) ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
find . -type f -executable -delete find . -type f -executable -delete
rm -fv *.o rm -fv *.o
endif endif
ifeq ($(PLATFORM),PLATFORM_WEB) ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
ifeq ($(PLATFORM_OS),WINDOWS) ifeq ($(PLATFORM_OS),WINDOWS)
del *.wasm *.html *.js *.data del *.wasm *.html *.js *.data
else else

27
examples/examples.rc Normal file
View File

@ -0,0 +1,27 @@
GLFW_ICON ICON "raylib.ico"
1 VERSIONINFO
FILEVERSION 1,0,0,0
PRODUCTVERSION 1,0,0,0
BEGIN
BLOCK "StringFileInfo"
BEGIN
//BLOCK "080904E4" // English UK
BLOCK "040904E4" // English US
BEGIN
VALUE "CompanyName", "raylib technologies"
VALUE "FileDescription", "raylib example"
VALUE "FileVersion", "1.0"
VALUE "InternalName", "raylib-example"
VALUE "LegalCopyright", "(c) 2024 raylib technologies (@raylibtech)"
//VALUE "OriginalFilename", "raylib_app.exe"
VALUE "ProductName", "raylib-example"
VALUE "ProductVersion", "1.0"
END
END
BLOCK "VarFileInfo"
BEGIN
//VALUE "Translation", 0x809, 1252 // English UK
VALUE "Translation", 0x409, 1252 // English US
END
END

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);
} }
@ -108,4 +110,4 @@ int main(void)
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
return 0; return 0;
} }

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,17 +42,14 @@ 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;
unsigned int animIndex = 0; unsigned int animIndex = 0;
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;
} }

BIN
examples/raylib.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

View File

@ -0,0 +1,106 @@
/*******************************************************************************************
*
* raylib [textures] example - Retrive image channel (mask)
*
* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM)
*
* Example originally created with raylib 5.1-dev, last time updated with raylib 5.1-dev
*
* Example contributed by Bruno Cabral (github.com/brccabral) and reviewed by Ramon Santamaria (@raysan5)
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
* Copyright (c) 2024-2024 Bruno Cabral (github.com/brccabral) and Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include <raylib.h>
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [textures] example - extract channel from image");
Image fudesumiImage = LoadImage("resources/fudesumi.png");
Image imageAlpha = ImageFromChannel(fudesumiImage, 3);
ImageAlphaMask(&imageAlpha, imageAlpha);
Image imageRed = ImageFromChannel(fudesumiImage, 0);
ImageAlphaMask(&imageRed, imageAlpha);
Image imageGreen = ImageFromChannel(fudesumiImage, 1);
ImageAlphaMask(&imageGreen, imageAlpha);
Image imageBlue = ImageFromChannel(fudesumiImage, 2);
ImageAlphaMask(&imageBlue, imageAlpha);
Image backgroundImage = GenImageChecked(screenWidth, screenHeight, screenWidth/20, screenHeight/20, ORANGE, YELLOW);
Texture2D fudesumiTexture = LoadTextureFromImage(fudesumiImage);
Texture2D textureAlpha = LoadTextureFromImage(imageAlpha);
Texture2D textureRed = LoadTextureFromImage(imageRed);
Texture2D textureGreen = LoadTextureFromImage(imageGreen);
Texture2D textureBlue = LoadTextureFromImage(imageBlue);
Texture2D backgroundTexture = LoadTextureFromImage(backgroundImage);
UnloadImage(fudesumiImage);
UnloadImage(imageAlpha);
UnloadImage(imageRed);
UnloadImage(imageGreen);
UnloadImage(imageBlue);
UnloadImage(backgroundImage);
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
Rectangle fudesumiRec = {0, 0, fudesumiImage.width, fudesumiImage.height};
Rectangle fudesumiPos = {50, 10, fudesumiImage.width*0.8f, fudesumiImage.height*0.8f};
Rectangle redPos = { 410, 10, fudesumiPos.width / 2, fudesumiPos.height / 2 };
Rectangle greenPos = { 600, 10, fudesumiPos.width / 2, fudesumiPos.height / 2 };
Rectangle bluePos = { 410, 230, fudesumiPos.width / 2, fudesumiPos.height / 2 };
Rectangle alphaPos = { 600, 230, fudesumiPos.width / 2, fudesumiPos.height / 2 };
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
DrawTexture(backgroundTexture, 0, 0, WHITE);
DrawTexturePro(fudesumiTexture, fudesumiRec, fudesumiPos, (Vector2) {0, 0}, 0, WHITE);
DrawTexturePro(textureRed, fudesumiRec, redPos, (Vector2) {0, 0}, 0, RED);
DrawTexturePro(textureGreen, fudesumiRec, greenPos, (Vector2) {0, 0}, 0, GREEN);
DrawTexturePro(textureBlue, fudesumiRec, bluePos, (Vector2) {0, 0}, 0, BLUE);
DrawTexturePro(textureAlpha, fudesumiRec, alphaPos, (Vector2) {0, 0}, 0, WHITE);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(backgroundTexture);
UnloadTexture(fudesumiTexture);
UnloadTexture(textureRed);
UnloadTexture(textureGreen);
UnloadTexture(textureBlue);
UnloadTexture(textureAlpha);
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

View File

@ -15,7 +15,7 @@
{ {
"name": "RAYLIB_VERSION_MINOR", "name": "RAYLIB_VERSION_MINOR",
"type": "INT", "type": "INT",
"value": 1, "value": 5,
"description": "" "description": ""
}, },
{ {
@ -27,7 +27,7 @@
{ {
"name": "RAYLIB_VERSION", "name": "RAYLIB_VERSION",
"type": "STRING", "type": "STRING",
"value": "5.1-dev", "value": "5.5",
"description": "" "description": ""
}, },
{ {
@ -1058,7 +1058,7 @@
{ {
"type": "Vector3", "type": "Vector3",
"name": "direction", "name": "direction",
"description": "Ray direction" "description": "Ray direction (normalized)"
} }
] ]
}, },
@ -7183,6 +7183,21 @@
} }
] ]
}, },
{
"name": "ImageFromChannel",
"description": "Create an image from a selected channel of another image (GRAYSCALE)",
"returnType": "Image",
"params": [
{
"type": "Image",
"name": "image"
},
{
"type": "int",
"name": "selectedChannel"
}
]
},
{ {
"name": "ImageText", "name": "ImageText",
"description": "Create an image from text (default font)", "description": "Create an image from text (default font)",
@ -10385,7 +10400,7 @@
}, },
{ {
"type": "float", "type": "float",
"name": "size" "name": "scale"
}, },
{ {
"type": "Color", "type": "Color",

View File

@ -15,7 +15,7 @@ return {
{ {
name = "RAYLIB_VERSION_MINOR", name = "RAYLIB_VERSION_MINOR",
type = "INT", type = "INT",
value = 1, value = 5,
description = "" description = ""
}, },
{ {
@ -27,7 +27,7 @@ return {
{ {
name = "RAYLIB_VERSION", name = "RAYLIB_VERSION",
type = "STRING", type = "STRING",
value = "5.1-dev", value = "5.5",
description = "" description = ""
}, },
{ {
@ -1058,7 +1058,7 @@ return {
{ {
type = "Vector3", type = "Vector3",
name = "direction", name = "direction",
description = "Ray direction" description = "Ray direction (normalized)"
} }
} }
}, },
@ -5521,6 +5521,15 @@ return {
{type = "Rectangle", name = "rec"} {type = "Rectangle", name = "rec"}
} }
}, },
{
name = "ImageFromChannel",
description = "Create an image from a selected channel of another image (GRAYSCALE)",
returnType = "Image",
params = {
{type = "Image", name = "image"},
{type = "int", name = "selectedChannel"}
}
},
{ {
name = "ImageText", name = "ImageText",
description = "Create an image from text (default font)", description = "Create an image from text (default font)",
@ -7221,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"}
} }
}, },

File diff suppressed because it is too large Load Diff

View File

@ -3,9 +3,9 @@
<Defines count="57"> <Defines count="57">
<Define name="RAYLIB_H" type="GUARD" value="" desc="" /> <Define name="RAYLIB_H" type="GUARD" value="" desc="" />
<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="1" 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.1-dev" desc="" /> <Define name="RAYLIB_VERSION" type="STRING" value="5.5" 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?" />
@ -670,7 +670,7 @@
<Param type="unsigned int" name="frames" desc="" /> <Param type="unsigned int" name="frames" desc="" />
</Callback> </Callback>
</Callbacks> </Callbacks>
<Functions count="572"> <Functions count="573">
<Function name="InitWindow" retType="void" paramCount="3" desc="Initialize window and OpenGL context"> <Function name="InitWindow" retType="void" paramCount="3" desc="Initialize window and OpenGL context">
<Param type="int" name="width" desc="" /> <Param type="int" name="width" desc="" />
<Param type="int" name="height" desc="" /> <Param type="int" name="height" desc="" />
@ -1798,6 +1798,10 @@
<Param type="Image" name="image" desc="" /> <Param type="Image" name="image" desc="" />
<Param type="Rectangle" name="rec" desc="" /> <Param type="Rectangle" name="rec" desc="" />
</Function> </Function>
<Function name="ImageFromChannel" retType="Image" paramCount="2" desc="Create an image from a selected channel of another image (GRAYSCALE)">
<Param type="Image" name="image" desc="" />
<Param type="int" name="selectedChannel" desc="" />
</Function>
<Function name="ImageText" retType="Image" paramCount="3" desc="Create an image from text (default font)"> <Function name="ImageText" retType="Image" paramCount="3" desc="Create an image from text (default font)">
<Param type="const char *" name="text" desc="" /> <Param type="const char *" name="text" desc="" />
<Param type="int" name="fontSize" desc="" /> <Param type="int" name="fontSize" desc="" />
@ -2641,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

@ -5,7 +5,7 @@ project(example)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# Dependencies # Dependencies
set(RAYLIB_VERSION 5.0) set(RAYLIB_VERSION 5.5)
find_package(raylib ${RAYLIB_VERSION} QUIET) # QUIET or REQUIRED find_package(raylib ${RAYLIB_VERSION} QUIET) # QUIET or REQUIRED
if (NOT raylib_FOUND) # If there's none, fetch and build raylib if (NOT raylib_FOUND) # If there's none, fetch and build raylib
include(FetchContent) include(FetchContent)

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

@ -1,7 +1,7 @@
# Setup the project and settings # Setup the project and settings
project(raylib C) project(raylib C)
set(PROJECT_VERSION 5.0.0) set(PROJECT_VERSION 5.5.0)
set(API_VERSION 500) set(API_VERSION 550)
include(GNUInstallDirs) include(GNUInstallDirs)
include(JoinPaths) include(JoinPaths)

View File

@ -4,7 +4,9 @@
# #
# This file supports building raylib library for the following platforms: # This file supports building raylib library for the following platforms:
# #
# > PLATFORM_DESKTOP (GLFW backend): # > PLATFORM_DESKTOP
# - Defaults to PLATFORM_DESKTOP_GLFW
# > PLATFORM_DESKTOP_GLFW (GLFW backend):
# - Windows (Win32, Win64) # - Windows (Win32, Win64)
# - Linux (X11/Wayland desktop mode) # - Linux (X11/Wayland desktop mode)
# - macOS/OSX (x64, arm64) # - macOS/OSX (x64, arm64)
@ -55,12 +57,18 @@
# Define required environment variables # Define required environment variables
#------------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------------------
# Define target platform: PLATFORM_DESKTOP, PLATFORM_DRM, PLATFORM_ANDROID, PLATFORM_WEB # Define target platform
PLATFORM ?= PLATFORM_DESKTOP PLATFORM ?= PLATFORM_DESKTOP
ifeq ($(PLATFORM), PLATFORM_DESKTOP)
TARGET_PLATFORM = PLATFORM_DESKTOP_GLFW
else
TARGET_PLATFORM = $(PLATFORM)
endif
# Define required raylib variables # Define required raylib variables
RAYLIB_VERSION = 5.0.0 RAYLIB_VERSION = 5.5.0
RAYLIB_API_VERSION = 500 RAYLIB_API_VERSION = 550
# Define raylib source code path # Define raylib source code path
RAYLIB_SRC_PATH ?= ../src RAYLIB_SRC_PATH ?= ../src
@ -119,7 +127,7 @@ HOST_PLATFORM_OS ?= WINDOWS
PLATFORM_OS ?= WINDOWS PLATFORM_OS ?= WINDOWS
# Determine PLATFORM_OS when required # Determine PLATFORM_OS when required
ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_DESKTOP PLATFORM_DESKTOP_SDL PLATFORM_WEB PLATFORM_ANDROID PLATFORM_DESKTOP_RGFW)) ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW PLATFORM_DESKTOP_SDL PLATFORM_DESKTOP_RGFW PLATFORM_WEB PLATFORM_ANDROID))
# No uname.exe on MinGW!, but OS=Windows_NT on Windows! # No uname.exe on MinGW!, but OS=Windows_NT on Windows!
# ifeq ($(UNAME),Msys) -> Windows # ifeq ($(UNAME),Msys) -> Windows
ifeq ($(OS),Windows_NT) ifeq ($(OS),Windows_NT)
@ -152,7 +160,7 @@ ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_DESKTOP PLATFORM_DESKTOP_SDL PLA
endif endif
endif endif
endif endif
ifeq ($(PLATFORM),PLATFORM_DRM) ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
UNAMEOS = $(shell uname) UNAMEOS = $(shell uname)
ifeq ($(UNAMEOS),Linux) ifeq ($(UNAMEOS),Linux)
PLATFORM_OS = LINUX PLATFORM_OS = LINUX
@ -161,7 +169,7 @@ ifeq ($(PLATFORM),PLATFORM_DRM)
PLATFORM_SHELL = sh PLATFORM_SHELL = sh
endif endif
endif endif
ifeq ($(PLATFORM),PLATFORM_WEB) ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
ifeq ($(PLATFORM_OS),LINUX) ifeq ($(PLATFORM_OS),LINUX)
ifndef PLATFORM_SHELL ifndef PLATFORM_SHELL
PLATFORM_SHELL = sh PLATFORM_SHELL = sh
@ -169,7 +177,7 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
endif endif
endif endif
ifeq ($(PLATFORM),PLATFORM_WEB) ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
ifeq ($(PLATFORM_OS), WINDOWS) ifeq ($(PLATFORM_OS), WINDOWS)
# Emscripten required variables # Emscripten required variables
EMSDK_PATH ?= C:/emsdk EMSDK_PATH ?= C:/emsdk
@ -181,7 +189,7 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
endif endif
endif endif
ifeq ($(PLATFORM),PLATFORM_ANDROID) ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
# Android architecture # Android architecture
# Starting at 2019 using arm64 is mandatory for published apps, # Starting at 2019 using arm64 is mandatory for published apps,
# Starting on August 2020, minimum required target API is Android 10 (API level 29) # Starting on August 2020, minimum required target API is Android 10 (API level 29)
@ -221,7 +229,7 @@ ifeq ($(PLATFORM),PLATFORM_ANDROID)
endif endif
# Define raylib graphics api depending on selected platform # Define raylib graphics api depending on selected platform
ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
# By default use OpenGL 3.3 on desktop platforms # By default use OpenGL 3.3 on desktop platforms
GRAPHICS ?= GRAPHICS_API_OPENGL_33 GRAPHICS ?= GRAPHICS_API_OPENGL_33
#GRAPHICS = GRAPHICS_API_OPENGL_11 # Uncomment to use OpenGL 1.1 #GRAPHICS = GRAPHICS_API_OPENGL_11 # Uncomment to use OpenGL 1.1
@ -229,28 +237,28 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
#GRAPHICS = GRAPHICS_API_OPENGL_43 # Uncomment to use OpenGL 4.3 #GRAPHICS = GRAPHICS_API_OPENGL_43 # Uncomment to use OpenGL 4.3
#GRAPHICS = GRAPHICS_API_OPENGL_ES2 # Uncomment to use OpenGL ES 2.0 (ANGLE) #GRAPHICS = GRAPHICS_API_OPENGL_ES2 # Uncomment to use OpenGL ES 2.0 (ANGLE)
endif endif
ifeq ($(PLATFORM),PLATFORM_DESKTOP_RGFW) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_SDL)
# By default use OpenGL 3.3 on desktop platforms
GRAPHICS ?= GRAPHICS_API_OPENGL_33
#GRAPHICS = GRAPHICS_API_OPENGL_11 # Uncomment to use OpenGL 1.1
#GRAPHICS = GRAPHICS_API_OPENGL_21 # Uncomment to use OpenGL 2.1
#GRAPHICS = GRAPHICS_API_OPENGL_43 # Uncomment to use OpenGL 4.3
#GRAPHICS = GRAPHICS_API_OPENGL_ES2 # Uncomment to use OpenGL ES 2.0 (ANGLE)
endif
ifeq ($(PLATFORM),PLATFORM_DESKTOP_SDL)
# By default use OpenGL 3.3 on desktop platform with SDL backend # By default use OpenGL 3.3 on desktop platform with SDL backend
GRAPHICS ?= GRAPHICS_API_OPENGL_33 GRAPHICS ?= GRAPHICS_API_OPENGL_33
endif endif
ifeq ($(PLATFORM),PLATFORM_DRM) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_RGFW)
# By default use OpenGL 3.3 on desktop platforms
GRAPHICS ?= GRAPHICS_API_OPENGL_33
#GRAPHICS = GRAPHICS_API_OPENGL_11 # Uncomment to use OpenGL 1.1
#GRAPHICS = GRAPHICS_API_OPENGL_21 # Uncomment to use OpenGL 2.1
#GRAPHICS = GRAPHICS_API_OPENGL_43 # Uncomment to use OpenGL 4.3
#GRAPHICS = GRAPHICS_API_OPENGL_ES2 # Uncomment to use OpenGL ES 2.0 (ANGLE)
endif
ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
# On DRM OpenGL ES 2.0 must be used # On DRM OpenGL ES 2.0 must be used
GRAPHICS = GRAPHICS_API_OPENGL_ES2 GRAPHICS = GRAPHICS_API_OPENGL_ES2
endif endif
ifeq ($(PLATFORM),PLATFORM_WEB) ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
# On HTML5 OpenGL ES 2.0 is used, emscripten translates it to WebGL 1.0 # On HTML5 OpenGL ES 2.0 is used, emscripten translates it to WebGL 1.0
GRAPHICS = GRAPHICS_API_OPENGL_ES2 GRAPHICS = GRAPHICS_API_OPENGL_ES2
#GRAPHICS = GRAPHICS_API_OPENGL_ES3 # Uncomment to use ES3/WebGL2 (preliminary support). #GRAPHICS = GRAPHICS_API_OPENGL_ES3 # Uncomment to use ES3/WebGL2 (preliminary support).
endif endif
ifeq ($(PLATFORM),PLATFORM_ANDROID) ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
# By default use OpenGL ES 2.0 on Android # By default use OpenGL ES 2.0 on Android
GRAPHICS = GRAPHICS_API_OPENGL_ES2 GRAPHICS = GRAPHICS_API_OPENGL_ES2
endif endif
@ -260,7 +268,7 @@ endif
CC = gcc CC = gcc
AR = ar AR = ar
ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
ifeq ($(PLATFORM_OS),OSX) ifeq ($(PLATFORM_OS),OSX)
# OSX default compiler # OSX default compiler
CC = clang CC = clang
@ -271,7 +279,7 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
CC = clang CC = clang
endif endif
endif endif
ifeq ($(PLATFORM),PLATFORM_DRM) ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
ifeq ($(USE_RPI_CROSS_COMPILER),TRUE) ifeq ($(USE_RPI_CROSS_COMPILER),TRUE)
# Define RPI cross-compiler # Define RPI cross-compiler
#CC = armv6j-hardfloat-linux-gnueabi-gcc #CC = armv6j-hardfloat-linux-gnueabi-gcc
@ -279,12 +287,12 @@ ifeq ($(PLATFORM),PLATFORM_DRM)
AR = $(RPI_TOOLCHAIN)/bin/$(RPI_TOOLCHAIN_NAME)-ar AR = $(RPI_TOOLCHAIN)/bin/$(RPI_TOOLCHAIN_NAME)-ar
endif endif
endif endif
ifeq ($(PLATFORM),PLATFORM_WEB) ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
# HTML5 emscripten compiler # HTML5 emscripten compiler
CC = emcc CC = emcc
AR = emar AR = emar
endif endif
ifeq ($(PLATFORM),PLATFORM_ANDROID) ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
# Android toolchain (must be provided for desired architecture and compiler) # Android toolchain (must be provided for desired architecture and compiler)
ifeq ($(ANDROID_ARCH),arm) ifeq ($(ANDROID_ARCH),arm)
CC = $(ANDROID_TOOLCHAIN)/bin/$(ANDROID_COMPILER_ARCH)-linux-androideabi$(ANDROID_API_VERSION)-clang CC = $(ANDROID_TOOLCHAIN)/bin/$(ANDROID_COMPILER_ARCH)-linux-androideabi$(ANDROID_API_VERSION)-clang
@ -316,13 +324,13 @@ endif
# -D_GNU_SOURCE access to lots of nonstandard GNU/Linux extension functions # -D_GNU_SOURCE access to lots of nonstandard GNU/Linux extension functions
# -Werror=pointer-arith catch unportable code that does direct arithmetic on void pointers # -Werror=pointer-arith catch unportable code that does direct arithmetic on void pointers
# -fno-strict-aliasing jar_xm.h does shady stuff (breaks strict aliasing) # -fno-strict-aliasing jar_xm.h does shady stuff (breaks strict aliasing)
CFLAGS = -Wall -D_GNU_SOURCE -D$(PLATFORM) -D$(GRAPHICS) -Wno-missing-braces -Werror=pointer-arith -fno-strict-aliasing CFLAGS = -Wall -D_GNU_SOURCE -D$(TARGET_PLATFORM) -D$(GRAPHICS) -Wno-missing-braces -Werror=pointer-arith -fno-strict-aliasing
ifneq ($(RAYLIB_CONFIG_FLAGS), NONE) ifneq ($(RAYLIB_CONFIG_FLAGS), NONE)
CFLAGS += -DEXTERNAL_CONFIG_FLAGS $(RAYLIB_CONFIG_FLAGS) CFLAGS += -DEXTERNAL_CONFIG_FLAGS $(RAYLIB_CONFIG_FLAGS)
endif endif
ifeq ($(PLATFORM), PLATFORM_WEB) ifeq ($(TARGET_PLATFORM), PLATFORM_WEB)
# NOTE: When using multi-threading in the user code, it requires -pthread enabled # NOTE: When using multi-threading in the user code, it requires -pthread enabled
CFLAGS += -std=gnu99 CFLAGS += -std=gnu99
else else
@ -338,13 +346,13 @@ ifeq ($(RAYLIB_BUILD_MODE),DEBUG)
endif endif
ifeq ($(RAYLIB_BUILD_MODE),RELEASE) ifeq ($(RAYLIB_BUILD_MODE),RELEASE)
ifeq ($(PLATFORM),PLATFORM_WEB) ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
CFLAGS += -Os CFLAGS += -Os
endif endif
ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
CFLAGS += -O1 CFLAGS += -O1
endif endif
ifeq ($(PLATFORM),PLATFORM_ANDROID) ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
CFLAGS += -O2 CFLAGS += -O2
endif endif
endif endif
@ -354,10 +362,10 @@ endif
# -Wmissing-prototypes warn if a global function is defined without a previous prototype declaration # -Wmissing-prototypes warn if a global function is defined without a previous prototype declaration
# -Wstrict-prototypes warn if a function is declared or defined without specifying the argument types # -Wstrict-prototypes warn if a function is declared or defined without specifying the argument types
# -Werror=implicit-function-declaration catch function calls without prior declaration # -Werror=implicit-function-declaration catch function calls without prior declaration
ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
CFLAGS += -Werror=implicit-function-declaration CFLAGS += -Werror=implicit-function-declaration
endif endif
ifeq ($(PLATFORM),PLATFORM_WEB) ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
# -Os # size optimization # -Os # size optimization
# -O2 # optimization level 2, if used, also set --memory-init-file 0 # -O2 # optimization level 2, if used, also set --memory-init-file 0
# -sUSE_GLFW=3 # Use glfw3 library (context/input management) -> Only for linker! # -sUSE_GLFW=3 # Use glfw3 library (context/input management) -> Only for linker!
@ -375,7 +383,7 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
endif endif
#CFLAGS += -sGL_ENABLE_GET_PROC_ADDRESS #CFLAGS += -sGL_ENABLE_GET_PROC_ADDRESS
endif endif
ifeq ($(PLATFORM),PLATFORM_ANDROID) ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
# Compiler flags for arquitecture # Compiler flags for arquitecture
ifeq ($(ANDROID_ARCH),arm) ifeq ($(ANDROID_ARCH),arm)
CFLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 CFLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16
@ -411,19 +419,18 @@ ifeq ($(RAYLIB_LIBTYPE),SHARED)
endif endif
endif endif
ifeq ($(PLATFORM),PLATFORM_DRM) ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
# without EGL_NO_X11 eglplatform.h tears Xlib.h in which tears X.h in # without EGL_NO_X11 eglplatform.h tears Xlib.h in which tears X.h in
# which contains a conflicting type Font # which contains a conflicting type Font
CFLAGS += -DEGL_NO_X11 CFLAGS += -DEGL_NO_X11
CFLAGS += -Werror=implicit-function-declaration CFLAGS += -Werror=implicit-function-declaration
endif endif
# Use Wayland display on Linux desktop # Use Wayland display on Linux desktop
ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
ifeq ($(PLATFORM_OS), LINUX) ifeq ($(PLATFORM_OS), LINUX)
ifeq ($(GLFW_LINUX_ENABLE_X11),TRUE) ifeq ($(GLFW_LINUX_ENABLE_X11),TRUE)
CFLAGS += -D_GLFW_X11 CFLAGS += -D_GLFW_X11
endif endif
ifeq ($(GLFW_LINUX_ENABLE_WAYLAND),TRUE) ifeq ($(GLFW_LINUX_ENABLE_WAYLAND),TRUE)
CFLAGS += -D_GLFW_WAYLAND CFLAGS += -D_GLFW_WAYLAND
LDFLAGS += $(shell pkg-config wayland-client wayland-cursor wayland-egl xkbcommon --libs) LDFLAGS += $(shell pkg-config wayland-client wayland-cursor wayland-egl xkbcommon --libs)
@ -457,26 +464,26 @@ CFLAGS += $(CUSTOM_CFLAGS)
INCLUDE_PATHS = -I. INCLUDE_PATHS = -I.
# Define additional directories containing required header files # Define additional directories containing required header files
ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
INCLUDE_PATHS += -Iexternal/glfw/include INCLUDE_PATHS += -Iexternal/glfw/include
ifeq ($(PLATFORM_OS),BSD) ifeq ($(PLATFORM_OS),BSD)
INCLUDE_PATHS += -I/usr/local/include INCLUDE_PATHS += -I/usr/local/include
endif endif
endif endif
ifeq ($(PLATFORM),PLATFORM_DESKTOP_SDL) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_SDL)
INCLUDE_PATHS += -I$(SDL_INCLUDE_PATH) INCLUDE_PATHS += -I$(SDL_INCLUDE_PATH)
endif endif
ifeq ($(PLATFORM),PLATFORM_WEB) ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
INCLUDE_PATHS += -Iexternal/glfw/include INCLUDE_PATHS += -Iexternal/glfw/include
endif endif
ifeq ($(PLATFORM),PLATFORM_DRM) ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
INCLUDE_PATHS += -I/usr/include/libdrm INCLUDE_PATHS += -I/usr/include/libdrm
ifeq ($(USE_RPI_CROSSCOMPILER), TRUE) ifeq ($(USE_RPI_CROSSCOMPILER), TRUE)
INCLUDE_PATHS += -I$(RPI_TOOLCHAIN_SYSROOT)/usr/include INCLUDE_PATHS += -I$(RPI_TOOLCHAIN_SYSROOT)/usr/include
INCLUDE_PATHS += -I$(RPI_TOOLCHAIN_SYSROOT)/opt/vc/include INCLUDE_PATHS += -I$(RPI_TOOLCHAIN_SYSROOT)/opt/vc/include
endif endif
endif endif
ifeq ($(PLATFORM),PLATFORM_ANDROID) ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
NATIVE_APP_GLUE = $(ANDROID_NDK)/sources/android/native_app_glue NATIVE_APP_GLUE = $(ANDROID_NDK)/sources/android/native_app_glue
# Include android_native_app_glue.h # Include android_native_app_glue.h
INCLUDE_PATHS += -I$(NATIVE_APP_GLUE) INCLUDE_PATHS += -I$(NATIVE_APP_GLUE)
@ -502,7 +509,7 @@ endif
#------------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------------------
LDFLAGS = $(CUSTOM_LDFLAGS) -L. -L$(RAYLIB_RELEASE_PATH) LDFLAGS = $(CUSTOM_LDFLAGS) -L. -L$(RAYLIB_RELEASE_PATH)
ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
ifeq ($(PLATFORM_OS),WINDOWS) ifeq ($(PLATFORM_OS),WINDOWS)
ifneq ($(CC), tcc) ifneq ($(CC), tcc)
LDFLAGS += -Wl,--out-implib,$(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME)dll.a LDFLAGS += -Wl,--out-implib,$(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME)dll.a
@ -518,17 +525,17 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
LDFLAGS += -Wl,-soname,lib$(RAYLIB_LIB_NAME).$(RAYLIB_API_VERSION).so -Lsrc -L/usr/local/lib LDFLAGS += -Wl,-soname,lib$(RAYLIB_LIB_NAME).$(RAYLIB_API_VERSION).so -Lsrc -L/usr/local/lib
endif endif
endif endif
ifeq ($(PLATFORM),PLATFORM_DESKTOP_SDL) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_SDL)
LDFLAGS += -Wl,-soname,lib$(RAYLIB_LIB_NAME).so.$(RAYLIB_API_VERSION) LDFLAGS += -Wl,-soname,lib$(RAYLIB_LIB_NAME).so.$(RAYLIB_API_VERSION)
LDFLAGS += -L$(SDL_LIBRARY_PATH) LDFLAGS += -L$(SDL_LIBRARY_PATH)
endif endif
ifeq ($(PLATFORM),PLATFORM_DRM) ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
LDFLAGS += -Wl,-soname,lib$(RAYLIB_LIB_NAME).so.$(RAYLIB_API_VERSION) LDFLAGS += -Wl,-soname,lib$(RAYLIB_LIB_NAME).so.$(RAYLIB_API_VERSION)
ifeq ($(USE_RPI_CROSSCOMPILER), TRUE) ifeq ($(USE_RPI_CROSSCOMPILER), TRUE)
LDFLAGS += -L$(RPI_TOOLCHAIN_SYSROOT)/opt/vc/lib -L$(RPI_TOOLCHAIN_SYSROOT)/usr/lib LDFLAGS += -L$(RPI_TOOLCHAIN_SYSROOT)/opt/vc/lib -L$(RPI_TOOLCHAIN_SYSROOT)/usr/lib
endif endif
endif endif
ifeq ($(PLATFORM),PLATFORM_ANDROID) ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
LDFLAGS += -Wl,-soname,libraylib.$(RAYLIB_API_VERSION).so -Wl,--exclude-libs,libatomic.a LDFLAGS += -Wl,-soname,libraylib.$(RAYLIB_API_VERSION).so -Wl,--exclude-libs,libatomic.a
LDFLAGS += -Wl,--build-id -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings LDFLAGS += -Wl,--build-id -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings
# Force linking of library module to define symbol # Force linking of library module to define symbol
@ -542,7 +549,7 @@ endif
# Define libraries required on linking: LDLIBS # Define libraries required on linking: LDLIBS
# NOTE: This is only required for dynamic library generation # NOTE: This is only required for dynamic library generation
#------------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------------------
ifeq ($(PLATFORM),PLATFORM_DESKTOP) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
ifeq ($(PLATFORM_OS),WINDOWS) ifeq ($(PLATFORM_OS),WINDOWS)
ifeq ($(CC), tcc) ifeq ($(CC), tcc)
LDLIBS = -lopengl32 -lgdi32 -lwinmm -lshell32 LDLIBS = -lopengl32 -lgdi32 -lwinmm -lshell32
@ -570,7 +577,7 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
LDLIBS = -lglfw LDLIBS = -lglfw
endif endif
endif endif
ifeq ($(PLATFORM),PLATFORM_DESKTOP_SDL) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_SDL)
ifeq ($(PLATFORM_OS),WINDOWS) ifeq ($(PLATFORM_OS),WINDOWS)
LDLIBS = -static-libgcc -lopengl32 -lgdi32 LDLIBS = -static-libgcc -lopengl32 -lgdi32
endif endif
@ -582,16 +589,7 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP_SDL)
endif endif
LDLIBS += -lSDL2 -lSDL2main LDLIBS += -lSDL2 -lSDL2main
endif endif
ifeq ($(PLATFORM),PLATFORM_DRM) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_RGFW)
LDLIBS = -lGLESv2 -lEGL -ldrm -lgbm -lpthread -lrt -lm -ldl
ifeq ($(RAYLIB_MODULE_AUDIO),TRUE)
LDLIBS += -latomic
endif
endif
ifeq ($(PLATFORM),PLATFORM_ANDROID)
LDLIBS = -llog -landroid -lEGL -lGLESv2 -lOpenSLES -lc -lm
endif
ifeq ($(PLATFORM),PLATFORM_DESKTOP_RGFW)
ifeq ($(PLATFORM_OS),WINDOWS) ifeq ($(PLATFORM_OS),WINDOWS)
# Libraries for Windows desktop compilation # Libraries for Windows desktop compilation
LDLIBS = -lgdi32 -lwinmm -lopengl32 LDLIBS = -lgdi32 -lwinmm -lopengl32
@ -615,6 +613,15 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP_RGFW)
LDLIBS += -lm -framework Foundation -framework AppKit -framework OpenGL -framework CoreVideo LDLIBS += -lm -framework Foundation -framework AppKit -framework OpenGL -framework CoreVideo
endif endif
endif endif
ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
LDLIBS = -lGLESv2 -lEGL -ldrm -lgbm -lpthread -lrt -lm -ldl
ifeq ($(RAYLIB_MODULE_AUDIO),TRUE)
LDLIBS += -latomic
endif
endif
ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
LDLIBS = -llog -landroid -lEGL -lGLESv2 -lOpenSLES -lc -lm
endif
# Define source code object files required # Define source code object files required
#------------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------------------
@ -624,8 +631,7 @@ OBJS = rcore.o \
rtext.o \ rtext.o \
utils.o utils.o
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(USE_EXTERNAL_GLFW),FALSE) ifeq ($(USE_EXTERNAL_GLFW),FALSE)
OBJS += rglfw.o OBJS += rglfw.o
endif endif
@ -640,7 +646,7 @@ ifeq ($(RAYLIB_MODULE_RAYGUI),TRUE)
OBJS += raygui.o OBJS += raygui.o
endif endif
ifeq ($(PLATFORM),PLATFORM_ANDROID) ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
OBJS += android_native_app_glue.o OBJS += android_native_app_glue.o
endif endif
@ -652,14 +658,14 @@ all: raylib
# Compile raylib library # Compile raylib library
# NOTE: Release directory is created if not exist # NOTE: Release directory is created if not exist
raylib: $(OBJS) raylib: $(OBJS)
ifeq ($(PLATFORM),PLATFORM_WEB) ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
# Compile raylib libray for web # Compile raylib libray for web
#$(CC) $(OBJS) -r -o $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).bc #$(CC) $(OBJS) -r -o $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).bc
$(AR) rcs $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).a $(OBJS) $(AR) rcs $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).a $(OBJS)
@echo "raylib library generated (lib$(RAYLIB_LIB_NAME).a)!" @echo "raylib library generated (lib$(RAYLIB_LIB_NAME).a)!"
else else
ifeq ($(RAYLIB_LIBTYPE),SHARED) ifeq ($(RAYLIB_LIBTYPE),SHARED)
ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_DESKTOP PLATFORM_DESKTOP_SDL PLATFORM_DESKTOP_RGFW)) ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW PLATFORM_DESKTOP_SDL PLATFORM_DESKTOP_RGFW))
ifeq ($(PLATFORM_OS),WINDOWS) ifeq ($(PLATFORM_OS),WINDOWS)
# NOTE: Linking with provided resource file # NOTE: Linking with provided resource file
$(CC) -shared -o $(RAYLIB_RELEASE_PATH)/$(RAYLIB_LIB_NAME).dll $(OBJS) $(RAYLIB_RES_FILE) $(LDFLAGS) $(LDLIBS) $(CC) -shared -o $(RAYLIB_RELEASE_PATH)/$(RAYLIB_LIB_NAME).dll $(OBJS) $(RAYLIB_RES_FILE) $(LDFLAGS) $(LDLIBS)
@ -688,7 +694,7 @@ else
cd $(RAYLIB_RELEASE_PATH) && ln -fs lib$(RAYLIB_LIB_NAME).$(RAYLIB_VERSION).so lib$(RAYLIB_LIB_NAME).so cd $(RAYLIB_RELEASE_PATH) && ln -fs lib$(RAYLIB_LIB_NAME).$(RAYLIB_VERSION).so lib$(RAYLIB_LIB_NAME).so
endif endif
endif endif
ifeq ($(PLATFORM),PLATFORM_DRM) ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
# Compile raylib shared library version $(RAYLIB_VERSION). # Compile raylib shared library version $(RAYLIB_VERSION).
# WARNING: you should type "make clean" before doing this target # WARNING: you should type "make clean" before doing this target
$(CC) -shared -o $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).so.$(RAYLIB_VERSION) $(OBJS) $(LDFLAGS) $(LDLIBS) $(CC) -shared -o $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).so.$(RAYLIB_VERSION) $(OBJS) $(LDFLAGS) $(LDLIBS)
@ -696,7 +702,7 @@ else
cd $(RAYLIB_RELEASE_PATH) && ln -fsv lib$(RAYLIB_LIB_NAME).so.$(RAYLIB_VERSION) lib$(RAYLIB_LIB_NAME).so.$(RAYLIB_API_VERSION) cd $(RAYLIB_RELEASE_PATH) && ln -fsv lib$(RAYLIB_LIB_NAME).so.$(RAYLIB_VERSION) lib$(RAYLIB_LIB_NAME).so.$(RAYLIB_API_VERSION)
cd $(RAYLIB_RELEASE_PATH) && ln -fsv lib$(RAYLIB_LIB_NAME).so.$(RAYLIB_API_VERSION) lib$(RAYLIB_LIB_NAME).so cd $(RAYLIB_RELEASE_PATH) && ln -fsv lib$(RAYLIB_LIB_NAME).so.$(RAYLIB_API_VERSION) lib$(RAYLIB_LIB_NAME).so
endif endif
ifeq ($(PLATFORM),PLATFORM_ANDROID) ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
$(CC) -shared -o $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).$(RAYLIB_VERSION).so $(OBJS) $(LDFLAGS) $(LDLIBS) $(CC) -shared -o $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).$(RAYLIB_VERSION).so $(OBJS) $(LDFLAGS) $(LDLIBS)
@echo "raylib shared library generated (lib$(RAYLIB_LIB_NAME).$(RAYLIB_VERSION).so)!" @echo "raylib shared library generated (lib$(RAYLIB_LIB_NAME).$(RAYLIB_VERSION).so)!"
# WARNING: symbolic links creation on Windows should be done using mklink command, no ln available # WARNING: symbolic links creation on Windows should be done using mklink command, no ln available
@ -851,7 +857,7 @@ clean: clean_shell_$(PLATFORM_SHELL)
clean_shell_sh: clean_shell_sh:
rm -fv *.o $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).a $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).bc $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).so* raygui.c $(RAYLIB_RELEASE_PATH)/*-protocol.h $(RAYLIB_RELEASE_PATH)/*-protocol-code.h rm -fv *.o $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).a $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).bc $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).so* raygui.c $(RAYLIB_RELEASE_PATH)/*-protocol.h $(RAYLIB_RELEASE_PATH)/*-protocol-code.h
ifeq ($(PLATFORM),PLATFORM_ANDROID) ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
rm -fv $(NATIVE_APP_GLUE)/android_native_app_glue.o rm -fv $(NATIVE_APP_GLUE)/android_native_app_glue.o
endif endif

View File

@ -207,15 +207,9 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
const cache_include = std.fs.path.join(b.allocator, &.{ b.sysroot.?, "cache", "sysroot", "include" }) catch @panic("Out of memory"); const cache_include = std.fs.path.join(b.allocator, &.{ b.sysroot.?, "cache", "sysroot", "include" }) catch @panic("Out of memory");
defer b.allocator.free(cache_include); defer b.allocator.free(cache_include);
if (comptime builtin.zig_version.minor > 12) { var dir = std.fs.openDirAbsolute(cache_include, std.fs.Dir.OpenDirOptions{ .access_sub_paths = true, .no_follow = true }) catch @panic("No emscripten cache. Generate it!");
var dir = std.fs.cwd().openDir(cache_include, std.fs.Dir.OpenDirOptions{ .access_sub_paths = true, .no_follow = true }) catch @panic("No emscripten cache. Generate it!"); dir.close();
dir.close(); raylib.addIncludePath(.{ .cwd_relative = cache_include });
raylib.addIncludePath(b.path(cache_include));
} else {
var dir = std.fs.openDirAbsolute(cache_include, std.fs.Dir.OpenDirOptions{ .access_sub_paths = true, .no_follow = true }) catch @panic("No emscripten cache. Generate it!");
dir.close();
raylib.addIncludePath(.{ .path = cache_include });
}
}, },
else => { else => {
@panic("Unsupported OS"); @panic("Unsupported OS");

4182
src/external/RGFW.h vendored

File diff suppressed because it is too large Load Diff

View File

@ -81,7 +81,7 @@ static PlatformData platform = { 0 }; // Platform specific data
// Local Variables Definition // Local Variables Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
#define KEYCODE_MAP_SIZE 162 #define KEYCODE_MAP_SIZE 162
static const KeyboardKey KeycodeMap[KEYCODE_MAP_SIZE] = { static const KeyboardKey mapKeycode[KEYCODE_MAP_SIZE] = {
KEY_NULL, // AKEYCODE_UNKNOWN KEY_NULL, // AKEYCODE_UNKNOWN
0, // AKEYCODE_SOFT_LEFT 0, // AKEYCODE_SOFT_LEFT
0, // AKEYCODE_SOFT_RIGHT 0, // AKEYCODE_SOFT_RIGHT
@ -660,7 +660,7 @@ void PollInputEvents(void)
CORE.Input.Gamepad.previousButtonState[i][k] = CORE.Input.Gamepad.currentButtonState[i][k]; CORE.Input.Gamepad.previousButtonState[i][k] = CORE.Input.Gamepad.currentButtonState[i][k];
} }
} }
// Register previous touch states // Register previous touch states
for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.previousTouchState[i] = CORE.Input.Touch.currentTouchState[i]; for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.previousTouchState[i] = CORE.Input.Touch.currentTouchState[i];
@ -1133,9 +1133,9 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
CORE.Input.Gamepad.axisState[0][GAMEPAD_AXIS_RIGHT_Y] = AMotionEvent_getAxisValue( CORE.Input.Gamepad.axisState[0][GAMEPAD_AXIS_RIGHT_Y] = AMotionEvent_getAxisValue(
event, AMOTION_EVENT_AXIS_RZ, 0); event, AMOTION_EVENT_AXIS_RZ, 0);
CORE.Input.Gamepad.axisState[0][GAMEPAD_AXIS_LEFT_TRIGGER] = AMotionEvent_getAxisValue( CORE.Input.Gamepad.axisState[0][GAMEPAD_AXIS_LEFT_TRIGGER] = AMotionEvent_getAxisValue(
event, AMOTION_EVENT_AXIS_BRAKE, 0) * 2.0f - 1.0f; event, AMOTION_EVENT_AXIS_BRAKE, 0)*2.0f - 1.0f;
CORE.Input.Gamepad.axisState[0][GAMEPAD_AXIS_RIGHT_TRIGGER] = AMotionEvent_getAxisValue( CORE.Input.Gamepad.axisState[0][GAMEPAD_AXIS_RIGHT_TRIGGER] = AMotionEvent_getAxisValue(
event, AMOTION_EVENT_AXIS_GAS, 0) * 2.0f - 1.0f; event, AMOTION_EVENT_AXIS_GAS, 0)*2.0f - 1.0f;
// dpad is reported as an axis on android // dpad is reported as an axis on android
float dpadX = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_HAT_X, 0); float dpadX = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_HAT_X, 0);
@ -1201,7 +1201,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
return 1; // Handled gamepad button return 1; // Handled gamepad button
} }
KeyboardKey key = (keycode > 0 && keycode < KEYCODE_MAP_SIZE) ? KeycodeMap[keycode] : KEY_NULL; KeyboardKey key = (keycode > 0 && keycode < KEYCODE_MAP_SIZE)? mapKeycode[keycode] : KEY_NULL;
if (key != KEY_NULL) if (key != KEY_NULL)
{ {
// Save current key and its state // Save current key and its state
@ -1252,10 +1252,10 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
CORE.Input.Touch.position[i] = (Vector2){ AMotionEvent_getX(event, i), AMotionEvent_getY(event, i) }; CORE.Input.Touch.position[i] = (Vector2){ AMotionEvent_getX(event, i), AMotionEvent_getY(event, i) };
// Normalize CORE.Input.Touch.position[i] for CORE.Window.screen.width and CORE.Window.screen.height // Normalize CORE.Input.Touch.position[i] for CORE.Window.screen.width and CORE.Window.screen.height
float widthRatio = (float)(CORE.Window.screen.width + CORE.Window.renderOffset.x) / (float)CORE.Window.display.width; float widthRatio = (float)(CORE.Window.screen.width + CORE.Window.renderOffset.x)/(float)CORE.Window.display.width;
float heightRatio = (float)(CORE.Window.screen.height + CORE.Window.renderOffset.y) / (float)CORE.Window.display.height; float heightRatio = (float)(CORE.Window.screen.height + CORE.Window.renderOffset.y)/(float)CORE.Window.display.height;
CORE.Input.Touch.position[i].x = CORE.Input.Touch.position[i].x * widthRatio - (float)CORE.Window.renderOffset.x / 2; CORE.Input.Touch.position[i].x = CORE.Input.Touch.position[i].x*widthRatio - (float)CORE.Window.renderOffset.x/2;
CORE.Input.Touch.position[i].y = CORE.Input.Touch.position[i].y * heightRatio - (float)CORE.Window.renderOffset.y / 2; CORE.Input.Touch.position[i].y = CORE.Input.Touch.position[i].y*heightRatio - (float)CORE.Window.renderOffset.y/2;
} }
int32_t action = AMotionEvent_getAction(event); int32_t action = AMotionEvent_getAction(event);

View File

@ -1147,7 +1147,7 @@ void PollInputEvents(void)
const unsigned char *buttons = state.buttons; const unsigned char *buttons = state.buttons;
for (int k = 0; (buttons != NULL) && (k < GLFW_GAMEPAD_BUTTON_DPAD_LEFT + 1) && (k < MAX_GAMEPAD_BUTTONS); k++) for (int k = 0; (buttons != NULL) && (k < MAX_GAMEPAD_BUTTONS); k++)
{ {
int button = -1; // GamepadButton enum values assigned int button = -1; // GamepadButton enum values assigned
@ -1189,7 +1189,7 @@ void PollInputEvents(void)
// Get current axis state // Get current axis state
const float *axes = state.axes; const float *axes = state.axes;
for (int k = 0; (axes != NULL) && (k < GLFW_GAMEPAD_AXIS_LAST + 1) && (k < MAX_GAMEPAD_AXIS); k++) for (int k = 0; (axes != NULL) && (k < GLFW_GAMEPAD_AXIS_LAST + 1); k++)
{ {
CORE.Input.Gamepad.axisState[i][k] = axes[k]; CORE.Input.Gamepad.axisState[i][k] = axes[k];
} }
@ -1617,7 +1617,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;
@ -1626,6 +1630,7 @@ int InitPlatform(void)
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;
} }
#endif
TRACELOG(LOG_INFO, "GLFW platform: %s", glfwPlatform); TRACELOG(LOG_INFO, "GLFW platform: %s", glfwPlatform);
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (GLFW): Initialized successfully"); TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (GLFW): Initialized successfully");
@ -1664,23 +1669,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.width = width;
CORE.Window.screen.height = height; 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 // 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
@ -49,64 +47,61 @@
**********************************************************************************************/ **********************************************************************************************/
#ifdef GRAPHICS_API_OPENGL_ES2 #ifdef 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
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
typedef struct { typedef struct {
// TODO: Define the platform specific variables required RGFW_window *window; // Native display device (physical screen connection)
RGFW_window* window; // Native display device (physical screen connection)
} PlatformData; } PlatformData;
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -114,9 +109,11 @@ typedef struct {
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
extern CoreData CORE; // Global CORE state context extern CoreData CORE; // Global CORE state context
static PlatformData platform = { NULL }; // Platform specific static PlatformData platform = { NULL }; // Platform specific
static const unsigned short RGFWKeyToRayKey[] = { static bool RGFW_disableCursor = false;
static const unsigned short keyMappingRGFW[] = {
[RGFW_KEY_NULL] = KEY_NULL, [RGFW_KEY_NULL] = KEY_NULL,
[RGFW_Quote] = KEY_APOSTROPHE, [RGFW_Quote] = KEY_APOSTROPHE,
[RGFW_Comma] = KEY_COMMA, [RGFW_Comma] = KEY_COMMA,
@ -157,7 +154,7 @@ static const unsigned short RGFWKeyToRayKey[] = {
[RGFW_SuperL] = KEY_LEFT_SUPER, [RGFW_SuperL] = KEY_LEFT_SUPER,
#ifndef RGFW_MACOS #ifndef RGFW_MACOS
[RGFW_ShiftR] = KEY_RIGHT_SHIFT, [RGFW_ShiftR] = KEY_RIGHT_SHIFT,
[RGFW_AltR] = KEY_RIGHT_ALT, [RGFW_AltR] = KEY_RIGHT_ALT,
#endif #endif
[RGFW_Space] = KEY_SPACE, [RGFW_Space] = KEY_SPACE,
@ -237,7 +234,7 @@ bool InitGraphicsDevice(void); // Initialize graphics device
// Check if application should close // Check if application should close
bool WindowShouldClose(void) bool WindowShouldClose(void)
{ {
if (CORE.Window.shouldClose == false) if (CORE.Window.shouldClose == false)
CORE.Window.shouldClose = RGFW_window_shouldClose(platform.window); CORE.Window.shouldClose = RGFW_window_shouldClose(platform.window);
if (CORE.Window.ready) return CORE.Window.shouldClose; if (CORE.Window.ready) return CORE.Window.shouldClose;
@ -254,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
@ -294,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));
} }
@ -315,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)
{ {
@ -327,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)
{ {
@ -335,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)
{ {
@ -410,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)
@ -430,33 +428,34 @@ void ClearWindowState(unsigned int flags)
// Set icon for window // Set icon for window
void SetWindowIcon(Image image) void SetWindowIcon(Image image)
{ {
i32 channels = 4; i32 channels = 4;
switch (image.format) { switch (image.format)
{
case PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: case PIXELFORMAT_UNCOMPRESSED_GRAYSCALE:
case PIXELFORMAT_UNCOMPRESSED_R16: // 16 bpp (1 channel - half float) case PIXELFORMAT_UNCOMPRESSED_R16: // 16 bpp (1 channel - half float)
case PIXELFORMAT_UNCOMPRESSED_R32: // 32 bpp (1 channel - float) case PIXELFORMAT_UNCOMPRESSED_R32: // 32 bpp (1 channel - float)
{
channels = 1; channels = 1;
break; } break;
case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: // 8*2 bpp (2 channels) case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: // 8*2 bpp (2 channels)
case PIXELFORMAT_UNCOMPRESSED_R5G6B5: // 16 bpp case PIXELFORMAT_UNCOMPRESSED_R5G6B5: // 16 bpp
case PIXELFORMAT_UNCOMPRESSED_R8G8B8: // 24 bpp case PIXELFORMAT_UNCOMPRESSED_R8G8B8: // 24 bpp
case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: // 16 bpp (1 bit alpha) case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: // 16 bpp (1 bit alpha)
case PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: // 16 bpp (4 bit alpha) case PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: // 16 bpp (4 bit alpha)
case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: // 32 bpp case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: // 32 bpp
{
channels = 2; channels = 2;
break; } break;
case PIXELFORMAT_UNCOMPRESSED_R32G32B32: // 32*3 bpp (3 channels - float) case PIXELFORMAT_UNCOMPRESSED_R32G32B32: // 32*3 bpp (3 channels - float)
case PIXELFORMAT_UNCOMPRESSED_R16G16B16: // 16*3 bpp (3 channels - half float) case PIXELFORMAT_UNCOMPRESSED_R16G16B16: // 16*3 bpp (3 channels - half float)
case PIXELFORMAT_COMPRESSED_DXT1_RGB: // 4 bpp (no alpha) case PIXELFORMAT_COMPRESSED_DXT1_RGB: // 4 bpp (no alpha)
case PIXELFORMAT_COMPRESSED_ETC1_RGB: // 4 bpp case PIXELFORMAT_COMPRESSED_ETC1_RGB: // 4 bpp
case PIXELFORMAT_COMPRESSED_ETC2_RGB: // 4 bpp case PIXELFORMAT_COMPRESSED_ETC2_RGB: // 4 bpp
case PIXELFORMAT_COMPRESSED_PVRT_RGB: // 4 bpp case PIXELFORMAT_COMPRESSED_PVRT_RGB: // 4 bpp
{
channels = 3; channels = 3;
break; } break;
case PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: // 32*4 bpp (4 channels - float) case PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: // 32*4 bpp (4 channels - float)
case PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: // 16*4 bpp (4 channels - half float) case PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: // 16*4 bpp (4 channels - half float)
case PIXELFORMAT_COMPRESSED_DXT1_RGBA: // 4 bpp (1 bit alpha) case PIXELFORMAT_COMPRESSED_DXT1_RGBA: // 4 bpp (1 bit alpha)
@ -465,10 +464,10 @@ void SetWindowIcon(Image image)
case PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA: // 8 bpp case PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA: // 8 bpp
case PIXELFORMAT_COMPRESSED_PVRT_RGBA: // 4 bpp case PIXELFORMAT_COMPRESSED_PVRT_RGBA: // 4 bpp
case PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: // 8 bpp case PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: // 8 bpp
case PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: // 2 bpp case PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: // 2 bpp
{
channels = 4; channels = 4;
break; } break;
default: break; default: break;
} }
@ -537,37 +536,42 @@ void SetWindowFocused(void)
// Get native window handle // Get native window handle
void *GetWindowHandle(void) void *GetWindowHandle(void)
{ {
#ifndef RGFW_WINDOWS #ifndef 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;
#endif #endif
} }
// Get number of monitors // Get number of monitors
int GetMonitorCount(void) int GetMonitorCount(void)
{ {
RGFW_monitor* mons = RGFW_getMonitors(); #define MAX_MONITORS_SUPPORTED 6
size_t i;
for (i = 0; i < 6; i++) { int count = MAX_MONITORS_SUPPORTED;
RGFW_monitor *mons = RGFW_getMonitors();
for (int i = 0; i < 6; i++)
{
if (!mons[i].rect.x && !mons[i].rect.y && !mons[i].rect.w && mons[i].rect.h) if (!mons[i].rect.x && !mons[i].rect.y && !mons[i].rect.w && mons[i].rect.h)
return i; {
count = i;
break;
}
} }
return 6; return count;
} }
// Get number of monitors // Get number of monitors
int GetCurrentMonitor(void) int GetCurrentMonitor(void)
{ {
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);
size_t i; for (int i = 0; i < 6; i++)
for (i = 0; i < 6; i++) { {
if (mons[i].rect.x == mon.rect.x && if ((mons[i].rect.x == mon.rect.x) && (mons[i].rect.y == mon.rect.y)) return i;
mons[i].rect.y == mon.rect.y)
return i;
} }
return 0; return 0;
@ -576,26 +580,25 @@ int GetCurrentMonitor(void)
// Get selected monitor position // Get selected monitor position
Vector2 GetMonitorPosition(int monitor) Vector2 GetMonitorPosition(int monitor)
{ {
RGFW_monitor* mons = RGFW_getMonitors(); RGFW_monitor *mons = RGFW_getMonitors();
return (Vector2){mons[monitor].rect.x, mons[monitor].rect.y}; return (Vector2){mons[monitor].rect.x, mons[monitor].rect.y};
} }
// Get selected monitor width (currently used by monitor) // Get selected monitor width (currently used by monitor)
int GetMonitorWidth(int monitor) int GetMonitorWidth(int monitor)
{ {
RGFW_monitor* mons = RGFW_getMonitors(); RGFW_monitor *mons = RGFW_getMonitors();
return mons[monitor].rect.w; return mons[monitor].rect.w;
} }
// Get selected monitor height (currently used by monitor) // Get selected monitor height (currently used by monitor)
int GetMonitorHeight(int monitor) int GetMonitorHeight(int monitor)
{ {
RGFW_monitor* mons = RGFW_getMonitors(); RGFW_monitor *mons = RGFW_getMonitors();
return mons[monitor].rect.h; return mons[monitor].rect.h;
return 0;
} }
// Get selected monitor physical width in millimetres // Get selected monitor physical width in millimetres
@ -603,15 +606,15 @@ int GetMonitorPhysicalWidth(int monitor)
{ {
RGFW_monitor* mons = RGFW_getMonitors(); RGFW_monitor* mons = RGFW_getMonitors();
return mons[monitor].physW; return mons[monitor].physW;
} }
// Get selected monitor physical height in millimetres // Get selected monitor physical height in millimetres
int GetMonitorPhysicalHeight(int monitor) int GetMonitorPhysicalHeight(int monitor)
{ {
RGFW_monitor* mons = RGFW_getMonitors(); RGFW_monitor *mons = RGFW_getMonitors();
return mons[monitor].physH; return mons[monitor].physH;
} }
// Get selected monitor refresh rate // Get selected monitor refresh rate
@ -624,7 +627,7 @@ int GetMonitorRefreshRate(int monitor)
// Get the human-readable, UTF-8 encoded name of the selected monitor // Get the human-readable, UTF-8 encoded name of the selected monitor
const char *GetMonitorName(int monitor) const char *GetMonitorName(int monitor)
{ {
RGFW_monitor* mons = RGFW_getMonitors(); RGFW_monitor *mons = RGFW_getMonitors();
return mons[monitor].name; return mons[monitor].name;
} }
@ -640,7 +643,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){((u32)monitor.scaleX)*platform.window->r.w, ((u32) monitor.scaleX)*platform.window->r.h};
} }
// Set clipboard text content // Set clipboard text content
@ -670,8 +673,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)
{ {
@ -688,6 +689,7 @@ void EnableCursor(void)
void DisableCursor(void) void DisableCursor(void)
{ {
RGFW_disableCursor = true; RGFW_disableCursor = true;
// Set cursor position in the middle // Set cursor position in the middle
SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2); SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2);
@ -725,7 +727,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
} }
} }
@ -756,8 +758,60 @@ void SetMouseCursor(int cursor)
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)
{ {
#if defined(SUPPORT_GESTURES_SYSTEM) #if defined(SUPPORT_GESTURES_SYSTEM)
// NOTE: Gestures update must be called every frame to reset gestures correctly // NOTE: Gestures update must be called every frame to reset gestures correctly
@ -774,7 +828,7 @@ void PollInputEvents(void)
CORE.Input.Mouse.currentWheelMove.y = 0; CORE.Input.Mouse.currentWheelMove.y = 0;
// Register previous mouse position // Register previous mouse position
// Reset last gamepad button/axis registered state // Reset last gamepad button/axis registered state
for (int i = 0; (i < 4) && (i < MAX_GAMEPADS); i++) for (int i = 0; (i < 4) && (i < MAX_GAMEPADS); i++)
@ -808,30 +862,31 @@ 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
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
CORE.Window.resizedLastFrame = false; CORE.Window.resizedLastFrame = false;
#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->src.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))
{ {
if (platform.window->event.type >= RGFW_jsButtonPressed && platform.window->event.type <= RGFW_jsAxisMove) { if ((platform.window->event.type >= RGFW_jsButtonPressed) && (platform.window->event.type <= RGFW_jsAxisMove))
{
if (!CORE.Input.Gamepad.ready[platform.window->event.joystick]) if (!CORE.Input.Gamepad.ready[platform.window->event.joystick])
{ {
CORE.Input.Gamepad.ready[platform.window->event.joystick] = true; CORE.Input.Gamepad.ready[platform.window->event.joystick] = true;
@ -842,17 +897,16 @@ 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)
{ {
case RGFW_quit: CORE.Window.shouldClose = true; break; case RGFW_quit: CORE.Window.shouldClose = true; break;
case RGFW_dnd: // Dropped file case RGFW_dnd: // Dropped file
{ {
size_t i; for (int i = 0; i < event->droppedFilesCount; i++)
for (i = 0; i < event->droppedFilesCount; i++) { {
if (CORE.Window.dropFileCount == 0) if (CORE.Window.dropFileCount == 0)
{ {
// When a new file is dropped, we reserve a fixed number of slots for all possible dropped files // When a new file is dropped, we reserve a fixed number of slots for all possible dropped files
@ -862,7 +916,7 @@ void PollInputEvents(void)
CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char));
strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event->droppedFiles[i]); strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event->droppedFiles[i]);
CORE.Window.dropFileCount++; CORE.Window.dropFileCount++;
} }
else if (CORE.Window.dropFileCount < 1024) else if (CORE.Window.dropFileCount < 1024)
@ -896,8 +950,9 @@ void PollInputEvents(void)
case RGFW_keyPressed: case RGFW_keyPressed:
{ {
KeyboardKey key = ConvertScancodeToKey(event->keyCode); KeyboardKey key = ConvertScancodeToKey(event->keyCode);
if (key != KEY_NULL) { if (key != KEY_NULL)
{
// If key was up, add it to the key pressed queue // If key was up, add it to the key pressed queue
if ((CORE.Input.Keyboard.currentKeyState[key] == 0) && (CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE)) if ((CORE.Input.Keyboard.currentKeyState[key] == 0) && (CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE))
{ {
@ -919,11 +974,10 @@ 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;
case RGFW_keyReleased: case RGFW_keyReleased:
{ {
KeyboardKey key = ConvertScancodeToKey(event->keyCode); KeyboardKey key = ConvertScancodeToKey(event->keyCode);
@ -933,7 +987,8 @@ void PollInputEvents(void)
// Check mouse events // Check mouse events
case RGFW_mouseButtonPressed: case RGFW_mouseButtonPressed:
{ {
if (event->button == RGFW_mouseScrollUp || event->button == RGFW_mouseScrollDown) { if ((event->button == RGFW_mouseScrollUp) || (event->button == RGFW_mouseScrollDown))
{
CORE.Input.Mouse.currentWheelMove.y = event->scroll; CORE.Input.Mouse.currentWheelMove.y = event->scroll;
break; break;
} }
@ -951,11 +1006,12 @@ void PollInputEvents(void)
case RGFW_mouseButtonReleased: case RGFW_mouseButtonReleased:
{ {
if (event->button == RGFW_mouseScrollUp || event->button == RGFW_mouseScrollDown) { if ((event->button == RGFW_mouseScrollUp) || (event->button == RGFW_mouseScrollDown))
{
CORE.Input.Mouse.currentWheelMove.y = event->scroll; CORE.Input.Mouse.currentWheelMove.y = event->scroll;
break; break;
} }
int btn = event->button; int btn = event->button;
if (btn == RGFW_mouseLeft) btn = 1; if (btn == RGFW_mouseLeft) btn = 1;
else if (btn == RGFW_mouseRight) btn = 2; else if (btn == RGFW_mouseRight) btn = 2;
@ -968,20 +1024,21 @@ void PollInputEvents(void)
} break; } break;
case RGFW_mousePosChanged: case RGFW_mousePosChanged:
{ {
if (platform.window->src.winArgs & RGFW_HOLD_MOUSE) { if (platform.window->src.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 - (platform.window->r.w/2))*2)
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 - (platform.window->r.h/2))*2)
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 = (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.y = (event->point.y - (platform.window->r.h/2))*2;
} }
else { else
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition; {
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
CORE.Input.Mouse.currentPosition.x = (float)event->point.x; CORE.Input.Mouse.currentPosition.x = (float)event->point.x;
CORE.Input.Mouse.currentPosition.y = (float)event->point.y; CORE.Input.Mouse.currentPosition.y = (float)event->point.y;
} }
@ -989,7 +1046,6 @@ void PollInputEvents(void)
CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition;
touchAction = 2; touchAction = 2;
} break; } break;
case RGFW_jsButtonPressed: case RGFW_jsButtonPressed:
{ {
int button = -1; int button = -1;
@ -1061,43 +1117,49 @@ void PollInputEvents(void)
case RGFW_jsAxisMove: case RGFW_jsAxisMove:
{ {
int axis = -1; int axis = -1;
for (int i = 0; i < event->axisesCount; i++)
size_t i;
for (i = 0; i < event->axisesCount; i++)
{ {
switch(i) { switch(i)
case 0: {
if (abs(event->axis[i].x) > abs(event->axis[i].y)) { case 0:
axis = GAMEPAD_AXIS_LEFT_X; {
if (abs(event->axis[i].x) > abs(event->axis[i].y))
{
axis = GAMEPAD_AXIS_LEFT_X;
break; break;
} }
axis = GAMEPAD_AXIS_LEFT_Y; axis = GAMEPAD_AXIS_LEFT_Y;
break; } break;
case 1: case 1:
if (abs(event->axis[i].x) > abs(event->axis[i].y)) { {
axis = GAMEPAD_AXIS_RIGHT_X; break; if (abs(event->axis[i].x) > abs(event->axis[i].y))
{
axis = GAMEPAD_AXIS_RIGHT_X;
break;
} }
axis = GAMEPAD_AXIS_RIGHT_Y; break; axis = GAMEPAD_AXIS_RIGHT_Y;
} break;
case 2: axis = GAMEPAD_AXIS_LEFT_TRIGGER; break; case 2: axis = GAMEPAD_AXIS_LEFT_TRIGGER; break;
case 3: axis = GAMEPAD_AXIS_RIGHT_TRIGGER; break; case 3: axis = GAMEPAD_AXIS_RIGHT_TRIGGER; break;
default: break; default: break;
} }
#ifdef __linux__ #ifdef __linux__
float value = (event->axis[i].x + event->axis[i].y) / (float) 32767; float value = (event->axis[i].x + event->axis[i].y)/(float)32767;
#else #else
float value = (event->axis[i].x + -event->axis[i].y) / (float) 32767; float value = (event->axis[i].x + -event->axis[i].y)/(float)32767;
#endif #endif
CORE.Input.Gamepad.axisState[event->joystick][axis] = value; CORE.Input.Gamepad.axisState[event->joystick][axis] = value;
// Register button state for triggers in addition to their axes // Register button state for triggers in addition to their axes
if ((axis == GAMEPAD_AXIS_LEFT_TRIGGER) || (axis == GAMEPAD_AXIS_RIGHT_TRIGGER)) if ((axis == GAMEPAD_AXIS_LEFT_TRIGGER) || (axis == GAMEPAD_AXIS_RIGHT_TRIGGER))
{ {
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;
} }
@ -1137,9 +1199,7 @@ void PollInputEvents(void)
#endif #endif
} }
if (RGFW_disableCursor && platform.window->event.inFocus) if (RGFW_disableCursor && platform.window->event.inFocus) RGFW_window_mouseHold(platform.window, RGFW_AREA(0, 0));
RGFW_window_mouseHold(platform.window, RGFW_AREA(0, 0));
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
} }
@ -1151,15 +1211,7 @@ void PollInputEvents(void)
// Initialize platform: graphics, inputs and more // Initialize platform: graphics, inputs and more
int InitPlatform(void) int InitPlatform(void)
{ {
// TODO: Initialize graphic device: display/window
// It usually requires setting up the platform display system configuration
// and connexion with the GPU through some system graphic API
// raylib uses OpenGL so, platform should create that kind of connection
// Below example illustrates that process using EGL library
//----------------------------------------------------------------------------
// Initialize RGFW internal global state, only required systems // Initialize RGFW internal global state, only required systems
// Initialize graphic device: display/window and graphic context
//----------------------------------------------------------------------------
unsigned int flags = RGFW_CENTER | RGFW_ALLOW_DND; unsigned int flags = RGFW_CENTER | RGFW_ALLOW_DND;
// Check window creation flags // Check window creation flags
@ -1199,16 +1251,15 @@ 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) if (CORE.Window.flags & FLAG_VSYNC_HINT) RGFW_window_swapInterval(platform.window, 1);
RGFW_window_swapInterval(platform.window, 1);
RGFW_window_makeCurrent(platform.window); RGFW_window_makeCurrent(platform.window);
// Check surface and context activation // Check surface and context activation
if (platform.window != NULL) if (platform.window != NULL)
{ {
CORE.Window.ready = true; CORE.Window.ready = true;
CORE.Window.render.width = CORE.Window.screen.width; CORE.Window.render.width = CORE.Window.screen.width;
CORE.Window.render.height = CORE.Window.screen.height; CORE.Window.render.height = CORE.Window.screen.height;
CORE.Window.currentFbo.width = CORE.Window.render.width; CORE.Window.currentFbo.width = CORE.Window.render.width;
@ -1241,7 +1292,7 @@ int InitPlatform(void)
TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height); TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height);
TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y); TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y);
// TODO: Load OpenGL extensions // Load OpenGL extensions
// NOTE: GL procedures address loader is required to load extensions // NOTE: GL procedures address loader is required to load extensions
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
rlLoadExtensions((void*)RGFW_getProcAddress); rlLoadExtensions((void*)RGFW_getProcAddress);
@ -1255,22 +1306,22 @@ int InitPlatform(void)
// ... // ...
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// TODO: Initialize timing system // Initialize timing system
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
InitTimer(); InitTimer();
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// TODO: Initialize storage system // Initialize storage system
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
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");
@ -1281,14 +1332,12 @@ int InitPlatform(void)
void ClosePlatform(void) void ClosePlatform(void)
{ {
RGFW_window_close(platform.window); RGFW_window_close(platform.window);
// TODO: De-initialize graphics, inputs and more
} }
// Keycode mapping
static KeyboardKey ConvertScancodeToKey(u32 keycode)
{
if (keycode > sizeof(keyMappingRGFW)/sizeof(unsigned short)) return 0;
static KeyboardKey ConvertScancodeToKey(u32 keycode) { return keyMappingRGFW[keycode];
if (keycode > sizeof(RGFWKeyToRayKey) / sizeof(unsigned short))
return 0;
return RGFWKeyToRayKey[keycode];
} }
// EOF

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;
@ -80,7 +80,7 @@ static PlatformData platform = { 0 }; // Platform specific data
// Local Variables Definition // Local Variables Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
#define SCANCODE_MAPPED_NUM 232 #define SCANCODE_MAPPED_NUM 232
static const KeyboardKey ScancodeToKey[SCANCODE_MAPPED_NUM] = { static const KeyboardKey mapScancodeToKey[SCANCODE_MAPPED_NUM] = {
KEY_NULL, // SDL_SCANCODE_UNKNOWN KEY_NULL, // SDL_SCANCODE_UNKNOWN
0, 0,
0, 0,
@ -476,9 +476,9 @@ void ClearWindowState(unsigned int flags)
// Set icon for window // Set icon for window
void SetWindowIcon(Image image) void SetWindowIcon(Image image)
{ {
SDL_Surface* iconSurface = NULL; SDL_Surface *iconSurface = NULL;
Uint32 rmask, gmask, bmask, amask; unsigned int rmask = 0, gmask = 0, bmask = 0, amask = 0;
int depth = 0; // Depth in bits int depth = 0; // Depth in bits
int pitch = 0; // Pixel spacing (pitch) in bytes int pitch = 0; // Pixel spacing (pitch) in bytes
@ -492,72 +492,67 @@ void SetWindowIcon(Image image)
case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA:
rmask = 0xFF, gmask = 0xFF00; rmask = 0xFF, gmask = 0xFF00;
bmask = 0, amask = 0; bmask = 0, amask = 0;
depth = 16, pitch = image.width * 2; depth = 16, pitch = image.width*2;
break; break;
case PIXELFORMAT_UNCOMPRESSED_R5G6B5: case PIXELFORMAT_UNCOMPRESSED_R5G6B5:
rmask = 0xF800, gmask = 0x07E0; rmask = 0xF800, gmask = 0x07E0;
bmask = 0x001F, amask = 0; bmask = 0x001F, amask = 0;
depth = 16, pitch = image.width * 2; depth = 16, pitch = image.width*2;
break; break;
case PIXELFORMAT_UNCOMPRESSED_R8G8B8: // Uses BGR for 24-bit case PIXELFORMAT_UNCOMPRESSED_R8G8B8: // Uses BGR for 24-bit
rmask = 0x0000FF, gmask = 0x00FF00; rmask = 0x0000FF, gmask = 0x00FF00;
bmask = 0xFF0000, amask = 0; bmask = 0xFF0000, amask = 0;
depth = 24, pitch = image.width * 3; depth = 24, pitch = image.width*3;
break; break;
case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1:
rmask = 0xF800, gmask = 0x07C0; rmask = 0xF800, gmask = 0x07C0;
bmask = 0x003E, amask = 0x0001; bmask = 0x003E, amask = 0x0001;
depth = 16, pitch = image.width * 2; depth = 16, pitch = image.width*2;
break; break;
case PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: case PIXELFORMAT_UNCOMPRESSED_R4G4B4A4:
rmask = 0xF000, gmask = 0x0F00; rmask = 0xF000, gmask = 0x0F00;
bmask = 0x00F0, amask = 0x000F; bmask = 0x00F0, amask = 0x000F;
depth = 16, pitch = image.width * 2; depth = 16, pitch = image.width*2;
break; break;
case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8:
rmask = 0xFF000000, gmask = 0x00FF0000; rmask = 0xFF000000, gmask = 0x00FF0000;
bmask = 0x0000FF00, amask = 0x000000FF; bmask = 0x0000FF00, amask = 0x000000FF;
depth = 32, pitch = image.width * 4; depth = 32, pitch = image.width*4;
break; break;
case PIXELFORMAT_UNCOMPRESSED_R32: case PIXELFORMAT_UNCOMPRESSED_R32:
rmask = 0xFFFFFFFF, gmask = 0; rmask = 0xFFFFFFFF, gmask = 0;
bmask = 0, amask = 0; bmask = 0, amask = 0;
depth = 32, pitch = image.width * 4; depth = 32, pitch = image.width*4;
break; break;
case PIXELFORMAT_UNCOMPRESSED_R32G32B32: case PIXELFORMAT_UNCOMPRESSED_R32G32B32:
rmask = 0xFFFFFFFF, gmask = 0xFFFFFFFF; rmask = 0xFFFFFFFF, gmask = 0xFFFFFFFF;
bmask = 0xFFFFFFFF, amask = 0; bmask = 0xFFFFFFFF, amask = 0;
depth = 96, pitch = image.width * 12; depth = 96, pitch = image.width*12;
break; break;
case PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: case PIXELFORMAT_UNCOMPRESSED_R32G32B32A32:
rmask = 0xFFFFFFFF, gmask = 0xFFFFFFFF; rmask = 0xFFFFFFFF, gmask = 0xFFFFFFFF;
bmask = 0xFFFFFFFF, amask = 0xFFFFFFFF; bmask = 0xFFFFFFFF, amask = 0xFFFFFFFF;
depth = 128, pitch = image.width * 16; depth = 128, pitch = image.width*16;
break; break;
case PIXELFORMAT_UNCOMPRESSED_R16: case PIXELFORMAT_UNCOMPRESSED_R16:
rmask = 0xFFFF, gmask = 0; rmask = 0xFFFF, gmask = 0;
bmask = 0, amask = 0; bmask = 0, amask = 0;
depth = 16, pitch = image.width * 2; depth = 16, pitch = image.width*2;
break; break;
case PIXELFORMAT_UNCOMPRESSED_R16G16B16: case PIXELFORMAT_UNCOMPRESSED_R16G16B16:
rmask = 0xFFFF, gmask = 0xFFFF; rmask = 0xFFFF, gmask = 0xFFFF;
bmask = 0xFFFF, amask = 0; bmask = 0xFFFF, amask = 0;
depth = 48, pitch = image.width * 6; depth = 48, pitch = image.width*6;
break; break;
case PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: case PIXELFORMAT_UNCOMPRESSED_R16G16B16A16:
rmask = 0xFFFF, gmask = 0xFFFF; rmask = 0xFFFF, gmask = 0xFFFF;
bmask = 0xFFFF, amask = 0xFFFF; bmask = 0xFFFF, amask = 0xFFFF;
depth = 64, pitch = image.width * 8; depth = 64, pitch = image.width*8;
break; break;
default: default: return; // Compressed formats are not supported
// Compressed formats are not supported
return;
} }
iconSurface = SDL_CreateRGBSurfaceFrom( iconSurface = SDL_CreateRGBSurfaceFrom( image.data, image.width, image.height, depth, pitch, rmask, gmask, bmask, amask );
image.data, image.width, image.height, depth, pitch,
rmask, gmask, bmask, amask
);
if (iconSurface) if (iconSurface)
{ {
@ -599,7 +594,7 @@ void SetWindowMonitor(int monitor)
// 1. SDL started supporting moving exclusive fullscreen windows between displays on SDL3, // 1. SDL started supporting moving exclusive fullscreen windows between displays on SDL3,
// see commit https://github.com/libsdl-org/SDL/commit/3f5ef7dd422057edbcf3e736107e34be4b75d9ba // see commit https://github.com/libsdl-org/SDL/commit/3f5ef7dd422057edbcf3e736107e34be4b75d9ba
// 2. A workaround for SDL2 is leaving fullscreen, moving the window, then entering full screen again. // 2. A workaround for SDL2 is leaving fullscreen, moving the window, then entering full screen again.
const bool wasFullscreen = ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) ? true : false; const bool wasFullscreen = ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0)? true : false;
const int screenWidth = CORE.Window.screen.width; const int screenWidth = CORE.Window.screen.width;
const int screenHeight = CORE.Window.screen.height; const int screenHeight = CORE.Window.screen.height;
@ -941,15 +936,15 @@ int SetGamepadMappings(const char *mappings)
// Set gamepad vibration // Set gamepad vibration
void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor) void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor)
{ {
//Limit input values to between 0.0f and 1.0f // Limit input values to between 0.0f and 1.0f
leftMotor = (0.0f > leftMotor) ? 0.0f : leftMotor; leftMotor = (0.0f > leftMotor)? 0.0f : leftMotor;
rightMotor = (0.0f > rightMotor) ? 0.0f : rightMotor; rightMotor = (0.0f > rightMotor)? 0.0f : rightMotor;
leftMotor = (1.0f < leftMotor) ? 1.0f : leftMotor; leftMotor = (1.0f < leftMotor)? 1.0f : leftMotor;
rightMotor = (1.0f < rightMotor) ? 1.0f : rightMotor; rightMotor = (1.0f < rightMotor)? 1.0f : 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));
} }
} }
@ -1132,7 +1127,8 @@ void PollInputEvents(void)
{ {
KeyboardKey key = ConvertScancodeToKey(event.key.keysym.scancode); KeyboardKey key = ConvertScancodeToKey(event.key.keysym.scancode);
if (key != KEY_NULL) { if (key != KEY_NULL)
{
// If key was up, add it to the key pressed queue // If key was up, add it to the key pressed queue
if ((CORE.Input.Keyboard.currentKeyState[key] == 0) && (CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE)) if ((CORE.Input.Keyboard.currentKeyState[key] == 0) && (CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE))
{ {
@ -1249,15 +1245,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
@ -1270,15 +1266,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;
@ -1312,7 +1308,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;
@ -1346,7 +1342,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;
@ -1364,13 +1360,13 @@ void PollInputEvents(void)
if (axis >= 0) if (axis >= 0)
{ {
// SDL axis value range is -32768 to 32767, we normalize it to RayLib's -1.0 to 1.0f range // SDL axis value range is -32768 to 32767, we normalize it to RayLib's -1.0 to 1.0f range
float value = event.jaxis.value / (float) 32767; float value = event.jaxis.value/(float)32767;
CORE.Input.Gamepad.axisState[event.jaxis.which][axis] = value; CORE.Input.Gamepad.axisState[event.jaxis.which][axis] = value;
// Register button state for triggers in addition to their axes // Register button state for triggers in addition to their axes
if ((axis == GAMEPAD_AXIS_LEFT_TRIGGER) || (axis == GAMEPAD_AXIS_RIGHT_TRIGGER)) if ((axis == GAMEPAD_AXIS_LEFT_TRIGGER) || (axis == GAMEPAD_AXIS_RIGHT_TRIGGER))
{ {
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.jaxis.which][button] = pressed; CORE.Input.Gamepad.currentButtonState[event.jaxis.which][button] = pressed;
if (pressed) CORE.Input.Gamepad.lastButtonPressed = button; if (pressed) CORE.Input.Gamepad.lastButtonPressed = button;
@ -1552,14 +1548,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());
@ -1579,13 +1576,15 @@ int InitPlatform(void)
CORE.Time.previous = GetTime(); // Get time as double CORE.Time.previous = GetTime(); // Get time as double
#if defined(_WIN32) && defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP) #if defined(_WIN32) && defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP)
SDL_SetHint(SDL_HINT_TIMER_RESOLUTION, "1"); // SDL equivalent of timeBeginPeriod() and timeEndPeriod() SDL_SetHint(SDL_HINT_TIMER_RESOLUTION, "1"); // SDL equivalent of timeBeginPeriod() and timeEndPeriod()
#endif #endif
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Initialize storage system // Initialize storage system
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
CORE.Storage.basePath = GetWorkingDirectory(); // Define base path for storage // Define base path for storage
CORE.Storage.basePath = SDL_GetBasePath(); // Alternative: GetWorkingDirectory();
CHDIR(CORE.Storage.basePath);
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (SDL): Initialized successfully"); TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (SDL): Initialized successfully");
@ -1607,8 +1606,9 @@ static KeyboardKey ConvertScancodeToKey(SDL_Scancode sdlScancode)
{ {
if (sdlScancode >= 0 && sdlScancode < SCANCODE_MAPPED_NUM) if (sdlScancode >= 0 && sdlScancode < SCANCODE_MAPPED_NUM)
{ {
return ScancodeToKey[sdlScancode]; return mapScancodeToKey[sdlScancode];
} }
return KEY_NULL; // No equivalent key in Raylib return KEY_NULL; // No equivalent key in Raylib
} }
// EOF // EOF

View File

@ -398,7 +398,7 @@ int GetMonitorWidth(int monitor)
{ {
width = platform.connector->modes[platform.modeIndex].hdisplay; width = platform.connector->modes[platform.modeIndex].hdisplay;
} }
return width; return width;
} }
@ -415,7 +415,7 @@ int GetMonitorHeight(int monitor)
{ {
height = platform.connector->modes[platform.modeIndex].vdisplay; height = platform.connector->modes[platform.modeIndex].vdisplay;
} }
return height; return height;
} }
@ -479,7 +479,7 @@ const char *GetMonitorName(int monitor)
{ {
name = platform.connector->modes[platform.modeIndex].name; name = platform.connector->modes[platform.modeIndex].name;
} }
return name; return name;
} }
@ -1028,7 +1028,7 @@ int InitPlatform(void)
// If graphic device is no properly initialized, we end program // If graphic device is no properly initialized, we end program
if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return -1; } if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return -1; }
else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor()) / 2 - CORE.Window.screen.width / 2, GetMonitorHeight(GetCurrentMonitor()) / 2 - CORE.Window.screen.height / 2); else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor())/2 - CORE.Window.screen.width/2, GetMonitorHeight(GetCurrentMonitor())/2 - CORE.Window.screen.height/2);
// Set some default window flags // Set some default window flags
CORE.Window.flags &= ~FLAG_WINDOW_HIDDEN; // false CORE.Window.flags &= ~FLAG_WINDOW_HIDDEN; // false
@ -1136,7 +1136,8 @@ void ClosePlatform(void)
// Close the evdev devices // Close the evdev devices
if (platform.mouseFd != -1) { if (platform.mouseFd != -1)
{
close(platform.mouseFd); close(platform.mouseFd);
platform.mouseFd = -1; platform.mouseFd = -1;
} }
@ -1613,7 +1614,7 @@ static void PollKeyboardEvents(void)
} }
} }
TRACELOG(LOG_DEBUG, "INPUT: KEY_%s Keycode(linux): %4i KeyCode(raylib): %4i", (event.value == 0) ? "UP " : "DOWN", event.code, keycode); TRACELOG(LOG_DEBUG, "INPUT: KEY_%s Keycode(linux): %4i KeyCode(raylib): %4i", (event.value == 0)? "UP " : "DOWN", event.code, keycode);
} }
} }
} }
@ -1640,7 +1641,7 @@ static void PollGamepadEvents(void)
{ {
short keycodeRaylib = linuxToRaylibMap[event.code]; short keycodeRaylib = linuxToRaylibMap[event.code];
TRACELOG(LOG_DEBUG, "INPUT: Gamepad %2i: KEY_%s Keycode(linux): %4i Keycode(raylib): %4i", i, (event.value == 0) ? "UP " : "DOWN", event.code, keycodeRaylib); TRACELOG(LOG_DEBUG, "INPUT: Gamepad %2i: KEY_%s Keycode(linux): %4i Keycode(raylib): %4i", i, (event.value == 0)? "UP" : "DOWN", event.code, keycodeRaylib);
if ((keycodeRaylib != 0) && (keycodeRaylib < MAX_GAMEPAD_BUTTONS)) if ((keycodeRaylib != 0) && (keycodeRaylib < MAX_GAMEPAD_BUTTONS))
{ {
@ -1665,7 +1666,7 @@ static void PollGamepadEvents(void)
int range = platform.gamepadAbsAxisRange[i][event.code][1]; int range = platform.gamepadAbsAxisRange[i][event.code][1];
// NOTE: Scaling of event.value to get values between -1..1 // NOTE: Scaling of event.value to get values between -1..1
CORE.Input.Gamepad.axisState[i][axisRaylib] = (2 * (float)(event.value - min) / range) - 1; CORE.Input.Gamepad.axisState[i][axisRaylib] = (2*(float)(event.value - min)/range) - 1;
} }
} }
} }
@ -1924,9 +1925,7 @@ static int FindNearestConnectorMode(const drmModeConnector *connector, uint widt
const int nearestHeightDiff = abs(platform.connector->modes[nearestIndex].vdisplay - height); const int nearestHeightDiff = abs(platform.connector->modes[nearestIndex].vdisplay - height);
const int nearestFpsDiff = abs(platform.connector->modes[nearestIndex].vrefresh - fps); const int nearestFpsDiff = abs(platform.connector->modes[nearestIndex].vrefresh - fps);
if ((widthDiff < nearestWidthDiff) || (heightDiff < nearestHeightDiff) || (fpsDiff < nearestFpsDiff)) { if ((widthDiff < nearestWidthDiff) || (heightDiff < nearestHeightDiff) || (fpsDiff < nearestFpsDiff)) nearestIndex = i;
nearestIndex = i;
}
} }
return nearestIndex; return nearestIndex;

View File

@ -190,7 +190,8 @@ void ToggleFullscreen(void)
if (enterFullscreen) if (enterFullscreen)
{ {
// NOTE: The setTimeouts handle the browser mode change delay // NOTE: The setTimeouts handle the browser mode change delay
EM_ASM( EM_ASM
(
setTimeout(function() setTimeout(function()
{ {
Module.requestFullscreen(false, false); Module.requestFullscreen(false, false);
@ -298,7 +299,8 @@ void ToggleBorderlessWindowed(void)
{ {
// NOTE: 1. The setTimeouts handle the browser mode change delay // NOTE: 1. The setTimeouts handle the browser mode change delay
// 2. The style unset handles the possibility of a width="value%" like on the default shell.html file // 2. The style unset handles the possibility of a width="value%" like on the default shell.html file
EM_ASM( EM_ASM
(
setTimeout(function() setTimeout(function()
{ {
Module.requestFullscreen(false, true); Module.requestFullscreen(false, true);

View File

@ -1464,7 +1464,7 @@ Music LoadMusicStream(const char *fileName)
jar_xm_reset(ctxXm); // Make sure we start at the beginning of the song jar_xm_reset(ctxXm); // Make sure we start at the beginning of the song
musicLoaded = true; musicLoaded = true;
} }
else else
{ {
jar_xm_free_context(ctxXm); jar_xm_free_context(ctxXm);
} }
@ -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)
{ {
@ -1566,7 +1566,7 @@ Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data,
music.looping = true; // Looping enabled by default music.looping = true; // Looping enabled by default
musicLoaded = true; musicLoaded = true;
} }
else else
{ {
stb_vorbis_close(ctxOgg); stb_vorbis_close(ctxOgg);
} }

View File

@ -1,8 +1,8 @@
GLFW_ICON ICON "raylib.ico" GLFW_ICON ICON "raylib.ico"
1 VERSIONINFO 1 VERSIONINFO
FILEVERSION 5,0,0,0 FILEVERSION 5,5,0,0
PRODUCTVERSION 5,0,0,0 PRODUCTVERSION 5,5,0,0
BEGIN BEGIN
BLOCK "StringFileInfo" BLOCK "StringFileInfo"
BEGIN BEGIN
@ -11,12 +11,12 @@ BEGIN
BEGIN BEGIN
//VALUE "CompanyName", "raylib technologies" //VALUE "CompanyName", "raylib technologies"
VALUE "FileDescription", "raylib dynamic library (www.raylib.com)" VALUE "FileDescription", "raylib dynamic library (www.raylib.com)"
VALUE "FileVersion", "5.0.0" VALUE "FileVersion", "5.5.0"
VALUE "InternalName", "raylib.dll" VALUE "InternalName", "raylib.dll"
VALUE "LegalCopyright", "(c) 2023 Ramon Santamaria (@raysan5)" VALUE "LegalCopyright", "(c) 2024 Ramon Santamaria (@raysan5)"
VALUE "OriginalFilename", "raylib.dll" VALUE "OriginalFilename", "raylib.dll"
VALUE "ProductName", "raylib" VALUE "ProductName", "raylib"
VALUE "ProductVersion", "5.0.0" VALUE "ProductVersion", "5.5.0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

Binary file not shown.

View File

@ -1,6 +1,6 @@
/********************************************************************************************** /**********************************************************************************************
* *
* raylib v5.1-dev - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com) * raylib v5.5 - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com)
* *
* FEATURES: * FEATURES:
* - NO external dependencies, all required libraries included with raylib * - NO external dependencies, all required libraries included with raylib
@ -82,9 +82,9 @@
#include <stdarg.h> // Required for: va_list - Only used by TraceLogCallback #include <stdarg.h> // Required for: va_list - Only used by TraceLogCallback
#define RAYLIB_VERSION_MAJOR 5 #define RAYLIB_VERSION_MAJOR 5
#define RAYLIB_VERSION_MINOR 1 #define RAYLIB_VERSION_MINOR 5
#define RAYLIB_VERSION_PATCH 0 #define RAYLIB_VERSION_PATCH 0
#define RAYLIB_VERSION "5.1-dev" #define RAYLIB_VERSION "5.5"
// 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
@ -1332,6 +1332,7 @@ RLAPI Image GenImageText(int width, int height, const char *text);
// Image manipulation functions // Image manipulation functions
RLAPI Image ImageCopy(Image image); // Create an image duplicate (useful for transformations) RLAPI Image ImageCopy(Image image); // Create an image duplicate (useful for transformations)
RLAPI Image ImageFromImage(Image image, Rectangle rec); // Create an image from another image piece RLAPI Image ImageFromImage(Image image, Rectangle rec); // Create an image from another image piece
RLAPI Image ImageFromChannel(Image image, int selectedChannel); // Create an image from a selected channel of another image (GRAYSCALE)
RLAPI Image ImageText(const char *text, int fontSize, Color color); // Create an image from text (default font) RLAPI Image ImageText(const char *text, int fontSize, Color color); // Create an image from text (default font)
RLAPI Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Color tint); // Create an image from text (custom sprite font) RLAPI Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Color tint); // Create an image from text (custom sprite font)
RLAPI void ImageFormat(Image *image, int newFormat); // Convert image data to desired format RLAPI void ImageFormat(Image *image, int newFormat); // Convert image data to desired format
@ -1545,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

@ -1,8 +1,8 @@
GLFW_ICON ICON "raylib.ico" GLFW_ICON ICON "raylib.ico"
1 VERSIONINFO 1 VERSIONINFO
FILEVERSION 5,0,0,0 FILEVERSION 5,5,0,0
PRODUCTVERSION 5,0,0,0 PRODUCTVERSION 5,5,0,0
BEGIN BEGIN
BLOCK "StringFileInfo" BLOCK "StringFileInfo"
BEGIN BEGIN
@ -11,12 +11,12 @@ BEGIN
BEGIN BEGIN
//VALUE "CompanyName", "raylib technologies" //VALUE "CompanyName", "raylib technologies"
VALUE "FileDescription", "raylib application (www.raylib.com)" VALUE "FileDescription", "raylib application (www.raylib.com)"
VALUE "FileVersion", "5.0.0" VALUE "FileVersion", "5.5.0"
VALUE "InternalName", "raylib app" VALUE "InternalName", "raylib app"
VALUE "LegalCopyright", "(c) 2023 Ramon Santamaria (@raysan5)" VALUE "LegalCopyright", "(c) 2024 Ramon Santamaria (@raysan5)"
//VALUE "OriginalFilename", "raylib_app.exe" //VALUE "OriginalFilename", "raylib_app"
VALUE "ProductName", "raylib app" VALUE "ProductName", "raylib app"
VALUE "ProductVersion", "5.0.0" VALUE "ProductVersion", "5.5.0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

Binary file not shown.

View File

@ -175,7 +175,7 @@ typedef struct float16 {
// Clamp float value // Clamp float value
RMAPI float Clamp(float value, float min, float max) RMAPI float Clamp(float value, float min, float max)
{ {
float result = (value < min) ? min : value; float result = (value < min)? min : value;
if (result > max) result = max; if (result > max) result = max;
@ -962,12 +962,12 @@ RMAPI Vector3 Vector3CubicHermite(Vector3 v1, Vector3 tangent1, Vector3 v2, Vect
{ {
Vector3 result = { 0 }; Vector3 result = { 0 };
float amountPow2 = amount * amount; float amountPow2 = amount*amount;
float amountPow3 = amount * amount * amount; float amountPow3 = amount*amount*amount;
result.x = (2 * amountPow3 - 3 * amountPow2 + 1) * v1.x + (amountPow3 - 2 * amountPow2 + amount) * tangent1.x + (-2 * amountPow3 + 3 * amountPow2) * v2.x + (amountPow3 - amountPow2) * tangent2.x; result.x = (2*amountPow3 - 3*amountPow2 + 1)*v1.x + (amountPow3 - 2*amountPow2 + amount)*tangent1.x + (-2*amountPow3 + 3*amountPow2)*v2.x + (amountPow3 - amountPow2)*tangent2.x;
result.y = (2 * amountPow3 - 3 * amountPow2 + 1) * v1.y + (amountPow3 - 2 * amountPow2 + amount) * tangent1.y + (-2 * amountPow3 + 3 * amountPow2) * v2.y + (amountPow3 - amountPow2) * tangent2.y; result.y = (2*amountPow3 - 3*amountPow2 + 1)*v1.y + (amountPow3 - 2*amountPow2 + amount)*tangent1.y + (-2*amountPow3 + 3*amountPow2)*v2.y + (amountPow3 - amountPow2)*tangent2.y;
result.z = (2 * amountPow3 - 3 * amountPow2 + 1) * v1.z + (amountPow3 - 2 * amountPow2 + amount) * tangent1.z + (-2 * amountPow3 + 3 * amountPow2) * v2.z + (amountPow3 - amountPow2) * tangent2.z; result.z = (2*amountPow3 - 3*amountPow2 + 1)*v1.z + (amountPow3 - 2*amountPow2 + amount)*tangent1.z + (-2*amountPow3 + 3*amountPow2)*v2.z + (amountPow3 - amountPow2)*tangent2.z;
return result; return result;
} }
@ -2218,12 +2218,12 @@ RMAPI Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount)
// as described in the GLTF 2.0 specification: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#interpolation-cubic // as described in the GLTF 2.0 specification: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#interpolation-cubic
RMAPI Quaternion QuaternionCubicHermiteSpline(Quaternion q1, Quaternion outTangent1, Quaternion q2, Quaternion inTangent2, float t) RMAPI Quaternion QuaternionCubicHermiteSpline(Quaternion q1, Quaternion outTangent1, Quaternion q2, Quaternion inTangent2, float t)
{ {
float t2 = t * t; float t2 = t*t;
float t3 = t2 * t; float t3 = t2*t;
float h00 = 2 * t3 - 3 * t2 + 1; float h00 = 2*t3 - 3*t2 + 1;
float h10 = t3 - 2 * t2 + t; float h10 = t3 - 2*t2 + t;
float h01 = -2 * t3 + 3 * t2; float h01 = -2*t3 + 3*t2;
float h11 = t3 - t2; float h11 = t3 - t2;
Quaternion p0 = QuaternionScale(q1, h00); Quaternion p0 = QuaternionScale(q1, h00);
Quaternion m0 = QuaternionScale(outTangent1, h10); Quaternion m0 = QuaternionScale(outTangent1, h10);
@ -2533,7 +2533,7 @@ RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotatio
translation->y = mat.m13; translation->y = mat.m13;
translation->z = mat.m14; translation->z = mat.m14;
// Extract upper-left for determinant computation. // Extract upper-left for determinant computation
const float a = mat.m0; const float a = mat.m0;
const float b = mat.m4; const float b = mat.m4;
const float c = mat.m8; const float c = mat.m8;
@ -2543,28 +2543,33 @@ RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotatio
const float g = mat.m2; const float g = mat.m2;
const float h = mat.m6; const float h = mat.m6;
const float i = mat.m10; const float i = mat.m10;
const float A = e * i - f * h; const float A = e*i - f*h;
const float B = f * g - d * i; const float B = f*g - d*i;
const float C = d * h - e * g; const float C = d*h - e*g;
// 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 };
Vector3 s = {scalex, scaley, scalez};
float scalex = Vector3Length(abc);
float scaley = Vector3Length(def);
float scalez = Vector3Length(ghi);
Vector3 s = { scalex, scaley, scalez };
if (det < 0) s = Vector3Negate(s); if (det < 0) s = Vector3Negate(s);
*scale = s; *scale = s;
// Remove scale from the matrix if it is not close to zero. // Remove scale from the matrix if it is not close to zero
Matrix clone = mat; Matrix clone = mat;
if (!FloatEquals(det, 0)) if (!FloatEquals(det, 0))
{ {
clone.m0 /= s.x; clone.m0 /= s.x;
clone.m5 /= s.y; clone.m5 /= s.y;
clone.m10 /= s.z; clone.m10 /= s.z;
// Extract rotation // Extract rotation
*rotation = QuaternionFromMatrix(clone); *rotation = QuaternionFromMatrix(clone);
} }

View File

@ -490,8 +490,8 @@ void UpdateCamera(Camera *camera, int mode)
if (IsGamepadAvailable(0)) if (IsGamepadAvailable(0))
{ {
// Gamepad controller support // Gamepad controller support
CameraYaw(camera, -(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_X) * 2)*CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget); CameraYaw(camera, -(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_X)*2)*CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget);
CameraPitch(camera, -(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_Y) * 2)*CAMERA_MOUSE_MOVE_SENSITIVITY, lockView, rotateAroundTarget, rotateUp); CameraPitch(camera, -(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_Y)*2)*CAMERA_MOUSE_MOVE_SENSITIVITY, lockView, rotateAroundTarget, rotateUp);
if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y) <= -0.25f) CameraMoveForward(camera, CAMERA_MOVE_SPEED, moveInWorldPlane); if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y) <= -0.25f) CameraMoveForward(camera, CAMERA_MOVE_SPEED, moveInWorldPlane);
if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X) <= -0.25f) CameraMoveRight(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane); if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X) <= -0.25f) CameraMoveRight(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane);

View File

@ -3,7 +3,7 @@
* rcore - Window/display management, Graphic device/context management and input management * rcore - Window/display management, Graphic device/context management and input management
* *
* PLATFORMS SUPPORTED: * PLATFORMS SUPPORTED:
* > PLATFORM_DESKTOP (GLFW backend): * > PLATFORM_DESKTOP_GLFW (GLFW backend):
* - Windows (Win32, Win64) * - Windows (Win32, Win64)
* - Linux (X11/Wayland desktop mode) * - Linux (X11/Wayland desktop mode)
* - macOS/OSX (x64, arm64) * - macOS/OSX (x64, arm64)
@ -493,9 +493,13 @@ void __stdcall Sleep(unsigned long msTimeout); // Required for: Wai
const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed' const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed'
#endif // !SUPPORT_MODULE_RTEXT #endif // !SUPPORT_MODULE_RTEXT
// Include platform-specific submodules
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP)
#include "platforms/rcore_desktop.c" #define PLATFORM_DESKTOP_GLFW
#endif
// Include platform-specific submodules
#if defined(PLATFORM_DESKTOP_GLFW)
#include "platforms/rcore_desktop_glfw.c"
#elif defined(PLATFORM_DESKTOP_SDL) #elif defined(PLATFORM_DESKTOP_SDL)
#include "platforms/rcore_desktop_sdl.c" #include "platforms/rcore_desktop_sdl.c"
#elif defined(PLATFORM_DESKTOP_RGFW) #elif defined(PLATFORM_DESKTOP_RGFW)
@ -564,10 +568,12 @@ void InitWindow(int width, int height, const char *title)
{ {
TRACELOG(LOG_INFO, "Initializing raylib %s", RAYLIB_VERSION); TRACELOG(LOG_INFO, "Initializing raylib %s", RAYLIB_VERSION);
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP_GLFW)
TRACELOG(LOG_INFO, "Platform backend: DESKTOP (GLFW)"); TRACELOG(LOG_INFO, "Platform backend: DESKTOP (GLFW)");
#elif defined(PLATFORM_DESKTOP_SDL) #elif defined(PLATFORM_DESKTOP_SDL)
TRACELOG(LOG_INFO, "Platform backend: DESKTOP (SDL)"); TRACELOG(LOG_INFO, "Platform backend: DESKTOP (SDL)");
#elif defined(PLATFORM_DESKTOP_RGFW)
TRACELOG(LOG_INFO, "Platform backend: DESKTOP (RGFW)");
#elif defined(PLATFORM_WEB) #elif defined(PLATFORM_WEB)
TRACELOG(LOG_INFO, "Platform backend: WEB (HTML5)"); TRACELOG(LOG_INFO, "Platform backend: WEB (HTML5)");
#elif defined(PLATFORM_DRM) #elif defined(PLATFORM_DRM)

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
@ -1560,7 +1560,7 @@ void rlNormal3f(float x, float y, float z)
float length = sqrtf(normalx*normalx + normaly*normaly + normalz*normalz); float length = sqrtf(normalx*normalx + normaly*normaly + normalz*normalz);
if (length != 0.0f) if (length != 0.0f)
{ {
float ilength = 1.0f / length; float ilength = 1.0f/length;
normalx *= ilength; normalx *= ilength;
normaly *= ilength; normaly *= ilength;
normalz *= ilength; normalz *= ilength;
@ -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");

View File

@ -424,11 +424,16 @@ void DrawSphere(Vector3 centerPos, float radius, Color color)
// Draw sphere with extended parameters // Draw sphere with extended parameters
void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color) void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color)
{ {
#if 0
// Basic implementation, do not use it!
// For a sphere with 16 rings and 16 slices it requires 8640 cos()/sin() function calls!
// New optimized version below only requires 4 cos()/sin() calls
rlPushMatrix(); rlPushMatrix();
// NOTE: Transformation is applied in inverse order (scale -> translate) // NOTE: Transformation is applied in inverse order (scale -> translate)
rlTranslatef(centerPos.x, centerPos.y, centerPos.z); rlTranslatef(centerPos.x, centerPos.y, centerPos.z);
rlScalef(radius, radius, radius); rlScalef(radius, radius, radius);
rlBegin(RL_TRIANGLES); rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
@ -459,6 +464,51 @@ void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color
} }
rlEnd(); rlEnd();
rlPopMatrix(); rlPopMatrix();
#endif
rlPushMatrix();
// NOTE: Transformation is applied in inverse order (scale -> translate)
rlTranslatef(centerPos.x, centerPos.y, centerPos.z);
rlScalef(radius, radius, radius);
rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
float ringangle = DEG2RAD*(180.0f/(rings + 1)); // Angle between latitudinal parallels
float sliceangle = DEG2RAD*(360.0f/slices); // Angle between longitudinal meridians
float cosring = cosf(ringangle);
float sinring = sinf(ringangle);
float cosslice = cosf(sliceangle);
float sinslice = sinf(sliceangle);
Vector3 vertices[4] = { 0 }; // Required to store face vertices
vertices[2] = (Vector3){ 0, 1, 0 };
vertices[3] = (Vector3){ sinring, cosring, 0 };
for (int i = 0; i < rings + 1; i++)
{
for (int j = 0; j < slices; j++)
{
vertices[0] = vertices[2]; // Rotate around y axis to set up vertices for next face
vertices[1] = vertices[3];
vertices[2] = (Vector3){ cosslice*vertices[2].x - sinslice*vertices[2].z, vertices[2].y, sinslice*vertices[2].x + cosslice*vertices[2].z }; // Rotation matrix around y axis
vertices[3] = (Vector3){ cosslice*vertices[3].x - sinslice*vertices[3].z, vertices[3].y, sinslice*vertices[3].x + cosslice*vertices[3].z };
rlVertex3f(vertices[0].x, vertices[0].y, vertices[0].z);
rlVertex3f(vertices[3].x, vertices[3].y, vertices[3].z);
rlVertex3f(vertices[1].x, vertices[1].y, vertices[1].z);
rlVertex3f(vertices[0].x, vertices[0].y, vertices[0].z);
rlVertex3f(vertices[2].x, vertices[2].y, vertices[2].z);
rlVertex3f(vertices[3].x, vertices[3].y, vertices[3].z);
}
vertices[2] = vertices[3]; // Rotate around z axis to set up starting vertices for next ring
vertices[3] = (Vector3){ cosring*vertices[3].x + sinring*vertices[3].y, -sinring*vertices[3].x + cosring*vertices[3].y, vertices[3].z }; // Rotation matrix around z axis
}
rlEnd();
rlPopMatrix();
} }
// Draw sphere wires // Draw sphere wires
@ -1022,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);
@ -3588,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)
@ -3601,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);
} }
@ -4278,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;
@ -4327,7 +4337,7 @@ static Model LoadIQM(const char *fileName)
model.materials[i].maps[MATERIAL_MAP_ALBEDO].texture = LoadTexture(TextFormat("%s/%s", basePath, material)); model.materials[i].maps[MATERIAL_MAP_ALBEDO].texture = LoadTexture(TextFormat("%s/%s", basePath, material));
model.meshMaterial[i] = i; model.meshMaterial[i] = i;
TRACELOG(LOG_DEBUG, "MODEL: [%s] mesh name (%s), material (%s)", fileName, name, material); TRACELOG(LOG_DEBUG, "MODEL: [%s] mesh name (%s), material (%s)", fileName, name, material);
model.meshes[i].vertexCount = imesh[i].num_vertexes; model.meshes[i].vertexCount = imesh[i].num_vertexes;
@ -4636,7 +4646,7 @@ static ModelAnimation *LoadModelAnimationsIQM(const char *fileName, int *animCou
animations[a].boneCount = iqmHeader->num_poses; animations[a].boneCount = iqmHeader->num_poses;
animations[a].bones = RL_MALLOC(iqmHeader->num_poses*sizeof(BoneInfo)); animations[a].bones = RL_MALLOC(iqmHeader->num_poses*sizeof(BoneInfo));
animations[a].framePoses = RL_MALLOC(anim[a].num_frames*sizeof(Transform *)); animations[a].framePoses = RL_MALLOC(anim[a].num_frames*sizeof(Transform *));
memcpy(animations[a].name, fileDataPtr + iqmHeader->ofs_text + anim[a].name, 32); // I don't like this 32 here memcpy(animations[a].name, fileDataPtr + iqmHeader->ofs_text + anim[a].name, 32); // I don't like this 32 here
TraceLog(LOG_INFO, "IQM Anim %s", animations[a].name); TraceLog(LOG_INFO, "IQM Anim %s", animations[a].name);
// animations[a].framerate = anim.framerate; // TODO: Use animation framerate data? // animations[a].framerate = anim.framerate; // TODO: Use animation framerate data?
@ -4913,7 +4923,7 @@ static Model LoadGLTF(const char *fileName)
PBR specular/glossiness flow and extended texture flows not supported PBR specular/glossiness flow and extended texture flows not supported
- Supports multiple meshes per model (every primitives is loaded as a separate mesh) - Supports multiple meshes per model (every primitives is loaded as a separate mesh)
- Supports basic animations - Supports basic animations
- Transforms, including parent-child relations, are applied on the mesh data, but the - Transforms, including parent-child relations, are applied on the mesh data, but the
hierarchy is not kept (as it can't be represented). hierarchy is not kept (as it can't be represented).
- Mesh instances in the glTF file (i.e. same mesh linked from multiple nodes) - Mesh instances in the glTF file (i.e. same mesh linked from multiple nodes)
are turned into separate raylib Meshes. are turned into separate raylib Meshes.
@ -5101,7 +5111,7 @@ static Model LoadGLTF(const char *fileName)
// Each primitive within a glTF node becomes a Raylib Mesh. // Each primitive within a glTF node becomes a Raylib Mesh.
// The local-to-world transform of each node is used to transform the // The local-to-world transform of each node is used to transform the
// points/normals/tangents of the created Mesh(es). // points/normals/tangents of the created Mesh(es).
// Any glTF mesh linked from more than one Node (i.e. instancing) // Any glTF mesh linked from more than one Node (i.e. instancing)
// is turned into multiple Mesh's, as each Node will have its own // is turned into multiple Mesh's, as each Node will have its own
// transform applied. // transform applied.
// Note: the code below disregards the scenes defined in the file, all nodes are used. // Note: the code below disregards the scenes defined in the file, all nodes are used.
@ -5156,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;
@ -5180,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;
@ -5204,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;
@ -5262,7 +5272,7 @@ static Model LoadGLTF(const char *fileName)
else TRACELOG(LOG_WARNING, "MODEL: [%s] Texcoords attribute data format not supported", fileName); else TRACELOG(LOG_WARNING, "MODEL: [%s] Texcoords attribute data format not supported", fileName);
} }
else TRACELOG(LOG_WARNING, "MODEL: [%s] Texcoords attribute data format not supported, use vec2 float", fileName); else TRACELOG(LOG_WARNING, "MODEL: [%s] Texcoords attribute data format not supported, use vec2 float", fileName);
int index = mesh->primitives[p].attributes[j].index; int index = mesh->primitives[p].attributes[j].index;
if (index == 0) model.meshes[meshIndex].texcoords = texcoordPtr; if (index == 0) model.meshes[meshIndex].texcoords = texcoordPtr;
else if (index == 1) model.meshes[meshIndex].texcoords2 = texcoordPtr; else if (index == 1) model.meshes[meshIndex].texcoords2 = texcoordPtr;
@ -5649,7 +5659,7 @@ static bool GetPoseAtTimeGLTF(cgltf_interpolation_type interpolationType, cgltf_
} }
// Constant animation, no need to interpolate // Constant animation, no need to interpolate
if (FloatEquals(tend, tstart)) return false; if (FloatEquals(tend, tstart)) return true;
float duration = fmaxf((tend - tstart), EPSILON); float duration = fmaxf((tend - tstart), EPSILON);
float t = (time - tstart)/duration; float t = (time - tstart)/duration;

View File

@ -337,7 +337,7 @@ void DrawCircleSector(Vector2 center, float radius, float startAngle, float endA
} }
// NOTE: In case number of segments is odd, we add one last piece to the cake // NOTE: In case number of segments is odd, we add one last piece to the cake
if (((unsigned int)segments%2) == 1) if ((((unsigned int)segments)%2) == 1)
{ {
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
@ -1834,7 +1834,7 @@ void DrawSplineBezierQuadratic(const Vector2 *points, int pointCount, float thic
if (pointCount >= 3) if (pointCount >= 3)
{ {
for (int i = 0; i < pointCount - 2; i += 2) DrawSplineSegmentBezierQuadratic(points[i], points[i + 1], points[i + 2], thick, color); for (int i = 0; i < pointCount - 2; i += 2) DrawSplineSegmentBezierQuadratic(points[i], points[i + 1], points[i + 2], thick, color);
// Cap circle drawing at the end of every segment // Cap circle drawing at the end of every segment
//for (int i = 2; i < pointCount - 2; i += 2) DrawCircleV(points[i], thick/2.0f, color); //for (int i = 2; i < pointCount - 2; i += 2) DrawCircleV(points[i], thick/2.0f, color);
} }
@ -1846,7 +1846,7 @@ void DrawSplineBezierCubic(const Vector2 *points, int pointCount, float thick, C
if (pointCount >= 4) if (pointCount >= 4)
{ {
for (int i = 0; i < pointCount - 3; i += 3) DrawSplineSegmentBezierCubic(points[i], points[i + 1], points[i + 2], points[i + 3], thick, color); for (int i = 0; i < pointCount - 3; i += 3) DrawSplineSegmentBezierCubic(points[i], points[i + 1], points[i + 2], points[i + 3], thick, color);
// Cap circle drawing at the end of every segment // Cap circle drawing at the end of every segment
//for (int i = 3; i < pointCount - 3; i += 3) DrawCircleV(points[i], thick/2.0f, color); //for (int i = 3; i < pointCount - 3; i += 3) DrawCircleV(points[i], thick/2.0f, color);
} }
@ -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;
} }
@ -2235,10 +2237,10 @@ bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, floa
float dx = center2.x - center1.x; // X distance between centers float dx = center2.x - center1.x; // X distance between centers
float dy = center2.y - center1.y; // Y distance between centers float dy = center2.y - center1.y; // Y distance between centers
float distanceSquared = dx * dx + dy * dy; // Distance between centers squared float distanceSquared = dx*dx + dy*dy; // Distance between centers squared
float radiusSum = radius1 + radius2; float radiusSum = radius1 + radius2;
collision = (distanceSquared <= (radiusSum * radiusSum)); collision = (distanceSquared <= (radiusSum*radiusSum));
return collision; return collision;
} }
@ -2329,17 +2331,17 @@ RLAPI bool CheckCollisionCircleLine(Vector2 center, float radius, Vector2 p1, Ve
return CheckCollisionCircles(p1, 0, center, radius); return CheckCollisionCircles(p1, 0, center, radius);
} }
float lengthSQ = ((dx * dx) + (dy * dy)); float lengthSQ = ((dx*dx) + (dy*dy));
float dotProduct = (((center.x - p1.x) * (p2.x - p1.x)) + ((center.y - p1.y) * (p2.y - p1.y))) / (lengthSQ); float dotProduct = (((center.x - p1.x)*(p2.x - p1.x)) + ((center.y - p1.y)*(p2.y - p1.y)))/(lengthSQ);
if (dotProduct > 1.0f) dotProduct = 1.0f; if (dotProduct > 1.0f) dotProduct = 1.0f;
else if (dotProduct < 0.0f) dotProduct = 0.0f; else if (dotProduct < 0.0f) dotProduct = 0.0f;
float dx2 = (p1.x - (dotProduct * (dx))) - center.x; float dx2 = (p1.x - (dotProduct*(dx))) - center.x;
float dy2 = (p1.y - (dotProduct * (dy))) - center.y; float dy2 = (p1.y - (dotProduct*(dy))) - center.y;
float distanceSQ = ((dx2 * dx2) + (dy2 * dy2)); float distanceSQ = ((dx2*dx2) + (dy2*dy2));
return (distanceSQ <= radius * radius); return (distanceSQ <= radius*radius);
} }
// Get collision rectangle for two rectangles collision // Get collision rectangle for two rectangles 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

@ -1630,6 +1630,174 @@ Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Co
return imText; return imText;
} }
// Create an image from a selected channel of another image
Image ImageFromChannel(Image image, int selectedChannel)
{
Image result = { 0 };
// Security check to avoid program crash
if ((image.data == NULL) || (image.width == 0) || (image.height == 0)) return result;
// Check selected channel is valid
if (selectedChannel < 0)
{
TRACELOG(LOG_WARNING, "Channel cannot be negative. Setting channel to 0.");
selectedChannel = 0;
}
if (image.format == PIXELFORMAT_UNCOMPRESSED_GRAYSCALE ||
image.format == PIXELFORMAT_UNCOMPRESSED_R32 ||
image.format == PIXELFORMAT_UNCOMPRESSED_R16)
{
if (selectedChannel > 0)
{
TRACELOG(LOG_WARNING, "This image has only 1 channel. Setting channel to it.");
selectedChannel = 0;
}
}
else if (image.format == PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA)
{
if (selectedChannel > 1)
{
TRACELOG(LOG_WARNING, "This image has only 2 channels. Setting channel to alpha.");
selectedChannel = 1;
}
}
else if (image.format == PIXELFORMAT_UNCOMPRESSED_R5G6B5 ||
image.format == PIXELFORMAT_UNCOMPRESSED_R8G8B8 ||
image.format == PIXELFORMAT_UNCOMPRESSED_R32G32B32 ||
image.format == PIXELFORMAT_UNCOMPRESSED_R16G16B16)
{
if (selectedChannel > 2)
{
TRACELOG(LOG_WARNING, "This image has only 3 channels. Setting channel to red.");
selectedChannel = 0;
}
}
// Check for RGBA formats
if (selectedChannel > 3)
{
TRACELOG(LOG_WARNING, "ImageFromChannel supports channels 0 to 3 (rgba). Setting channel to alpha.");
selectedChannel = 3;
}
// TODO: Consider other one-channel formats: R16, R32
result.format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE;
result.height = image.height;
result.width = image.width;
result.mipmaps = 1;
unsigned char *pixels = (unsigned char *)RL_CALLOC(image.width*image.height, sizeof(unsigned char)); // Values from 0 to 255
if (image.format >= PIXELFORMAT_COMPRESSED_DXT1_RGB) TRACELOG(LOG_WARNING, "IMAGE: Pixel data retrieval not supported for compressed image formats");
else
{
for (int i = 0, k = 0; i < image.width*image.height; i++)
{
float pixelValue = -1;
switch (image.format)
{
case PIXELFORMAT_UNCOMPRESSED_GRAYSCALE:
{
pixelValue = (float)((unsigned char *)image.data)[i + selectedChannel]/255.0f;
} break;
case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA:
{
pixelValue = (float)((unsigned char *)image.data)[k + selectedChannel]/255.0f;
k += 2;
} break;
case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1:
{
unsigned short pixel = ((unsigned short *)image.data)[i];
if (selectedChannel == 0) pixelValue = (float)((pixel & 0b1111100000000000) >> 11)*(1.0f/31);
else if (selectedChannel == 1) pixelValue = (float)((pixel & 0b0000011111000000) >> 6)*(1.0f/31);
else if (selectedChannel == 2) pixelValue = (float)((pixel & 0b0000000000111110) >> 1)*(1.0f/31);
else if (selectedChannel == 3) pixelValue = ((pixel & 0b0000000000000001) == 0)? 0.0f : 1.0f;
} break;
case PIXELFORMAT_UNCOMPRESSED_R5G6B5:
{
unsigned short pixel = ((unsigned short *)image.data)[i];
if (selectedChannel == 0) pixelValue = (float)((pixel & 0b1111100000000000) >> 11)*(1.0f/31);
else if (selectedChannel == 1) pixelValue = (float)((pixel & 0b0000011111100000) >> 5)*(1.0f/63);
else if (selectedChannel == 2) pixelValue = (float)(pixel & 0b0000000000011111)*(1.0f/31);
} break;
case PIXELFORMAT_UNCOMPRESSED_R4G4B4A4:
{
unsigned short pixel = ((unsigned short *)image.data)[i];
if (selectedChannel == 0) pixelValue = (float)((pixel & 0b1111000000000000) >> 12)*(1.0f/15);
else if (selectedChannel == 1) pixelValue = (float)((pixel & 0b0000111100000000) >> 8)*(1.0f/15);
else if (selectedChannel == 2) pixelValue = (float)((pixel & 0b0000000011110000) >> 4)*(1.0f/15);
else if (selectedChannel == 3) pixelValue = (float)(pixel & 0b0000000000001111)*(1.0f/15);
} break;
case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8:
{
pixelValue = (float)((unsigned char *)image.data)[k + selectedChannel]/255.0f;
k += 4;
} break;
case PIXELFORMAT_UNCOMPRESSED_R8G8B8:
{
pixelValue = (float)((unsigned char *)image.data)[k + selectedChannel]/255.0f;
k += 3;
} break;
case PIXELFORMAT_UNCOMPRESSED_R32:
{
pixelValue = ((float *)image.data)[k];
k += 1;
} break;
case PIXELFORMAT_UNCOMPRESSED_R32G32B32:
{
pixelValue = ((float *)image.data)[k + selectedChannel];
k += 3;
} break;
case PIXELFORMAT_UNCOMPRESSED_R32G32B32A32:
{
pixelValue = ((float *)image.data)[k + selectedChannel];
k += 4;
} break;
case PIXELFORMAT_UNCOMPRESSED_R16:
{
pixelValue = HalfToFloat(((unsigned short *)image.data)[k]);
k += 1;
} break;
case PIXELFORMAT_UNCOMPRESSED_R16G16B16:
{
pixelValue = HalfToFloat(((unsigned short *)image.data)[k+selectedChannel]);
k += 3;
} break;
case PIXELFORMAT_UNCOMPRESSED_R16G16B16A16:
{
pixelValue = HalfToFloat(((unsigned short *)image.data)[k + selectedChannel]);
k += 4;
} break;
default: break;
}
pixels[i] = (unsigned char)(pixelValue*255);
}
}
result.data = pixels;
return result;
}
// Resize and image to new size using Nearest-Neighbor scaling algorithm // Resize and image to new size using Nearest-Neighbor scaling algorithm
void ImageResizeNN(Image *image,int newWidth,int newHeight) void ImageResizeNN(Image *image,int newWidth,int newHeight)
{ {
@ -2943,6 +3111,7 @@ Color *LoadImageColors(Image image)
pixels[i].b = 0; pixels[i].b = 0;
pixels[i].a = 255; pixels[i].a = 255;
k += 1;
} break; } break;
case PIXELFORMAT_UNCOMPRESSED_R32G32B32: case PIXELFORMAT_UNCOMPRESSED_R32G32B32:
{ {
@ -2956,9 +3125,9 @@ Color *LoadImageColors(Image image)
case PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: case PIXELFORMAT_UNCOMPRESSED_R32G32B32A32:
{ {
pixels[i].r = (unsigned char)(((float *)image.data)[k]*255.0f); pixels[i].r = (unsigned char)(((float *)image.data)[k]*255.0f);
pixels[i].g = (unsigned char)(((float *)image.data)[k]*255.0f); pixels[i].g = (unsigned char)(((float *)image.data)[k + 1]*255.0f);
pixels[i].b = (unsigned char)(((float *)image.data)[k]*255.0f); pixels[i].b = (unsigned char)(((float *)image.data)[k + 2]*255.0f);
pixels[i].a = (unsigned char)(((float *)image.data)[k]*255.0f); pixels[i].a = (unsigned char)(((float *)image.data)[k + 3]*255.0f);
k += 4; k += 4;
} break; } break;
@ -2969,6 +3138,7 @@ Color *LoadImageColors(Image image)
pixels[i].b = 0; pixels[i].b = 0;
pixels[i].a = 255; pixels[i].a = 255;
k += 1;
} break; } break;
case PIXELFORMAT_UNCOMPRESSED_R16G16B16: case PIXELFORMAT_UNCOMPRESSED_R16G16B16:
{ {
@ -2982,9 +3152,9 @@ Color *LoadImageColors(Image image)
case PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: case PIXELFORMAT_UNCOMPRESSED_R16G16B16A16:
{ {
pixels[i].r = (unsigned char)(HalfToFloat(((unsigned short *)image.data)[k])*255.0f); pixels[i].r = (unsigned char)(HalfToFloat(((unsigned short *)image.data)[k])*255.0f);
pixels[i].g = (unsigned char)(HalfToFloat(((unsigned short *)image.data)[k])*255.0f); pixels[i].g = (unsigned char)(HalfToFloat(((unsigned short *)image.data)[k + 1])*255.0f);
pixels[i].b = (unsigned char)(HalfToFloat(((unsigned short *)image.data)[k])*255.0f); pixels[i].b = (unsigned char)(HalfToFloat(((unsigned short *)image.data)[k + 2])*255.0f);
pixels[i].a = (unsigned char)(HalfToFloat(((unsigned short *)image.data)[k])*255.0f); pixels[i].a = (unsigned char)(HalfToFloat(((unsigned short *)image.data)[k + 3])*255.0f);
k += 4; k += 4;
} break; } break;
@ -3431,7 +3601,7 @@ void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int en
} }
// Calculate fixed-point increment for shorter length // Calculate fixed-point increment for shorter length
int decInc = (longLen == 0)? 0 : (shortLen<<16) / longLen; int decInc = (longLen == 0)? 0 : (shortLen << 16)/longLen;
// Draw the line pixel by pixel // Draw the line pixel by pixel
if (yLonger) if (yLonger)
@ -3440,7 +3610,7 @@ void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int en
for (int i = 0, j = 0; i != endVal; i += sgnInc, j += decInc) for (int i = 0, j = 0; i != endVal; i += sgnInc, j += decInc)
{ {
// Calculate pixel position and draw it // Calculate pixel position and draw it
ImageDrawPixel(dst, startPosX + (j>>16), startPosY + i, color); ImageDrawPixel(dst, startPosX + (j >> 16), startPosY + i, color);
} }
} }
else else
@ -3449,7 +3619,7 @@ void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int en
for (int i = 0, j = 0; i != endVal; i += sgnInc, j += decInc) for (int i = 0, j = 0; i != endVal; i += sgnInc, j += decInc)
{ {
// Calculate pixel position and draw it // Calculate pixel position and draw it
ImageDrawPixel(dst, startPosX + i, startPosY + (j>>16), color); ImageDrawPixel(dst, startPosX + i, startPosY + (j >> 16), color);
} }
} }
} }
@ -3488,7 +3658,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++)
@ -3501,7 +3671,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++)
@ -3647,10 +3817,10 @@ void ImageDrawTriangle(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color col
{ {
// Calculate the 2D bounding box of the triangle // Calculate the 2D bounding box of the triangle
// Determine the minimum and maximum x and y coordinates of the triangle vertices // Determine the minimum and maximum x and y coordinates of the triangle vertices
int xMin = (int)((v1.x < v2.x)? ((v1.x < v3.x) ? v1.x : v3.x) : ((v2.x < v3.x) ? v2.x : v3.x)); int xMin = (int)((v1.x < v2.x)? ((v1.x < v3.x)? v1.x : v3.x) : ((v2.x < v3.x)? v2.x : v3.x));
int yMin = (int)((v1.y < v2.y)? ((v1.y < v3.y) ? v1.y : v3.y) : ((v2.y < v3.y) ? v2.y : v3.y)); int yMin = (int)((v1.y < v2.y)? ((v1.y < v3.y)? v1.y : v3.y) : ((v2.y < v3.y)? v2.y : v3.y));
int xMax = (int)((v1.x > v2.x)? ((v1.x > v3.x) ? v1.x : v3.x) : ((v2.x > v3.x) ? v2.x : v3.x)); int xMax = (int)((v1.x > v2.x)? ((v1.x > v3.x)? v1.x : v3.x) : ((v2.x > v3.x)? v2.x : v3.x));
int yMax = (int)((v1.y > v2.y)? ((v1.y > v3.y) ? v1.y : v3.y) : ((v2.y > v3.y) ? v2.y : v3.y)); int yMax = (int)((v1.y > v2.y)? ((v1.y > v3.y)? v1.y : v3.y) : ((v2.y > v3.y)? v2.y : v3.y));
// Clamp the bounding box to the image dimensions // Clamp the bounding box to the image dimensions
if (xMin < 0) xMin = 0; if (xMin < 0) xMin = 0;
@ -4709,12 +4879,12 @@ Color Fade(Color color, float alpha)
int ColorToInt(Color color) int ColorToInt(Color color)
{ {
int result = 0; int result = 0;
result = (int)(((unsigned int)color.r << 24) | result = (int)(((unsigned int)color.r << 24) |
((unsigned int)color.g << 16) | ((unsigned int)color.g << 16) |
((unsigned int)color.b << 8) | ((unsigned int)color.b << 8) |
(unsigned int)color.a); (unsigned int)color.a);
return result; return result;
} }