Merge remote-tracking branch 'refs/remotes/upstream/master'

This commit is contained in:
lesleyrs 2023-06-16 01:14:36 +02:00
commit 95d910bb70
19 changed files with 2027 additions and 1390 deletions

View File

@ -31,6 +31,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to
| h-raylib | **4.5** | [Haskell](https://haskell.org/) | Apache-2.0 | https://github.com/Anut-py/h-raylib | | h-raylib | **4.5** | [Haskell](https://haskell.org/) | Apache-2.0 | https://github.com/Anut-py/h-raylib |
| raylib-hx | 4.2 | [Haxe](https://haxe.org/) | Zlib | https://github.com/foreignsasquatch/raylib-hx | | raylib-hx | 4.2 | [Haxe](https://haxe.org/) | Zlib | https://github.com/foreignsasquatch/raylib-hx |
| hb-raylib | 3.5 | [Harbour](https://harbour.github.io) | MIT | https://github.com/MarcosLeonardoMendezGerencir/hb-raylib | | hb-raylib | 3.5 | [Harbour](https://harbour.github.io) | MIT | https://github.com/MarcosLeonardoMendezGerencir/hb-raylib |
| jaylib | 4.5 | [Janet](https://janet-lang.org/) | MIT | https://github.com/janet-lang/jaylib |
| jaylib | 4.2 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | GPLv3+CE | https://github.com/electronstudio/jaylib/ | | jaylib | 4.2 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | GPLv3+CE | https://github.com/electronstudio/jaylib/ |
| raylib-j | 4.0 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | Zlib | https://github.com/CreedVI/Raylib-J | | raylib-j | 4.0 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | Zlib | https://github.com/CreedVI/Raylib-J |
| raylib.jl | 4.2 | [Julia](https://julialang.org/) | Zlib | https://github.com/irishgreencitrus/raylib.jl | | raylib.jl | 4.2 | [Julia](https://julialang.org/) | Zlib | https://github.com/irishgreencitrus/raylib.jl |
@ -133,7 +134,6 @@ These are older raylib bindings that are more than 2 versions old or have not be
| raylib-jai | 3.1-dev | [Jai](https://github.com/BSVino/JaiPrimer/blob/master/JaiPrimer.md) | https://github.com/kujukuju/raylib-jai | | raylib-jai | 3.1-dev | [Jai](https://github.com/BSVino/JaiPrimer/blob/master/JaiPrimer.md) | https://github.com/kujukuju/raylib-jai |
| ray.zig | 2.5 | [Zig](https://ziglang.org/) | https://github.com/BitPuffin/zig-raylib-experiments | | ray.zig | 2.5 | [Zig](https://ziglang.org/) | https://github.com/BitPuffin/zig-raylib-experiments |
| raylib-Ada | 3.0 | [Ada](https://www.adacore.com/about-ada) | https://github.com/mimo/raylib-Ada | | raylib-Ada | 3.0 | [Ada](https://www.adacore.com/about-ada) | https://github.com/mimo/raylib-Ada |
| jaylib | 3.0 | [Janet](https://janet-lang.org/) | https://github.com/janet-lang/jaylib |
| raykit | ? | [Kit](https://www.kitlang.org/) | https://github.com/Gamerfiend/raykit | | raykit | ? | [Kit](https://www.kitlang.org/) | https://github.com/Gamerfiend/raykit |
| ray.mod | 3.0 | [BlitzMax](https://blitzmax.org/) | https://github.com/bmx-ng/ray.mod | | ray.mod | 3.0 | [BlitzMax](https://blitzmax.org/) | https://github.com/bmx-ng/ray.mod |
| raylib-mosaic | 3.0 | [Mosaic](https://github.com/sal55/langs/tree/master/Mosaic) | https://github.com/pluckyporcupine/raylib-mosaic | | raylib-mosaic | 3.0 | [Mosaic](https://github.com/sal55/langs/tree/master/Mosaic) | https://github.com/pluckyporcupine/raylib-mosaic |

2
FAQ.md
View File

@ -14,7 +14,7 @@
- [What does raylib provide that other engines or libraries don't?](#what-does-raylib-provide-that-other-engines-or-libraries-dont) - [What does raylib provide that other engines or libraries don't?](#what-does-raylib-provide-that-other-engines-or-libraries-dont)
- [How does raylib compare to Unity/Unreal/Godot?](#how-does-raylib-compare-to-unityunrealgodot) - [How does raylib compare to Unity/Unreal/Godot?](#how-does-raylib-compare-to-unityunrealgodot)
- [What development tools are required for raylib?](#what-development-tools-are-required-for-raylib) - [What development tools are required for raylib?](#what-development-tools-are-required-for-raylib)
- [Which are raylib external dependencies?](#which-are-raylib-external-dependencies) - [What are raylib's external dependencies?](#what-are-raylibs-external-dependencies)
- [Can I use raylib with other technologies or libraries?](#can-i-use-raylib-with-other-technologies-or-libraries) - [Can I use raylib with other technologies or libraries?](#can-i-use-raylib-with-other-technologies-or-libraries)
- [What file formats are supported by raylib?](#what-file-formats-are-supported-by-raylib) - [What file formats are supported by raylib?](#what-file-formats-are-supported-by-raylib)
- [Does raylib support the Vulkan API?](#does-raylib-support-the-vulkan-api) - [Does raylib support the Vulkan API?](#does-raylib-support-the-vulkan-api)

View File

@ -25,7 +25,7 @@ if (${PLATFORM} MATCHES "Desktop")
add_definitions(-D_CRT_SECURE_NO_WARNINGS) add_definitions(-D_CRT_SECURE_NO_WARNINGS)
find_package(OpenGL QUIET) find_package(OpenGL QUIET)
set(LIBS_PRIVATE ${OPENGL_LIBRARIES} winmm) set(LIBS_PRIVATE ${OPENGL_LIBRARIES} winmm)
else () elseif (UNIX)
find_library(pthread NAMES pthread) find_library(pthread NAMES pthread)
find_package(OpenGL QUIET) find_package(OpenGL QUIET)
if ("${OPENGL_LIBRARIES}" STREQUAL "") if ("${OPENGL_LIBRARIES}" STREQUAL "")
@ -36,9 +36,22 @@ if (${PLATFORM} MATCHES "Desktop")
find_library(OSS_LIBRARY ossaudio) find_library(OSS_LIBRARY ossaudio)
endif () endif ()
set(LIBS_PRIVATE m pthread ${OPENGL_LIBRARIES} ${OSS_LIBRARY})
else ()
find_library(pthread NAMES pthread)
find_package(OpenGL QUIET)
if ("${OPENGL_LIBRARIES}" STREQUAL "")
set(OPENGL_LIBRARIES "GL")
endif ()
set(LIBS_PRIVATE m atomic pthread ${OPENGL_LIBRARIES} ${OSS_LIBRARY}) set(LIBS_PRIVATE m atomic pthread ${OPENGL_LIBRARIES} ${OSS_LIBRARY})
if (USE_AUDIO) if ("${CMAKE_SYSTEM_NAME}" MATCHES "(Net|Open)BSD")
find_library(OSS_LIBRARY ossaudio)
set(LIBS_PRIVATE m pthread ${OPENGL_LIBRARIES} ${OSS_LIBRARY})
endif ()
if (NOT "${CMAKE_SYSTEM_NAME}" MATCHES "(Net|Open)BSD" AND USE_AUDIO)
set(LIBS_PRIVATE ${LIBS_PRIVATE} dl) set(LIBS_PRIVATE ${LIBS_PRIVATE} dl)
endif () endif ()
endif () endif ()

View File

@ -49,6 +49,8 @@ int main(void)
SetTargetFPS(60); // Set our game to run at 60 frames-per-second SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
int gamepad = 0; // which gamepad to display
// Main game loop // Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key while (!WindowShouldClose()) // Detect window close button or ESC key
{ {
@ -63,102 +65,114 @@ int main(void)
ClearBackground(RAYWHITE); ClearBackground(RAYWHITE);
if (IsGamepadAvailable(0)) if (IsKeyPressed(KEY_LEFT) && gamepad > 0) gamepad--;
{ if (IsKeyPressed(KEY_RIGHT)) gamepad++;
DrawText(TextFormat("GP1: %s", GetGamepadName(0)), 10, 10, 10, BLACK);
if (TextIsEqual(GetGamepadName(0), XBOX360_NAME_ID) || TextIsEqual(GetGamepadName(0), XBOX360_LEGACY_NAME_ID)) if (IsGamepadAvailable(gamepad))
{
DrawText(TextFormat("GP%d: %s", gamepad, GetGamepadName(gamepad)), 10, 10, 10, BLACK);
if (true)
{ {
DrawTexture(texXboxPad, 0, 0, DARKGRAY); DrawTexture(texXboxPad, 0, 0, DARKGRAY);
// Draw buttons: xbox home // Draw buttons: xbox home
if (IsGamepadButtonDown(0, GAMEPAD_BUTTON_MIDDLE)) DrawCircle(394, 89, 19, RED); if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_MIDDLE)) DrawCircle(394, 89, 19, RED);
// Draw buttons: basic // Draw buttons: basic
if (IsGamepadButtonDown(0, GAMEPAD_BUTTON_MIDDLE_RIGHT)) DrawCircle(436, 150, 9, RED); if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_MIDDLE_RIGHT)) DrawCircle(436, 150, 9, RED);
if (IsGamepadButtonDown(0, GAMEPAD_BUTTON_MIDDLE_LEFT)) DrawCircle(352, 150, 9, RED); if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_MIDDLE_LEFT)) DrawCircle(352, 150, 9, RED);
if (IsGamepadButtonDown(0, GAMEPAD_BUTTON_RIGHT_FACE_LEFT)) DrawCircle(501, 151, 15, BLUE); if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_FACE_LEFT)) DrawCircle(501, 151, 15, BLUE);
if (IsGamepadButtonDown(0, GAMEPAD_BUTTON_RIGHT_FACE_DOWN)) DrawCircle(536, 187, 15, LIME); if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_FACE_DOWN)) DrawCircle(536, 187, 15, LIME);
if (IsGamepadButtonDown(0, GAMEPAD_BUTTON_RIGHT_FACE_RIGHT)) DrawCircle(572, 151, 15, MAROON); if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_FACE_RIGHT)) DrawCircle(572, 151, 15, MAROON);
if (IsGamepadButtonDown(0, GAMEPAD_BUTTON_RIGHT_FACE_UP)) DrawCircle(536, 115, 15, GOLD); if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_FACE_UP)) DrawCircle(536, 115, 15, GOLD);
// Draw buttons: d-pad // Draw buttons: d-pad
DrawRectangle(317, 202, 19, 71, BLACK); DrawRectangle(317, 202, 19, 71, BLACK);
DrawRectangle(293, 228, 69, 19, BLACK); DrawRectangle(293, 228, 69, 19, BLACK);
if (IsGamepadButtonDown(0, GAMEPAD_BUTTON_LEFT_FACE_UP)) DrawRectangle(317, 202, 19, 26, RED); if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_FACE_UP)) DrawRectangle(317, 202, 19, 26, RED);
if (IsGamepadButtonDown(0, GAMEPAD_BUTTON_LEFT_FACE_DOWN)) DrawRectangle(317, 202 + 45, 19, 26, RED); if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_FACE_DOWN)) DrawRectangle(317, 202 + 45, 19, 26, RED);
if (IsGamepadButtonDown(0, GAMEPAD_BUTTON_LEFT_FACE_LEFT)) DrawRectangle(292, 228, 25, 19, RED); if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_FACE_LEFT)) DrawRectangle(292, 228, 25, 19, RED);
if (IsGamepadButtonDown(0, GAMEPAD_BUTTON_LEFT_FACE_RIGHT)) DrawRectangle(292 + 44, 228, 26, 19, RED); if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_FACE_RIGHT)) DrawRectangle(292 + 44, 228, 26, 19, RED);
// Draw buttons: left-right back // Draw buttons: left-right back
if (IsGamepadButtonDown(0, GAMEPAD_BUTTON_LEFT_TRIGGER_1)) DrawCircle(259, 61, 20, RED); if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_TRIGGER_1)) DrawCircle(259, 61, 20, RED);
if (IsGamepadButtonDown(0, GAMEPAD_BUTTON_RIGHT_TRIGGER_1)) DrawCircle(536, 61, 20, RED); if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_TRIGGER_1)) DrawCircle(536, 61, 20, RED);
// Draw axis: left joystick // Draw axis: left joystick
Color leftGamepadColor = BLACK;
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_THUMB)) leftGamepadColor = RED;
DrawCircle(259, 152, 39, BLACK); DrawCircle(259, 152, 39, BLACK);
DrawCircle(259, 152, 34, LIGHTGRAY); DrawCircle(259, 152, 34, LIGHTGRAY);
DrawCircle(259 + (int)(GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X)*20), DrawCircle(259 + (int)(GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_LEFT_X)*20),
152 + (int)(GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y)*20), 25, BLACK); 152 + (int)(GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_LEFT_Y)*20), 25, leftGamepadColor);
// Draw axis: right joystick // Draw axis: right joystick
Color rightGamepadColor = BLACK;
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_THUMB)) rightGamepadColor = RED;
DrawCircle(461, 237, 38, BLACK); DrawCircle(461, 237, 38, BLACK);
DrawCircle(461, 237, 33, LIGHTGRAY); DrawCircle(461, 237, 33, LIGHTGRAY);
DrawCircle(461 + (int)(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_X)*20), DrawCircle(461 + (int)(GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_RIGHT_X)*20),
237 + (int)(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_Y)*20), 25, BLACK); 237 + (int)(GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_RIGHT_Y)*20), 25, rightGamepadColor);
// Draw axis: left-right triggers // Draw axis: left-right triggers
DrawRectangle(170, 30, 15, 70, GRAY); DrawRectangle(170, 30, 15, 70, GRAY);
DrawRectangle(604, 30, 15, 70, GRAY); DrawRectangle(604, 30, 15, 70, GRAY);
DrawRectangle(170, 30, 15, (int)(((1 + GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_TRIGGER))/2)*70), RED); DrawRectangle(170, 30, 15, (int)(((1 + GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_LEFT_TRIGGER))/2)*70), RED);
DrawRectangle(604, 30, 15, (int)(((1 + GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_TRIGGER))/2)*70), RED); DrawRectangle(604, 30, 15, (int)(((1 + GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_RIGHT_TRIGGER))/2)*70), RED);
//DrawText(TextFormat("Xbox axis LT: %02.02f", GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_TRIGGER)), 10, 40, 10, BLACK); //DrawText(TextFormat("Xbox axis LT: %02.02f", GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_LEFT_TRIGGER)), 10, 40, 10, BLACK);
//DrawText(TextFormat("Xbox axis RT: %02.02f", GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_TRIGGER)), 10, 60, 10, BLACK); //DrawText(TextFormat("Xbox axis RT: %02.02f", GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_RIGHT_TRIGGER)), 10, 60, 10, BLACK);
} }
else if (TextIsEqual(GetGamepadName(0), PS3_NAME_ID)) else if (TextIsEqual(GetGamepadName(gamepad), PS3_NAME_ID))
{ {
DrawTexture(texPs3Pad, 0, 0, DARKGRAY); DrawTexture(texPs3Pad, 0, 0, DARKGRAY);
// Draw buttons: ps // Draw buttons: ps
if (IsGamepadButtonDown(0, GAMEPAD_BUTTON_MIDDLE)) DrawCircle(396, 222, 13, RED); if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_MIDDLE)) DrawCircle(396, 222, 13, RED);
// Draw buttons: basic // Draw buttons: basic
if (IsGamepadButtonDown(0, GAMEPAD_BUTTON_MIDDLE_LEFT)) DrawRectangle(328, 170, 32, 13, RED); if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_MIDDLE_LEFT)) DrawRectangle(328, 170, 32, 13, RED);
if (IsGamepadButtonDown(0, GAMEPAD_BUTTON_MIDDLE_RIGHT)) DrawTriangle((Vector2){ 436, 168 }, (Vector2){ 436, 185 }, (Vector2){ 464, 177 }, RED); if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_MIDDLE_RIGHT)) DrawTriangle((Vector2){ 436, 168 }, (Vector2){ 436, 185 }, (Vector2){ 464, 177 }, RED);
if (IsGamepadButtonDown(0, GAMEPAD_BUTTON_RIGHT_FACE_UP)) DrawCircle(557, 144, 13, LIME); if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_FACE_UP)) DrawCircle(557, 144, 13, LIME);
if (IsGamepadButtonDown(0, GAMEPAD_BUTTON_RIGHT_FACE_RIGHT)) DrawCircle(586, 173, 13, RED); if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_FACE_RIGHT)) DrawCircle(586, 173, 13, RED);
if (IsGamepadButtonDown(0, GAMEPAD_BUTTON_RIGHT_FACE_DOWN)) DrawCircle(557, 203, 13, VIOLET); if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_FACE_DOWN)) DrawCircle(557, 203, 13, VIOLET);
if (IsGamepadButtonDown(0, GAMEPAD_BUTTON_RIGHT_FACE_LEFT)) DrawCircle(527, 173, 13, PINK); if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_FACE_LEFT)) DrawCircle(527, 173, 13, PINK);
// Draw buttons: d-pad // Draw buttons: d-pad
DrawRectangle(225, 132, 24, 84, BLACK); DrawRectangle(225, 132, 24, 84, BLACK);
DrawRectangle(195, 161, 84, 25, BLACK); DrawRectangle(195, 161, 84, 25, BLACK);
if (IsGamepadButtonDown(0, GAMEPAD_BUTTON_LEFT_FACE_UP)) DrawRectangle(225, 132, 24, 29, RED); if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_FACE_UP)) DrawRectangle(225, 132, 24, 29, RED);
if (IsGamepadButtonDown(0, GAMEPAD_BUTTON_LEFT_FACE_DOWN)) DrawRectangle(225, 132 + 54, 24, 30, RED); if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_FACE_DOWN)) DrawRectangle(225, 132 + 54, 24, 30, RED);
if (IsGamepadButtonDown(0, GAMEPAD_BUTTON_LEFT_FACE_LEFT)) DrawRectangle(195, 161, 30, 25, RED); if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_FACE_LEFT)) DrawRectangle(195, 161, 30, 25, RED);
if (IsGamepadButtonDown(0, GAMEPAD_BUTTON_LEFT_FACE_RIGHT)) DrawRectangle(195 + 54, 161, 30, 25, RED); if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_FACE_RIGHT)) DrawRectangle(195 + 54, 161, 30, 25, RED);
// Draw buttons: left-right back buttons // Draw buttons: left-right back buttons
if (IsGamepadButtonDown(0, GAMEPAD_BUTTON_LEFT_TRIGGER_1)) DrawCircle(239, 82, 20, RED); if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_TRIGGER_1)) DrawCircle(239, 82, 20, RED);
if (IsGamepadButtonDown(0, GAMEPAD_BUTTON_RIGHT_TRIGGER_1)) DrawCircle(557, 82, 20, RED); if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_TRIGGER_1)) DrawCircle(557, 82, 20, RED);
// Draw axis: left joystick // Draw axis: left joystick
DrawCircle(319, 255, 35, BLACK); Color leftGamepadColor = BLACK;
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_THUMB)) leftGamepadColor = RED;
DrawCircle(319, 255, 35, leftGamepadColor);
DrawCircle(319, 255, 31, LIGHTGRAY); DrawCircle(319, 255, 31, LIGHTGRAY);
DrawCircle(319 + (int)(GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X) * 20), DrawCircle(319 + (int)(GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_LEFT_X) * 20),
255 + (int)(GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y) * 20), 25, BLACK); 255 + (int)(GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_LEFT_Y) * 20), 25, leftGamepadColor);
// Draw axis: right joystick // Draw axis: right joystick
Color rightGamepadColor = BLACK;
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_THUMB)) rightGamepadColor = RED;
DrawCircle(475, 255, 35, BLACK); DrawCircle(475, 255, 35, BLACK);
DrawCircle(475, 255, 31, LIGHTGRAY); DrawCircle(475, 255, 31, LIGHTGRAY);
DrawCircle(475 + (int)(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_X) * 20), DrawCircle(475 + (int)(GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_RIGHT_X) * 20),
255 + (int)(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_Y) * 20), 25, BLACK); 255 + (int)(GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_RIGHT_Y) * 20), 25, rightGamepadColor);
// Draw axis: left-right triggers // Draw axis: left-right triggers
DrawRectangle(169, 48, 15, 70, GRAY); DrawRectangle(169, 48, 15, 70, GRAY);
DrawRectangle(611, 48, 15, 70, GRAY); DrawRectangle(611, 48, 15, 70, GRAY);
DrawRectangle(169, 48, 15, (int)(((1 - GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_TRIGGER)) / 2) * 70), RED); DrawRectangle(169, 48, 15, (int)(((1 - GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_LEFT_TRIGGER)) / 2) * 70), RED);
DrawRectangle(611, 48, 15, (int)(((1 - GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_TRIGGER)) / 2) * 70), RED); DrawRectangle(611, 48, 15, (int)(((1 - GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_RIGHT_TRIGGER)) / 2) * 70), RED);
} }
else else
{ {
@ -179,7 +193,7 @@ int main(void)
} }
else else
{ {
DrawText("GP1: NOT DETECTED", 10, 10, 10, GRAY); DrawText(TextFormat("GP%d: NOT DETECTED", gamepad), 10, 10, 10, GRAY);
DrawTexture(texXboxPad, 0, 0, LIGHTGRAY); DrawTexture(texXboxPad, 0, 0, LIGHTGRAY);
} }

File diff suppressed because it is too large Load Diff

View File

@ -35,8 +35,8 @@ int main(void)
float outerRadius = 180.0f; float outerRadius = 180.0f;
float startAngle = 0.0f; float startAngle = 0.0f;
float endAngle = 180.0f; float endAngle = 180.0f;
int segments = 0; float segments = 10.0f;
int minSegments = 4; float minSegments = 4;
SetTargetFPS(60); // Set our game to run at 60 frames-per-second SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
@ -58,16 +58,16 @@ int main(void)
DrawLine(500, 0, 500, GetScreenHeight(), Fade(LIGHTGRAY, 0.6f)); DrawLine(500, 0, 500, GetScreenHeight(), Fade(LIGHTGRAY, 0.6f));
DrawRectangle(500, 0, GetScreenWidth() - 500, GetScreenHeight(), Fade(LIGHTGRAY, 0.3f)); DrawRectangle(500, 0, GetScreenWidth() - 500, GetScreenHeight(), Fade(LIGHTGRAY, 0.3f));
DrawCircleSector(center, outerRadius, startAngle, endAngle, segments, Fade(MAROON, 0.3f)); DrawCircleSector(center, outerRadius, startAngle, endAngle, (int)segments, Fade(MAROON, 0.3f));
DrawCircleSectorLines(center, outerRadius, startAngle, endAngle, segments, Fade(MAROON, 0.6f)); DrawCircleSectorLines(center, outerRadius, startAngle, endAngle, (int)segments, Fade(MAROON, 0.6f));
// Draw GUI controls // Draw GUI controls
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
startAngle = GuiSliderBar((Rectangle){ 600, 40, 120, 20}, "StartAngle", NULL, startAngle, 0, 720); GuiSliderBar((Rectangle){ 600, 40, 120, 20}, "StartAngle", NULL, &startAngle, 0, 720);
endAngle = GuiSliderBar((Rectangle){ 600, 70, 120, 20}, "EndAngle", NULL, endAngle, 0, 720); GuiSliderBar((Rectangle){ 600, 70, 120, 20}, "EndAngle", NULL, &endAngle, 0, 720);
outerRadius = GuiSliderBar((Rectangle){ 600, 140, 120, 20}, "Radius", NULL, outerRadius, 0, 200); GuiSliderBar((Rectangle){ 600, 140, 120, 20}, "Radius", NULL, &outerRadius, 0, 200);
segments = (int)GuiSliderBar((Rectangle){ 600, 170, 120, 20}, "Segments", NULL, (float)segments, 0, 100); GuiSliderBar((Rectangle){ 600, 170, 120, 20}, "Segments", NULL, &segments, 0, 100);
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
minSegments = (int)ceilf((endAngle - startAngle) / 90); minSegments = (int)ceilf((endAngle - startAngle) / 90);

View File

@ -31,10 +31,10 @@ int main(void)
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - draw rectangle rounded"); InitWindow(screenWidth, screenHeight, "raylib [shapes] example - draw rectangle rounded");
float roundness = 0.2f; float roundness = 0.2f;
int width = 200; float width = 200.0f;
int height = 100; float height = 100.0f;
int segments = 0; float segments = 0.0f;
int lineThick = 1; float lineThick = 1.0f;
bool drawRect = false; bool drawRect = false;
bool drawRoundedRect = true; bool drawRoundedRect = true;
@ -61,20 +61,20 @@ int main(void)
DrawRectangle(560, 0, GetScreenWidth() - 500, GetScreenHeight(), Fade(LIGHTGRAY, 0.3f)); DrawRectangle(560, 0, GetScreenWidth() - 500, GetScreenHeight(), Fade(LIGHTGRAY, 0.3f));
if (drawRect) DrawRectangleRec(rec, Fade(GOLD, 0.6f)); if (drawRect) DrawRectangleRec(rec, Fade(GOLD, 0.6f));
if (drawRoundedRect) DrawRectangleRounded(rec, roundness, segments, Fade(MAROON, 0.2f)); if (drawRoundedRect) DrawRectangleRounded(rec, roundness, (int)segments, Fade(MAROON, 0.2f));
if (drawRoundedLines) DrawRectangleRoundedLines(rec,roundness, segments, (float)lineThick, Fade(MAROON, 0.4f)); if (drawRoundedLines) DrawRectangleRoundedLines(rec, roundness, (int)segments, lineThick, Fade(MAROON, 0.4f));
// Draw GUI controls // Draw GUI controls
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
width = (int)GuiSliderBar((Rectangle){ 640, 40, 105, 20 }, "Width", NULL, (float)width, 0, (float)GetScreenWidth() - 300); GuiSliderBar((Rectangle){ 640, 40, 105, 20 }, "Width", NULL, &width, 0, (float)GetScreenWidth() - 300);
height = (int)GuiSliderBar((Rectangle){ 640, 70, 105, 20 }, "Height", NULL, (float)height, 0, (float)GetScreenHeight() - 50); GuiSliderBar((Rectangle){ 640, 70, 105, 20 }, "Height", NULL, &height, 0, (float)GetScreenHeight() - 50);
roundness = GuiSliderBar((Rectangle){ 640, 140, 105, 20 }, "Roundness", NULL, roundness, 0.0f, 1.0f); GuiSliderBar((Rectangle){ 640, 140, 105, 20 }, "Roundness", NULL, &roundness, 0.0f, 1.0f);
lineThick = (int)GuiSliderBar((Rectangle){ 640, 170, 105, 20 }, "Thickness", NULL, (float)lineThick, 0, 20); GuiSliderBar((Rectangle){ 640, 170, 105, 20 }, "Thickness", NULL, &lineThick, 0, 20);
segments = (int)GuiSliderBar((Rectangle){ 640, 240, 105, 20}, "Segments", NULL, (float)segments, 0, 60); GuiSliderBar((Rectangle){ 640, 240, 105, 20}, "Segments", NULL, &segments, 0, 60);
drawRoundedRect = GuiCheckBox((Rectangle){ 640, 320, 20, 20 }, "DrawRoundedRect", drawRoundedRect); GuiCheckBox((Rectangle){ 640, 320, 20, 20 }, "DrawRoundedRect", &drawRoundedRect);
drawRoundedLines = GuiCheckBox((Rectangle){ 640, 350, 20, 20 }, "DrawRoundedLines", drawRoundedLines); GuiCheckBox((Rectangle){ 640, 350, 20, 20 }, "DrawRoundedLines", &drawRoundedLines);
drawRect = GuiCheckBox((Rectangle){ 640, 380, 20, 20}, "DrawRect", drawRect); GuiCheckBox((Rectangle){ 640, 380, 20, 20}, "DrawRect", &drawRect);
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
DrawText(TextFormat("MODE: %s", (segments >= 4)? "MANUAL" : "AUTO"), 640, 280, 10, (segments >= 4)? MAROON : DARKGRAY); DrawText(TextFormat("MODE: %s", (segments >= 4)? "MANUAL" : "AUTO"), 640, 280, 10, (segments >= 4)? MAROON : DARKGRAY);

View File

@ -37,7 +37,7 @@ int main(void)
float startAngle = 0.0f; float startAngle = 0.0f;
float endAngle = 360.0f; float endAngle = 360.0f;
int segments = 0; float segments = 0.0f;
bool drawRing = true; bool drawRing = true;
bool drawRingLines = false; bool drawRingLines = false;
@ -63,23 +63,23 @@ int main(void)
DrawLine(500, 0, 500, GetScreenHeight(), Fade(LIGHTGRAY, 0.6f)); DrawLine(500, 0, 500, GetScreenHeight(), Fade(LIGHTGRAY, 0.6f));
DrawRectangle(500, 0, GetScreenWidth() - 500, GetScreenHeight(), Fade(LIGHTGRAY, 0.3f)); DrawRectangle(500, 0, GetScreenWidth() - 500, GetScreenHeight(), Fade(LIGHTGRAY, 0.3f));
if (drawRing) DrawRing(center, innerRadius, outerRadius, startAngle, endAngle, segments, Fade(MAROON, 0.3f)); if (drawRing) DrawRing(center, innerRadius, outerRadius, startAngle, endAngle, (int)segments, Fade(MAROON, 0.3f));
if (drawRingLines) DrawRingLines(center, innerRadius, outerRadius, startAngle, endAngle, segments, Fade(BLACK, 0.4f)); if (drawRingLines) DrawRingLines(center, innerRadius, outerRadius, startAngle, endAngle, (int)segments, Fade(BLACK, 0.4f));
if (drawCircleLines) DrawCircleSectorLines(center, outerRadius, startAngle, endAngle, segments, Fade(BLACK, 0.4f)); if (drawCircleLines) DrawCircleSectorLines(center, outerRadius, startAngle, endAngle, (int)segments, Fade(BLACK, 0.4f));
// Draw GUI controls // Draw GUI controls
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
startAngle = GuiSliderBar((Rectangle){ 600, 40, 120, 20 }, "StartAngle", NULL, startAngle, -450, 450); GuiSliderBar((Rectangle){ 600, 40, 120, 20 }, "StartAngle", NULL, &startAngle, -450, 450);
endAngle = GuiSliderBar((Rectangle){ 600, 70, 120, 20 }, "EndAngle", NULL, endAngle, -450, 450); GuiSliderBar((Rectangle){ 600, 70, 120, 20 }, "EndAngle", NULL, &endAngle, -450, 450);
innerRadius = GuiSliderBar((Rectangle){ 600, 140, 120, 20 }, "InnerRadius", NULL, innerRadius, 0, 100); GuiSliderBar((Rectangle){ 600, 140, 120, 20 }, "InnerRadius", NULL, &innerRadius, 0, 100);
outerRadius = GuiSliderBar((Rectangle){ 600, 170, 120, 20 }, "OuterRadius", NULL, outerRadius, 0, 200); GuiSliderBar((Rectangle){ 600, 170, 120, 20 }, "OuterRadius", NULL, &outerRadius, 0, 200);
segments = (int)GuiSliderBar((Rectangle){ 600, 240, 120, 20 }, "Segments", NULL, (float)segments, 0, 100); GuiSliderBar((Rectangle){ 600, 240, 120, 20 }, "Segments", NULL, &segments, 0, 100);
drawRing = GuiCheckBox((Rectangle){ 600, 320, 20, 20 }, "Draw Ring", drawRing); GuiCheckBox((Rectangle){ 600, 320, 20, 20 }, "Draw Ring", &drawRing);
drawRingLines = GuiCheckBox((Rectangle){ 600, 350, 20, 20 }, "Draw RingLines", drawRingLines); GuiCheckBox((Rectangle){ 600, 350, 20, 20 }, "Draw RingLines", &drawRingLines);
drawCircleLines = GuiCheckBox((Rectangle){ 600, 380, 20, 20 }, "Draw CircleLines", drawCircleLines); GuiCheckBox((Rectangle){ 600, 380, 20, 20 }, "Draw CircleLines", &drawCircleLines);
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int minSegments = (int)ceilf((endAngle - startAngle)/90); int minSegments = (int)ceilf((endAngle - startAngle)/90);

View File

@ -95,12 +95,11 @@ USE_EXTERNAL_GLFW ?= FALSE
USE_WAYLAND_DISPLAY ?= FALSE USE_WAYLAND_DISPLAY ?= FALSE
# Use cross-compiler for PLATFORM_RPI # Use cross-compiler for PLATFORM_RPI
ifeq ($(PLATFORM),PLATFORM_RPI) USE_RPI_CROSS_COMPILER ?= FALSE
USE_RPI_CROSS_COMPILER ?= FALSE ifeq ($(USE_RPI_CROSS_COMPILER),TRUE)
ifeq ($(USE_RPI_CROSS_COMPILER),TRUE)
RPI_TOOLCHAIN ?= C:/SysGCC/Raspberry RPI_TOOLCHAIN ?= C:/SysGCC/Raspberry
RPI_TOOLCHAIN_SYSROOT ?= $(RPI_TOOLCHAIN)/arm-linux-gnueabihf/sysroot RPI_TOOLCHAIN_NAME ?= arm-linux-gnueabihf
endif RPI_TOOLCHAIN_SYSROOT ?= $(RPI_TOOLCHAIN)/$(RPI_TOOLCHAIN_NAME)/sysroot
endif endif
# Determine if the file has root access (only required to install raylib) # Determine if the file has root access (only required to install raylib)
@ -247,6 +246,7 @@ endif
ifeq ($(PLATFORM),PLATFORM_WEB) ifeq ($(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).
endif endif
ifeq ($(PLATFORM),PLATFORM_ANDROID) ifeq ($(PLATFORM),PLATFORM_ANDROID)
# By default use OpenGL ES 2.0 on Android # By default use OpenGL ES 2.0 on Android
@ -273,8 +273,16 @@ ifeq ($(PLATFORM),PLATFORM_RPI)
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
CC = $(RPI_TOOLCHAIN)/bin/arm-linux-gnueabihf-gcc CC = $(RPI_TOOLCHAIN)/bin/$(RPI_TOOLCHAIN_NAME)-gcc
AR = $(RPI_TOOLCHAIN)/bin/arm-linux-gnueabihf-ar AR = $(RPI_TOOLCHAIN)/bin/$(RPI_TOOLCHAIN_NAME)-ar
endif
endif
ifeq ($(PLATFORM),PLATFORM_DRM)
ifeq ($(USE_RPI_CROSS_COMPILER),TRUE)
# Define RPI cross-compiler
#CC = armv6j-hardfloat-linux-gnueabi-gcc
CC = $(RPI_TOOLCHAIN)/bin/$(RPI_TOOLCHAIN_NAME)-gcc
AR = $(RPI_TOOLCHAIN)/bin/$(RPI_TOOLCHAIN_NAME)-ar
endif endif
endif endif
ifeq ($(PLATFORM),PLATFORM_WEB) ifeq ($(PLATFORM),PLATFORM_WEB)
@ -451,6 +459,10 @@ ifeq ($(PLATFORM),PLATFORM_RPI)
endif endif
ifeq ($(PLATFORM),PLATFORM_DRM) ifeq ($(PLATFORM),PLATFORM_DRM)
INCLUDE_PATHS += -I/usr/include/libdrm INCLUDE_PATHS += -I/usr/include/libdrm
ifeq ($(USE_RPI_CROSSCOMPILER), TRUE)
INCLUDE_PATHS += -I$(RPI_TOOLCHAIN_SYSROOT)/usr/include
INCLUDE_PATHS += -I$(RPI_TOOLCHAIN_SYSROOT)/opt/vc/include
endif
endif endif
ifeq ($(PLATFORM),PLATFORM_ANDROID) ifeq ($(PLATFORM),PLATFORM_ANDROID)
NATIVE_APP_GLUE = $(ANDROID_NDK)/sources/android/native_app_glue NATIVE_APP_GLUE = $(ANDROID_NDK)/sources/android/native_app_glue
@ -499,6 +511,9 @@ ifeq ($(PLATFORM),PLATFORM_RPI)
endif endif
ifeq ($(PLATFORM),PLATFORM_DRM) ifeq ($(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)
INCLUDE_PATHS += -L$(RPI_TOOLCHAIN_SYSROOT)/opt/vc/lib -L$(RPI_TOOLCHAIN_SYSROOT)/usr/lib
endif
endif endif
ifeq ($(PLATFORM),PLATFORM_ANDROID) ifeq ($(PLATFORM),PLATFORM_ANDROID)
LDFLAGS += -Wl,-soname,libraylib.$(API_VERSION).so -Wl,--exclude-libs,libatomic.a LDFLAGS += -Wl,-soname,libraylib.$(API_VERSION).so -Wl,--exclude-libs,libatomic.a

View File

@ -45,6 +45,7 @@ pub fn addRaylib(b: *std.Build, target: std.zig.CrossTarget, optimize: std.built
raylib.linkSystemLibrary("dl"); raylib.linkSystemLibrary("dl");
raylib.linkSystemLibrary("m"); raylib.linkSystemLibrary("m");
raylib.linkSystemLibrary("X11"); raylib.linkSystemLibrary("X11");
raylib.addIncludePath("/usr/include");
raylib.defineCMacro("PLATFORM_DESKTOP", null); raylib.defineCMacro("PLATFORM_DESKTOP", null);
}, },

43
src/external/sdefl.h vendored
View File

@ -38,10 +38,10 @@ this file implementation in *one* C or C++ file to prevent collisions.
| zlib 1.2.11 -1 | 72 MB/s | 307 MB/s | 42298774 | 42.30 | | zlib 1.2.11 -1 | 72 MB/s | 307 MB/s | 42298774 | 42.30 |
| zlib 1.2.11 -6 | 24 MB/s | 313 MB/s | 36548921 | 36.55 | | zlib 1.2.11 -6 | 24 MB/s | 313 MB/s | 36548921 | 36.55 |
| zlib 1.2.11 -9 | 20 MB/s | 314 MB/s | 36475792 | 36.48 | | zlib 1.2.11 -9 | 20 MB/s | 314 MB/s | 36475792 | 36.48 |
| sdefl 1.0 -0 | 127 MB/s | 371 MB/s | 40004116 | 39.88 | | sdefl 1.0 -0 | 127 MB/s | 355 MB/s | 40004116 | 39.88 |
| sdefl 1.0 -1 | 111 MB/s | 398 MB/s | 38940674 | 38.82 | | sdefl 1.0 -1 | 111 MB/s | 413 MB/s | 38940674 | 38.82 |
| sdefl 1.0 -5 | 45 MB/s | 420 MB/s | 36577183 | 36.46 | | sdefl 1.0 -5 | 45 MB/s | 436 MB/s | 36577183 | 36.46 |
| sdefl 1.0 -7 | 38 MB/s | 423 MB/s | 36523781 | 36.41 | | sdefl 1.0 -7 | 38 MB/s | 432 MB/s | 36523781 | 36.41 |
| libdeflate 1.3 -1 | 147 MB/s | 667 MB/s | 39597378 | 39.60 | | libdeflate 1.3 -1 | 147 MB/s | 667 MB/s | 39597378 | 39.60 |
| libdeflate 1.3 -6 | 69 MB/s | 689 MB/s | 36648318 | 36.65 | | libdeflate 1.3 -6 | 69 MB/s | 689 MB/s | 36648318 | 36.65 |
| libdeflate 1.3 -9 | 13 MB/s | 672 MB/s | 35197141 | 35.20 | | libdeflate 1.3 -9 | 13 MB/s | 672 MB/s | 35197141 | 35.20 |
@ -51,8 +51,8 @@ this file implementation in *one* C or C++ file to prevent collisions.
Results on the [Silesia compression corpus](http://sun.aei.polsl.pl/~sdeor/index.php?page=silesia): Results on the [Silesia compression corpus](http://sun.aei.polsl.pl/~sdeor/index.php?page=silesia):
| File | Original | `sdefl 0` | `sdefl 5` | `sdefl 7` | | File | Original | `sdefl 0` | `sdefl 5` | `sdefl 7` |
| :------ | ---------: | -----------------: | ---------: | ----------: | | --------| -----------| -------------| ---------- | ------------|
| dickens | 10.192.446 | 4,260,187| 3,845,261| 3,833,657 | | dickens | 10.192.446 | 4,260,187 | 3,845,261 | 3,833,657 |
| mozilla | 51.220.480 | 20,774,706 | 19,607,009 | 19,565,867 | | mozilla | 51.220.480 | 20,774,706 | 19,607,009 | 19,565,867 |
| mr | 9.970.564 | 3,860,531 | 3,673,460 | 3,665,627 | | mr | 9.970.564 | 3,860,531 | 3,673,460 | 3,665,627 |
| nci | 33.553.445 | 4,030,283 | 3,094,526 | 3,006,075 | | nci | 33.553.445 | 4,030,283 | 3,094,526 | 3,006,075 |
@ -62,7 +62,7 @@ Results on the [Silesia compression corpus](http://sun.aei.polsl.pl/~sdeor/index
| samba | 21.606.400 | 6,121,797 | 5,462,670 | 5,450,762 | | samba | 21.606.400 | 6,121,797 | 5,462,670 | 5,450,762 |
| sao | 7.251.944 | 5,612,421 | 5,485,380 | 5,481,765 | | sao | 7.251.944 | 5,612,421 | 5,485,380 | 5,481,765 |
| webster | 41.458.703 | 13,972,648 | 12,059,432 | 11,991,421 | | webster | 41.458.703 | 13,972,648 | 12,059,432 | 11,991,421 |
| xml | 5.345.280 | 886,620| 674,009 | 662,141 | | xml | 5.345.280 | 886,620 | 674,009 | 662,141 |
| x-ray | 8.474.240 | 6,304,655 | 6,244,779 | 6,244,779 | | x-ray | 8.474.240 | 6,304,655 | 6,244,779 | 6,244,779 |
## License ## License
@ -462,8 +462,12 @@ sdefl_match_codes(struct sdefl_match_codes *cod, int dist, int len) {
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 28 27, 27, 28
}; };
assert(len <= 258);
assert(dist <= 32768);
cod->ls = lslot[len]; cod->ls = lslot[len];
cod->lc = 257 + cod->ls; cod->lc = 257 + cod->ls;
assert(cod->lc <= 285);
cod->dx = sdefl_ilog2(sdefl_npow2(dist) >> 2); cod->dx = sdefl_ilog2(sdefl_npow2(dist) >> 2);
cod->dc = cod->dx ? ((cod->dx + 1) << 1) + (dist > dxmax[cod->dx]) : dist-1; cod->dc = cod->dx ? ((cod->dx + 1) << 1) + (dist > dxmax[cod->dx]) : dist-1;
} }
@ -501,7 +505,9 @@ sdefl_flush(unsigned char **dst, struct sdefl *s, int is_last,
sdefl_precode(&symcnt, freqs, items, s->cod.len.lit, s->cod.len.off); sdefl_precode(&symcnt, freqs, items, s->cod.len.lit, s->cod.len.off);
sdefl_huff(lens, codes, freqs, SDEFL_PRE_MAX, SDEFL_PRE_CODES); sdefl_huff(lens, codes, freqs, SDEFL_PRE_MAX, SDEFL_PRE_CODES);
for (item_cnt = SDEFL_PRE_MAX; item_cnt > 4; item_cnt--) { for (item_cnt = SDEFL_PRE_MAX; item_cnt > 4; item_cnt--) {
if (lens[perm[item_cnt - 1]]) break; if (lens[perm[item_cnt - 1]]){
break;
}
} }
/* block header */ /* block header */
sdefl_put(dst, s, is_last ? 0x01 : 0x00, 1); /* block */ sdefl_put(dst, s, is_last ? 0x01 : 0x00, 1); /* block */
@ -509,8 +515,9 @@ sdefl_flush(unsigned char **dst, struct sdefl *s, int is_last,
sdefl_put(dst, s, symcnt.lit - 257, 5); sdefl_put(dst, s, symcnt.lit - 257, 5);
sdefl_put(dst, s, symcnt.off - 1, 5); sdefl_put(dst, s, symcnt.off - 1, 5);
sdefl_put(dst, s, item_cnt - 4, 4); sdefl_put(dst, s, item_cnt - 4, 4);
for (i = 0; i < item_cnt; ++i) for (i = 0; i < item_cnt; ++i) {
sdefl_put(dst, s, lens[perm[i]], 3); sdefl_put(dst, s, lens[perm[i]], 3);
}
for (i = 0; i < symcnt.items; ++i) { for (i = 0; i < symcnt.items; ++i) {
unsigned sym = items[i] & 0x1F; unsigned sym = items[i] & 0x1F;
sdefl_put(dst, s, (int)codes[sym], lens[sym]); sdefl_put(dst, s, (int)codes[sym], lens[sym]);
@ -521,12 +528,14 @@ sdefl_flush(unsigned char **dst, struct sdefl *s, int is_last,
} }
/* block sequences */ /* block sequences */
for (i = 0; i < s->seq_cnt; ++i) { for (i = 0; i < s->seq_cnt; ++i) {
if (s->seq[i].off >= 0) if (s->seq[i].off >= 0) {
for (j = 0; j < s->seq[i].len; ++j) { for (j = 0; j < s->seq[i].len; ++j) {
int c = in[s->seq[i].off + j]; int c = in[s->seq[i].off + j];
sdefl_put(dst, s, (int)s->cod.word.lit[c], s->cod.len.lit[c]); sdefl_put(dst, s, (int)s->cod.word.lit[c], s->cod.len.lit[c]);
} }
else sdefl_match(dst, s, -s->seq[i].off, s->seq[i].len); } else {
sdefl_match(dst, s, -s->seq[i].off, s->seq[i].len);
}
} }
sdefl_put(dst, s, (int)(s)->cod.word.lit[SDEFL_EOB], (s)->cod.len.lit[SDEFL_EOB]); sdefl_put(dst, s, (int)(s)->cod.word.lit[SDEFL_EOB], (s)->cod.len.lit[SDEFL_EOB]);
memset(&s->freq, 0, sizeof(s->freq)); memset(&s->freq, 0, sizeof(s->freq));
@ -579,12 +588,13 @@ sdefl_compr(struct sdefl *s, unsigned char *out, const unsigned char *in,
for (n = 0; n < SDEFL_HASH_SIZ; ++n) { for (n = 0; n < SDEFL_HASH_SIZ; ++n) {
s->tbl[n] = SDEFL_NIL; s->tbl[n] = SDEFL_NIL;
} }
do {int blk_end = i + SDEFL_BLK_MAX < in_len ? i + SDEFL_BLK_MAX : in_len; do {int blk_end = ((i + SDEFL_BLK_MAX) < in_len) ? (i + SDEFL_BLK_MAX) : in_len;
while (i < blk_end) { while (i < blk_end) {
struct sdefl_match m = {0}; struct sdefl_match m = {0};
int max_match = ((in_len-i)>SDEFL_MAX_MATCH) ? SDEFL_MAX_MATCH:(in_len-i); int left = blk_end - i;
int max_match = (left >= SDEFL_MAX_MATCH) ? SDEFL_MAX_MATCH : left;
int nice_match = pref[lvl] < max_match ? pref[lvl] : max_match; int nice_match = pref[lvl] < max_match ? pref[lvl] : max_match;
int run = 1, inc = 1, run_inc; int run = 1, inc = 1, run_inc = 0;
if (max_match > SDEFL_MIN_MATCH) { if (max_match > SDEFL_MIN_MATCH) {
sdefl_fnd(&m, s, max_chain, max_match, in, i); sdefl_fnd(&m, s, max_chain, max_match, in, i);
} }
@ -615,9 +625,11 @@ sdefl_compr(struct sdefl *s, unsigned char *out, const unsigned char *in,
unsigned h = sdefl_hash32(&in[i]); unsigned h = sdefl_hash32(&in[i]);
s->prv[i&SDEFL_WIN_MSK] = s->tbl[h]; s->prv[i&SDEFL_WIN_MSK] = s->tbl[h];
s->tbl[h] = i, i += inc; s->tbl[h] = i, i += inc;
assert(i <= blk_end);
} }
} else { } else {
i += run_inc; i += run_inc;
assert(i <= blk_end);
} }
} }
if (litlen) { if (litlen) {
@ -627,8 +639,9 @@ sdefl_compr(struct sdefl *s, unsigned char *out, const unsigned char *in,
sdefl_flush(&q, s, blk_end == in_len, in); sdefl_flush(&q, s, blk_end == in_len, in);
} while (i < in_len); } while (i < in_len);
if (s->bitcnt) if (s->bitcnt > 0)
sdefl_put(&q, s, 0x00, 8 - s->bitcnt); sdefl_put(&q, s, 0x00, 8 - s->bitcnt);
return (int)(q - out); return (int)(q - out);
} }
extern int extern int

113
src/external/sinfl.h vendored
View File

@ -10,7 +10,7 @@ as needed to keep the implementation as concise as possible.
- Dual license with either MIT or public domain - Dual license with either MIT or public domain
- Small implementation - Small implementation
- Deflate: 525 LoC - Deflate: 525 LoC
- Inflate: 320 LoC - Inflate: 500 LoC
- Webassembly: - Webassembly:
- Deflate ~3.7 KB (~2.2KB compressed) - Deflate ~3.7 KB (~2.2KB compressed)
- Inflate ~3.6 KB (~2.2KB compressed) - Inflate ~3.6 KB (~2.2KB compressed)
@ -39,10 +39,10 @@ this file implementation in *one* C or C++ file to prevent collisions.
| zlib 1.2.11 -1 | 72 MB/s | 307 MB/s | 42298774 | 42.30 | | zlib 1.2.11 -1 | 72 MB/s | 307 MB/s | 42298774 | 42.30 |
| zlib 1.2.11 -6 | 24 MB/s | 313 MB/s | 36548921 | 36.55 | | zlib 1.2.11 -6 | 24 MB/s | 313 MB/s | 36548921 | 36.55 |
| zlib 1.2.11 -9 | 20 MB/s | 314 MB/s | 36475792 | 36.48 | | zlib 1.2.11 -9 | 20 MB/s | 314 MB/s | 36475792 | 36.48 |
| sdefl 1.0 -0 | 127 MB/s | 371 MB/s | 40004116 | 39.88 | | sdefl 1.0 -0 | 127 MB/s | 355 MB/s | 40004116 | 39.88 |
| sdefl 1.0 -1 | 111 MB/s | 398 MB/s | 38940674 | 38.82 | | sdefl 1.0 -1 | 111 MB/s | 413 MB/s | 38940674 | 38.82 |
| sdefl 1.0 -5 | 45 MB/s | 420 MB/s | 36577183 | 36.46 | | sdefl 1.0 -5 | 45 MB/s | 436 MB/s | 36577183 | 36.46 |
| sdefl 1.0 -7 | 38 MB/s | 423 MB/s | 36523781 | 36.41 | | sdefl 1.0 -7 | 38 MB/s | 432 MB/s | 36523781 | 36.41 |
| libdeflate 1.3 -1 | 147 MB/s | 667 MB/s | 39597378 | 39.60 | | libdeflate 1.3 -1 | 147 MB/s | 667 MB/s | 39597378 | 39.60 |
| libdeflate 1.3 -6 | 69 MB/s | 689 MB/s | 36648318 | 36.65 | | libdeflate 1.3 -6 | 69 MB/s | 689 MB/s | 36648318 | 36.65 |
| libdeflate 1.3 -9 | 13 MB/s | 672 MB/s | 35197141 | 35.20 | | libdeflate 1.3 -9 | 13 MB/s | 672 MB/s | 35197141 | 35.20 |
@ -52,8 +52,8 @@ this file implementation in *one* C or C++ file to prevent collisions.
Results on the [Silesia compression corpus](http://sun.aei.polsl.pl/~sdeor/index.php?page=silesia): Results on the [Silesia compression corpus](http://sun.aei.polsl.pl/~sdeor/index.php?page=silesia):
| File | Original | `sdefl 0` | `sdefl 5` | `sdefl 7` | | File | Original | `sdefl 0` | `sdefl 5` | `sdefl 7` |
| :------ | ---------: | -----------------: | ---------: | ----------: | | --------| -----------| -------------| ---------- | ------------|
| dickens | 10.192.446 | 4,260,187| 3,845,261| 3,833,657 | | dickens | 10.192.446 | 4,260,187 | 3,845,261 | 3,833,657 |
| mozilla | 51.220.480 | 20,774,706 | 19,607,009 | 19,565,867 | | mozilla | 51.220.480 | 20,774,706 | 19,607,009 | 19,565,867 |
| mr | 9.970.564 | 3,860,531 | 3,673,460 | 3,665,627 | | mr | 9.970.564 | 3,860,531 | 3,673,460 | 3,665,627 |
| nci | 33.553.445 | 4,030,283 | 3,094,526 | 3,006,075 | | nci | 33.553.445 | 4,030,283 | 3,094,526 | 3,006,075 |
@ -63,7 +63,7 @@ Results on the [Silesia compression corpus](http://sun.aei.polsl.pl/~sdeor/index
| samba | 21.606.400 | 6,121,797 | 5,462,670 | 5,450,762 | | samba | 21.606.400 | 6,121,797 | 5,462,670 | 5,450,762 |
| sao | 7.251.944 | 5,612,421 | 5,485,380 | 5,481,765 | | sao | 7.251.944 | 5,612,421 | 5,485,380 | 5,481,765 |
| webster | 41.458.703 | 13,972,648 | 12,059,432 | 11,991,421 | | webster | 41.458.703 | 13,972,648 | 12,059,432 | 11,991,421 |
| xml | 5.345.280 | 886,620| 674,009 | 662,141 | | xml | 5.345.280 | 886,620 | 674,009 | 662,141 |
| x-ray | 8.474.240 | 6,304,655 | 6,244,779 | 6,244,779 | | x-ray | 8.474.240 | 6,304,655 | 6,244,779 | 6,244,779 |
## License ## License
@ -151,7 +151,7 @@ extern int zsinflate(void *out, int cap, const void *in, int size);
#endif #endif
#ifndef SINFL_NO_SIMD #ifndef SINFL_NO_SIMD
#if __x86_64__ || defined(_WIN32) || defined(_WIN64) #if defined(__x86_64__) || defined(_WIN32) || defined(_WIN64)
#include <emmintrin.h> #include <emmintrin.h>
#define sinfl_char16 __m128i #define sinfl_char16 __m128i
#define sinfl_char16_ld(p) _mm_loadu_si128((const __m128i *)(void*)(p)) #define sinfl_char16_ld(p) _mm_loadu_si128((const __m128i *)(void*)(p))
@ -183,6 +183,18 @@ sinfl_read64(const void *p) {
memcpy(&n, p, 8); memcpy(&n, p, 8);
return n; return n;
} }
static void
sinfl_copy64(unsigned char **dst, unsigned char **src) {
unsigned long long n;
memcpy(&n, *src, 8);
memcpy(*dst, &n, 8);
*dst += 8, *src += 8;
}
static unsigned char*
sinfl_write64(unsigned char *dst, unsigned long long w) {
memcpy(dst, &w, 8);
return dst + 8;
}
#ifndef SINFL_NO_SIMD #ifndef SINFL_NO_SIMD
static unsigned char* static unsigned char*
sinfl_write128(unsigned char *dst, sinfl_char16 w) { sinfl_write128(unsigned char *dst, sinfl_char16 w) {
@ -195,25 +207,12 @@ sinfl_copy128(unsigned char **dst, unsigned char **src) {
sinfl_char16_str(*dst, n); sinfl_char16_str(*dst, n);
*dst += 16, *src += 16; *dst += 16, *src += 16;
} }
#else
static unsigned char*
sinfl_write64(unsigned char *dst, unsigned long long w) {
memcpy(dst, &w, 8);
return dst + 8;
}
static void
sinfl_copy64(unsigned char **dst, unsigned char **src) {
unsigned long long n;
memcpy(&n, *src, 8);
memcpy(*dst, &n, 8);
*dst += 8, *src += 8;
}
#endif #endif
static void static void
sinfl_refill(struct sinfl *s) { sinfl_refill(struct sinfl *s) {
s->bitbuf |= sinfl_read64(s->bitptr) << s->bitcnt; s->bitbuf |= sinfl_read64(s->bitptr) << s->bitcnt;
s->bitptr += (63 - s->bitcnt) >> 3; s->bitptr += (63 - s->bitcnt) >> 3;
s->bitcnt |= 56; /* bitcount is in range [56,63] */ s->bitcnt |= 56; /* bitcount in range [56,63] */
} }
static int static int
sinfl_peek(struct sinfl *s, int cnt) { sinfl_peek(struct sinfl *s, int cnt) {
@ -222,7 +221,7 @@ sinfl_peek(struct sinfl *s, int cnt) {
return s->bitbuf & ((1ull << cnt) - 1); return s->bitbuf & ((1ull << cnt) - 1);
} }
static void static void
sinfl_consume(struct sinfl *s, int cnt) { sinfl_eat(struct sinfl *s, int cnt) {
assert(cnt <= s->bitcnt); assert(cnt <= s->bitcnt);
s->bitbuf >>= cnt; s->bitbuf >>= cnt;
s->bitcnt -= cnt; s->bitcnt -= cnt;
@ -230,7 +229,7 @@ sinfl_consume(struct sinfl *s, int cnt) {
static int static int
sinfl__get(struct sinfl *s, int cnt) { sinfl__get(struct sinfl *s, int cnt) {
int res = sinfl_peek(s, cnt); int res = sinfl_peek(s, cnt);
sinfl_consume(s, cnt); sinfl_eat(s, cnt);
return res; return res;
} }
static int static int
@ -285,7 +284,7 @@ sinfl_build_subtbl(struct sinfl_gen *gen, unsigned *tbl, int tbl_bits,
while (1) { while (1) {
unsigned entry; unsigned entry;
int bit, stride, i; int bit, stride, i;
/* start new subtable */ /* start new sub-table */
if ((gen->word & ((1 << tbl_bits)-1)) != sub_prefix) { if ((gen->word & ((1 << tbl_bits)-1)) != sub_prefix) {
int used = 0; int used = 0;
sub_prefix = gen->word & ((1 << tbl_bits)-1); sub_prefix = gen->word & ((1 << tbl_bits)-1);
@ -299,7 +298,7 @@ sinfl_build_subtbl(struct sinfl_gen *gen, unsigned *tbl, int tbl_bits,
tbl_end = sub_start + (1 << sub_bits); tbl_end = sub_start + (1 << sub_bits);
tbl[sub_prefix] = (sub_start << 16) | 0x10 | (sub_bits & 0xf); tbl[sub_prefix] = (sub_start << 16) | 0x10 | (sub_bits & 0xf);
} }
/* fill subtable */ /* fill sub-table */
entry = (*gen->sorted << 16) | ((gen->len - tbl_bits) & 0xf); entry = (*gen->sorted << 16) | ((gen->len - tbl_bits) & 0xf);
gen->sorted++; gen->sorted++;
i = sub_start + (gen->word >> tbl_bits); i = sub_start + (gen->word >> tbl_bits);
@ -353,18 +352,17 @@ sinfl_build(unsigned *tbl, unsigned char *lens, int tbl_bits, int maxlen,
} }
static int static int
sinfl_decode(struct sinfl *s, const unsigned *tbl, int bit_len) { sinfl_decode(struct sinfl *s, const unsigned *tbl, int bit_len) {
sinfl_refill(s); int idx = sinfl_peek(s, bit_len);
{int idx = sinfl_peek(s, bit_len);
unsigned key = tbl[idx]; unsigned key = tbl[idx];
if (key & 0x10) { if (key & 0x10) {
/* sub-table lookup */ /* sub-table lookup */
int len = key & 0x0f; int len = key & 0x0f;
sinfl_consume(s, bit_len); sinfl_eat(s, bit_len);
idx = sinfl_peek(s, len); idx = sinfl_peek(s, len);
key = tbl[((key >> 16) & 0xffff) + (unsigned)idx]; key = tbl[((key >> 16) & 0xffff) + (unsigned)idx];
} }
sinfl_consume(s, key & 0x0f); sinfl_eat(s, key & 0x0f);
return (key >> 16) & 0x0fff;} return (key >> 16) & 0x0fff;
} }
static int static int
sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size) { sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size) {
@ -402,11 +400,11 @@ sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size)
} break; } break;
case stored: { case stored: {
/* uncompressed block */ /* uncompressed block */
int len; int len, nlen;
sinfl_refill(&s); sinfl_refill(&s);
sinfl__get(&s,s.bitcnt & 7); sinfl__get(&s,s.bitcnt & 7);
len = sinfl__get(&s,16); len = sinfl__get(&s,16);
//int nlen = sinfl__get(&s,16); // @raysan5: Unused variable? nlen = sinfl__get(&s,16);
in -= 2; s.bitcnt = 0; in -= 2; s.bitcnt = 0;
if (len > (e-in) || !len) if (len > (e-in) || !len)
@ -445,6 +443,7 @@ sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size)
/* decode code lengths */ /* decode code lengths */
for (n = 0; n < nlit + ndist;) { for (n = 0; n < nlit + ndist;) {
sinfl_refill(&s);
int sym = sinfl_decode(&s, hlens, 7); int sym = sinfl_decode(&s, hlens, 7);
switch (sym) {default: lens[n++] = (unsigned char)sym; break; switch (sym) {default: lens[n++] = (unsigned char)sym; break;
case 16: for (i=3+sinfl_get(&s,2);i;i--,n++) lens[n]=lens[n-1]; break; case 16: for (i=3+sinfl_get(&s,2);i;i--,n++) lens[n]=lens[n-1]; break;
@ -458,12 +457,33 @@ sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size)
} break; } break;
case blk: { case blk: {
/* decompress block */ /* decompress block */
while (1) {
sinfl_refill(&s);
int sym = sinfl_decode(&s, s.lits, 10); int sym = sinfl_decode(&s, s.lits, 10);
if (sym < 256) { if (sym < 256) {
/* literal */ /* literal */
if (sinfl_unlikely(out >= oe)) {
return (int)(out-o);
}
*out++ = (unsigned char)sym; *out++ = (unsigned char)sym;
} else if (sym > 256) {sym -= 257; /* match symbol */ sym = sinfl_decode(&s, s.lits, 10);
sinfl_refill(&s); if (sym < 256) {
*out++ = (unsigned char)sym;
continue;
}
}
if (sinfl_unlikely(sym == 256)) {
/* end of block */
if (last) return (int)(out-o);
state = hdr;
break;
}
/* match */
if (sym >= 286) {
/* length codes 286 and 287 must not appear in compressed data */
return (int)(out-o);
}
sym -= 257;
{int len = sinfl__get(&s, lbits[sym]) + lbase[sym]; {int len = sinfl__get(&s, lbits[sym]) + lbase[sym];
int dsym = sinfl_decode(&s, s.dsts, 8); int dsym = sinfl_decode(&s, s.dsts, 8);
int offs = sinfl__get(&s, dbits[dsym]) + dbase[dsym]; int offs = sinfl__get(&s, dbits[dsym]) + dbase[dsym];
@ -476,11 +496,17 @@ sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size)
#ifndef SINFL_NO_SIMD #ifndef SINFL_NO_SIMD
if (sinfl_likely(oe - out >= 16 * 3)) { if (sinfl_likely(oe - out >= 16 * 3)) {
if (offs >= 16) { if (offs >= 16) {
/* copy match */ /* simd copy match */
sinfl_copy128(&dst, &src); sinfl_copy128(&dst, &src);
sinfl_copy128(&dst, &src); sinfl_copy128(&dst, &src);
do sinfl_copy128(&dst, &src); do sinfl_copy128(&dst, &src);
while (dst < out); while (dst < out);
} else if (offs >= 8) {
/* word copy match */
sinfl_copy64(&dst, &src);
sinfl_copy64(&dst, &src);
do sinfl_copy64(&dst, &src);
while (dst < out);
} else if (offs == 1) { } else if (offs == 1) {
/* rle match copying */ /* rle match copying */
sinfl_char16 w = sinfl_char16_char(src[0]); sinfl_char16 w = sinfl_char16_char(src[0]);
@ -489,6 +515,7 @@ sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size)
do dst = sinfl_write128(dst, w); do dst = sinfl_write128(dst, w);
while (dst < out); while (dst < out);
} else { } else {
/* byte copy match */
*dst++ = *src++; *dst++ = *src++;
*dst++ = *src++; *dst++ = *src++;
do *dst++ = *src++; do *dst++ = *src++;
@ -498,7 +525,7 @@ sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size)
#else #else
if (sinfl_likely(oe - out >= 3 * 8 - 3)) { if (sinfl_likely(oe - out >= 3 * 8 - 3)) {
if (offs >= 8) { if (offs >= 8) {
/* copy match */ /* word copy match */
sinfl_copy64(&dst, &src); sinfl_copy64(&dst, &src);
sinfl_copy64(&dst, &src); sinfl_copy64(&dst, &src);
do sinfl_copy64(&dst, &src); do sinfl_copy64(&dst, &src);
@ -513,6 +540,7 @@ sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size)
do dst = sinfl_write64(dst, w); do dst = sinfl_write64(dst, w);
while (dst < out); while (dst < out);
} else { } else {
/* byte copy match */
*dst++ = *src++; *dst++ = *src++;
*dst++ = *src++; *dst++ = *src++;
do *dst++ = *src++; do *dst++ = *src++;
@ -524,13 +552,8 @@ sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size)
*dst++ = *src++; *dst++ = *src++;
*dst++ = *src++; *dst++ = *src++;
do *dst++ = *src++; do *dst++ = *src++;
while (dst < out);} while (dst < out);
} }}
} else {
/* end of block */
if (last) return (int)(out-o);
state = hdr;
break;
} }
} break;} } break;}
} }

View File

@ -555,7 +555,7 @@ int Vox_LoadFromMemory(unsigned char* pvoxData, unsigned int voxDataSize, VoxArr
version = ((unsigned int*)fileDataPtr)[0]; version = ((unsigned int*)fileDataPtr)[0];
fileDataPtr += 4; fileDataPtr += 4;
if (version != 150) if (version != 150 && version != 200)
{ {
return VOX_ERROR_FILE_VERSION_NOT_MATCH; //"MagicaVoxel version doesn't match" return VOX_ERROR_FILE_VERSION_NOT_MATCH; //"MagicaVoxel version doesn't match"
} }

View File

@ -133,12 +133,20 @@
// NOTE: MSVC C++ compiler does not support compound literals (C99 feature) // NOTE: MSVC C++ compiler does not support compound literals (C99 feature)
// Plain structures in C++ (without constructors) can be initialized with { } // Plain structures in C++ (without constructors) can be initialized with { }
// This is called aggregate initialization (C++11 feature)
#if defined(__cplusplus) #if defined(__cplusplus)
#define CLITERAL(type) type #define CLITERAL(type) type
#else #else
#define CLITERAL(type) (type) #define CLITERAL(type) (type)
#endif #endif
// Some compilers (mostly macos clang) default to C++98,
// where aggregate initialization can't be used
// So, give a more clear error stating how to fix this
#if !defined(_MSC_VER) && (defined(__cplusplus) && __cplusplus < 201103L)
#error "C++11 or later is required. Add -std=c++11"
#endif
// NOTE: We set some defines with some data types declared by raylib // NOTE: We set some defines with some data types declared by raylib
// Other modules (raymath, rlgl) also require some of those types, so, // Other modules (raymath, rlgl) also require some of those types, so,
// to be able to use those other modules as standalone (not depending on raylib) // to be able to use those other modules as standalone (not depending on raylib)
@ -1235,6 +1243,7 @@ RLAPI Image LoadImageFromScreen(void);
RLAPI bool IsImageReady(Image image); // Check if an image is ready RLAPI bool IsImageReady(Image image); // Check if an image is ready
RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM) RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM)
RLAPI bool ExportImage(Image image, const char *fileName); // Export image data to file, returns true on success RLAPI bool ExportImage(Image image, const char *fileName); // Export image data to file, returns true on success
RLAPI unsigned char *ExportImageToMemory(Image image, const char *fileType, int *fileSize); // Export image to memory buffer
RLAPI bool ExportImageAsCode(Image image, const char *fileName); // Export image as code file defining an array of bytes, returns true on success RLAPI bool ExportImageAsCode(Image image, const char *fileName); // Export image as code file defining an array of bytes, returns true on success
// Image generation functions // Image generation functions

View File

@ -465,10 +465,10 @@ void UpdateCamera(Camera *camera, int mode)
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.75f) 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.75f) CameraMoveRight(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_Y) >= 0.75f) 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.75f) CameraMoveRight(camera, CAMERA_MOVE_SPEED, moveInWorldPlane); if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X) >= 0.25f) CameraMoveRight(camera, CAMERA_MOVE_SPEED, moveInWorldPlane);
} }
//if (IsKeyDown(KEY_SPACE)) CameraMoveUp(camera, CAMERA_MOVE_SPEED); //if (IsKeyDown(KEY_SPACE)) CameraMoveUp(camera, CAMERA_MOVE_SPEED);

View File

@ -291,6 +291,7 @@
#if defined(PLATFORM_WEB) #if defined(PLATFORM_WEB)
#define GLFW_INCLUDE_ES2 // GLFW3: Enable OpenGL ES 2.0 (translated to WebGL) #define GLFW_INCLUDE_ES2 // GLFW3: Enable OpenGL ES 2.0 (translated to WebGL)
//#define GLFW_INCLUDE_ES3 // GLFW3: Enable OpenGL ES 3.0 (transalted to WebGL2?)
#include "GLFW/glfw3.h" // GLFW3: Windows, OpenGL context and Input management #include "GLFW/glfw3.h" // GLFW3: Windows, OpenGL context and Input management
#include <sys/time.h> // Required for: timespec, nanosleep(), select() - POSIX #include <sys/time.h> // Required for: timespec, nanosleep(), select() - POSIX
@ -2451,7 +2452,7 @@ VrStereoConfig LoadVrStereoConfig(VrDeviceInfo device)
{ {
VrStereoConfig config = { 0 }; VrStereoConfig config = { 0 };
if ((rlGetVersion() == RL_OPENGL_33) || (rlGetVersion() == RL_OPENGL_ES_20)) if ((rlGetVersion() == RL_OPENGL_33) || (rlGetVersion() >= RL_OPENGL_ES_20))
{ {
// Compute aspect ratio // Compute aspect ratio
float aspect = ((float)device.hResolution*0.5f)/(float)device.vResolution; float aspect = ((float)device.hResolution*0.5f)/(float)device.vResolution;
@ -3430,7 +3431,7 @@ unsigned char *CompressData(const unsigned char *data, int dataSize, int *compDa
struct sdefl sdefl = { 0 }; struct sdefl sdefl = { 0 };
int bounds = sdefl_bound(dataSize); int bounds = sdefl_bound(dataSize);
compData = (unsigned char *)RL_CALLOC(bounds, 1); compData = (unsigned char *)RL_CALLOC(bounds, 1);
*compDataSize = sdeflate(&sdefl, compData, data, dataSize, COMPRESSION_QUALITY_DEFLATE); // Compression level 8, same as stbwi *compDataSize = sdeflate(&sdefl, compData, data, dataSize, COMPRESSION_QUALITY_DEFLATE); // Compression level 8, same as stbiw
TRACELOG(LOG_INFO, "SYSTEM: Compress data: Original size: %i -> Comp. size: %i", dataSize, *compDataSize); TRACELOG(LOG_INFO, "SYSTEM: Compress data: Original size: %i -> Comp. size: %i", dataSize, *compDataSize);
#endif #endif
@ -4172,6 +4173,17 @@ static bool InitGraphicsDevice(int width, int height)
glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API); glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API);
#else #else
glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_NATIVE_CONTEXT_API); glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_NATIVE_CONTEXT_API);
#endif
}
else if (rlGetVersion() == RL_OPENGL_ES_30) // Request OpenGL ES 3.0 context
{
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
#if defined(PLATFORM_DESKTOP)
glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API);
#else
glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_NATIVE_CONTEXT_API);
#endif #endif
} }
@ -4543,7 +4555,7 @@ static bool InitGraphicsDevice(int width, int height)
const EGLint framebufferAttribs[] = const EGLint framebufferAttribs[] =
{ {
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, // Type of context support -> Required on RPI? EGL_RENDERABLE_TYPE, (rlGetVersion() == RL_OPENGL_ES_30)? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT, // Type of context support
#if defined(PLATFORM_DRM) #if defined(PLATFORM_DRM)
EGL_SURFACE_TYPE, EGL_WINDOW_BIT, // Don't use it on Android! EGL_SURFACE_TYPE, EGL_WINDOW_BIT, // Don't use it on Android!
#endif #endif

View File

@ -26,6 +26,7 @@
* #define GRAPHICS_API_OPENGL_33 * #define GRAPHICS_API_OPENGL_33
* #define GRAPHICS_API_OPENGL_43 * #define GRAPHICS_API_OPENGL_43
* #define GRAPHICS_API_OPENGL_ES2 * #define GRAPHICS_API_OPENGL_ES2
* #define GRAPHICS_API_OPENGL_ES3
* Use selected OpenGL graphics backend, should be supported by platform * Use selected OpenGL graphics backend, should be supported by platform
* Those preprocessor defines are only used on rlgl module, if OpenGL version is * Those preprocessor defines are only used on rlgl module, if OpenGL version is
* required by any other module, use rlGetVersion() to check it * required by any other module, use rlGetVersion() to check it
@ -147,7 +148,8 @@
!defined(GRAPHICS_API_OPENGL_21) && \ !defined(GRAPHICS_API_OPENGL_21) && \
!defined(GRAPHICS_API_OPENGL_33) && \ !defined(GRAPHICS_API_OPENGL_33) && \
!defined(GRAPHICS_API_OPENGL_43) && \ !defined(GRAPHICS_API_OPENGL_43) && \
!defined(GRAPHICS_API_OPENGL_ES2) !defined(GRAPHICS_API_OPENGL_ES2) && \
!defined(GRAPHICS_API_OPENGL_ES3)
#define GRAPHICS_API_OPENGL_33 #define GRAPHICS_API_OPENGL_33
#endif #endif
@ -178,6 +180,11 @@
#define GRAPHICS_API_OPENGL_33 #define GRAPHICS_API_OPENGL_33
#endif #endif
// OpenGL ES 3.0 uses OpenGL ES 2.0 functionality (and more)
#if defined(GRAPHICS_API_OPENGL_ES3)
#define GRAPHICS_API_OPENGL_ES2
#endif
// Support framebuffer objects by default // Support framebuffer objects by default
// NOTE: Some driver implementation do not support it, despite they should // NOTE: Some driver implementation do not support it, despite they should
#define RLGL_RENDER_TEXTURES_HINT #define RLGL_RENDER_TEXTURES_HINT
@ -382,7 +389,8 @@ typedef enum {
RL_OPENGL_21, // OpenGL 2.1 (GLSL 120) RL_OPENGL_21, // OpenGL 2.1 (GLSL 120)
RL_OPENGL_33, // OpenGL 3.3 (GLSL 330) RL_OPENGL_33, // OpenGL 3.3 (GLSL 330)
RL_OPENGL_43, // OpenGL 4.3 (using GLSL 330) RL_OPENGL_43, // OpenGL 4.3 (using GLSL 330)
RL_OPENGL_ES_20 // OpenGL ES 2.0 (GLSL 100) RL_OPENGL_ES_20, // OpenGL ES 2.0 (GLSL 100)
RL_OPENGL_ES_30 // OpenGL ES 3.0 (GLSL 300 es)
} rlGlVersion; } rlGlVersion;
// Trace log level // Trace log level
@ -1704,7 +1712,7 @@ void rlDisableFramebuffer(void)
// NOTE: One color buffer is always active by default // NOTE: One color buffer is always active by default
void rlActiveDrawBuffers(int count) void rlActiveDrawBuffers(int count)
{ {
#if (defined(GRAPHICS_API_OPENGL_33) && defined(RLGL_RENDER_TEXTURES_HINT)) #if ((defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES3)) && defined(RLGL_RENDER_TEXTURES_HINT))
// NOTE: Maximum number of draw buffers supported is implementation dependant, // NOTE: Maximum number of draw buffers supported is implementation dependant,
// it can be queried with glGet*() but it must be at least 8 // it can be queried with glGet*() but it must be at least 8
//GLint maxDrawBuffers = 0; //GLint maxDrawBuffers = 0;
@ -1716,6 +1724,16 @@ void rlActiveDrawBuffers(int count)
else else
{ {
unsigned int buffers[8] = { unsigned int buffers[8] = {
#if defined(GRAPHICS_API_OPENGL_ES3)
GL_COLOR_ATTACHMENT0_EXT,
GL_COLOR_ATTACHMENT1_EXT,
GL_COLOR_ATTACHMENT2_EXT,
GL_COLOR_ATTACHMENT3_EXT,
GL_COLOR_ATTACHMENT4_EXT,
GL_COLOR_ATTACHMENT5_EXT,
GL_COLOR_ATTACHMENT6_EXT,
GL_COLOR_ATTACHMENT7_EXT,
#else
GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT1,
GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT2,
@ -1724,9 +1742,14 @@ void rlActiveDrawBuffers(int count)
GL_COLOR_ATTACHMENT5, GL_COLOR_ATTACHMENT5,
GL_COLOR_ATTACHMENT6, GL_COLOR_ATTACHMENT6,
GL_COLOR_ATTACHMENT7, GL_COLOR_ATTACHMENT7,
#endif
}; };
#if defined(GRAPHICS_API_OPENGL_ES3)
glDrawBuffersEXT(count, buffers);
#else
glDrawBuffers(count, buffers); glDrawBuffers(count, buffers);
#endif
} }
} }
else TRACELOG(LOG_WARNING, "GL: One color buffer active by default"); else TRACELOG(LOG_WARNING, "GL: One color buffer active by default");
@ -2194,11 +2217,34 @@ void rlLoadExtensions(void *loader)
#endif // GRAPHICS_API_OPENGL_33 #endif // GRAPHICS_API_OPENGL_33
#if defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_ES3)
// Register supported extensions flags
// OpenGL ES 3.0 extensions supported by default
RLGL.ExtSupported.vao = true;
RLGL.ExtSupported.instancing = true;
RLGL.ExtSupported.texNPOT = true;
RLGL.ExtSupported.texFloat32 = true;
RLGL.ExtSupported.texDepth = true;
RLGL.ExtSupported.texDepthWebGL = true;
RLGL.ExtSupported.maxDepthBits = 24;
RLGL.ExtSupported.texAnisoFilter = true;
RLGL.ExtSupported.texMirrorClamp = true;
// TODO: Make sure that the ones above are actually present by default
// TODO: Check for these...
// RLGL.ExtSupported.texCompDXT
// RLGL.ExtSupported.texCompETC1
// RLGL.ExtSupported.texCompETC2
// RLGL.ExtSupported.texCompPVRT
// RLGL.ExtSupported.texCompASTC
// RLGL.ExtSupported.computeShader
// RLGL.ExtSupported.ssbo
// RLGL.ExtSupported.maxAnisotropyLevel
#elif defined(GRAPHICS_API_OPENGL_ES2)
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP)
// TODO: Support 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 ES2.0 loaded successfully"); else TRACELOG(RL_LOG_INFO, "GLAD: OpenGL ES 2.0 loaded successfully");
#endif #endif
// Get supported extensions list // Get supported extensions list
@ -2389,15 +2435,17 @@ int rlGetVersion(void)
#endif #endif
#if defined(GRAPHICS_API_OPENGL_21) #if defined(GRAPHICS_API_OPENGL_21)
glVersion = RL_OPENGL_21; glVersion = RL_OPENGL_21;
#elif defined(GRAPHICS_API_OPENGL_43)
glVersion = RL_OPENGL_43;
#elif defined(GRAPHICS_API_OPENGL_33) #elif defined(GRAPHICS_API_OPENGL_33)
glVersion = RL_OPENGL_33; glVersion = RL_OPENGL_33;
#endif #endif
#if defined(GRAPHICS_API_OPENGL_43) #if defined(GRAPHICS_API_OPENGL_ES3)
glVersion = RL_OPENGL_43; glVersion = RL_OPENGL_ES_30;
#endif #elif defined(GRAPHICS_API_OPENGL_ES2)
#if defined(GRAPHICS_API_OPENGL_ES2)
glVersion = RL_OPENGL_ES_20; glVersion = RL_OPENGL_ES_20;
#endif #endif
return glVersion; return glVersion;
} }
@ -3047,7 +3095,7 @@ unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer)
// Possible formats: GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT32 and GL_DEPTH_COMPONENT32F // Possible formats: GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT32 and GL_DEPTH_COMPONENT32F
unsigned int glInternalFormat = GL_DEPTH_COMPONENT; unsigned int glInternalFormat = GL_DEPTH_COMPONENT;
#if defined(GRAPHICS_API_OPENGL_ES2) #if (defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_ES3))
// WARNING: WebGL platform requires unsized internal format definition (GL_DEPTH_COMPONENT) // WARNING: WebGL platform requires unsized internal format definition (GL_DEPTH_COMPONENT)
// while other platforms using OpenGL ES 2.0 require/support sized internal formats depending on the GPU capabilities // while other platforms using OpenGL ES 2.0 require/support sized internal formats depending on the GPU capabilities
if (!RLGL.ExtSupported.texDepthWebGL || useRenderBuffer) if (!RLGL.ExtSupported.texDepthWebGL || useRenderBuffer)
@ -3204,10 +3252,16 @@ void rlGetGlTextureFormats(int format, unsigned int *glInternalFormat, unsigned
case RL_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_UNSIGNED_SHORT_4_4_4_4; break; case RL_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_UNSIGNED_SHORT_4_4_4_4; break;
case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_UNSIGNED_BYTE; break; case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_UNSIGNED_BYTE; break;
#if !defined(GRAPHICS_API_OPENGL_11) #if !defined(GRAPHICS_API_OPENGL_11)
#if defined(GRAPHICS_API_OPENGL_ES3)
case RL_PIXELFORMAT_UNCOMPRESSED_R32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_R32F_EXT; *glFormat = GL_RED_EXT; *glType = GL_FLOAT; break;
case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_RGB32F_EXT; *glFormat = GL_RGB; *glType = GL_FLOAT; break;
case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_RGBA32F_EXT; *glFormat = GL_RGBA; *glType = GL_FLOAT; break;
#else
case RL_PIXELFORMAT_UNCOMPRESSED_R32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_LUMINANCE; *glFormat = GL_LUMINANCE; *glType = GL_FLOAT; break; // NOTE: Requires extension OES_texture_float case RL_PIXELFORMAT_UNCOMPRESSED_R32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_LUMINANCE; *glFormat = GL_LUMINANCE; *glType = GL_FLOAT; break; // NOTE: Requires extension OES_texture_float
case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_RGB; *glFormat = GL_RGB; *glType = GL_FLOAT; break; // NOTE: Requires extension OES_texture_float case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_RGB; *glFormat = GL_RGB; *glType = GL_FLOAT; break; // NOTE: Requires extension OES_texture_float
case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_FLOAT; break; // NOTE: Requires extension OES_texture_float case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_FLOAT; break; // NOTE: Requires extension OES_texture_float
#endif #endif
#endif
#elif defined(GRAPHICS_API_OPENGL_33) #elif defined(GRAPHICS_API_OPENGL_33)
case RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: *glInternalFormat = GL_R8; *glFormat = GL_RED; *glType = GL_UNSIGNED_BYTE; break; case RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: *glInternalFormat = GL_R8; *glFormat = GL_RED; *glType = GL_UNSIGNED_BYTE; break;
case RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: *glInternalFormat = GL_RG8; *glFormat = GL_RG; *glType = GL_UNSIGNED_BYTE; break; case RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: *glInternalFormat = GL_RG8; *glFormat = GL_RG; *glType = GL_UNSIGNED_BYTE; break;

View File

@ -5201,7 +5201,9 @@ static Model LoadGLTF(const char *fileName)
model.meshes[meshIndex].animVertices = RL_CALLOC(model.meshes[meshIndex].vertexCount*3, sizeof(float)); model.meshes[meshIndex].animVertices = RL_CALLOC(model.meshes[meshIndex].vertexCount*3, sizeof(float));
memcpy(model.meshes[meshIndex].animVertices, model.meshes[meshIndex].vertices, model.meshes[meshIndex].vertexCount*3*sizeof(float)); memcpy(model.meshes[meshIndex].animVertices, model.meshes[meshIndex].vertices, model.meshes[meshIndex].vertexCount*3*sizeof(float));
model.meshes[meshIndex].animNormals = RL_CALLOC(model.meshes[meshIndex].vertexCount*3, sizeof(float)); model.meshes[meshIndex].animNormals = RL_CALLOC(model.meshes[meshIndex].vertexCount*3, sizeof(float));
if (model.meshes[meshIndex].normals != NULL) {
memcpy(model.meshes[meshIndex].animNormals, model.meshes[meshIndex].normals, model.meshes[meshIndex].vertexCount*3*sizeof(float)); memcpy(model.meshes[meshIndex].animNormals, model.meshes[meshIndex].normals, model.meshes[meshIndex].vertexCount*3*sizeof(float));
}
meshIndex++; // Move to next mesh meshIndex++; // Move to next mesh
} }

View File

@ -605,6 +605,34 @@ bool ExportImage(Image image, const char *fileName)
return success; return success;
} }
// Export image to memory buffer
unsigned char *ExportImageToMemory(Image image, const char *fileType, int *dataSize)
{
unsigned char *fileData = NULL;
*dataSize = 0;
if ((image.width == 0) || (image.height == 0) || (image.data == NULL)) return NULL;
#if defined(SUPPORT_IMAGE_EXPORT)
int channels = 4;
if (image.format == PIXELFORMAT_UNCOMPRESSED_GRAYSCALE) channels = 1;
else if (image.format == PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA) channels = 2;
else if (image.format == PIXELFORMAT_UNCOMPRESSED_R8G8B8) channels = 3;
else if (image.format == PIXELFORMAT_UNCOMPRESSED_R8G8B8A8) channels = 4;
#if defined(SUPPORT_FILEFORMAT_PNG)
if ((strcmp(fileType, ".png") == 0) || (strcmp(fileType, ".PNG") == 0))
{
fileData = stbi_write_png_to_mem((const unsigned char *)image.data, image.width*channels, image.width, image.height, channels, dataSize);
}
#endif
#endif
return fileData;
}
// Export image as code file (.h) defining an array of bytes // Export image as code file (.h) defining an array of bytes
bool ExportImageAsCode(Image image, const char *fileName) bool ExportImageAsCode(Image image, const char *fileName)
{ {
@ -1013,7 +1041,7 @@ Image ImageCopy(Image image)
if (height < 1) height = 1; if (height < 1) height = 1;
} }
newImage.data = RL_MALLOC(size); newImage.data = RL_CALLOC(size, 1);
if (newImage.data != NULL) if (newImage.data != NULL)
{ {
@ -2128,27 +2156,27 @@ void ImageRotate(Image *image, int degrees)
if (image->format >= PIXELFORMAT_COMPRESSED_DXT1_RGB) TRACELOG(LOG_WARNING, "Image manipulation not supported for compressed formats"); if (image->format >= PIXELFORMAT_COMPRESSED_DXT1_RGB) TRACELOG(LOG_WARNING, "Image manipulation not supported for compressed formats");
else else
{ {
float rad = degrees * PI / 180.0f; float rad = degrees*PI/180.0f;
float sinRadius = sin(rad); float sinRadius = sin(rad);
float cosRadius = cos(rad); float cosRadius = cos(rad);
int width = abs(image->width * cosRadius) + abs(image->height * sinRadius); int width = fabsf(image->width*cosRadius) + fabsf(image->height*sinRadius);
int height = abs(image->height * cosRadius) + abs(image->width * sinRadius); int height = fabsf(image->height*cosRadius) + fabsf(image->width*sinRadius);
int bytesPerPixel = GetPixelDataSize(1, 1, image->format); int bytesPerPixel = GetPixelDataSize(1, 1, image->format);
unsigned char *rotatedData = (unsigned char *)RL_CALLOC(width * height, bytesPerPixel); unsigned char *rotatedData = (unsigned char *)RL_CALLOC(width*height, bytesPerPixel);
for (int y = 0; y < height; y++) for (int y = 0; y < height; y++)
{ {
for (int x = 0; x < width; x++) for (int x = 0; x < width; x++)
{ {
float oldX = ((x - width / 2.0f) * cosRadius + (y - height / 2.0f) * sinRadius) + image->width / 2.0f; float oldX = ((x - width/2.0f)*cosRadius + (y - height/2.0f)*sinRadius) + image->width/2.0f;
float oldY = ((y - height / 2.0f) * cosRadius - (x - width / 2.0f) * sinRadius) + image->height / 2.0f; float oldY = ((y - height/2.0f)*cosRadius - (x - width/2.0f)*sinRadius) + image->height/2.0f;
if (oldX >= 0 && oldX < image->width && oldY >= 0 && oldY < image->height) if ((oldX >= 0) && (oldX < image->width) && (oldY >= 0) && (oldY < image->height))
{ {
int x1 = (int)floor(oldX); int x1 = (int)floorf(oldX);
int y1 = (int)floor(oldY); int y1 = (int)floorf(oldY);
int x2 = MIN(x1 + 1, image->width - 1); int x2 = MIN(x1 + 1, image->width - 1);
int y2 = MIN(y1 + 1, image->height - 1); int y2 = MIN(y1 + 1, image->height - 1);
@ -2157,14 +2185,14 @@ void ImageRotate(Image *image, int degrees)
for (int i = 0; i < bytesPerPixel; i++) for (int i = 0; i < bytesPerPixel; i++)
{ {
float f1 = ((unsigned char *)image->data)[(y1 * image->width + x1) * bytesPerPixel + i]; float f1 = ((unsigned char *)image->data)[(y1*image->width + x1)*bytesPerPixel + i];
float f2 = ((unsigned char *)image->data)[(y1 * image->width + x2) * bytesPerPixel + i]; float f2 = ((unsigned char *)image->data)[(y1*image->width + x2)*bytesPerPixel + i];
float f3 = ((unsigned char *)image->data)[(y2 * image->width + x1) * bytesPerPixel + i]; float f3 = ((unsigned char *)image->data)[(y2*image->width + x1)*bytesPerPixel + i];
float f4 = ((unsigned char *)image->data)[(y2 * image->width + x2) * bytesPerPixel + i]; float f4 = ((unsigned char *)image->data)[(y2*image->width + x2)*bytesPerPixel + i];
float val = f1 * (1 - px) * (1 - py) + f2 * px * (1 - py) + f3 * (1 - px) * py + f4 * px * py; float val = f1*(1 - px)*(1 - py) + f2*px*(1 - py) + f3*(1 - px)*py + f4*px*py;
rotatedData[(y * width + x) * bytesPerPixel + i] = (unsigned char)val; rotatedData[(y*width + x)*bytesPerPixel + i] = (unsigned char)val;
} }
} }
} }