diff --git a/.github/workflows/analyze_codeql.yml b/.github/workflows/analyze_codeql.yml
index 98d32a499..5fd169dd0 100644
--- a/.github/workflows/analyze_codeql.yml
+++ b/.github/workflows/analyze_codeql.yml
@@ -71,7 +71,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
- uses: github/codeql-action/init@v2
+ uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -90,7 +90,7 @@ jobs:
cmake --build . --config $BUILD_TYPE
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v2
+ uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"
upload: false
diff --git a/.github/workflows/parse_api.yml b/.github/workflows/parse_api.yml
index c8665e1d4..e095e4a55 100644
--- a/.github/workflows/parse_api.yml
+++ b/.github/workflows/parse_api.yml
@@ -14,7 +14,7 @@ jobs:
- uses: actions/checkout@v4
- name: Update parse files
- working-directory: tools/parser
+ working-directory: tools/rlparser
run: |
make raylib_api
mv raylib_api.* output
@@ -22,7 +22,7 @@ jobs:
- name: Diff parse files
id: diff
run: |
- git add -N tools/parser
+ git add -N tools/rlparser
git diff --name-only --exit-code
continue-on-error: true
@@ -32,6 +32,6 @@ jobs:
set -x
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
- git add tools/parser
- git commit -m "Update raylib_api.* by CI"
+ git add tools/rlparser
+ git commit -m "rlparser: update raylib_api.* by CI"
git push
diff --git a/.gitignore b/.gitignore
index ac4f016e4..fa4c4c49d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -55,6 +55,8 @@ packages/
*.so
*.so.*
*.dll
+*.h.pch
+./*.obj
# Emscripten
emsdk
@@ -81,6 +83,7 @@ DerivedData/
# VSCode project
.vscode
+.clangd
# Jetbrains project
.idea/
diff --git a/build.zig b/build.zig
index a8f0df618..031a6824d 100644
--- a/build.zig
+++ b/build.zig
@@ -386,6 +386,8 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
setDesktopPlatform(raylib, options.platform);
},
.emscripten => {
+ const activate_emsdk_step = emsdk.zemscripten.activateEmsdkStep(b);
+ raylib.step.dependOn(activate_emsdk_step);
raylib.root_module.addCMacro("PLATFORM_WEB", "");
if (options.opengl_version == .auto) {
raylib.root_module.addCMacro("GRAPHICS_API_OPENGL_ES3", "");
diff --git a/examples/Makefile b/examples/Makefile
index ec0d2e696..eb6725756 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -512,9 +512,11 @@ CORE = \
core/core_automation_events \
core/core_basic_screen_manager \
core/core_basic_window \
+ core/core_clipboard_text \
core/core_custom_frame_control \
core/core_custom_logging \
core/core_delta_time \
+ core/core_directory_files \
core/core_drop_files \
core/core_high_dpi \
core/core_input_actions \
@@ -545,6 +547,7 @@ SHAPES = \
shapes/shapes_bouncing_ball \
shapes/shapes_bullet_hell \
shapes/shapes_circle_sector_drawing \
+ shapes/shapes_clock_of_clocks \
shapes/shapes_collision_area \
shapes/shapes_colors_palette \
shapes/shapes_dashed_line \
@@ -554,17 +557,23 @@ SHAPES = \
shapes/shapes_easings_box \
shapes/shapes_easings_rectangles \
shapes/shapes_following_eyes \
+ shapes/shapes_kaleidoscope \
shapes/shapes_lines_bezier \
shapes/shapes_logo_raylib \
shapes/shapes_logo_raylib_anim \
+ shapes/shapes_mouse_trail \
+ shapes/shapes_pie_chart \
shapes/shapes_rectangle_advanced \
shapes/shapes_rectangle_scaling \
+ shapes/shapes_recursive_tree \
shapes/shapes_ring_drawing \
shapes/shapes_rounded_rectangle_drawing \
+ shapes/shapes_simple_particles \
shapes/shapes_splines_drawing \
+ shapes/shapes_starfield \
shapes/shapes_top_down_lights \
- shapes/shapes_vector_angle \
- shapes/shapes_translation_rotation_scale
+ shapes/shapes_triangle_strip \
+ shapes/shapes_vector_angle
TEXTURES = \
textures/textures_background_scrolling \
@@ -608,6 +617,7 @@ TEXT = \
text/text_sprite_fonts \
text/text_unicode_emojis \
text/text_unicode_ranges \
+ text/text_words_alignment \
text/text_writing_anim
MODELS = \
diff --git a/examples/Makefile.Web b/examples/Makefile.Web
index 3817c421d..e365a5fee 100644
--- a/examples/Makefile.Web
+++ b/examples/Makefile.Web
@@ -512,9 +512,11 @@ CORE = \
core/core_automation_events \
core/core_basic_screen_manager \
core/core_basic_window \
+ core/core_clipboard_text \
core/core_custom_frame_control \
core/core_custom_logging \
core/core_delta_time \
+ core/core_directory_files \
core/core_drop_files \
core/core_high_dpi \
core/core_input_actions \
@@ -545,6 +547,7 @@ SHAPES = \
shapes/shapes_bouncing_ball \
shapes/shapes_bullet_hell \
shapes/shapes_circle_sector_drawing \
+ shapes/shapes_clock_of_clocks \
shapes/shapes_collision_area \
shapes/shapes_colors_palette \
shapes/shapes_dashed_line \
@@ -554,17 +557,23 @@ SHAPES = \
shapes/shapes_easings_box \
shapes/shapes_easings_rectangles \
shapes/shapes_following_eyes \
+ shapes/shapes_kaleidoscope \
shapes/shapes_lines_bezier \
shapes/shapes_logo_raylib \
shapes/shapes_logo_raylib_anim \
+ shapes/shapes_mouse_trail \
+ shapes/shapes_pie_chart \
shapes/shapes_rectangle_advanced \
shapes/shapes_rectangle_scaling \
+ shapes/shapes_recursive_tree \
shapes/shapes_ring_drawing \
shapes/shapes_rounded_rectangle_drawing \
+ shapes/shapes_simple_particles \
shapes/shapes_splines_drawing \
+ shapes/shapes_starfield \
shapes/shapes_top_down_lights \
- shapes/shapes_vector_angle \
- shapes/shapes_translation_rotation_scale
+ shapes/shapes_triangle_strip \
+ shapes/shapes_vector_angle
TEXTURES = \
textures/textures_background_scrolling \
@@ -608,6 +617,7 @@ TEXT = \
text/text_sprite_fonts \
text/text_unicode_emojis \
text/text_unicode_ranges \
+ text/text_words_alignment \
text/text_writing_anim
MODELS = \
@@ -730,6 +740,9 @@ core/core_basic_screen_manager: core/core_basic_screen_manager.c
core/core_basic_window: core/core_basic_window.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+core/core_clipboard_text: core/core_clipboard_text.c
+ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+
core/core_custom_frame_control: core/core_custom_frame_control.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
@@ -739,6 +752,9 @@ core/core_custom_logging: core/core_custom_logging.c
core/core_delta_time: core/core_delta_time.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+core/core_directory_files: core/core_directory_files.c
+ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+
core/core_drop_files: core/core_drop_files.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
@@ -827,6 +843,9 @@ shapes/shapes_bullet_hell: shapes/shapes_bullet_hell.c
shapes/shapes_circle_sector_drawing: shapes/shapes_circle_sector_drawing.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+shapes/shapes_clock_of_clocks: shapes/shapes_clock_of_clocks.c
+ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+
shapes/shapes_collision_area: shapes/shapes_collision_area.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
@@ -854,6 +873,9 @@ shapes/shapes_easings_rectangles: shapes/shapes_easings_rectangles.c
shapes/shapes_following_eyes: shapes/shapes_following_eyes.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+shapes/shapes_kaleidoscope: shapes/shapes_kaleidoscope.c
+ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+
shapes/shapes_lines_bezier: shapes/shapes_lines_bezier.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
@@ -863,24 +885,42 @@ shapes/shapes_logo_raylib: shapes/shapes_logo_raylib.c
shapes/shapes_logo_raylib_anim: shapes/shapes_logo_raylib_anim.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+shapes/shapes_mouse_trail: shapes/shapes_mouse_trail.c
+ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+
+shapes/shapes_pie_chart: shapes/shapes_pie_chart.c
+ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+
shapes/shapes_rectangle_advanced: shapes/shapes_rectangle_advanced.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
shapes/shapes_rectangle_scaling: shapes/shapes_rectangle_scaling.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+shapes/shapes_recursive_tree: shapes/shapes_recursive_tree.c
+ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+
shapes/shapes_ring_drawing: shapes/shapes_ring_drawing.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
shapes/shapes_rounded_rectangle_drawing: shapes/shapes_rounded_rectangle_drawing.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+shapes/shapes_simple_particles: shapes/shapes_simple_particles.c
+ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+
shapes/shapes_splines_drawing: shapes/shapes_splines_drawing.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+shapes/shapes_starfield: shapes/shapes_starfield.c
+ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+
shapes/shapes_top_down_lights: shapes/shapes_top_down_lights.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+shapes/shapes_triangle_strip: shapes/shapes_triangle_strip.c
+ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+
shapes/shapes_vector_angle: shapes/shapes_vector_angle.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
@@ -1057,6 +1097,9 @@ text/text_unicode_ranges: text/text_unicode_ranges.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file text/resources/NotoSansTC-Regular.ttf@resources/NotoSansTC-Regular.ttf
+text/text_words_alignment: text/text_words_alignment.c
+ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+
text/text_writing_anim: text/text_writing_anim.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
diff --git a/examples/README.md b/examples/README.md
index 70e07df2b..e8b6ba4bf 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -17,9 +17,9 @@ You may find it easier to use than other toolchains, especially when it comes to
- `zig build [module]` to compile all examples for a module (e.g. `zig build core`)
- `zig build [example]` to compile _and run_ a particular example (e.g. `zig build core_basic_window`)
-## EXAMPLES COLLECTION [TOTAL: 172]
+## EXAMPLES COLLECTION [TOTAL: 183]
-### category: core [40]
+### category: core [42]
Examples using raylib[core](../src/rcore.c) platform functionality like window creation, inputs, drawing modes and system functionality.
@@ -65,8 +65,10 @@ Examples using raylib[core](../src/rcore.c) platform functionality like window c
| [core_render_texture](core/core_render_texture.c) |
| ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
| [core_undo_redo](core/core_undo_redo.c) |
| ⭐⭐⭐☆ | 5.5 | 5.6 | [Ramon Santamaria](https://github.com/raysan5) |
| [core_input_actions](core/core_input_actions.c) |
| ⭐⭐☆☆ | 5.5 | 5.6 | [Jett](https://github.com/JettMonstersGoBoom) |
+| [core_directory_files](core/core_directory_files.c) |
| ⭐☆☆☆ | 5.5 | 5.6 | [Hugo ARNAL](https://github.com/hugoarnal) |
+| [core_clipboard_text](core/core_clipboard_text.c) |
| ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Robin](https://github.com/RobinsAviary) |
-### category: shapes [23]
+### category: shapes [31]
Examples using raylib shapes drawing functionality, provided by raylib [shapes](../src/rshapes.c) module.
@@ -85,6 +87,7 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes](
| [shapes_easings_ball](shapes/shapes_easings_ball.c) |
| ⭐⭐☆☆ | 2.5 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
| [shapes_easings_box](shapes/shapes_easings_box.c) |
| ⭐⭐☆☆ | 2.5 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
| [shapes_easings_rectangles](shapes/shapes_easings_rectangles.c) |
| ⭐⭐⭐☆ | 2.0 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
+| [shapes_recursive_tree](shapes/shapes_recursive_tree.c) |
| ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [Jopestpe](https://github.com/jopestpe) |
| [shapes_ring_drawing](shapes/shapes_ring_drawing.c) |
| ⭐⭐⭐☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
| [shapes_circle_sector_drawing](shapes/shapes_circle_sector_drawing.c) |
| ⭐⭐⭐☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
| [shapes_rounded_rectangle_drawing](shapes/shapes_rounded_rectangle_drawing.c) |
| ⭐⭐⭐☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
@@ -94,7 +97,14 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes](
| [shapes_digital_clock](shapes/shapes_digital_clock.c) |
| ⭐⭐⭐⭐️ | 5.5 | 5.6 | [Hamza RAHAL](https://github.com/hmz-rhl) |
| [shapes_double_pendulum](shapes/shapes_double_pendulum.c) |
| ⭐⭐☆☆ | 5.5 | 5.5 | [JoeCheong](https://github.com/Joecheong2006) |
| [shapes_dashed_line](shapes/shapes_dashed_line.c) |
| ⭐☆☆☆ | 5.5 | 5.5 | [Luís Almeida](https://github.com/luis605) |
+| [shapes_triangle_strip](shapes/shapes_triangle_strip.c) |
| ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Jopestpe](https://github.com/jopestpe) |
| [shapes_vector_angle](shapes/shapes_vector_angle.c) |
| ⭐⭐☆☆ | 1.0 | 5.0 | [Ramon Santamaria](https://github.com/raysan5) |
+| [shapes_pie_chart](shapes/shapes_pie_chart.c) |
| ⭐☆☆☆ | 5.5 | 5.6 | [Gideon Serfontein](https://github.com/GideonSerf) |
+| [shapes_kaleidoscope](shapes/shapes_kaleidoscope.c) |
| ⭐⭐☆☆ | 5.5 | 5.6 | [Hugo ARNAL](https://github.com/hugoarnal) |
+| [shapes_clock_of_clocks](shapes/shapes_clock_of_clocks.c) |
| ⭐⭐☆☆ | 5.5 | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) |
+| [shapes_mouse_trail](shapes/shapes_mouse_trail.c) |
| ⭐☆☆☆ | 5.6 | 5.6-dev | [[Balamurugan R]](https://github.com/[Bala050814]) |
+| [shapes_simple_particles](shapes/shapes_simple_particles.c) |
| ⭐☆☆☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) |
+| [shapes_starfield](shapes/shapes_starfield.c) |
| ⭐☆☆☆ | 5.5 | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) |
### category: textures [26]
@@ -129,7 +139,7 @@ Examples using raylib textures functionality, including image/textures loading/g
| [textures_image_rotate](textures/textures_image_rotate.c) |
| ⭐⭐☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) |
| [textures_textured_curve](textures/textures_textured_curve.c) |
| ⭐⭐⭐☆ | 4.5 | 4.5 | [Jeffery Myers](https://github.com/JeffM2501) |
-### category: text [14]
+### category: text [15]
Examples using raylib text functionality, including sprite fonts loading/generation and text drawing, provided by raylib [text](../src/rtext.c) module.
@@ -145,10 +155,11 @@ Examples using raylib text functionality, including sprite fonts loading/generat
| [text_writing_anim](text/text_writing_anim.c) |
| ⭐⭐☆☆ | 1.4 | 1.4 | [Ramon Santamaria](https://github.com/raysan5) |
| [text_rectangle_bounds](text/text_rectangle_bounds.c) |
| ⭐⭐⭐⭐️ | 2.5 | 4.0 | [Vlad Adrian](https://github.com/demizdor) |
| [text_unicode_emojis](text/text_unicode_emojis.c) |
| ⭐⭐⭐⭐️ | 2.5 | 4.0 | [Vlad Adrian](https://github.com/demizdor) |
-| [text_unicode_ranges](text/text_unicode_ranges.c) |
| ⭐⭐⭐⭐️ | 5.5 | 5.6 | [Vlad Adrian](https://github.com/demizdor) |
+| [text_unicode_ranges](text/text_unicode_ranges.c) |
| ⭐⭐⭐⭐️ | 5.5 | 5.6 | [Vadim Gunko](https://github.com/GuvaCode) |
| [text_3d_drawing](text/text_3d_drawing.c) |
| ⭐⭐⭐⭐️ | 3.5 | 4.0 | [Vlad Adrian](https://github.com/demizdor) |
| [text_codepoints_loading](text/text_codepoints_loading.c) |
| ⭐⭐⭐☆ | 4.2 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
| [text_inline_styling](text/text_inline_styling.c) |
| ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [Wagner Barongello](https://github.com/SultansOfCode) |
+| [text_words_alignment](text/text_words_alignment.c) |
| ⭐☆☆☆ | 5.6-dev | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) |
### category: models [25]
diff --git a/examples/audio/audio_sound_positioning.c b/examples/audio/audio_sound_positioning.c
index 69756fa23..4d29954f6 100644
--- a/examples/audio/audio_sound_positioning.c
+++ b/examples/audio/audio_sound_positioning.c
@@ -60,7 +60,7 @@ int main(void)
//----------------------------------------------------------------------------------
UpdateCamera(&camera, CAMERA_FREE);
- float th = GetTime();
+ float th = (float)GetTime();
Vector3 spherePos = {
.x = 5.0f*cosf(th),
diff --git a/examples/core/core_3d_camera_fps.c b/examples/core/core_3d_camera_fps.c
index c3c779431..7aa79c174 100644
--- a/examples/core/core_3d_camera_fps.c
+++ b/examples/core/core_3d_camera_fps.c
@@ -198,8 +198,8 @@ void UpdateBody(Body *body, float rot, char side, char forward, bool jumpPressed
//PlaySound(fxJump);
}
- Vector3 front = (Vector3){ sin(rot), 0.f, cos(rot) };
- Vector3 right = (Vector3){ cos(-rot), 0.f, sin(-rot) };
+ Vector3 front = (Vector3){ sinf(rot), 0.f, cosf(rot) };
+ Vector3 right = (Vector3){ cosf(-rot), 0.f, sinf(-rot) };
Vector3 desiredDir = (Vector3){ input.x*right.x + input.y*front.x, 0.0f, input.x*right.z + input.y*front.z, };
body->dir = Vector3Lerp(body->dir, desiredDir, CONTROL*delta);
@@ -267,8 +267,8 @@ static void UpdateCameraFPS(Camera *camera)
// Head animation
// Rotate up direction around forward axis
- float headSin = sin(headTimer*PI);
- float headCos = cos(headTimer*PI);
+ float headSin = sinf(headTimer*PI);
+ float headCos = cosf(headTimer*PI);
const float stepRotation = 0.01f;
camera->up = Vector3RotateByAxisAngle(up, pitch, headSin*stepRotation + lean.x);
diff --git a/examples/core/core_clipboard_text.c b/examples/core/core_clipboard_text.c
new file mode 100644
index 000000000..2be64154b
--- /dev/null
+++ b/examples/core/core_clipboard_text.c
@@ -0,0 +1,208 @@
+/*******************************************************************************************
+*
+* raylib [core] example - clipboard text
+*
+* Example complexity rating: [★☆☆☆] 1/4
+*
+* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
+*
+* Example contributed by Robin (@RobinsAviary) 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) 2025 Robin (@RobinsAviary)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#include
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [core] example - clipboard text");
+
+ const char* clipboardText = NULL;
+
+ // List of text the user can switch through and copy
+ const char* copyableText[] = {"raylib is fun", "hello, clipboard!", "potato chips"};
+
+ unsigned int textIndex = 0;
+
+ const char* popupText = NULL;
+
+ // Initialize timers
+ // The amount of time the pop-up text is on screen, before fading
+ const float maxTime = 3.0f;
+ float textTimer = 0.0f;
+ // The length of time text is offset
+ const float animMaxTime = 0.1f;
+ float pasteAnim = 0.0f;
+ float copyAnim = 0.0f;
+ int copyAnimMult = 1;
+ float textAnim = 0.0f;
+ float textAlpha = 0.0f;
+ // Offset amount for animations
+ const int offsetAmount = -4;
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ // Check if the user has pressed the copy/paste key combinations
+ bool pastePressed = (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_V));
+ bool copyPressed = (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_C));
+
+ // Update animation timers
+ if (textTimer > 0) textTimer -= GetFrameTime();
+ if (pasteAnim > 0) pasteAnim -= GetFrameTime();
+ if (copyAnim > 0) copyAnim -= GetFrameTime();
+ if (textAnim > 0) textAnim -= GetFrameTime();
+
+ // React to the user pressing paste
+ if (pastePressed)
+ {
+ // Most operating systems hide this information until the user presses Ctrl-V on the window.
+
+ // Check to see if the clipboard contains an image
+ // This function does nothing outside of Windows, as it directly calls the Windows API
+ Image image = GetClipboardImage();
+
+ if (IsImageValid(image))
+ {
+ // Unload the image
+ UnloadImage(image);
+ // Update visuals
+ popupText = "clipboard contains image";
+ }
+ else
+ {
+ // Get text from the user's clipboard
+ clipboardText = GetClipboardText();
+
+ // Update visuals
+ popupText = "text pasted";
+ pasteAnim = animMaxTime;
+ }
+
+ // Reset animation values
+ textTimer = maxTime;
+ textAnim = animMaxTime;
+ textAlpha = 1;
+ }
+
+ // React to the user pressing copy
+ if (copyPressed)
+ {
+ // Set the text on the user's clipboard
+ SetClipboardText(copyableText[textIndex]);
+
+ // Reset values
+ textTimer = maxTime;
+ textAnim = animMaxTime;
+ copyAnim = animMaxTime;
+ copyAnimMult = 1;
+ textAlpha = 1;
+ // Update the text that pops up at the bottom of the screen
+ popupText = "text copied";
+ }
+
+ // Switch to the next item in the list when the user presses up
+ if (IsKeyPressed(KEY_UP))
+ {
+ // Reset animation
+ copyAnim = animMaxTime;
+ copyAnimMult = 1;
+
+ textIndex += 1;
+
+ if (textIndex >= sizeof(copyableText) / sizeof(const char*)) // Length of array
+ {
+ // Loop back to the other end
+ textIndex = 0;
+ }
+ }
+
+ // Switch to the previous item in the list when the user presses down
+ if (IsKeyPressed(KEY_DOWN))
+ {
+ // Reset animation
+ copyAnim = animMaxTime;
+ copyAnimMult = -1;
+
+ if (textIndex == 0)
+ {
+ // Loop back to the other end
+ textIndex = (sizeof(copyableText) / sizeof(const char*)) - 1; // Length of array minus one
+ }
+ else
+ {
+ textIndex -= 1;
+ }
+ }
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ // Draw the user's pasted text, if there is any yet
+ if (clipboardText)
+ {
+ // Offset animation
+ int offset = 0;
+ if (pasteAnim > 0) offset = offsetAmount;
+
+ // Draw the pasted text
+ DrawText("pasted clipboard:", 10, 10 + offset, 20, DARKGREEN);
+ DrawText(clipboardText, 10, 30 + offset, 20, DARKGRAY);
+ }
+
+ // Offset animation
+ int textOffset = 0;
+ if (copyAnim > 0) textOffset = offsetAmount;
+
+ // Draw copyable text and controls
+ DrawText(copyableText[textIndex], 10, 330 + (textOffset * copyAnimMult), 20, MAROON);
+ DrawText("up/down to change string, ctrl-c to copy, ctrl-v to paste", 10, 355, 20, DARKGRAY);
+
+ // Alpha / Offset animation
+ if (textAlpha > 0)
+ {
+ // Offset animation
+ int offset = 0;
+ if (textAnim > 0) offset = offsetAmount;
+ // Draw pop up text
+ DrawText(popupText, 10, 425 + offset, 20, ColorAlpha(DARKGREEN, textAlpha));
+
+ // Fade-out animation
+ if (textTimer < 0)
+ {
+ textAlpha -= GetFrameTime();
+ }
+ }
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
\ No newline at end of file
diff --git a/examples/core/core_clipboard_text.png b/examples/core/core_clipboard_text.png
new file mode 100644
index 000000000..caa9b314a
Binary files /dev/null and b/examples/core/core_clipboard_text.png differ
diff --git a/examples/core/core_directory_files.c b/examples/core/core_directory_files.c
new file mode 100644
index 000000000..b7e11b686
--- /dev/null
+++ b/examples/core/core_directory_files.c
@@ -0,0 +1,103 @@
+/*******************************************************************************************
+*
+* raylib [core] example - directory files
+*
+* Example complexity rating: [★☆☆☆] 1/4
+*
+* Example originally created with raylib 5.5, last time updated with raylib 5.6
+*
+* Example contributed by Hugo ARNAL (@hugoarnal) 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) 2025 Hugo ARNAL (@hugoarnal)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#define RAYGUI_IMPLEMENTATION
+#include "raygui.h" // Required for GUI controls
+
+#include // Required for: strcpy()
+
+#define MAX_FILEPATH_SIZE 2048
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [core] example - directory files");
+
+ char directory[MAX_FILEPATH_SIZE] = { 0 };
+ strcpy(directory, GetWorkingDirectory());
+
+ FilePathList files = LoadDirectoryFiles(directory);
+
+ int btnBackPressed = false;
+
+ SetTargetFPS(60);
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ if (btnBackPressed)
+ {
+ strcpy(directory, GetPrevDirectoryPath(directory));
+ UnloadDirectoryFiles(files);
+ files = LoadDirectoryFiles(directory);
+ }
+
+
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+ ClearBackground(RAYWHITE);
+
+ DrawText(directory, 100, 40, 20, DARKGRAY);
+
+ btnBackPressed = GuiButton((Rectangle){ 40.0f, 40.0f, 20, 20 }, "<");
+
+ for (int i = 0; i < (int)files.count; i++)
+ {
+ Color color = Fade(LIGHTGRAY, 0.3f);
+
+ if (!IsPathFile(files.paths[i]))
+ {
+ if (GuiButton((Rectangle){0.0f, 85.0f + 40.0f*(float)i, screenWidth, 40}, ""))
+ {
+ strcpy(directory, files.paths[i]);
+ UnloadDirectoryFiles(files);
+ files = LoadDirectoryFiles(directory);
+ }
+ }
+
+ DrawRectangle(0, 85 + 40*i, screenWidth, 40, color);
+ DrawText(GetFileName(files.paths[i]), 120, 100 + 40*i, 10, GRAY);
+ }
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ UnloadDirectoryFiles(files);
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
diff --git a/examples/core/core_directory_files.png b/examples/core/core_directory_files.png
new file mode 100644
index 000000000..285e1745f
Binary files /dev/null and b/examples/core/core_directory_files.png differ
diff --git a/examples/core/core_input_gestures_testbed.c b/examples/core/core_input_gestures_testbed.c
index 055240801..dc47136c2 100644
--- a/examples/core/core_input_gestures_testbed.c
+++ b/examples/core/core_input_gestures_testbed.c
@@ -177,33 +177,33 @@ int main(void)
ClearBackground(RAYWHITE);
// Draw common elements
- DrawText("*", messagePosition.x + 5, messagePosition.y + 5, 10, BLACK);
- DrawText("Example optimized for Web/HTML5\non Smartphones with Touch Screen.", messagePosition.x + 15, messagePosition.y + 5, 10, BLACK);
- DrawText("*", messagePosition.x + 5, messagePosition.y + 35, 10, BLACK);
- DrawText("While running on Desktop Web Browsers,\ninspect and turn on Touch Emulation.", messagePosition.x + 15, messagePosition.y + 35, 10, BLACK);
+ DrawText("*", (int)messagePosition.x + 5, (int)messagePosition.y + 5, 10, BLACK);
+ DrawText("Example optimized for Web/HTML5\non Smartphones with Touch Screen.", (int)messagePosition.x + 15, (int)messagePosition.y + 5, 10, BLACK);
+ DrawText("*", (int)messagePosition.x + 5, (int)messagePosition.y + 35, 10, BLACK);
+ DrawText("While running on Desktop Web Browsers,\ninspect and turn on Touch Emulation.", (int)messagePosition.x + 15, (int)messagePosition.y + 35, 10, BLACK);
// Draw last gesture
- DrawText("Last gesture", lastGesturePosition.x + 33, lastGesturePosition.y - 47, 20, BLACK);
- DrawText("Swipe Tap Pinch Touch", lastGesturePosition.x + 17, lastGesturePosition.y - 18, 10, BLACK);
- DrawRectangle(lastGesturePosition.x + 20, lastGesturePosition.y, 20, 20, lastGesture == GESTURE_SWIPE_UP ? RED : LIGHTGRAY);
- DrawRectangle(lastGesturePosition.x, lastGesturePosition.y + 20, 20, 20, lastGesture == GESTURE_SWIPE_LEFT ? RED : LIGHTGRAY);
- DrawRectangle(lastGesturePosition.x + 40, lastGesturePosition.y + 20, 20, 20, lastGesture == GESTURE_SWIPE_RIGHT ? RED : LIGHTGRAY);
- DrawRectangle(lastGesturePosition.x + 20, lastGesturePosition.y + 40, 20, 20, lastGesture == GESTURE_SWIPE_DOWN ? RED : LIGHTGRAY);
- DrawCircle(lastGesturePosition.x + 80, lastGesturePosition.y + 16, 10, lastGesture == GESTURE_TAP ? BLUE : LIGHTGRAY);
+ DrawText("Last gesture", (int)lastGesturePosition.x + 33, (int)lastGesturePosition.y - 47, 20, BLACK);
+ DrawText("Swipe Tap Pinch Touch", (int)lastGesturePosition.x + 17, (int)lastGesturePosition.y - 18, 10, BLACK);
+ DrawRectangle((int)lastGesturePosition.x + 20, (int)lastGesturePosition.y, 20, 20, lastGesture == GESTURE_SWIPE_UP ? RED : LIGHTGRAY);
+ DrawRectangle((int)lastGesturePosition.x, (int)lastGesturePosition.y + 20, 20, 20, lastGesture == GESTURE_SWIPE_LEFT ? RED : LIGHTGRAY);
+ DrawRectangle((int)lastGesturePosition.x + 40, (int)lastGesturePosition.y + 20, 20, 20, lastGesture == GESTURE_SWIPE_RIGHT ? RED : LIGHTGRAY);
+ DrawRectangle((int)lastGesturePosition.x + 20, (int)lastGesturePosition.y + 40, 20, 20, lastGesture == GESTURE_SWIPE_DOWN ? RED : LIGHTGRAY);
+ DrawCircle((int)lastGesturePosition.x + 80, (int)lastGesturePosition.y + 16, 10, lastGesture == GESTURE_TAP ? BLUE : LIGHTGRAY);
DrawRing( (Vector2){lastGesturePosition.x + 103, lastGesturePosition.y + 16}, 6.0f, 11.0f, 0.0f, 360.0f, 0, lastGesture == GESTURE_DRAG ? LIME : LIGHTGRAY);
- DrawCircle(lastGesturePosition.x + 80, lastGesturePosition.y + 43, 10, lastGesture == GESTURE_DOUBLETAP ? SKYBLUE : LIGHTGRAY);
- DrawCircle(lastGesturePosition.x + 103, lastGesturePosition.y + 43, 10, lastGesture == GESTURE_DOUBLETAP ? SKYBLUE : LIGHTGRAY);
- DrawTriangle((Vector2){ lastGesturePosition.x + 122, lastGesturePosition.y + 16 }, (Vector2){ lastGesturePosition.x + 137, lastGesturePosition.y + 26 }, (Vector2){ lastGesturePosition.x + 137, lastGesturePosition.y + 6 }, lastGesture == GESTURE_PINCH_OUT? ORANGE : LIGHTGRAY);
+ DrawCircle((int)lastGesturePosition.x + 80, (int)lastGesturePosition.y + 43, 10, lastGesture == GESTURE_DOUBLETAP ? SKYBLUE : LIGHTGRAY);
+ DrawCircle((int)lastGesturePosition.x + 103, (int)lastGesturePosition.y + 43, 10, lastGesture == GESTURE_DOUBLETAP ? SKYBLUE : LIGHTGRAY);
+ DrawTriangle((Vector2){ lastGesturePosition.x + 122, lastGesturePosition.y + 16 }, (Vector2){ lastGesturePosition.x + 137, lastGesturePosition.y + 26 }, (Vector2){lastGesturePosition.x + 137, lastGesturePosition.y + 6 }, lastGesture == GESTURE_PINCH_OUT? ORANGE : LIGHTGRAY);
DrawTriangle((Vector2){ lastGesturePosition.x + 147, lastGesturePosition.y + 6 }, (Vector2){ lastGesturePosition.x + 147, lastGesturePosition.y + 26 }, (Vector2){ lastGesturePosition.x + 162, lastGesturePosition.y + 16 }, lastGesture == GESTURE_PINCH_OUT? ORANGE : LIGHTGRAY);
DrawTriangle((Vector2){ lastGesturePosition.x + 125, lastGesturePosition.y + 33 }, (Vector2){ lastGesturePosition.x + 125, lastGesturePosition.y + 53 }, (Vector2){ lastGesturePosition.x + 140, lastGesturePosition.y + 43 }, lastGesture == GESTURE_PINCH_IN? VIOLET : LIGHTGRAY);
DrawTriangle((Vector2){ lastGesturePosition.x + 144, lastGesturePosition.y + 43 }, (Vector2){ lastGesturePosition.x + 159, lastGesturePosition.y + 53 }, (Vector2){ lastGesturePosition.x + 159, lastGesturePosition.y + 33 }, lastGesture == GESTURE_PINCH_IN? VIOLET : LIGHTGRAY);
- for (i = 0; i < 4; i++) DrawCircle(lastGesturePosition.x + 180, lastGesturePosition.y + 7 + i*15, 5, touchCount <= i? LIGHTGRAY : gestureColor);
+ for (i = 0; i < 4; i++) DrawCircle((int)lastGesturePosition.x + 180, (int)lastGesturePosition.y + 7 + i*15, 5, touchCount <= i? LIGHTGRAY : gestureColor);
// Draw gesture log
- DrawText("Log", gestureLogPosition.x, gestureLogPosition.y, 20, BLACK);
+ DrawText("Log", (int)gestureLogPosition.x, (int)gestureLogPosition.y, 20, BLACK);
// Loop in both directions to print the gesture log array in the inverted order (and looping around if the index started somewhere in the middle)
- for (i = 0, ii = gestureLogIndex; i < GESTURE_LOG_SIZE; i++, ii = (ii + 1) % GESTURE_LOG_SIZE) DrawText(gestureLog[ii], gestureLogPosition.x, gestureLogPosition.y + 410 - i*20, 20, (i == 0 ? gestureColor : LIGHTGRAY));
+ for (i = 0, ii = gestureLogIndex; i < GESTURE_LOG_SIZE; i++, ii = (ii + 1) % GESTURE_LOG_SIZE) DrawText(gestureLog[ii], (int)gestureLogPosition.x, (int)gestureLogPosition.y + 410 - i*20, 20, (i == 0 ? gestureColor : LIGHTGRAY));
Color logButton1Color, logButton2Color;
switch (logMode)
{
@@ -213,31 +213,31 @@ int main(void)
default: logButton1Color=GRAY; logButton2Color=GRAY; break;
}
DrawRectangleRec(logButton1, logButton1Color);
- DrawText("Hide", logButton1.x + 7, logButton1.y + 3, 10, WHITE);
- DrawText("Repeat", logButton1.x + 7, logButton1.y + 13, 10, WHITE);
+ DrawText("Hide", (int)logButton1.x + 7, (int)logButton1.y + 3, 10, WHITE);
+ DrawText("Repeat", (int)logButton1.x + 7, (int)logButton1.y + 13, 10, WHITE);
DrawRectangleRec(logButton2, logButton2Color);
- DrawText("Hide", logButton1.x + 62, logButton1.y + 3, 10, WHITE);
- DrawText("Hold", logButton1.x + 62, logButton1.y + 13, 10, WHITE);
+ DrawText("Hide", (int)logButton1.x + 62, (int)logButton1.y + 3, 10, WHITE);
+ DrawText("Hold", (int)logButton1.x + 62, (int)logButton1.y + 13, 10, WHITE);
// Draw protractor
- DrawText("Angle", protractorPosition.x + 55, protractorPosition.y + 76, 10, BLACK);
+ DrawText("Angle", (int)protractorPosition.x + 55, (int)protractorPosition.y + 76, 10, BLACK);
const char *angleString = TextFormat("%f", currentAngleDegrees);
const int angleStringDot = TextFindIndex(angleString, ".");
const char *angleStringTrim = TextSubtext(angleString, 0, angleStringDot + 3);
- DrawText( angleStringTrim, protractorPosition.x + 55, protractorPosition.y + 92, 20, gestureColor);
- DrawCircle(protractorPosition.x, protractorPosition.y, 80.0f, WHITE);
+ DrawText( angleStringTrim, (int)protractorPosition.x + 55, (int)protractorPosition.y + 92, 20, gestureColor);
+ DrawCircleV(protractorPosition, 80.0f, WHITE);
DrawLineEx((Vector2){ protractorPosition.x - 90, protractorPosition.y }, (Vector2){ protractorPosition.x + 90, protractorPosition.y }, 3.0f, LIGHTGRAY);
DrawLineEx((Vector2){ protractorPosition.x, protractorPosition.y - 90 }, (Vector2){ protractorPosition.x, protractorPosition.y + 90 }, 3.0f, LIGHTGRAY);
DrawLineEx((Vector2){ protractorPosition.x - 80, protractorPosition.y - 45 }, (Vector2){ protractorPosition.x + 80, protractorPosition.y + 45 }, 3.0f, GREEN);
DrawLineEx((Vector2){ protractorPosition.x - 80, protractorPosition.y + 45 }, (Vector2){ protractorPosition.x + 80, protractorPosition.y - 45 }, 3.0f, GREEN);
- DrawText("0", protractorPosition.x + 96, protractorPosition.y - 9, 20, BLACK);
- DrawText("30", protractorPosition.x + 74, protractorPosition.y - 68, 20, BLACK);
- DrawText("90", protractorPosition.x - 11, protractorPosition.y - 110, 20, BLACK);
- DrawText("150", protractorPosition.x - 100, protractorPosition.y - 68, 20, BLACK);
- DrawText("180", protractorPosition.x - 124, protractorPosition.y - 9, 20, BLACK);
- DrawText("210", protractorPosition.x - 100, protractorPosition.y + 50, 20, BLACK);
- DrawText("270", protractorPosition.x - 18, protractorPosition.y + 92, 20, BLACK);
- DrawText("330", protractorPosition.x + 72, protractorPosition.y + 50, 20, BLACK);
+ DrawText("0", (int)protractorPosition.x + 96, (int)protractorPosition.y - 9, 20, BLACK);
+ DrawText("30", (int)protractorPosition.x + 74, (int)protractorPosition.y - 68, 20, BLACK);
+ DrawText("90", (int)protractorPosition.x - 11, (int)protractorPosition.y - 110, 20, BLACK);
+ DrawText("150", (int)protractorPosition.x - 100, (int)protractorPosition.y - 68, 20, BLACK);
+ DrawText("180", (int)protractorPosition.x - 124, (int)protractorPosition.y - 9, 20, BLACK);
+ DrawText("210", (int)protractorPosition.x - 100, (int)protractorPosition.y + 50, 20, BLACK);
+ DrawText("270", (int)protractorPosition.x - 18, (int)protractorPosition.y + 92, 20, BLACK);
+ DrawText("330", (int)protractorPosition.x + 72, (int)protractorPosition.y + 50, 20, BLACK);
if (currentAngleDegrees != 0.0f) DrawLineEx(protractorPosition, finalVector, 3.0f, gestureColor);
// Draw touch and mouse pointer points
@@ -251,7 +251,7 @@ int main(void)
DrawCircleV(touchPosition[i], 5.0f, gestureColor);
}
- if (touchCount == 2) DrawLineEx(touchPosition[0], touchPosition[1], ((currentGesture == 512)? 8 : 12), gestureColor);
+ if (touchCount == 2) DrawLineEx(touchPosition[0], touchPosition[1], ((currentGesture == 512)? 8.0f : 12.0f), gestureColor);
}
else
{
diff --git a/examples/core/core_monitor_change.c b/examples/core/core_monitor_change.c
index c85b3f633..3286ba22d 100644
--- a/examples/core/core_monitor_change.c
+++ b/examples/core/core_monitor_change.c
@@ -22,7 +22,7 @@
// Monitor Details
typedef struct Monitor {
Vector2 position;
- char *name;
+ const char *name;
int width;
int height;
int physicalWidth;
@@ -76,10 +76,10 @@ int main(void)
GetMonitorPhysicalHeight(i),
GetMonitorRefreshRate(i)
};
- if (monitors[i].position.x < monitorOffsetX) monitorOffsetX = monitors[i].position.x*-1;
+ if (monitors[i].position.x < monitorOffsetX) monitorOffsetX = (int)monitors[i].position.x*-1;
- const int width = monitors[i].position.x + monitors[i].width;
- const int height = monitors[i].position.y + monitors[i].height;
+ const int width = (int)monitors[i].position.x + monitors[i].width;
+ const int height = (int)monitors[i].position.y + monitors[i].height;
if (maxWidth < width) maxWidth = width;
if (maxHeight < height) maxHeight = height;
@@ -99,9 +99,8 @@ int main(void)
// Get currentMonitorIndex if manually moved
currentMonitorIndex = GetCurrentMonitor();
}
- const Monitor currentMonitor = monitors[currentMonitorIndex];
- float monitorScale = 0.6;
+ float monitorScale = 0.6f;
if(maxHeight > maxWidth + monitorOffsetX) monitorScale *= ((float)screenHeight/(float)maxHeight);
else monitorScale *= ((float)screenWidth/(float)(maxWidth + monitorOffsetX));
@@ -128,7 +127,7 @@ int main(void)
};
// Draw monitor name and information inside the rectangle
- DrawText(TextFormat("[%i] %s", i, monitors[i].name), rec.x + 10, rec.y + (int)(100*monitorScale), (int)(120*monitorScale), BLUE);
+ DrawText(TextFormat("[%i] %s", i, monitors[i].name), (int)rec.x + 10, (int)rec.y + (int)(100*monitorScale), (int)(120*monitorScale), BLUE);
DrawText(
TextFormat("Resolution: [%ipx x %ipx]\nRefreshRate: [%ihz]\nPhysical Size: [%imm x %imm]\nPosition: %3.0f x %3.0f",
monitors[i].width,
@@ -138,7 +137,7 @@ int main(void)
monitors[i].physicalHeight,
monitors[i].position.x,
monitors[i].position.y
- ), rec.x + 10, rec.y + (int)(200*monitorScale), (int)(120*monitorScale), DARKGRAY);
+ ), (int)rec.x + 10, (int)rec.y + (int)(200*monitorScale), (int)(120*monitorScale), DARKGRAY);
// Highlight current monitor
if (i == currentMonitorIndex)
diff --git a/examples/core/core_render_texture.c b/examples/core/core_render_texture.c
index a48982b3d..47dc66e0f 100644
--- a/examples/core/core_render_texture.c
+++ b/examples/core/core_render_texture.c
@@ -65,6 +65,7 @@ int main(void)
ClearBackground(SKYBLUE);
+ DrawRectangle(0, 0, 20, 20, RED);
DrawCircleV(ballPosition, (float)ballRadius, MAROON);
EndTextureMode();
@@ -75,11 +76,12 @@ int main(void)
ClearBackground(RAYWHITE);
// Draw our render texture with rotation applied
- // NOTE: We set the origin of the texture to the center of the render texture
+ // NOTE 1: We set the origin of the texture to the center of the render texture
+ // NOTE 2: We flip vertically the texture setting negative source rectangle height
DrawTexturePro(target.texture,
- (Rectangle){ 0, 0, target.texture.width, -target.texture.height },
- (Rectangle){ screenWidth/2, screenHeight/2, target.texture.width, -target.texture.height },
- (Vector2){ target.texture.width/2, target.texture.height/2 }, rotation, WHITE);
+ (Rectangle){ 0, 0, (float)target.texture.width, (float)-target.texture.height },
+ (Rectangle){ screenWidth/2.0f, screenHeight/2.0f, (float)target.texture.width, (float)target.texture.height },
+ (Vector2){ target.texture.width/2.0f, target.texture.height/2.0f }, rotation, WHITE);
DrawText("DRAWING BOUNCING BALL INSIDE RENDER TEXTURE!", 10, screenHeight - 40, 20, BLACK);
diff --git a/examples/core/core_undo_redo.c b/examples/core/core_undo_redo.c
index 874f68800..45b19e10f 100644
--- a/examples/core/core_undo_redo.c
+++ b/examples/core/core_undo_redo.c
@@ -187,42 +187,42 @@ int main(void)
if (lastUndoIndex > firstUndoIndex)
{
for (int i = firstUndoIndex; i < currentUndoIndex; i++)
- DrawRectangle(gridPosition.x + states[i].cell.x*GRID_CELL_SIZE, gridPosition.y + states[i].cell.y*GRID_CELL_SIZE,
- GRID_CELL_SIZE, GRID_CELL_SIZE, LIGHTGRAY);
+ DrawRectangleRec((Rectangle){gridPosition.x + states[i].cell.x * GRID_CELL_SIZE, gridPosition.y + states[i].cell.y * GRID_CELL_SIZE,
+ GRID_CELL_SIZE, GRID_CELL_SIZE }, LIGHTGRAY);
}
else if (firstUndoIndex > lastUndoIndex)
{
if ((currentUndoIndex < MAX_UNDO_STATES) && (currentUndoIndex > lastUndoIndex))
{
for (int i = firstUndoIndex; i < currentUndoIndex; i++)
- DrawRectangle(gridPosition.x + states[i].cell.x*GRID_CELL_SIZE, gridPosition.y + states[i].cell.y*GRID_CELL_SIZE,
- GRID_CELL_SIZE, GRID_CELL_SIZE, LIGHTGRAY);
+ DrawRectangleRec((Rectangle) { gridPosition.x + states[i].cell.x * GRID_CELL_SIZE, gridPosition.y + states[i].cell.y * GRID_CELL_SIZE,
+ GRID_CELL_SIZE, GRID_CELL_SIZE }, LIGHTGRAY);
}
else
{
for (int i = firstUndoIndex; i < MAX_UNDO_STATES; i++)
- DrawRectangle(gridPosition.x + states[i].cell.x*GRID_CELL_SIZE, gridPosition.y + states[i].cell.y*GRID_CELL_SIZE,
+ DrawRectangle((int)gridPosition.x + states[i].cell.x*GRID_CELL_SIZE, (int)gridPosition.y + states[i].cell.y*GRID_CELL_SIZE,
GRID_CELL_SIZE, GRID_CELL_SIZE, LIGHTGRAY);
for (int i = 0; i < currentUndoIndex; i++)
- DrawRectangle(gridPosition.x + states[i].cell.x*GRID_CELL_SIZE, gridPosition.y + states[i].cell.y*GRID_CELL_SIZE,
+ DrawRectangle((int)gridPosition.x + states[i].cell.x*GRID_CELL_SIZE, (int)gridPosition.y + states[i].cell.y*GRID_CELL_SIZE,
GRID_CELL_SIZE, GRID_CELL_SIZE, LIGHTGRAY);
}
}
// Draw game grid
for (int y = 0; y <= MAX_GRID_CELLS_Y; y++)
- DrawLine(gridPosition.x, gridPosition.y + y*GRID_CELL_SIZE,
- gridPosition.x + MAX_GRID_CELLS_X*GRID_CELL_SIZE, gridPosition.y + y*GRID_CELL_SIZE, GRAY);
+ DrawLine((int)gridPosition.x, (int)gridPosition.y + y*GRID_CELL_SIZE,
+ (int)gridPosition.x + MAX_GRID_CELLS_X*GRID_CELL_SIZE, (int)gridPosition.y + y*GRID_CELL_SIZE, GRAY);
for (int x = 0; x <= MAX_GRID_CELLS_X; x++)
- DrawLine(gridPosition.x + x*GRID_CELL_SIZE, gridPosition.y,
- gridPosition.x + x*GRID_CELL_SIZE, gridPosition.y + MAX_GRID_CELLS_Y*GRID_CELL_SIZE, GRAY);
+ DrawLine((int)gridPosition.x + x*GRID_CELL_SIZE, (int)gridPosition.y,
+ (int)gridPosition.x + x*GRID_CELL_SIZE, (int)gridPosition.y + MAX_GRID_CELLS_Y*GRID_CELL_SIZE, GRAY);
// Draw player
- DrawRectangle(gridPosition.x + player.cell.x*GRID_CELL_SIZE, gridPosition.y + player.cell.y*GRID_CELL_SIZE,
+ DrawRectangle((int)gridPosition.x + player.cell.x*GRID_CELL_SIZE, (int)gridPosition.y + player.cell.y*GRID_CELL_SIZE,
GRID_CELL_SIZE + 1, GRID_CELL_SIZE + 1, player.color);
// Draw undo system buffer info
- DrawText("UNDO STATES:", undoInfoPos.x - 85, undoInfoPos.y + 9, 10, DARKGRAY);
+ DrawText("UNDO STATES:", (int)undoInfoPos.x - 85, (int)undoInfoPos.y + 9, 10, DARKGRAY);
DrawUndoBuffer(undoInfoPos, firstUndoIndex, lastUndoIndex, currentUndoIndex, 24);
EndDrawing();
@@ -247,15 +247,15 @@ int main(void)
static void DrawUndoBuffer(Vector2 position, int firstUndoIndex, int lastUndoIndex, int currentUndoIndex, int slotSize)
{
// Draw index marks
- DrawRectangle(position.x + 8 + slotSize*currentUndoIndex, position.y - 10, 8, 8, RED);
- DrawRectangleLines(position.x + 2 + slotSize*firstUndoIndex, position.y + 27, 8, 8, BLACK);
- DrawRectangle(position.x + 14 + slotSize*lastUndoIndex, position.y + 27, 8, 8, BLACK);
+ DrawRectangle((int)position.x + 8 + slotSize*currentUndoIndex, (int)position.y - 10, 8, 8, RED);
+ DrawRectangleLines((int)position.x + 2 + slotSize*firstUndoIndex, (int)position.y + 27, 8, 8, BLACK);
+ DrawRectangle((int)position.x + 14 + slotSize*lastUndoIndex, (int)position.y + 27, 8, 8, BLACK);
// Draw background gray slots
for (int i = 0; i < MAX_UNDO_STATES; i++)
{
- DrawRectangle(position.x + slotSize*i, position.y, slotSize, slotSize, LIGHTGRAY);
- DrawRectangleLines(position.x + slotSize*i, position.y, slotSize, slotSize, GRAY);
+ DrawRectangle((int)position.x + slotSize*i, (int)position.y, slotSize, slotSize, LIGHTGRAY);
+ DrawRectangleLines((int)position.x + slotSize*i, (int)position.y, slotSize, slotSize, GRAY);
}
// Draw occupied slots: firstUndoIndex --> lastUndoIndex
@@ -263,22 +263,22 @@ static void DrawUndoBuffer(Vector2 position, int firstUndoIndex, int lastUndoInd
{
for (int i = firstUndoIndex; i < lastUndoIndex + 1; i++)
{
- DrawRectangle(position.x + slotSize*i, position.y, slotSize, slotSize, SKYBLUE);
- DrawRectangleLines(position.x + slotSize*i, position.y, slotSize, slotSize, BLUE);
+ DrawRectangle((int)position.x + slotSize*i, (int)position.y, slotSize, slotSize, SKYBLUE);
+ DrawRectangleLines((int)position.x + slotSize*i, (int)position.y, slotSize, slotSize, BLUE);
}
}
else if (lastUndoIndex < firstUndoIndex)
{
for (int i = firstUndoIndex; i < MAX_UNDO_STATES; i++)
{
- DrawRectangle(position.x + slotSize*i, position.y, slotSize, slotSize, SKYBLUE);
- DrawRectangleLines(position.x + slotSize*i, position.y, slotSize, slotSize, BLUE);
+ DrawRectangle((int)position.x + slotSize*i, (int)position.y, slotSize, slotSize, SKYBLUE);
+ DrawRectangleLines((int)position.x + slotSize*i, (int)position.y, slotSize, slotSize, BLUE);
}
for (int i = 0; i < lastUndoIndex + 1; i++)
{
- DrawRectangle(position.x + slotSize*i, position.y, slotSize, slotSize, SKYBLUE);
- DrawRectangleLines(position.x + slotSize*i, position.y, slotSize, slotSize, BLUE);
+ DrawRectangle((int)position.x + slotSize*i, (int)position.y, slotSize, slotSize, SKYBLUE);
+ DrawRectangleLines((int)position.x + slotSize*i, (int)position.y, slotSize, slotSize, BLUE);
}
}
@@ -287,26 +287,26 @@ static void DrawUndoBuffer(Vector2 position, int firstUndoIndex, int lastUndoInd
{
for (int i = firstUndoIndex; i < currentUndoIndex; i++)
{
- DrawRectangle(position.x + slotSize*i, position.y, slotSize, slotSize, GREEN);
- DrawRectangleLines(position.x + slotSize*i, position.y, slotSize, slotSize, LIME);
+ DrawRectangle((int)position.x + slotSize*i, (int)position.y, slotSize, slotSize, GREEN);
+ DrawRectangleLines((int)position.x + slotSize*i, (int)position.y, slotSize, slotSize, LIME);
}
}
else if (currentUndoIndex < firstUndoIndex)
{
for (int i = firstUndoIndex; i < MAX_UNDO_STATES; i++)
{
- DrawRectangle(position.x + slotSize*i, position.y, slotSize, slotSize, GREEN);
- DrawRectangleLines(position.x + slotSize*i, position.y, slotSize, slotSize, LIME);
+ DrawRectangle((int)position.x + slotSize*i, (int)position.y, slotSize, slotSize, GREEN);
+ DrawRectangleLines((int)position.x + slotSize*i, (int)position.y, slotSize, slotSize, LIME);
}
for (int i = 0; i < currentUndoIndex; i++)
{
- DrawRectangle(position.x + slotSize*i, position.y, slotSize, slotSize, GREEN);
- DrawRectangleLines(position.x + slotSize*i, position.y, slotSize, slotSize, LIME);
+ DrawRectangle((int)position.x + slotSize*i, (int)position.y, slotSize, slotSize, GREEN);
+ DrawRectangleLines((int)position.x + slotSize*i, (int)position.y, slotSize, slotSize, LIME);
}
}
// Draw current selected UNDO slot
- DrawRectangle(position.x + slotSize*currentUndoIndex, position.y, slotSize, slotSize, GOLD);
- DrawRectangleLines(position.x + slotSize*currentUndoIndex, position.y, slotSize, slotSize, ORANGE);
+ DrawRectangle((int)position.x + slotSize*currentUndoIndex, (int)position.y, slotSize, slotSize, GOLD);
+ DrawRectangleLines((int)position.x + slotSize*currentUndoIndex, (int)position.y, slotSize, slotSize, ORANGE);
}
diff --git a/examples/core/raygui.h b/examples/core/raygui.h
new file mode 100644
index 000000000..a3fc51f0f
--- /dev/null
+++ b/examples/core/raygui.h
@@ -0,0 +1,5757 @@
+/*******************************************************************************************
+*
+* raygui v4.5-dev - A simple and easy-to-use immediate-mode gui library
+*
+* DESCRIPTION:
+* raygui is a tools-dev-focused immediate-mode-gui library based on raylib but also
+* available as a standalone library, as long as input and drawing functions are provided.
+*
+* FEATURES:
+* - Immediate-mode gui, minimal retained data
+* - +25 controls provided (basic and advanced)
+* - Styling system for colors, font and metrics
+* - Icons supported, embedded as a 1-bit icons pack
+* - Standalone mode option (custom input/graphics backend)
+* - Multiple support tools provided for raygui development
+*
+* POSSIBLE IMPROVEMENTS:
+* - Better standalone mode API for easy plug of custom backends
+* - Externalize required inputs, allow user easier customization
+*
+* LIMITATIONS:
+* - No editable multi-line word-wraped text box supported
+* - No auto-layout mechanism, up to the user to define controls position and size
+* - Standalone mode requires library modification and some user work to plug another backend
+*
+* NOTES:
+* - WARNING: GuiLoadStyle() and GuiLoadStyle{Custom}() functions, allocate memory for
+* font atlas recs and glyphs, freeing that memory is (usually) up to the user,
+* no unload function is explicitly provided... but note that GuiLoadStyleDefault() unloads
+* by default any previously loaded font (texture, recs, glyphs).
+* - Global UI alpha (guiAlpha) is applied inside GuiDrawRectangle() and GuiDrawText() functions
+*
+* CONTROLS PROVIDED:
+* # Container/separators Controls
+* - WindowBox --> StatusBar, Panel
+* - GroupBox --> Line
+* - Line
+* - Panel --> StatusBar
+* - ScrollPanel --> StatusBar
+* - TabBar --> Button
+*
+* # Basic Controls
+* - Label
+* - LabelButton --> Label
+* - Button
+* - Toggle
+* - ToggleGroup --> Toggle
+* - ToggleSlider
+* - CheckBox
+* - ComboBox
+* - DropdownBox
+* - TextBox
+* - ValueBox --> TextBox
+* - Spinner --> Button, ValueBox
+* - Slider
+* - SliderBar --> Slider
+* - ProgressBar
+* - StatusBar
+* - DummyRec
+* - Grid
+*
+* # Advance Controls
+* - ListView
+* - ColorPicker --> ColorPanel, ColorBarHue
+* - MessageBox --> Window, Label, Button
+* - TextInputBox --> Window, Label, TextBox, Button
+*
+* It also provides a set of functions for styling the controls based on its properties (size, color).
+*
+*
+* RAYGUI STYLE (guiStyle):
+* raygui uses a global data array for all gui style properties (allocated on data segment by default),
+* when a new style is loaded, it is loaded over the global style... but a default gui style could always be
+* recovered with GuiLoadStyleDefault() function, that overwrites the current style to the default one
+*
+* The global style array size is fixed and depends on the number of controls and properties:
+*
+* static unsigned int guiStyle[RAYGUI_MAX_CONTROLS*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED)];
+*
+* guiStyle size is by default: 16*(16 + 8) = 384*4 = 1536 bytes = 1.5 KB
+*
+* Note that the first set of BASE properties (by default guiStyle[0..15]) belong to the generic style
+* used for all controls, when any of those base values is set, it is automatically populated to all
+* controls, so, specific control values overwriting generic style should be set after base values.
+*
+* After the first BASE set we have the EXTENDED properties (by default guiStyle[16..23]), those
+* properties are actually common to all controls and can not be overwritten individually (like BASE ones)
+* Some of those properties are: TEXT_SIZE, TEXT_SPACING, LINE_COLOR, BACKGROUND_COLOR
+*
+* Custom control properties can be defined using the EXTENDED properties for each independent control.
+*
+* TOOL: rGuiStyler is a visual tool to customize raygui style: github.com/raysan5/rguistyler
+*
+*
+* RAYGUI ICONS (guiIcons):
+* raygui could use a global array containing icons data (allocated on data segment by default),
+* a custom icons set could be loaded over this array using GuiLoadIcons(), but loaded icons set
+* must be same RAYGUI_ICON_SIZE and no more than RAYGUI_ICON_MAX_ICONS will be loaded
+*
+* Every icon is codified in binary form, using 1 bit per pixel, so, every 16x16 icon
+* requires 8 integers (16*16/32) to be stored in memory.
+*
+* When the icon is draw, actually one quad per pixel is drawn if the bit for that pixel is set.
+*
+* The global icons array size is fixed and depends on the number of icons and size:
+*
+* static unsigned int guiIcons[RAYGUI_ICON_MAX_ICONS*RAYGUI_ICON_DATA_ELEMENTS];
+*
+* guiIcons size is by default: 256*(16*16/32) = 2048*4 = 8192 bytes = 8 KB
+*
+* TOOL: rGuiIcons is a visual tool to customize/create raygui icons: github.com/raysan5/rguiicons
+*
+* RAYGUI LAYOUT:
+* raygui currently does not provide an auto-layout mechanism like other libraries,
+* layouts must be defined manually on controls drawing, providing the right bounds Rectangle for it.
+*
+* TOOL: rGuiLayout is a visual tool to create raygui layouts: github.com/raysan5/rguilayout
+*
+* CONFIGURATION:
+* #define RAYGUI_IMPLEMENTATION
+* Generates the implementation of the library into the included file.
+* If not defined, the library is in header only mode and can be included in other headers
+* or source files without problems. But only ONE file should hold the implementation.
+*
+* #define RAYGUI_STANDALONE
+* Avoid raylib.h header inclusion in this file. Data types defined on raylib are defined
+* internally in the library and input management and drawing functions must be provided by
+* the user (check library implementation for further details).
+*
+* #define RAYGUI_NO_ICONS
+* Avoid including embedded ricons data (256 icons, 16x16 pixels, 1-bit per pixel, 2KB)
+*
+* #define RAYGUI_CUSTOM_ICONS
+* Includes custom ricons.h header defining a set of custom icons,
+* this file can be generated using rGuiIcons tool
+*
+* #define RAYGUI_DEBUG_RECS_BOUNDS
+* Draw control bounds rectangles for debug
+*
+* #define RAYGUI_DEBUG_TEXT_BOUNDS
+* Draw text bounds rectangles for debug
+*
+* VERSIONS HISTORY:
+* 4.5-dev (Sep-2024) Current dev version...
+* ADDED: guiControlExclusiveMode and guiControlExclusiveRec for exclusive modes
+* ADDED: GuiValueBoxFloat()
+* ADDED: GuiDropdonwBox() properties: DROPDOWN_ARROW_HIDDEN, DROPDOWN_ROLL_UP
+* ADDED: GuiListView() property: LIST_ITEMS_BORDER_WIDTH
+* ADDED: Multiple new icons
+* REVIEWED: GuiTabBar(), close tab with mouse middle button
+* REVIEWED: GuiScrollPanel(), scroll speed proportional to content
+* REVIEWED: GuiDropdownBox(), support roll up and hidden arrow
+* REVIEWED: GuiTextBox(), cursor position initialization
+* REVIEWED: GuiSliderPro(), control value change check
+* REVIEWED: GuiGrid(), simplified implementation
+* REVIEWED: GuiIconText(), increase buffer size and reviewed padding
+* REVIEWED: GuiDrawText(), improved wrap mode drawing
+* REVIEWED: GuiScrollBar(), minor tweaks
+* REVIEWED: Functions descriptions, removed wrong return value reference
+* REDESIGNED: GuiColorPanel(), improved HSV <-> RGBA convertion
+*
+* 4.0 (12-Sep-2023) ADDED: GuiToggleSlider()
+* ADDED: GuiColorPickerHSV() and GuiColorPanelHSV()
+* ADDED: Multiple new icons, mostly compiler related
+* ADDED: New DEFAULT properties: TEXT_LINE_SPACING, TEXT_ALIGNMENT_VERTICAL, TEXT_WRAP_MODE
+* ADDED: New enum values: GuiTextAlignment, GuiTextAlignmentVertical, GuiTextWrapMode
+* ADDED: Support loading styles with custom font charset from external file
+* REDESIGNED: GuiTextBox(), support mouse cursor positioning
+* REDESIGNED: GuiDrawText(), support multiline and word-wrap modes (read only)
+* REDESIGNED: GuiProgressBar() to be more visual, progress affects border color
+* REDESIGNED: Global alpha consideration moved to GuiDrawRectangle() and GuiDrawText()
+* REDESIGNED: GuiScrollPanel(), get parameters by reference and return result value
+* REDESIGNED: GuiToggleGroup(), get parameters by reference and return result value
+* REDESIGNED: GuiComboBox(), get parameters by reference and return result value
+* REDESIGNED: GuiCheckBox(), get parameters by reference and return result value
+* REDESIGNED: GuiSlider(), get parameters by reference and return result value
+* REDESIGNED: GuiSliderBar(), get parameters by reference and return result value
+* REDESIGNED: GuiProgressBar(), get parameters by reference and return result value
+* REDESIGNED: GuiListView(), get parameters by reference and return result value
+* REDESIGNED: GuiColorPicker(), get parameters by reference and return result value
+* REDESIGNED: GuiColorPanel(), get parameters by reference and return result value
+* REDESIGNED: GuiColorBarAlpha(), get parameters by reference and return result value
+* REDESIGNED: GuiColorBarHue(), get parameters by reference and return result value
+* REDESIGNED: GuiGrid(), get parameters by reference and return result value
+* REDESIGNED: GuiGrid(), added extra parameter
+* REDESIGNED: GuiListViewEx(), change parameters order
+* REDESIGNED: All controls return result as int value
+* REVIEWED: GuiScrollPanel() to avoid smallish scroll-bars
+* REVIEWED: All examples and specially controls_test_suite
+* RENAMED: gui_file_dialog module to gui_window_file_dialog
+* UPDATED: All styles to include ISO-8859-15 charset (as much as possible)
+*
+* 3.6 (10-May-2023) ADDED: New icon: SAND_TIMER
+* ADDED: GuiLoadStyleFromMemory() (binary only)
+* REVIEWED: GuiScrollBar() horizontal movement key
+* REVIEWED: GuiTextBox() crash on cursor movement
+* REVIEWED: GuiTextBox(), additional inputs support
+* REVIEWED: GuiLabelButton(), avoid text cut
+* REVIEWED: GuiTextInputBox(), password input
+* REVIEWED: Local GetCodepointNext(), aligned with raylib
+* REDESIGNED: GuiSlider*()/GuiScrollBar() to support out-of-bounds
+*
+* 3.5 (20-Apr-2023) ADDED: GuiTabBar(), based on GuiToggle()
+* ADDED: Helper functions to split text in separate lines
+* ADDED: Multiple new icons, useful for code editing tools
+* REMOVED: Unneeded icon editing functions
+* REMOVED: GuiTextBoxMulti(), very limited and broken
+* REMOVED: MeasureTextEx() dependency, logic directly implemented
+* REMOVED: DrawTextEx() dependency, logic directly implemented
+* REVIEWED: GuiScrollBar(), improve mouse-click behaviour
+* REVIEWED: Library header info, more info, better organized
+* REDESIGNED: GuiTextBox() to support cursor movement
+* REDESIGNED: GuiDrawText() to divide drawing by lines
+*
+* 3.2 (22-May-2022) RENAMED: Some enum values, for unification, avoiding prefixes
+* REMOVED: GuiScrollBar(), only internal
+* REDESIGNED: GuiPanel() to support text parameter
+* REDESIGNED: GuiScrollPanel() to support text parameter
+* REDESIGNED: GuiColorPicker() to support text parameter
+* REDESIGNED: GuiColorPanel() to support text parameter
+* REDESIGNED: GuiColorBarAlpha() to support text parameter
+* REDESIGNED: GuiColorBarHue() to support text parameter
+* REDESIGNED: GuiTextInputBox() to support password
+*
+* 3.1 (12-Jan-2022) REVIEWED: Default style for consistency (aligned with rGuiLayout v2.5 tool)
+* REVIEWED: GuiLoadStyle() to support compressed font atlas image data and unload previous textures
+* REVIEWED: External icons usage logic
+* REVIEWED: GuiLine() for centered alignment when including text
+* RENAMED: Multiple controls properties definitions to prepend RAYGUI_
+* RENAMED: RICON_ references to RAYGUI_ICON_ for library consistency
+* Projects updated and multiple tweaks
+*
+* 3.0 (04-Nov-2021) Integrated ricons data to avoid external file
+* REDESIGNED: GuiTextBoxMulti()
+* REMOVED: GuiImageButton*()
+* Multiple minor tweaks and bugs corrected
+*
+* 2.9 (17-Mar-2021) REMOVED: Tooltip API
+* 2.8 (03-May-2020) Centralized rectangles drawing to GuiDrawRectangle()
+* 2.7 (20-Feb-2020) ADDED: Possible tooltips API
+* 2.6 (09-Sep-2019) ADDED: GuiTextInputBox()
+* REDESIGNED: GuiListView*(), GuiDropdownBox(), GuiSlider*(), GuiProgressBar(), GuiMessageBox()
+* REVIEWED: GuiTextBox(), GuiSpinner(), GuiValueBox(), GuiLoadStyle()
+* Replaced property INNER_PADDING by TEXT_PADDING, renamed some properties
+* ADDED: 8 new custom styles ready to use
+* Multiple minor tweaks and bugs corrected
+*
+* 2.5 (28-May-2019) Implemented extended GuiTextBox(), GuiValueBox(), GuiSpinner()
+* 2.3 (29-Apr-2019) ADDED: rIcons auxiliar library and support for it, multiple controls reviewed
+* Refactor all controls drawing mechanism to use control state
+* 2.2 (05-Feb-2019) ADDED: GuiScrollBar(), GuiScrollPanel(), reviewed GuiListView(), removed Gui*Ex() controls
+* 2.1 (26-Dec-2018) REDESIGNED: GuiCheckBox(), GuiComboBox(), GuiDropdownBox(), GuiToggleGroup() > Use combined text string
+* REDESIGNED: Style system (breaking change)
+* 2.0 (08-Nov-2018) ADDED: Support controls guiLock and custom fonts
+* REVIEWED: GuiComboBox(), GuiListView()...
+* 1.9 (09-Oct-2018) REVIEWED: GuiGrid(), GuiTextBox(), GuiTextBoxMulti(), GuiValueBox()...
+* 1.8 (01-May-2018) Lot of rework and redesign to align with rGuiStyler and rGuiLayout
+* 1.5 (21-Jun-2017) Working in an improved styles system
+* 1.4 (15-Jun-2017) Rewritten all GUI functions (removed useless ones)
+* 1.3 (12-Jun-2017) Complete redesign of style system
+* 1.1 (01-Jun-2017) Complete review of the library
+* 1.0 (07-Jun-2016) Converted to header-only by Ramon Santamaria.
+* 0.9 (07-Mar-2016) Reviewed and tested by Albert Martos, Ian Eito, Sergio Martinez and Ramon Santamaria.
+* 0.8 (27-Aug-2015) Initial release. Implemented by Kevin Gato, Daniel Nicolás and Ramon Santamaria.
+*
+* DEPENDENCIES:
+* raylib 5.0 - Inputs reading (keyboard/mouse), shapes drawing, font loading and text drawing
+*
+* STANDALONE MODE:
+* By default raygui depends on raylib mostly for the inputs and the drawing functionality but that dependency can be disabled
+* with the config flag RAYGUI_STANDALONE. In that case is up to the user to provide another backend to cover library needs.
+*
+* The following functions should be redefined for a custom backend:
+*
+* - Vector2 GetMousePosition(void);
+* - float GetMouseWheelMove(void);
+* - bool IsMouseButtonDown(int button);
+* - bool IsMouseButtonPressed(int button);
+* - bool IsMouseButtonReleased(int button);
+* - bool IsKeyDown(int key);
+* - bool IsKeyPressed(int key);
+* - int GetCharPressed(void); // -- GuiTextBox(), GuiValueBox()
+*
+* - void DrawRectangle(int x, int y, int width, int height, Color color); // -- GuiDrawRectangle()
+* - void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4); // -- GuiColorPicker()
+*
+* - Font GetFontDefault(void); // -- GuiLoadStyleDefault()
+* - Font LoadFontEx(const char *fileName, int fontSize, int *codepoints, int codepointCount); // -- GuiLoadStyle()
+* - Texture2D LoadTextureFromImage(Image image); // -- GuiLoadStyle(), required to load texture from embedded font atlas image
+* - void SetShapesTexture(Texture2D tex, Rectangle rec); // -- GuiLoadStyle(), required to set shapes rec to font white rec (optimization)
+* - char *LoadFileText(const char *fileName); // -- GuiLoadStyle(), required to load charset data
+* - void UnloadFileText(char *text); // -- GuiLoadStyle(), required to unload charset data
+* - const char *GetDirectoryPath(const char *filePath); // -- GuiLoadStyle(), required to find charset/font file from text .rgs
+* - int *LoadCodepoints(const char *text, int *count); // -- GuiLoadStyle(), required to load required font codepoints list
+* - void UnloadCodepoints(int *codepoints); // -- GuiLoadStyle(), required to unload codepoints list
+* - unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize); // -- GuiLoadStyle()
+*
+* CONTRIBUTORS:
+* Ramon Santamaria: Supervision, review, redesign, update and maintenance
+* Vlad Adrian: Complete rewrite of GuiTextBox() to support extended features (2019)
+* Sergio Martinez: Review, testing (2015) and redesign of multiple controls (2018)
+* Adria Arranz: Testing and implementation of additional controls (2018)
+* Jordi Jorba: Testing and implementation of additional controls (2018)
+* Albert Martos: Review and testing of the library (2015)
+* Ian Eito: Review and testing of the library (2015)
+* Kevin Gato: Initial implementation of basic components (2014)
+* Daniel Nicolas: Initial implementation of basic components (2014)
+*
+*
+* LICENSE: zlib/libpng
+*
+* Copyright (c) 2014-2024 Ramon Santamaria (@raysan5)
+*
+* This software is provided "as-is", without any express or implied warranty. In no event
+* will the authors be held liable for any damages arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose, including commercial
+* applications, and to alter it and redistribute it freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not claim that you
+* wrote the original software. If you use this software in a product, an acknowledgment
+* in the product documentation would be appreciated but is not required.
+*
+* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
+* as being the original software.
+*
+* 3. This notice may not be removed or altered from any source distribution.
+*
+**********************************************************************************************/
+
+#ifndef RAYGUI_H
+#define RAYGUI_H
+
+#define RAYGUI_VERSION_MAJOR 4
+#define RAYGUI_VERSION_MINOR 5
+#define RAYGUI_VERSION_PATCH 0
+#define RAYGUI_VERSION "4.5-dev"
+
+#if !defined(RAYGUI_STANDALONE)
+ #include "raylib.h"
+#endif
+
+// Function specifiers in case library is build/used as a shared library (Windows)
+// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
+#if defined(_WIN32)
+ #if defined(BUILD_LIBTYPE_SHARED)
+ #define RAYGUIAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll)
+ #elif defined(USE_LIBTYPE_SHARED)
+ #define RAYGUIAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll)
+ #endif
+#endif
+
+// Function specifiers definition
+#ifndef RAYGUIAPI
+ #define RAYGUIAPI // Functions defined as 'extern' by default (implicit specifiers)
+#endif
+
+//----------------------------------------------------------------------------------
+// Defines and Macros
+//----------------------------------------------------------------------------------
+// Allow custom memory allocators
+#ifndef RAYGUI_MALLOC
+ #define RAYGUI_MALLOC(sz) malloc(sz)
+#endif
+#ifndef RAYGUI_CALLOC
+ #define RAYGUI_CALLOC(n,sz) calloc(n,sz)
+#endif
+#ifndef RAYGUI_FREE
+ #define RAYGUI_FREE(p) free(p)
+#endif
+
+// Simple log system to avoid printf() calls if required
+// NOTE: Avoiding those calls, also avoids const strings memory usage
+#define RAYGUI_SUPPORT_LOG_INFO
+#if defined(RAYGUI_SUPPORT_LOG_INFO)
+ #define RAYGUI_LOG(...) printf(__VA_ARGS__)
+#else
+ #define RAYGUI_LOG(...)
+#endif
+
+//----------------------------------------------------------------------------------
+// Types and Structures Definition
+// NOTE: Some types are required for RAYGUI_STANDALONE usage
+//----------------------------------------------------------------------------------
+#if defined(RAYGUI_STANDALONE)
+ #ifndef __cplusplus
+ // Boolean type
+ #ifndef true
+ typedef enum { false, true } bool;
+ #endif
+ #endif
+
+ // Vector2 type
+ typedef struct Vector2 {
+ float x;
+ float y;
+ } Vector2;
+
+ // Vector3 type // -- ConvertHSVtoRGB(), ConvertRGBtoHSV()
+ typedef struct Vector3 {
+ float x;
+ float y;
+ float z;
+ } Vector3;
+
+ // Color type, RGBA (32bit)
+ typedef struct Color {
+ unsigned char r;
+ unsigned char g;
+ unsigned char b;
+ unsigned char a;
+ } Color;
+
+ // Rectangle type
+ typedef struct Rectangle {
+ float x;
+ float y;
+ float width;
+ float height;
+ } Rectangle;
+
+ // TODO: Texture2D type is very coupled to raylib, required by Font type
+ // It should be redesigned to be provided by user
+ typedef struct Texture2D {
+ unsigned int id; // OpenGL texture id
+ int width; // Texture base width
+ int height; // Texture base height
+ int mipmaps; // Mipmap levels, 1 by default
+ int format; // Data format (PixelFormat type)
+ } Texture2D;
+
+ // Image, pixel data stored in CPU memory (RAM)
+ typedef struct Image {
+ void *data; // Image raw data
+ int width; // Image base width
+ int height; // Image base height
+ int mipmaps; // Mipmap levels, 1 by default
+ int format; // Data format (PixelFormat type)
+ } Image;
+
+ // GlyphInfo, font characters glyphs info
+ typedef struct GlyphInfo {
+ int value; // Character value (Unicode)
+ int offsetX; // Character offset X when drawing
+ int offsetY; // Character offset Y when drawing
+ int advanceX; // Character advance position X
+ Image image; // Character image data
+ } GlyphInfo;
+
+ // TODO: Font type is very coupled to raylib, mostly required by GuiLoadStyle()
+ // It should be redesigned to be provided by user
+ typedef struct Font {
+ int baseSize; // Base size (default chars height)
+ int glyphCount; // Number of glyph characters
+ int glyphPadding; // Padding around the glyph characters
+ Texture2D texture; // Texture atlas containing the glyphs
+ Rectangle *recs; // Rectangles in texture for the glyphs
+ GlyphInfo *glyphs; // Glyphs info data
+ } Font;
+#endif
+
+// Style property
+// NOTE: Used when exporting style as code for convenience
+typedef struct GuiStyleProp {
+ unsigned short controlId; // Control identifier
+ unsigned short propertyId; // Property identifier
+ int propertyValue; // Property value
+} GuiStyleProp;
+
+/*
+// Controls text style -NOT USED-
+// NOTE: Text style is defined by control
+typedef struct GuiTextStyle {
+ unsigned int size;
+ int charSpacing;
+ int lineSpacing;
+ int alignmentH;
+ int alignmentV;
+ int padding;
+} GuiTextStyle;
+*/
+
+// Gui control state
+typedef enum {
+ STATE_NORMAL = 0,
+ STATE_FOCUSED,
+ STATE_PRESSED,
+ STATE_DISABLED
+} GuiState;
+
+// Gui control text alignment
+typedef enum {
+ TEXT_ALIGN_LEFT = 0,
+ TEXT_ALIGN_CENTER,
+ TEXT_ALIGN_RIGHT
+} GuiTextAlignment;
+
+// Gui control text alignment vertical
+// NOTE: Text vertical position inside the text bounds
+typedef enum {
+ TEXT_ALIGN_TOP = 0,
+ TEXT_ALIGN_MIDDLE,
+ TEXT_ALIGN_BOTTOM
+} GuiTextAlignmentVertical;
+
+// Gui control text wrap mode
+// NOTE: Useful for multiline text
+typedef enum {
+ TEXT_WRAP_NONE = 0,
+ TEXT_WRAP_CHAR,
+ TEXT_WRAP_WORD
+} GuiTextWrapMode;
+
+// Gui controls
+typedef enum {
+ // Default -> populates to all controls when set
+ DEFAULT = 0,
+
+ // Basic controls
+ LABEL, // Used also for: LABELBUTTON
+ BUTTON,
+ TOGGLE, // Used also for: TOGGLEGROUP
+ SLIDER, // Used also for: SLIDERBAR, TOGGLESLIDER
+ PROGRESSBAR,
+ CHECKBOX,
+ COMBOBOX,
+ DROPDOWNBOX,
+ TEXTBOX, // Used also for: TEXTBOXMULTI
+ VALUEBOX,
+ SPINNER, // Uses: BUTTON, VALUEBOX
+ LISTVIEW,
+ COLORPICKER,
+ SCROLLBAR,
+ STATUSBAR
+} GuiControl;
+
+// Gui base properties for every control
+// NOTE: RAYGUI_MAX_PROPS_BASE properties (by default 16 properties)
+typedef enum {
+ BORDER_COLOR_NORMAL = 0, // Control border color in STATE_NORMAL
+ BASE_COLOR_NORMAL, // Control base color in STATE_NORMAL
+ TEXT_COLOR_NORMAL, // Control text color in STATE_NORMAL
+ BORDER_COLOR_FOCUSED, // Control border color in STATE_FOCUSED
+ BASE_COLOR_FOCUSED, // Control base color in STATE_FOCUSED
+ TEXT_COLOR_FOCUSED, // Control text color in STATE_FOCUSED
+ BORDER_COLOR_PRESSED, // Control border color in STATE_PRESSED
+ BASE_COLOR_PRESSED, // Control base color in STATE_PRESSED
+ TEXT_COLOR_PRESSED, // Control text color in STATE_PRESSED
+ BORDER_COLOR_DISABLED, // Control border color in STATE_DISABLED
+ BASE_COLOR_DISABLED, // Control base color in STATE_DISABLED
+ TEXT_COLOR_DISABLED, // Control text color in STATE_DISABLED
+ BORDER_WIDTH, // Control border size, 0 for no border
+ //TEXT_SIZE, // Control text size (glyphs max height) -> GLOBAL for all controls
+ //TEXT_SPACING, // Control text spacing between glyphs -> GLOBAL for all controls
+ //TEXT_LINE_SPACING // Control text spacing between lines -> GLOBAL for all controls
+ TEXT_PADDING, // Control text padding, not considering border
+ TEXT_ALIGNMENT, // Control text horizontal alignment inside control text bound (after border and padding)
+ //TEXT_WRAP_MODE // Control text wrap-mode inside text bounds -> GLOBAL for all controls
+} GuiControlProperty;
+
+// TODO: Which text styling properties should be global or per-control?
+// At this moment TEXT_PADDING and TEXT_ALIGNMENT is configured and saved per control while
+// TEXT_SIZE, TEXT_SPACING, TEXT_LINE_SPACING, TEXT_ALIGNMENT_VERTICAL, TEXT_WRAP_MODE are global and
+// should be configured by user as needed while defining the UI layout
+
+// Gui extended properties depend on control
+// NOTE: RAYGUI_MAX_PROPS_EXTENDED properties (by default, max 8 properties)
+//----------------------------------------------------------------------------------
+// DEFAULT extended properties
+// NOTE: Those properties are common to all controls or global
+// WARNING: We only have 8 slots for those properties by default!!! -> New global control: TEXT?
+typedef enum {
+ TEXT_SIZE = 16, // Text size (glyphs max height)
+ TEXT_SPACING, // Text spacing between glyphs
+ LINE_COLOR, // Line control color
+ BACKGROUND_COLOR, // Background color
+ TEXT_LINE_SPACING, // Text spacing between lines
+ TEXT_ALIGNMENT_VERTICAL, // Text vertical alignment inside text bounds (after border and padding)
+ TEXT_WRAP_MODE // Text wrap-mode inside text bounds
+ //TEXT_DECORATION // Text decoration: 0-None, 1-Underline, 2-Line-through, 3-Overline
+ //TEXT_DECORATION_THICK // Text decoration line thickness
+} GuiDefaultProperty;
+
+// Other possible text properties:
+// TEXT_WEIGHT // Normal, Italic, Bold -> Requires specific font change
+// TEXT_INDENT // Text indentation -> Now using TEXT_PADDING...
+
+// Label
+//typedef enum { } GuiLabelProperty;
+
+// Button/Spinner
+//typedef enum { } GuiButtonProperty;
+
+// Toggle/ToggleGroup
+typedef enum {
+ GROUP_PADDING = 16, // ToggleGroup separation between toggles
+} GuiToggleProperty;
+
+// Slider/SliderBar
+typedef enum {
+ SLIDER_WIDTH = 16, // Slider size of internal bar
+ SLIDER_PADDING // Slider/SliderBar internal bar padding
+} GuiSliderProperty;
+
+// ProgressBar
+typedef enum {
+ PROGRESS_PADDING = 16, // ProgressBar internal padding
+} GuiProgressBarProperty;
+
+// ScrollBar
+typedef enum {
+ ARROWS_SIZE = 16, // ScrollBar arrows size
+ ARROWS_VISIBLE, // ScrollBar arrows visible
+ SCROLL_SLIDER_PADDING, // ScrollBar slider internal padding
+ SCROLL_SLIDER_SIZE, // ScrollBar slider size
+ SCROLL_PADDING, // ScrollBar scroll padding from arrows
+ SCROLL_SPEED, // ScrollBar scrolling speed
+} GuiScrollBarProperty;
+
+// CheckBox
+typedef enum {
+ CHECK_PADDING = 16 // CheckBox internal check padding
+} GuiCheckBoxProperty;
+
+// ComboBox
+typedef enum {
+ COMBO_BUTTON_WIDTH = 16, // ComboBox right button width
+ COMBO_BUTTON_SPACING // ComboBox button separation
+} GuiComboBoxProperty;
+
+// DropdownBox
+typedef enum {
+ ARROW_PADDING = 16, // DropdownBox arrow separation from border and items
+ DROPDOWN_ITEMS_SPACING, // DropdownBox items separation
+ DROPDOWN_ARROW_HIDDEN, // DropdownBox arrow hidden
+ DROPDOWN_ROLL_UP // DropdownBox roll up flag (default rolls down)
+} GuiDropdownBoxProperty;
+
+// TextBox/TextBoxMulti/ValueBox/Spinner
+typedef enum {
+ TEXT_READONLY = 16, // TextBox in read-only mode: 0-text editable, 1-text no-editable
+} GuiTextBoxProperty;
+
+// Spinner
+typedef enum {
+ SPIN_BUTTON_WIDTH = 16, // Spinner left/right buttons width
+ SPIN_BUTTON_SPACING, // Spinner buttons separation
+} GuiSpinnerProperty;
+
+// ListView
+typedef enum {
+ LIST_ITEMS_HEIGHT = 16, // ListView items height
+ LIST_ITEMS_SPACING, // ListView items separation
+ SCROLLBAR_WIDTH, // ListView scrollbar size (usually width)
+ SCROLLBAR_SIDE, // ListView scrollbar side (0-SCROLLBAR_LEFT_SIDE, 1-SCROLLBAR_RIGHT_SIDE)
+ LIST_ITEMS_BORDER_WIDTH // ListView items border width
+} GuiListViewProperty;
+
+// ColorPicker
+typedef enum {
+ COLOR_SELECTOR_SIZE = 16,
+ HUEBAR_WIDTH, // ColorPicker right hue bar width
+ HUEBAR_PADDING, // ColorPicker right hue bar separation from panel
+ HUEBAR_SELECTOR_HEIGHT, // ColorPicker right hue bar selector height
+ HUEBAR_SELECTOR_OVERFLOW // ColorPicker right hue bar selector overflow
+} GuiColorPickerProperty;
+
+#define SCROLLBAR_LEFT_SIDE 0
+#define SCROLLBAR_RIGHT_SIDE 1
+
+//----------------------------------------------------------------------------------
+// Global Variables Definition
+//----------------------------------------------------------------------------------
+// ...
+
+//----------------------------------------------------------------------------------
+// Module Functions Declaration
+//----------------------------------------------------------------------------------
+
+#if defined(__cplusplus)
+extern "C" { // Prevents name mangling of functions
+#endif
+
+// Global gui state control functions
+RAYGUIAPI void GuiEnable(void); // Enable gui controls (global state)
+RAYGUIAPI void GuiDisable(void); // Disable gui controls (global state)
+RAYGUIAPI void GuiLock(void); // Lock gui controls (global state)
+RAYGUIAPI void GuiUnlock(void); // Unlock gui controls (global state)
+RAYGUIAPI bool GuiIsLocked(void); // Check if gui is locked (global state)
+RAYGUIAPI void GuiSetAlpha(float alpha); // Set gui controls alpha (global state), alpha goes from 0.0f to 1.0f
+RAYGUIAPI void GuiSetState(int state); // Set gui state (global state)
+RAYGUIAPI int GuiGetState(void); // Get gui state (global state)
+
+// Font set/get functions
+RAYGUIAPI void GuiSetFont(Font font); // Set gui custom font (global state)
+RAYGUIAPI Font GuiGetFont(void); // Get gui custom font (global state)
+
+// Style set/get functions
+RAYGUIAPI void GuiSetStyle(int control, int property, int value); // Set one style property
+RAYGUIAPI int GuiGetStyle(int control, int property); // Get one style property
+
+// Styles loading functions
+RAYGUIAPI void GuiLoadStyle(const char *fileName); // Load style file over global style variable (.rgs)
+RAYGUIAPI void GuiLoadStyleDefault(void); // Load style default over global style
+
+// Tooltips management functions
+RAYGUIAPI void GuiEnableTooltip(void); // Enable gui tooltips (global state)
+RAYGUIAPI void GuiDisableTooltip(void); // Disable gui tooltips (global state)
+RAYGUIAPI void GuiSetTooltip(const char *tooltip); // Set tooltip string
+
+// Icons functionality
+RAYGUIAPI const char *GuiIconText(int iconId, const char *text); // Get text with icon id prepended (if supported)
+#if !defined(RAYGUI_NO_ICONS)
+RAYGUIAPI void GuiSetIconScale(int scale); // Set default icon drawing size
+RAYGUIAPI unsigned int *GuiGetIcons(void); // Get raygui icons data pointer
+RAYGUIAPI char **GuiLoadIcons(const char *fileName, bool loadIconsName); // Load raygui icons file (.rgi) into internal icons data
+RAYGUIAPI void GuiDrawIcon(int iconId, int posX, int posY, int pixelSize, Color color); // Draw icon using pixel size at specified position
+#endif
+
+// Controls
+//----------------------------------------------------------------------------------------------------------
+// Container/separator controls, useful for controls organization
+RAYGUIAPI int GuiWindowBox(Rectangle bounds, const char *title); // Window Box control, shows a window that can be closed
+RAYGUIAPI int GuiGroupBox(Rectangle bounds, const char *text); // Group Box control with text name
+RAYGUIAPI int GuiLine(Rectangle bounds, const char *text); // Line separator control, could contain text
+RAYGUIAPI int GuiPanel(Rectangle bounds, const char *text); // Panel control, useful to group controls
+RAYGUIAPI int GuiTabBar(Rectangle bounds, const char **text, int count, int *active); // Tab Bar control, returns TAB to be closed or -1
+RAYGUIAPI int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector2 *scroll, Rectangle *view); // Scroll Panel control
+
+// Basic controls set
+RAYGUIAPI int GuiLabel(Rectangle bounds, const char *text); // Label control
+RAYGUIAPI int GuiButton(Rectangle bounds, const char *text); // Button control, returns true when clicked
+RAYGUIAPI int GuiLabelButton(Rectangle bounds, const char *text); // Label button control, returns true when clicked
+RAYGUIAPI int GuiToggle(Rectangle bounds, const char *text, bool *active); // Toggle Button control
+RAYGUIAPI int GuiToggleGroup(Rectangle bounds, const char *text, int *active); // Toggle Group control
+RAYGUIAPI int GuiToggleSlider(Rectangle bounds, const char *text, int *active); // Toggle Slider control
+RAYGUIAPI int GuiCheckBox(Rectangle bounds, const char *text, bool *checked); // Check Box control, returns true when active
+RAYGUIAPI int GuiComboBox(Rectangle bounds, const char *text, int *active); // Combo Box control
+
+RAYGUIAPI int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMode); // Dropdown Box control
+RAYGUIAPI int GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode); // Spinner control
+RAYGUIAPI int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode); // Value Box control, updates input text with numbers
+RAYGUIAPI int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float *value, bool editMode); // Value box control for float values
+RAYGUIAPI int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode); // Text Box control, updates input text
+
+RAYGUIAPI int GuiSlider(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue); // Slider control
+RAYGUIAPI int GuiSliderBar(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue); // Slider Bar control
+RAYGUIAPI int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue); // Progress Bar control
+RAYGUIAPI int GuiStatusBar(Rectangle bounds, const char *text); // Status Bar control, shows info text
+RAYGUIAPI int GuiDummyRec(Rectangle bounds, const char *text); // Dummy control for placeholders
+RAYGUIAPI int GuiGrid(Rectangle bounds, const char *text, float spacing, int subdivs, Vector2 *mouseCell); // Grid control
+
+// Advance controls set
+RAYGUIAPI int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *active); // List View control
+RAYGUIAPI int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus); // List View with extended parameters
+RAYGUIAPI int GuiMessageBox(Rectangle bounds, const char *title, const char *message, const char *buttons); // Message Box control, displays a message
+RAYGUIAPI int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, const char *buttons, char *text, int textMaxSize, bool *secretViewActive); // Text Input Box control, ask for text, supports secret
+RAYGUIAPI int GuiColorPicker(Rectangle bounds, const char *text, Color *color); // Color Picker control (multiple color controls)
+RAYGUIAPI int GuiColorPanel(Rectangle bounds, const char *text, Color *color); // Color Panel control
+RAYGUIAPI int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha); // Color Bar Alpha control
+RAYGUIAPI int GuiColorBarHue(Rectangle bounds, const char *text, float *value); // Color Bar Hue control
+RAYGUIAPI int GuiColorPickerHSV(Rectangle bounds, const char *text, Vector3 *colorHsv); // Color Picker control that avoids conversion to RGB on each call (multiple color controls)
+RAYGUIAPI int GuiColorPanelHSV(Rectangle bounds, const char *text, Vector3 *colorHsv); // Color Panel control that updates Hue-Saturation-Value color value, used by GuiColorPickerHSV()
+//----------------------------------------------------------------------------------------------------------
+
+#if !defined(RAYGUI_NO_ICONS)
+
+#if !defined(RAYGUI_CUSTOM_ICONS)
+//----------------------------------------------------------------------------------
+// Icons enumeration
+//----------------------------------------------------------------------------------
+typedef enum {
+ ICON_NONE = 0,
+ ICON_FOLDER_FILE_OPEN = 1,
+ ICON_FILE_SAVE_CLASSIC = 2,
+ ICON_FOLDER_OPEN = 3,
+ ICON_FOLDER_SAVE = 4,
+ ICON_FILE_OPEN = 5,
+ ICON_FILE_SAVE = 6,
+ ICON_FILE_EXPORT = 7,
+ ICON_FILE_ADD = 8,
+ ICON_FILE_DELETE = 9,
+ ICON_FILETYPE_TEXT = 10,
+ ICON_FILETYPE_AUDIO = 11,
+ ICON_FILETYPE_IMAGE = 12,
+ ICON_FILETYPE_PLAY = 13,
+ ICON_FILETYPE_VIDEO = 14,
+ ICON_FILETYPE_INFO = 15,
+ ICON_FILE_COPY = 16,
+ ICON_FILE_CUT = 17,
+ ICON_FILE_PASTE = 18,
+ ICON_CURSOR_HAND = 19,
+ ICON_CURSOR_POINTER = 20,
+ ICON_CURSOR_CLASSIC = 21,
+ ICON_PENCIL = 22,
+ ICON_PENCIL_BIG = 23,
+ ICON_BRUSH_CLASSIC = 24,
+ ICON_BRUSH_PAINTER = 25,
+ ICON_WATER_DROP = 26,
+ ICON_COLOR_PICKER = 27,
+ ICON_RUBBER = 28,
+ ICON_COLOR_BUCKET = 29,
+ ICON_TEXT_T = 30,
+ ICON_TEXT_A = 31,
+ ICON_SCALE = 32,
+ ICON_RESIZE = 33,
+ ICON_FILTER_POINT = 34,
+ ICON_FILTER_BILINEAR = 35,
+ ICON_CROP = 36,
+ ICON_CROP_ALPHA = 37,
+ ICON_SQUARE_TOGGLE = 38,
+ ICON_SYMMETRY = 39,
+ ICON_SYMMETRY_HORIZONTAL = 40,
+ ICON_SYMMETRY_VERTICAL = 41,
+ ICON_LENS = 42,
+ ICON_LENS_BIG = 43,
+ ICON_EYE_ON = 44,
+ ICON_EYE_OFF = 45,
+ ICON_FILTER_TOP = 46,
+ ICON_FILTER = 47,
+ ICON_TARGET_POINT = 48,
+ ICON_TARGET_SMALL = 49,
+ ICON_TARGET_BIG = 50,
+ ICON_TARGET_MOVE = 51,
+ ICON_CURSOR_MOVE = 52,
+ ICON_CURSOR_SCALE = 53,
+ ICON_CURSOR_SCALE_RIGHT = 54,
+ ICON_CURSOR_SCALE_LEFT = 55,
+ ICON_UNDO = 56,
+ ICON_REDO = 57,
+ ICON_REREDO = 58,
+ ICON_MUTATE = 59,
+ ICON_ROTATE = 60,
+ ICON_REPEAT = 61,
+ ICON_SHUFFLE = 62,
+ ICON_EMPTYBOX = 63,
+ ICON_TARGET = 64,
+ ICON_TARGET_SMALL_FILL = 65,
+ ICON_TARGET_BIG_FILL = 66,
+ ICON_TARGET_MOVE_FILL = 67,
+ ICON_CURSOR_MOVE_FILL = 68,
+ ICON_CURSOR_SCALE_FILL = 69,
+ ICON_CURSOR_SCALE_RIGHT_FILL = 70,
+ ICON_CURSOR_SCALE_LEFT_FILL = 71,
+ ICON_UNDO_FILL = 72,
+ ICON_REDO_FILL = 73,
+ ICON_REREDO_FILL = 74,
+ ICON_MUTATE_FILL = 75,
+ ICON_ROTATE_FILL = 76,
+ ICON_REPEAT_FILL = 77,
+ ICON_SHUFFLE_FILL = 78,
+ ICON_EMPTYBOX_SMALL = 79,
+ ICON_BOX = 80,
+ ICON_BOX_TOP = 81,
+ ICON_BOX_TOP_RIGHT = 82,
+ ICON_BOX_RIGHT = 83,
+ ICON_BOX_BOTTOM_RIGHT = 84,
+ ICON_BOX_BOTTOM = 85,
+ ICON_BOX_BOTTOM_LEFT = 86,
+ ICON_BOX_LEFT = 87,
+ ICON_BOX_TOP_LEFT = 88,
+ ICON_BOX_CENTER = 89,
+ ICON_BOX_CIRCLE_MASK = 90,
+ ICON_POT = 91,
+ ICON_ALPHA_MULTIPLY = 92,
+ ICON_ALPHA_CLEAR = 93,
+ ICON_DITHERING = 94,
+ ICON_MIPMAPS = 95,
+ ICON_BOX_GRID = 96,
+ ICON_GRID = 97,
+ ICON_BOX_CORNERS_SMALL = 98,
+ ICON_BOX_CORNERS_BIG = 99,
+ ICON_FOUR_BOXES = 100,
+ ICON_GRID_FILL = 101,
+ ICON_BOX_MULTISIZE = 102,
+ ICON_ZOOM_SMALL = 103,
+ ICON_ZOOM_MEDIUM = 104,
+ ICON_ZOOM_BIG = 105,
+ ICON_ZOOM_ALL = 106,
+ ICON_ZOOM_CENTER = 107,
+ ICON_BOX_DOTS_SMALL = 108,
+ ICON_BOX_DOTS_BIG = 109,
+ ICON_BOX_CONCENTRIC = 110,
+ ICON_BOX_GRID_BIG = 111,
+ ICON_OK_TICK = 112,
+ ICON_CROSS = 113,
+ ICON_ARROW_LEFT = 114,
+ ICON_ARROW_RIGHT = 115,
+ ICON_ARROW_DOWN = 116,
+ ICON_ARROW_UP = 117,
+ ICON_ARROW_LEFT_FILL = 118,
+ ICON_ARROW_RIGHT_FILL = 119,
+ ICON_ARROW_DOWN_FILL = 120,
+ ICON_ARROW_UP_FILL = 121,
+ ICON_AUDIO = 122,
+ ICON_FX = 123,
+ ICON_WAVE = 124,
+ ICON_WAVE_SINUS = 125,
+ ICON_WAVE_SQUARE = 126,
+ ICON_WAVE_TRIANGULAR = 127,
+ ICON_CROSS_SMALL = 128,
+ ICON_PLAYER_PREVIOUS = 129,
+ ICON_PLAYER_PLAY_BACK = 130,
+ ICON_PLAYER_PLAY = 131,
+ ICON_PLAYER_PAUSE = 132,
+ ICON_PLAYER_STOP = 133,
+ ICON_PLAYER_NEXT = 134,
+ ICON_PLAYER_RECORD = 135,
+ ICON_MAGNET = 136,
+ ICON_LOCK_CLOSE = 137,
+ ICON_LOCK_OPEN = 138,
+ ICON_CLOCK = 139,
+ ICON_TOOLS = 140,
+ ICON_GEAR = 141,
+ ICON_GEAR_BIG = 142,
+ ICON_BIN = 143,
+ ICON_HAND_POINTER = 144,
+ ICON_LASER = 145,
+ ICON_COIN = 146,
+ ICON_EXPLOSION = 147,
+ ICON_1UP = 148,
+ ICON_PLAYER = 149,
+ ICON_PLAYER_JUMP = 150,
+ ICON_KEY = 151,
+ ICON_DEMON = 152,
+ ICON_TEXT_POPUP = 153,
+ ICON_GEAR_EX = 154,
+ ICON_CRACK = 155,
+ ICON_CRACK_POINTS = 156,
+ ICON_STAR = 157,
+ ICON_DOOR = 158,
+ ICON_EXIT = 159,
+ ICON_MODE_2D = 160,
+ ICON_MODE_3D = 161,
+ ICON_CUBE = 162,
+ ICON_CUBE_FACE_TOP = 163,
+ ICON_CUBE_FACE_LEFT = 164,
+ ICON_CUBE_FACE_FRONT = 165,
+ ICON_CUBE_FACE_BOTTOM = 166,
+ ICON_CUBE_FACE_RIGHT = 167,
+ ICON_CUBE_FACE_BACK = 168,
+ ICON_CAMERA = 169,
+ ICON_SPECIAL = 170,
+ ICON_LINK_NET = 171,
+ ICON_LINK_BOXES = 172,
+ ICON_LINK_MULTI = 173,
+ ICON_LINK = 174,
+ ICON_LINK_BROKE = 175,
+ ICON_TEXT_NOTES = 176,
+ ICON_NOTEBOOK = 177,
+ ICON_SUITCASE = 178,
+ ICON_SUITCASE_ZIP = 179,
+ ICON_MAILBOX = 180,
+ ICON_MONITOR = 181,
+ ICON_PRINTER = 182,
+ ICON_PHOTO_CAMERA = 183,
+ ICON_PHOTO_CAMERA_FLASH = 184,
+ ICON_HOUSE = 185,
+ ICON_HEART = 186,
+ ICON_CORNER = 187,
+ ICON_VERTICAL_BARS = 188,
+ ICON_VERTICAL_BARS_FILL = 189,
+ ICON_LIFE_BARS = 190,
+ ICON_INFO = 191,
+ ICON_CROSSLINE = 192,
+ ICON_HELP = 193,
+ ICON_FILETYPE_ALPHA = 194,
+ ICON_FILETYPE_HOME = 195,
+ ICON_LAYERS_VISIBLE = 196,
+ ICON_LAYERS = 197,
+ ICON_WINDOW = 198,
+ ICON_HIDPI = 199,
+ ICON_FILETYPE_BINARY = 200,
+ ICON_HEX = 201,
+ ICON_SHIELD = 202,
+ ICON_FILE_NEW = 203,
+ ICON_FOLDER_ADD = 204,
+ ICON_ALARM = 205,
+ ICON_CPU = 206,
+ ICON_ROM = 207,
+ ICON_STEP_OVER = 208,
+ ICON_STEP_INTO = 209,
+ ICON_STEP_OUT = 210,
+ ICON_RESTART = 211,
+ ICON_BREAKPOINT_ON = 212,
+ ICON_BREAKPOINT_OFF = 213,
+ ICON_BURGER_MENU = 214,
+ ICON_CASE_SENSITIVE = 215,
+ ICON_REG_EXP = 216,
+ ICON_FOLDER = 217,
+ ICON_FILE = 218,
+ ICON_SAND_TIMER = 219,
+ ICON_WARNING = 220,
+ ICON_HELP_BOX = 221,
+ ICON_INFO_BOX = 222,
+ ICON_PRIORITY = 223,
+ ICON_LAYERS_ISO = 224,
+ ICON_LAYERS2 = 225,
+ ICON_MLAYERS = 226,
+ ICON_MAPS = 227,
+ ICON_HOT = 228,
+ ICON_229 = 229,
+ ICON_230 = 230,
+ ICON_231 = 231,
+ ICON_232 = 232,
+ ICON_233 = 233,
+ ICON_234 = 234,
+ ICON_235 = 235,
+ ICON_236 = 236,
+ ICON_237 = 237,
+ ICON_238 = 238,
+ ICON_239 = 239,
+ ICON_240 = 240,
+ ICON_241 = 241,
+ ICON_242 = 242,
+ ICON_243 = 243,
+ ICON_244 = 244,
+ ICON_245 = 245,
+ ICON_246 = 246,
+ ICON_247 = 247,
+ ICON_248 = 248,
+ ICON_249 = 249,
+ ICON_250 = 250,
+ ICON_251 = 251,
+ ICON_252 = 252,
+ ICON_253 = 253,
+ ICON_254 = 254,
+ ICON_255 = 255,
+} GuiIconName;
+#endif
+
+#endif
+
+#if defined(__cplusplus)
+} // Prevents name mangling of functions
+#endif
+
+#endif // RAYGUI_H
+
+/***********************************************************************************
+*
+* RAYGUI IMPLEMENTATION
+*
+************************************************************************************/
+
+#if defined(RAYGUI_IMPLEMENTATION)
+
+#include // required for: isspace() [GuiTextBox()]
+#include // Required for: FILE, fopen(), fclose(), fprintf(), feof(), fscanf(), vsprintf() [GuiLoadStyle(), GuiLoadIcons()]
+#include // Required for: malloc(), calloc(), free() [GuiLoadStyle(), GuiLoadIcons()]
+#include // Required for: strlen() [GuiTextBox(), GuiValueBox()], memset(), memcpy()
+#include // Required for: va_list, va_start(), vfprintf(), va_end() [TextFormat()]
+#include // Required for: roundf() [GuiColorPicker()]
+
+#ifdef __cplusplus
+ #define RAYGUI_CLITERAL(name) name
+#else
+ #define RAYGUI_CLITERAL(name) (name)
+#endif
+
+// Check if two rectangles are equal, used to validate a slider bounds as an id
+#ifndef CHECK_BOUNDS_ID
+ #define CHECK_BOUNDS_ID(src, dst) ((src.x == dst.x) && (src.y == dst.y) && (src.width == dst.width) && (src.height == dst.height))
+#endif
+
+#if !defined(RAYGUI_NO_ICONS) && !defined(RAYGUI_CUSTOM_ICONS)
+
+// Embedded icons, no external file provided
+#define RAYGUI_ICON_SIZE 16 // Size of icons in pixels (squared)
+#define RAYGUI_ICON_MAX_ICONS 256 // Maximum number of icons
+#define RAYGUI_ICON_MAX_NAME_LENGTH 32 // Maximum length of icon name id
+
+// Icons data is defined by bit array (every bit represents one pixel)
+// Those arrays are stored as unsigned int data arrays, so,
+// every array element defines 32 pixels (bits) of information
+// One icon is defined by 8 int, (8 int * 32 bit = 256 bit = 16*16 pixels)
+// NOTE: Number of elemens depend on RAYGUI_ICON_SIZE (by default 16x16 pixels)
+#define RAYGUI_ICON_DATA_ELEMENTS (RAYGUI_ICON_SIZE*RAYGUI_ICON_SIZE/32)
+
+//----------------------------------------------------------------------------------
+// Icons data for all gui possible icons (allocated on data segment by default)
+//
+// NOTE 1: Every icon is codified in binary form, using 1 bit per pixel, so,
+// every 16x16 icon requires 8 integers (16*16/32) to be stored
+//
+// NOTE 2: A different icon set could be loaded over this array using GuiLoadIcons(),
+// but loaded icons set must be same RAYGUI_ICON_SIZE and no more than RAYGUI_ICON_MAX_ICONS
+//
+// guiIcons size is by default: 256*(16*16/32) = 2048*4 = 8192 bytes = 8 KB
+//----------------------------------------------------------------------------------
+static unsigned int guiIcons[RAYGUI_ICON_MAX_ICONS*RAYGUI_ICON_DATA_ELEMENTS] = {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_NONE
+ 0x3ff80000, 0x2f082008, 0x2042207e, 0x40027fc2, 0x40024002, 0x40024002, 0x40024002, 0x00007ffe, // ICON_FOLDER_FILE_OPEN
+ 0x3ffe0000, 0x44226422, 0x400247e2, 0x5ffa4002, 0x57ea500a, 0x500a500a, 0x40025ffa, 0x00007ffe, // ICON_FILE_SAVE_CLASSIC
+ 0x00000000, 0x0042007e, 0x40027fc2, 0x40024002, 0x41024002, 0x44424282, 0x793e4102, 0x00000100, // ICON_FOLDER_OPEN
+ 0x00000000, 0x0042007e, 0x40027fc2, 0x40024002, 0x41024102, 0x44424102, 0x793e4282, 0x00000000, // ICON_FOLDER_SAVE
+ 0x3ff00000, 0x201c2010, 0x20042004, 0x21042004, 0x24442284, 0x21042104, 0x20042104, 0x00003ffc, // ICON_FILE_OPEN
+ 0x3ff00000, 0x201c2010, 0x20042004, 0x21042004, 0x21042104, 0x22842444, 0x20042104, 0x00003ffc, // ICON_FILE_SAVE
+ 0x3ff00000, 0x201c2010, 0x00042004, 0x20041004, 0x20844784, 0x00841384, 0x20042784, 0x00003ffc, // ICON_FILE_EXPORT
+ 0x3ff00000, 0x201c2010, 0x20042004, 0x20042004, 0x22042204, 0x22042f84, 0x20042204, 0x00003ffc, // ICON_FILE_ADD
+ 0x3ff00000, 0x201c2010, 0x20042004, 0x20042004, 0x25042884, 0x25042204, 0x20042884, 0x00003ffc, // ICON_FILE_DELETE
+ 0x3ff00000, 0x201c2010, 0x20042004, 0x20042ff4, 0x20042ff4, 0x20042ff4, 0x20042004, 0x00003ffc, // ICON_FILETYPE_TEXT
+ 0x3ff00000, 0x201c2010, 0x27042004, 0x244424c4, 0x26442444, 0x20642664, 0x20042004, 0x00003ffc, // ICON_FILETYPE_AUDIO
+ 0x3ff00000, 0x201c2010, 0x26042604, 0x20042004, 0x35442884, 0x2414222c, 0x20042004, 0x00003ffc, // ICON_FILETYPE_IMAGE
+ 0x3ff00000, 0x201c2010, 0x20c42004, 0x22442144, 0x22442444, 0x20c42144, 0x20042004, 0x00003ffc, // ICON_FILETYPE_PLAY
+ 0x3ff00000, 0x3ffc2ff0, 0x3f3c2ff4, 0x3dbc2eb4, 0x3dbc2bb4, 0x3f3c2eb4, 0x3ffc2ff4, 0x00002ff4, // ICON_FILETYPE_VIDEO
+ 0x3ff00000, 0x201c2010, 0x21842184, 0x21842004, 0x21842184, 0x21842184, 0x20042184, 0x00003ffc, // ICON_FILETYPE_INFO
+ 0x0ff00000, 0x381c0810, 0x28042804, 0x28042804, 0x28042804, 0x28042804, 0x20102ffc, 0x00003ff0, // ICON_FILE_COPY
+ 0x00000000, 0x701c0000, 0x079c1e14, 0x55a000f0, 0x079c00f0, 0x701c1e14, 0x00000000, 0x00000000, // ICON_FILE_CUT
+ 0x01c00000, 0x13e41bec, 0x3f841004, 0x204420c4, 0x20442044, 0x20442044, 0x207c2044, 0x00003fc0, // ICON_FILE_PASTE
+ 0x00000000, 0x3aa00fe0, 0x2abc2aa0, 0x2aa42aa4, 0x20042aa4, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_CURSOR_HAND
+ 0x00000000, 0x003c000c, 0x030800c8, 0x30100c10, 0x10202020, 0x04400840, 0x01800280, 0x00000000, // ICON_CURSOR_POINTER
+ 0x00000000, 0x00180000, 0x01f00078, 0x03e007f0, 0x07c003e0, 0x04000e40, 0x00000000, 0x00000000, // ICON_CURSOR_CLASSIC
+ 0x00000000, 0x04000000, 0x11000a00, 0x04400a80, 0x01100220, 0x00580088, 0x00000038, 0x00000000, // ICON_PENCIL
+ 0x04000000, 0x15000a00, 0x50402880, 0x14102820, 0x05040a08, 0x015c028c, 0x007c00bc, 0x00000000, // ICON_PENCIL_BIG
+ 0x01c00000, 0x01400140, 0x01400140, 0x0ff80140, 0x0ff80808, 0x0aa80808, 0x0aa80aa8, 0x00000ff8, // ICON_BRUSH_CLASSIC
+ 0x1ffc0000, 0x5ffc7ffe, 0x40004000, 0x00807f80, 0x01c001c0, 0x01c001c0, 0x01c001c0, 0x00000080, // ICON_BRUSH_PAINTER
+ 0x00000000, 0x00800000, 0x01c00080, 0x03e001c0, 0x07f003e0, 0x036006f0, 0x000001c0, 0x00000000, // ICON_WATER_DROP
+ 0x00000000, 0x3e003800, 0x1f803f80, 0x0c201e40, 0x02080c10, 0x00840104, 0x00380044, 0x00000000, // ICON_COLOR_PICKER
+ 0x00000000, 0x07800300, 0x1fe00fc0, 0x3f883fd0, 0x0e021f04, 0x02040402, 0x00f00108, 0x00000000, // ICON_RUBBER
+ 0x00c00000, 0x02800140, 0x08200440, 0x20081010, 0x2ffe3004, 0x03f807fc, 0x00e001f0, 0x00000040, // ICON_COLOR_BUCKET
+ 0x00000000, 0x21843ffc, 0x01800180, 0x01800180, 0x01800180, 0x01800180, 0x03c00180, 0x00000000, // ICON_TEXT_T
+ 0x00800000, 0x01400180, 0x06200340, 0x0c100620, 0x1ff80c10, 0x380c1808, 0x70067004, 0x0000f80f, // ICON_TEXT_A
+ 0x78000000, 0x50004000, 0x00004800, 0x03c003c0, 0x03c003c0, 0x00100000, 0x0002000a, 0x0000000e, // ICON_SCALE
+ 0x75560000, 0x5e004002, 0x54001002, 0x41001202, 0x408200fe, 0x40820082, 0x40820082, 0x00006afe, // ICON_RESIZE
+ 0x00000000, 0x3f003f00, 0x3f003f00, 0x3f003f00, 0x00400080, 0x001c0020, 0x001c001c, 0x00000000, // ICON_FILTER_POINT
+ 0x6d800000, 0x00004080, 0x40804080, 0x40800000, 0x00406d80, 0x001c0020, 0x001c001c, 0x00000000, // ICON_FILTER_BILINEAR
+ 0x40080000, 0x1ffe2008, 0x14081008, 0x11081208, 0x10481088, 0x10081028, 0x10047ff8, 0x00001002, // ICON_CROP
+ 0x00100000, 0x3ffc0010, 0x2ab03550, 0x22b02550, 0x20b02150, 0x20302050, 0x2000fff0, 0x00002000, // ICON_CROP_ALPHA
+ 0x40000000, 0x1ff82000, 0x04082808, 0x01082208, 0x00482088, 0x00182028, 0x35542008, 0x00000002, // ICON_SQUARE_TOGGLE
+ 0x00000000, 0x02800280, 0x06c006c0, 0x0ea00ee0, 0x1e901eb0, 0x3e883e98, 0x7efc7e8c, 0x00000000, // ICON_SYMMETRY
+ 0x01000000, 0x05600100, 0x1d480d50, 0x7d423d44, 0x3d447d42, 0x0d501d48, 0x01000560, 0x00000100, // ICON_SYMMETRY_HORIZONTAL
+ 0x01800000, 0x04200240, 0x10080810, 0x00001ff8, 0x00007ffe, 0x0ff01ff8, 0x03c007e0, 0x00000180, // ICON_SYMMETRY_VERTICAL
+ 0x00000000, 0x010800f0, 0x02040204, 0x02040204, 0x07f00308, 0x1c000e00, 0x30003800, 0x00000000, // ICON_LENS
+ 0x00000000, 0x061803f0, 0x08240c0c, 0x08040814, 0x0c0c0804, 0x23f01618, 0x18002400, 0x00000000, // ICON_LENS_BIG
+ 0x00000000, 0x00000000, 0x1c7007c0, 0x638e3398, 0x1c703398, 0x000007c0, 0x00000000, 0x00000000, // ICON_EYE_ON
+ 0x00000000, 0x10002000, 0x04700fc0, 0x610e3218, 0x1c703098, 0x001007a0, 0x00000008, 0x00000000, // ICON_EYE_OFF
+ 0x00000000, 0x00007ffc, 0x40047ffc, 0x10102008, 0x04400820, 0x02800280, 0x02800280, 0x00000100, // ICON_FILTER_TOP
+ 0x00000000, 0x40027ffe, 0x10082004, 0x04200810, 0x02400240, 0x02400240, 0x01400240, 0x000000c0, // ICON_FILTER
+ 0x00800000, 0x00800080, 0x00000080, 0x3c9e0000, 0x00000000, 0x00800080, 0x00800080, 0x00000000, // ICON_TARGET_POINT
+ 0x00800000, 0x00800080, 0x00800080, 0x3f7e01c0, 0x008001c0, 0x00800080, 0x00800080, 0x00000000, // ICON_TARGET_SMALL
+ 0x00800000, 0x00800080, 0x03e00080, 0x3e3e0220, 0x03e00220, 0x00800080, 0x00800080, 0x00000000, // ICON_TARGET_BIG
+ 0x01000000, 0x04400280, 0x01000100, 0x43842008, 0x43849ab2, 0x01002008, 0x04400100, 0x01000280, // ICON_TARGET_MOVE
+ 0x01000000, 0x04400280, 0x01000100, 0x41042108, 0x41049ff2, 0x01002108, 0x04400100, 0x01000280, // ICON_CURSOR_MOVE
+ 0x781e0000, 0x500a4002, 0x04204812, 0x00000240, 0x02400000, 0x48120420, 0x4002500a, 0x0000781e, // ICON_CURSOR_SCALE
+ 0x00000000, 0x20003c00, 0x24002800, 0x01000200, 0x00400080, 0x00140024, 0x003c0004, 0x00000000, // ICON_CURSOR_SCALE_RIGHT
+ 0x00000000, 0x0004003c, 0x00240014, 0x00800040, 0x02000100, 0x28002400, 0x3c002000, 0x00000000, // ICON_CURSOR_SCALE_LEFT
+ 0x00000000, 0x00100020, 0x10101fc8, 0x10001020, 0x10001000, 0x10001000, 0x00001fc0, 0x00000000, // ICON_UNDO
+ 0x00000000, 0x08000400, 0x080813f8, 0x00080408, 0x00080008, 0x00080008, 0x000003f8, 0x00000000, // ICON_REDO
+ 0x00000000, 0x3ffc0000, 0x20042004, 0x20002000, 0x20402000, 0x3f902020, 0x00400020, 0x00000000, // ICON_REREDO
+ 0x00000000, 0x3ffc0000, 0x20042004, 0x27fc2004, 0x20202000, 0x3fc82010, 0x00200010, 0x00000000, // ICON_MUTATE
+ 0x00000000, 0x0ff00000, 0x10081818, 0x11801008, 0x10001180, 0x18101020, 0x00100fc8, 0x00000020, // ICON_ROTATE
+ 0x00000000, 0x04000200, 0x240429fc, 0x20042204, 0x20442004, 0x3f942024, 0x00400020, 0x00000000, // ICON_REPEAT
+ 0x00000000, 0x20001000, 0x22104c0e, 0x00801120, 0x11200040, 0x4c0e2210, 0x10002000, 0x00000000, // ICON_SHUFFLE
+ 0x7ffe0000, 0x50024002, 0x44024802, 0x41024202, 0x40424082, 0x40124022, 0x4002400a, 0x00007ffe, // ICON_EMPTYBOX
+ 0x00800000, 0x03e00080, 0x08080490, 0x3c9e0808, 0x08080808, 0x03e00490, 0x00800080, 0x00000000, // ICON_TARGET
+ 0x00800000, 0x00800080, 0x00800080, 0x3ffe01c0, 0x008001c0, 0x00800080, 0x00800080, 0x00000000, // ICON_TARGET_SMALL_FILL
+ 0x00800000, 0x00800080, 0x03e00080, 0x3ffe03e0, 0x03e003e0, 0x00800080, 0x00800080, 0x00000000, // ICON_TARGET_BIG_FILL
+ 0x01000000, 0x07c00380, 0x01000100, 0x638c2008, 0x638cfbbe, 0x01002008, 0x07c00100, 0x01000380, // ICON_TARGET_MOVE_FILL
+ 0x01000000, 0x07c00380, 0x01000100, 0x610c2108, 0x610cfffe, 0x01002108, 0x07c00100, 0x01000380, // ICON_CURSOR_MOVE_FILL
+ 0x781e0000, 0x6006700e, 0x04204812, 0x00000240, 0x02400000, 0x48120420, 0x700e6006, 0x0000781e, // ICON_CURSOR_SCALE_FILL
+ 0x00000000, 0x38003c00, 0x24003000, 0x01000200, 0x00400080, 0x000c0024, 0x003c001c, 0x00000000, // ICON_CURSOR_SCALE_RIGHT_FILL
+ 0x00000000, 0x001c003c, 0x0024000c, 0x00800040, 0x02000100, 0x30002400, 0x3c003800, 0x00000000, // ICON_CURSOR_SCALE_LEFT_FILL
+ 0x00000000, 0x00300020, 0x10301ff8, 0x10001020, 0x10001000, 0x10001000, 0x00001fc0, 0x00000000, // ICON_UNDO_FILL
+ 0x00000000, 0x0c000400, 0x0c081ff8, 0x00080408, 0x00080008, 0x00080008, 0x000003f8, 0x00000000, // ICON_REDO_FILL
+ 0x00000000, 0x3ffc0000, 0x20042004, 0x20002000, 0x20402000, 0x3ff02060, 0x00400060, 0x00000000, // ICON_REREDO_FILL
+ 0x00000000, 0x3ffc0000, 0x20042004, 0x27fc2004, 0x20202000, 0x3ff82030, 0x00200030, 0x00000000, // ICON_MUTATE_FILL
+ 0x00000000, 0x0ff00000, 0x10081818, 0x11801008, 0x10001180, 0x18301020, 0x00300ff8, 0x00000020, // ICON_ROTATE_FILL
+ 0x00000000, 0x06000200, 0x26042ffc, 0x20042204, 0x20442004, 0x3ff42064, 0x00400060, 0x00000000, // ICON_REPEAT_FILL
+ 0x00000000, 0x30001000, 0x32107c0e, 0x00801120, 0x11200040, 0x7c0e3210, 0x10003000, 0x00000000, // ICON_SHUFFLE_FILL
+ 0x00000000, 0x30043ffc, 0x24042804, 0x21042204, 0x20442084, 0x20142024, 0x3ffc200c, 0x00000000, // ICON_EMPTYBOX_SMALL
+ 0x00000000, 0x20043ffc, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_BOX
+ 0x00000000, 0x23c43ffc, 0x23c423c4, 0x200423c4, 0x20042004, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_BOX_TOP
+ 0x00000000, 0x3e043ffc, 0x3e043e04, 0x20043e04, 0x20042004, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_BOX_TOP_RIGHT
+ 0x00000000, 0x20043ffc, 0x20042004, 0x3e043e04, 0x3e043e04, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_BOX_RIGHT
+ 0x00000000, 0x20043ffc, 0x20042004, 0x20042004, 0x3e042004, 0x3e043e04, 0x3ffc3e04, 0x00000000, // ICON_BOX_BOTTOM_RIGHT
+ 0x00000000, 0x20043ffc, 0x20042004, 0x20042004, 0x23c42004, 0x23c423c4, 0x3ffc23c4, 0x00000000, // ICON_BOX_BOTTOM
+ 0x00000000, 0x20043ffc, 0x20042004, 0x20042004, 0x207c2004, 0x207c207c, 0x3ffc207c, 0x00000000, // ICON_BOX_BOTTOM_LEFT
+ 0x00000000, 0x20043ffc, 0x20042004, 0x207c207c, 0x207c207c, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_BOX_LEFT
+ 0x00000000, 0x207c3ffc, 0x207c207c, 0x2004207c, 0x20042004, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_BOX_TOP_LEFT
+ 0x00000000, 0x20043ffc, 0x20042004, 0x23c423c4, 0x23c423c4, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_BOX_CENTER
+ 0x7ffe0000, 0x40024002, 0x47e24182, 0x4ff247e2, 0x47e24ff2, 0x418247e2, 0x40024002, 0x00007ffe, // ICON_BOX_CIRCLE_MASK
+ 0x7fff0000, 0x40014001, 0x40014001, 0x49555ddd, 0x4945495d, 0x400149c5, 0x40014001, 0x00007fff, // ICON_POT
+ 0x7ffe0000, 0x53327332, 0x44ce4cce, 0x41324332, 0x404e40ce, 0x48125432, 0x4006540e, 0x00007ffe, // ICON_ALPHA_MULTIPLY
+ 0x7ffe0000, 0x53327332, 0x44ce4cce, 0x41324332, 0x5c4e40ce, 0x44124432, 0x40065c0e, 0x00007ffe, // ICON_ALPHA_CLEAR
+ 0x7ffe0000, 0x42fe417e, 0x42fe417e, 0x42fe417e, 0x42fe417e, 0x42fe417e, 0x42fe417e, 0x00007ffe, // ICON_DITHERING
+ 0x07fe0000, 0x1ffa0002, 0x7fea000a, 0x402a402a, 0x5b2a512a, 0x5128552a, 0x40205128, 0x00007fe0, // ICON_MIPMAPS
+ 0x00000000, 0x1ff80000, 0x12481248, 0x12481ff8, 0x1ff81248, 0x12481248, 0x00001ff8, 0x00000000, // ICON_BOX_GRID
+ 0x12480000, 0x7ffe1248, 0x12481248, 0x12487ffe, 0x7ffe1248, 0x12481248, 0x12487ffe, 0x00001248, // ICON_GRID
+ 0x00000000, 0x1c380000, 0x1c3817e8, 0x08100810, 0x08100810, 0x17e81c38, 0x00001c38, 0x00000000, // ICON_BOX_CORNERS_SMALL
+ 0x700e0000, 0x700e5ffa, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x5ffa700e, 0x0000700e, // ICON_BOX_CORNERS_BIG
+ 0x3f7e0000, 0x21422142, 0x21422142, 0x00003f7e, 0x21423f7e, 0x21422142, 0x3f7e2142, 0x00000000, // ICON_FOUR_BOXES
+ 0x00000000, 0x3bb80000, 0x3bb83bb8, 0x3bb80000, 0x3bb83bb8, 0x3bb80000, 0x3bb83bb8, 0x00000000, // ICON_GRID_FILL
+ 0x7ffe0000, 0x7ffe7ffe, 0x77fe7000, 0x77fe77fe, 0x777e7700, 0x777e777e, 0x777e777e, 0x0000777e, // ICON_BOX_MULTISIZE
+ 0x781e0000, 0x40024002, 0x00004002, 0x01800000, 0x00000180, 0x40020000, 0x40024002, 0x0000781e, // ICON_ZOOM_SMALL
+ 0x781e0000, 0x40024002, 0x00004002, 0x03c003c0, 0x03c003c0, 0x40020000, 0x40024002, 0x0000781e, // ICON_ZOOM_MEDIUM
+ 0x781e0000, 0x40024002, 0x07e04002, 0x07e007e0, 0x07e007e0, 0x400207e0, 0x40024002, 0x0000781e, // ICON_ZOOM_BIG
+ 0x781e0000, 0x5ffa4002, 0x1ff85ffa, 0x1ff81ff8, 0x1ff81ff8, 0x5ffa1ff8, 0x40025ffa, 0x0000781e, // ICON_ZOOM_ALL
+ 0x00000000, 0x2004381c, 0x00002004, 0x00000000, 0x00000000, 0x20040000, 0x381c2004, 0x00000000, // ICON_ZOOM_CENTER
+ 0x00000000, 0x1db80000, 0x10081008, 0x10080000, 0x00001008, 0x10081008, 0x00001db8, 0x00000000, // ICON_BOX_DOTS_SMALL
+ 0x35560000, 0x00002002, 0x00002002, 0x00002002, 0x00002002, 0x00002002, 0x35562002, 0x00000000, // ICON_BOX_DOTS_BIG
+ 0x7ffe0000, 0x40024002, 0x48124ff2, 0x49924812, 0x48124992, 0x4ff24812, 0x40024002, 0x00007ffe, // ICON_BOX_CONCENTRIC
+ 0x00000000, 0x10841ffc, 0x10841084, 0x1ffc1084, 0x10841084, 0x10841084, 0x00001ffc, 0x00000000, // ICON_BOX_GRID_BIG
+ 0x00000000, 0x00000000, 0x10000000, 0x04000800, 0x01040200, 0x00500088, 0x00000020, 0x00000000, // ICON_OK_TICK
+ 0x00000000, 0x10080000, 0x04200810, 0x01800240, 0x02400180, 0x08100420, 0x00001008, 0x00000000, // ICON_CROSS
+ 0x00000000, 0x02000000, 0x00800100, 0x00200040, 0x00200010, 0x00800040, 0x02000100, 0x00000000, // ICON_ARROW_LEFT
+ 0x00000000, 0x00400000, 0x01000080, 0x04000200, 0x04000800, 0x01000200, 0x00400080, 0x00000000, // ICON_ARROW_RIGHT
+ 0x00000000, 0x00000000, 0x00000000, 0x08081004, 0x02200410, 0x00800140, 0x00000000, 0x00000000, // ICON_ARROW_DOWN
+ 0x00000000, 0x00000000, 0x01400080, 0x04100220, 0x10040808, 0x00000000, 0x00000000, 0x00000000, // ICON_ARROW_UP
+ 0x00000000, 0x02000000, 0x03800300, 0x03e003c0, 0x03e003f0, 0x038003c0, 0x02000300, 0x00000000, // ICON_ARROW_LEFT_FILL
+ 0x00000000, 0x00400000, 0x01c000c0, 0x07c003c0, 0x07c00fc0, 0x01c003c0, 0x004000c0, 0x00000000, // ICON_ARROW_RIGHT_FILL
+ 0x00000000, 0x00000000, 0x00000000, 0x0ff81ffc, 0x03e007f0, 0x008001c0, 0x00000000, 0x00000000, // ICON_ARROW_DOWN_FILL
+ 0x00000000, 0x00000000, 0x01c00080, 0x07f003e0, 0x1ffc0ff8, 0x00000000, 0x00000000, 0x00000000, // ICON_ARROW_UP_FILL
+ 0x00000000, 0x18a008c0, 0x32881290, 0x24822686, 0x26862482, 0x12903288, 0x08c018a0, 0x00000000, // ICON_AUDIO
+ 0x00000000, 0x04800780, 0x004000c0, 0x662000f0, 0x08103c30, 0x130a0e18, 0x0000318e, 0x00000000, // ICON_FX
+ 0x00000000, 0x00800000, 0x08880888, 0x2aaa0a8a, 0x0a8a2aaa, 0x08880888, 0x00000080, 0x00000000, // ICON_WAVE
+ 0x00000000, 0x00600000, 0x01080090, 0x02040108, 0x42044204, 0x24022402, 0x00001800, 0x00000000, // ICON_WAVE_SINUS
+ 0x00000000, 0x07f80000, 0x04080408, 0x04080408, 0x04080408, 0x7c0e0408, 0x00000000, 0x00000000, // ICON_WAVE_SQUARE
+ 0x00000000, 0x00000000, 0x00a00040, 0x22084110, 0x08021404, 0x00000000, 0x00000000, 0x00000000, // ICON_WAVE_TRIANGULAR
+ 0x00000000, 0x00000000, 0x04200000, 0x01800240, 0x02400180, 0x00000420, 0x00000000, 0x00000000, // ICON_CROSS_SMALL
+ 0x00000000, 0x18380000, 0x12281428, 0x10a81128, 0x112810a8, 0x14281228, 0x00001838, 0x00000000, // ICON_PLAYER_PREVIOUS
+ 0x00000000, 0x18000000, 0x11801600, 0x10181060, 0x10601018, 0x16001180, 0x00001800, 0x00000000, // ICON_PLAYER_PLAY_BACK
+ 0x00000000, 0x00180000, 0x01880068, 0x18080608, 0x06081808, 0x00680188, 0x00000018, 0x00000000, // ICON_PLAYER_PLAY
+ 0x00000000, 0x1e780000, 0x12481248, 0x12481248, 0x12481248, 0x12481248, 0x00001e78, 0x00000000, // ICON_PLAYER_PAUSE
+ 0x00000000, 0x1ff80000, 0x10081008, 0x10081008, 0x10081008, 0x10081008, 0x00001ff8, 0x00000000, // ICON_PLAYER_STOP
+ 0x00000000, 0x1c180000, 0x14481428, 0x15081488, 0x14881508, 0x14281448, 0x00001c18, 0x00000000, // ICON_PLAYER_NEXT
+ 0x00000000, 0x03c00000, 0x08100420, 0x10081008, 0x10081008, 0x04200810, 0x000003c0, 0x00000000, // ICON_PLAYER_RECORD
+ 0x00000000, 0x0c3007e0, 0x13c81818, 0x14281668, 0x14281428, 0x1c381c38, 0x08102244, 0x00000000, // ICON_MAGNET
+ 0x07c00000, 0x08200820, 0x3ff80820, 0x23882008, 0x21082388, 0x20082108, 0x1ff02008, 0x00000000, // ICON_LOCK_CLOSE
+ 0x07c00000, 0x08000800, 0x3ff80800, 0x23882008, 0x21082388, 0x20082108, 0x1ff02008, 0x00000000, // ICON_LOCK_OPEN
+ 0x01c00000, 0x0c180770, 0x3086188c, 0x60832082, 0x60034781, 0x30062002, 0x0c18180c, 0x01c00770, // ICON_CLOCK
+ 0x0a200000, 0x1b201b20, 0x04200e20, 0x04200420, 0x04700420, 0x0e700e70, 0x0e700e70, 0x04200e70, // ICON_TOOLS
+ 0x01800000, 0x3bdc318c, 0x0ff01ff8, 0x7c3e1e78, 0x1e787c3e, 0x1ff80ff0, 0x318c3bdc, 0x00000180, // ICON_GEAR
+ 0x01800000, 0x3ffc318c, 0x1c381ff8, 0x781e1818, 0x1818781e, 0x1ff81c38, 0x318c3ffc, 0x00000180, // ICON_GEAR_BIG
+ 0x00000000, 0x08080ff8, 0x08081ffc, 0x0aa80aa8, 0x0aa80aa8, 0x0aa80aa8, 0x08080aa8, 0x00000ff8, // ICON_BIN
+ 0x00000000, 0x00000000, 0x20043ffc, 0x08043f84, 0x04040f84, 0x04040784, 0x000007fc, 0x00000000, // ICON_HAND_POINTER
+ 0x00000000, 0x24400400, 0x00001480, 0x6efe0e00, 0x00000e00, 0x24401480, 0x00000400, 0x00000000, // ICON_LASER
+ 0x00000000, 0x03c00000, 0x08300460, 0x11181118, 0x11181118, 0x04600830, 0x000003c0, 0x00000000, // ICON_COIN
+ 0x00000000, 0x10880080, 0x06c00810, 0x366c07e0, 0x07e00240, 0x00001768, 0x04200240, 0x00000000, // ICON_EXPLOSION
+ 0x00000000, 0x3d280000, 0x2528252c, 0x3d282528, 0x05280528, 0x05e80528, 0x00000000, 0x00000000, // ICON_1UP
+ 0x01800000, 0x03c003c0, 0x018003c0, 0x0ff007e0, 0x0bd00bd0, 0x0a500bd0, 0x02400240, 0x02400240, // ICON_PLAYER
+ 0x01800000, 0x03c003c0, 0x118013c0, 0x03c81ff8, 0x07c003c8, 0x04400440, 0x0c080478, 0x00000000, // ICON_PLAYER_JUMP
+ 0x3ff80000, 0x30183ff8, 0x30183018, 0x3ff83ff8, 0x03000300, 0x03c003c0, 0x03e00300, 0x000003e0, // ICON_KEY
+ 0x3ff80000, 0x3ff83ff8, 0x33983ff8, 0x3ff83398, 0x3ff83ff8, 0x00000540, 0x0fe00aa0, 0x00000fe0, // ICON_DEMON
+ 0x00000000, 0x0ff00000, 0x20041008, 0x25442004, 0x10082004, 0x06000bf0, 0x00000300, 0x00000000, // ICON_TEXT_POPUP
+ 0x00000000, 0x11440000, 0x07f00be8, 0x1c1c0e38, 0x1c1c0c18, 0x07f00e38, 0x11440be8, 0x00000000, // ICON_GEAR_EX
+ 0x00000000, 0x20080000, 0x0c601010, 0x07c00fe0, 0x07c007c0, 0x0c600fe0, 0x20081010, 0x00000000, // ICON_CRACK
+ 0x00000000, 0x20080000, 0x0c601010, 0x04400fe0, 0x04405554, 0x0c600fe0, 0x20081010, 0x00000000, // ICON_CRACK_POINTS
+ 0x00000000, 0x00800080, 0x01c001c0, 0x1ffc3ffe, 0x03e007f0, 0x07f003e0, 0x0c180770, 0x00000808, // ICON_STAR
+ 0x0ff00000, 0x08180810, 0x08100818, 0x0a100810, 0x08180810, 0x08100818, 0x08100810, 0x00001ff8, // ICON_DOOR
+ 0x0ff00000, 0x08100810, 0x08100810, 0x10100010, 0x4f902010, 0x10102010, 0x08100010, 0x00000ff0, // ICON_EXIT
+ 0x00040000, 0x001f000e, 0x0ef40004, 0x12f41284, 0x0ef41214, 0x10040004, 0x7ffc3004, 0x10003000, // ICON_MODE_2D
+ 0x78040000, 0x501f600e, 0x0ef44004, 0x12f41284, 0x0ef41284, 0x10140004, 0x7ffc300c, 0x10003000, // ICON_MODE_3D
+ 0x7fe00000, 0x50286030, 0x47fe4804, 0x44224402, 0x44224422, 0x241275e2, 0x0c06140a, 0x000007fe, // ICON_CUBE
+ 0x7fe00000, 0x5ff87ff0, 0x47fe4ffc, 0x44224402, 0x44224422, 0x241275e2, 0x0c06140a, 0x000007fe, // ICON_CUBE_FACE_TOP
+ 0x7fe00000, 0x50386030, 0x47c2483c, 0x443e443e, 0x443e443e, 0x241e75fe, 0x0c06140e, 0x000007fe, // ICON_CUBE_FACE_LEFT
+ 0x7fe00000, 0x50286030, 0x47fe4804, 0x47fe47fe, 0x47fe47fe, 0x27fe77fe, 0x0ffe17fe, 0x000007fe, // ICON_CUBE_FACE_FRONT
+ 0x7fe00000, 0x50286030, 0x47fe4804, 0x44224402, 0x44224422, 0x3bf27be2, 0x0bfe1bfa, 0x000007fe, // ICON_CUBE_FACE_BOTTOM
+ 0x7fe00000, 0x70286030, 0x7ffe7804, 0x7c227c02, 0x7c227c22, 0x3c127de2, 0x0c061c0a, 0x000007fe, // ICON_CUBE_FACE_RIGHT
+ 0x7fe00000, 0x6fe85ff0, 0x781e77e4, 0x7be27be2, 0x7be27be2, 0x24127be2, 0x0c06140a, 0x000007fe, // ICON_CUBE_FACE_BACK
+ 0x00000000, 0x2a0233fe, 0x22022602, 0x22022202, 0x2a022602, 0x00a033fe, 0x02080110, 0x00000000, // ICON_CAMERA
+ 0x00000000, 0x200c3ffc, 0x000c000c, 0x3ffc000c, 0x30003000, 0x30003000, 0x3ffc3004, 0x00000000, // ICON_SPECIAL
+ 0x00000000, 0x0022003e, 0x012201e2, 0x0100013e, 0x01000100, 0x79000100, 0x4f004900, 0x00007800, // ICON_LINK_NET
+ 0x00000000, 0x44007c00, 0x45004600, 0x00627cbe, 0x00620022, 0x45007cbe, 0x44004600, 0x00007c00, // ICON_LINK_BOXES
+ 0x00000000, 0x0044007c, 0x0010007c, 0x3f100010, 0x3f1021f0, 0x3f100010, 0x3f0021f0, 0x00000000, // ICON_LINK_MULTI
+ 0x00000000, 0x0044007c, 0x00440044, 0x0010007c, 0x00100010, 0x44107c10, 0x440047f0, 0x00007c00, // ICON_LINK
+ 0x00000000, 0x0044007c, 0x00440044, 0x0000007c, 0x00000010, 0x44007c10, 0x44004550, 0x00007c00, // ICON_LINK_BROKE
+ 0x02a00000, 0x22a43ffc, 0x20042004, 0x20042ff4, 0x20042ff4, 0x20042ff4, 0x20042004, 0x00003ffc, // ICON_TEXT_NOTES
+ 0x3ffc0000, 0x20042004, 0x245e27c4, 0x27c42444, 0x2004201e, 0x201e2004, 0x20042004, 0x00003ffc, // ICON_NOTEBOOK
+ 0x00000000, 0x07e00000, 0x04200420, 0x24243ffc, 0x24242424, 0x24242424, 0x3ffc2424, 0x00000000, // ICON_SUITCASE
+ 0x00000000, 0x0fe00000, 0x08200820, 0x40047ffc, 0x7ffc5554, 0x40045554, 0x7ffc4004, 0x00000000, // ICON_SUITCASE_ZIP
+ 0x00000000, 0x20043ffc, 0x3ffc2004, 0x13c81008, 0x100813c8, 0x10081008, 0x1ff81008, 0x00000000, // ICON_MAILBOX
+ 0x00000000, 0x40027ffe, 0x5ffa5ffa, 0x5ffa5ffa, 0x40025ffa, 0x03c07ffe, 0x1ff81ff8, 0x00000000, // ICON_MONITOR
+ 0x0ff00000, 0x6bfe7ffe, 0x7ffe7ffe, 0x68167ffe, 0x08106816, 0x08100810, 0x0ff00810, 0x00000000, // ICON_PRINTER
+ 0x3ff80000, 0xfffe2008, 0x870a8002, 0x904a888a, 0x904a904a, 0x870a888a, 0xfffe8002, 0x00000000, // ICON_PHOTO_CAMERA
+ 0x0fc00000, 0xfcfe0cd8, 0x8002fffe, 0x84428382, 0x84428442, 0x80028382, 0xfffe8002, 0x00000000, // ICON_PHOTO_CAMERA_FLASH
+ 0x00000000, 0x02400180, 0x08100420, 0x20041008, 0x23c42004, 0x22442244, 0x3ffc2244, 0x00000000, // ICON_HOUSE
+ 0x00000000, 0x1c700000, 0x3ff83ef8, 0x3ff83ff8, 0x0fe01ff0, 0x038007c0, 0x00000100, 0x00000000, // ICON_HEART
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0xe000c000, // ICON_CORNER
+ 0x00000000, 0x14001c00, 0x15c01400, 0x15401540, 0x155c1540, 0x15541554, 0x1ddc1554, 0x00000000, // ICON_VERTICAL_BARS
+ 0x00000000, 0x03000300, 0x1b001b00, 0x1b601b60, 0x1b6c1b60, 0x1b6c1b6c, 0x1b6c1b6c, 0x00000000, // ICON_VERTICAL_BARS_FILL
+ 0x00000000, 0x00000000, 0x403e7ffe, 0x7ffe403e, 0x7ffe0000, 0x43fe43fe, 0x00007ffe, 0x00000000, // ICON_LIFE_BARS
+ 0x7ffc0000, 0x43844004, 0x43844284, 0x43844004, 0x42844284, 0x42844284, 0x40044384, 0x00007ffc, // ICON_INFO
+ 0x40008000, 0x10002000, 0x04000800, 0x01000200, 0x00400080, 0x00100020, 0x00040008, 0x00010002, // ICON_CROSSLINE
+ 0x00000000, 0x1ff01ff0, 0x18301830, 0x1f001830, 0x03001f00, 0x00000300, 0x03000300, 0x00000000, // ICON_HELP
+ 0x3ff00000, 0x2abc3550, 0x2aac3554, 0x2aac3554, 0x2aac3554, 0x2aac3554, 0x2aac3554, 0x00003ffc, // ICON_FILETYPE_ALPHA
+ 0x3ff00000, 0x201c2010, 0x22442184, 0x28142424, 0x29942814, 0x2ff42994, 0x20042004, 0x00003ffc, // ICON_FILETYPE_HOME
+ 0x07fe0000, 0x04020402, 0x7fe20402, 0x44224422, 0x44224422, 0x402047fe, 0x40204020, 0x00007fe0, // ICON_LAYERS_VISIBLE
+ 0x07fe0000, 0x04020402, 0x7c020402, 0x44024402, 0x44024402, 0x402047fe, 0x40204020, 0x00007fe0, // ICON_LAYERS
+ 0x00000000, 0x40027ffe, 0x7ffe4002, 0x40024002, 0x40024002, 0x40024002, 0x7ffe4002, 0x00000000, // ICON_WINDOW
+ 0x09100000, 0x09f00910, 0x09100910, 0x00000910, 0x24a2779e, 0x27a224a2, 0x709e20a2, 0x00000000, // ICON_HIDPI
+ 0x3ff00000, 0x201c2010, 0x2a842e84, 0x2e842a84, 0x2ba42004, 0x2aa42aa4, 0x20042ba4, 0x00003ffc, // ICON_FILETYPE_BINARY
+ 0x00000000, 0x00000000, 0x00120012, 0x4a5e4bd2, 0x485233d2, 0x00004bd2, 0x00000000, 0x00000000, // ICON_HEX
+ 0x01800000, 0x381c0660, 0x23c42004, 0x23c42044, 0x13c82204, 0x08101008, 0x02400420, 0x00000180, // ICON_SHIELD
+ 0x007e0000, 0x20023fc2, 0x40227fe2, 0x400a403a, 0x400a400a, 0x400a400a, 0x4008400e, 0x00007ff8, // ICON_FILE_NEW
+ 0x00000000, 0x0042007e, 0x40027fc2, 0x44024002, 0x5f024402, 0x44024402, 0x7ffe4002, 0x00000000, // ICON_FOLDER_ADD
+ 0x44220000, 0x12482244, 0xf3cf0000, 0x14280420, 0x48122424, 0x08100810, 0x1ff81008, 0x03c00420, // ICON_ALARM
+ 0x0aa00000, 0x1ff80aa0, 0x1068700e, 0x1008706e, 0x1008700e, 0x1008700e, 0x0aa01ff8, 0x00000aa0, // ICON_CPU
+ 0x07e00000, 0x04201db8, 0x04a01c38, 0x04a01d38, 0x04a01d38, 0x04a01d38, 0x04201d38, 0x000007e0, // ICON_ROM
+ 0x00000000, 0x03c00000, 0x3c382ff0, 0x3c04380c, 0x01800000, 0x03c003c0, 0x00000180, 0x00000000, // ICON_STEP_OVER
+ 0x01800000, 0x01800180, 0x01800180, 0x03c007e0, 0x00000180, 0x01800000, 0x03c003c0, 0x00000180, // ICON_STEP_INTO
+ 0x01800000, 0x07e003c0, 0x01800180, 0x01800180, 0x00000180, 0x01800000, 0x03c003c0, 0x00000180, // ICON_STEP_OUT
+ 0x00000000, 0x0ff003c0, 0x181c1c34, 0x303c301c, 0x30003000, 0x1c301800, 0x03c00ff0, 0x00000000, // ICON_RESTART
+ 0x00000000, 0x00000000, 0x07e003c0, 0x0ff00ff0, 0x0ff00ff0, 0x03c007e0, 0x00000000, 0x00000000, // ICON_BREAKPOINT_ON
+ 0x00000000, 0x00000000, 0x042003c0, 0x08100810, 0x08100810, 0x03c00420, 0x00000000, 0x00000000, // ICON_BREAKPOINT_OFF
+ 0x00000000, 0x00000000, 0x1ff81ff8, 0x1ff80000, 0x00001ff8, 0x1ff81ff8, 0x00000000, 0x00000000, // ICON_BURGER_MENU
+ 0x00000000, 0x00000000, 0x00880070, 0x0c880088, 0x1e8810f8, 0x3e881288, 0x00000000, 0x00000000, // ICON_CASE_SENSITIVE
+ 0x00000000, 0x02000000, 0x07000a80, 0x07001fc0, 0x02000a80, 0x00300030, 0x00000000, 0x00000000, // ICON_REG_EXP
+ 0x00000000, 0x0042007e, 0x40027fc2, 0x40024002, 0x40024002, 0x40024002, 0x7ffe4002, 0x00000000, // ICON_FOLDER
+ 0x3ff00000, 0x201c2010, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x00003ffc, // ICON_FILE
+ 0x1ff00000, 0x20082008, 0x17d02fe8, 0x05400ba0, 0x09200540, 0x23881010, 0x2fe827c8, 0x00001ff0, // ICON_SAND_TIMER
+ 0x01800000, 0x02400240, 0x05a00420, 0x09900990, 0x11881188, 0x21842004, 0x40024182, 0x00003ffc, // ICON_WARNING
+ 0x7ffe0000, 0x4ff24002, 0x4c324ff2, 0x4f824c02, 0x41824f82, 0x41824002, 0x40024182, 0x00007ffe, // ICON_HELP_BOX
+ 0x7ffe0000, 0x41824002, 0x40024182, 0x41824182, 0x41824182, 0x41824182, 0x40024182, 0x00007ffe, // ICON_INFO_BOX
+ 0x01800000, 0x04200240, 0x10080810, 0x7bde2004, 0x0a500a50, 0x08500bd0, 0x08100850, 0x00000ff0, // ICON_PRIORITY
+ 0x01800000, 0x18180660, 0x80016006, 0x98196006, 0x99996666, 0x19986666, 0x01800660, 0x00000000, // ICON_LAYERS_ISO
+ 0x07fe0000, 0x1c020402, 0x74021402, 0x54025402, 0x54025402, 0x500857fe, 0x40205ff8, 0x00007fe0, // ICON_LAYERS2
+ 0x0ffe0000, 0x3ffa0802, 0x7fea200a, 0x402a402a, 0x422a422a, 0x422e422a, 0x40384e28, 0x00007fe0, // ICON_MLAYERS
+ 0x0ffe0000, 0x3ffa0802, 0x7fea200a, 0x402a402a, 0x5b2a512a, 0x512e552a, 0x40385128, 0x00007fe0, // ICON_MAPS
+ 0x04200000, 0x1cf00c60, 0x11f019f0, 0x0f3807b8, 0x1e3c0f3c, 0x1c1c1e1c, 0x1e3c1c1c, 0x00000f70, // ICON_HOT
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_229
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_230
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_231
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_232
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_233
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_234
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_235
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_236
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_237
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_238
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_239
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_240
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_241
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_242
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_243
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_244
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_245
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_246
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_247
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_248
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_249
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_250
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_251
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_252
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_253
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_254
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_255
+};
+
+// NOTE: A pointer to current icons array should be defined
+static unsigned int *guiIconsPtr = guiIcons;
+
+#endif // !RAYGUI_NO_ICONS && !RAYGUI_CUSTOM_ICONS
+
+#ifndef RAYGUI_ICON_SIZE
+ #define RAYGUI_ICON_SIZE 0
+#endif
+
+// WARNING: Those values define the total size of the style data array,
+// if changed, previous saved styles could become incompatible
+#define RAYGUI_MAX_CONTROLS 16 // Maximum number of controls
+#define RAYGUI_MAX_PROPS_BASE 16 // Maximum number of base properties
+#define RAYGUI_MAX_PROPS_EXTENDED 8 // Maximum number of extended properties
+
+//----------------------------------------------------------------------------------
+// Types and Structures Definition
+//----------------------------------------------------------------------------------
+// Gui control property style color element
+typedef enum { BORDER = 0, BASE, TEXT, OTHER } GuiPropertyElement;
+
+//----------------------------------------------------------------------------------
+// Global Variables Definition
+//----------------------------------------------------------------------------------
+static GuiState guiState = STATE_NORMAL; // Gui global state, if !STATE_NORMAL, forces defined state
+
+static Font guiFont = { 0 }; // Gui current font (WARNING: highly coupled to raylib)
+static bool guiLocked = false; // Gui lock state (no inputs processed)
+static float guiAlpha = 1.0f; // Gui controls transparency
+
+static unsigned int guiIconScale = 1; // Gui icon default scale (if icons enabled)
+
+static bool guiTooltip = false; // Tooltip enabled/disabled
+static const char *guiTooltipPtr = NULL; // Tooltip string pointer (string provided by user)
+
+static bool guiControlExclusiveMode = false; // Gui control exclusive mode (no inputs processed except current control)
+static Rectangle guiControlExclusiveRec = { 0 }; // Gui control exclusive bounds rectangle, used as an unique identifier
+
+static int textBoxCursorIndex = 0; // Cursor index, shared by all GuiTextBox*()
+//static int blinkCursorFrameCounter = 0; // Frame counter for cursor blinking
+static int autoCursorCooldownCounter = 0; // Cooldown frame counter for automatic cursor movement on key-down
+static int autoCursorDelayCounter = 0; // Delay frame counter for automatic cursor movement
+
+//----------------------------------------------------------------------------------
+// Style data array for all gui style properties (allocated on data segment by default)
+//
+// NOTE 1: First set of BASE properties are generic to all controls but could be individually
+// overwritten per control, first set of EXTENDED properties are generic to all controls and
+// can not be overwritten individually but custom EXTENDED properties can be used by control
+//
+// NOTE 2: A new style set could be loaded over this array using GuiLoadStyle(),
+// but default gui style could always be recovered with GuiLoadStyleDefault()
+//
+// guiStyle size is by default: 16*(16 + 8) = 384*4 = 1536 bytes = 1.5 KB
+//----------------------------------------------------------------------------------
+static unsigned int guiStyle[RAYGUI_MAX_CONTROLS*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED)] = { 0 };
+
+static bool guiStyleLoaded = false; // Style loaded flag for lazy style initialization
+
+//----------------------------------------------------------------------------------
+// Standalone Mode Functions Declaration
+//
+// NOTE: raygui depend on some raylib input and drawing functions
+// To use raygui as standalone library, below functions must be defined by the user
+//----------------------------------------------------------------------------------
+#if defined(RAYGUI_STANDALONE)
+
+#define KEY_RIGHT 262
+#define KEY_LEFT 263
+#define KEY_DOWN 264
+#define KEY_UP 265
+#define KEY_BACKSPACE 259
+#define KEY_ENTER 257
+
+#define MOUSE_LEFT_BUTTON 0
+
+// Input required functions
+//-------------------------------------------------------------------------------
+static Vector2 GetMousePosition(void);
+static float GetMouseWheelMove(void);
+static bool IsMouseButtonDown(int button);
+static bool IsMouseButtonPressed(int button);
+static bool IsMouseButtonReleased(int button);
+
+static bool IsKeyDown(int key);
+static bool IsKeyPressed(int key);
+static int GetCharPressed(void); // -- GuiTextBox(), GuiValueBox()
+//-------------------------------------------------------------------------------
+
+// Drawing required functions
+//-------------------------------------------------------------------------------
+static void DrawRectangle(int x, int y, int width, int height, Color color); // -- GuiDrawRectangle()
+static void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4); // -- GuiColorPicker()
+//-------------------------------------------------------------------------------
+
+// Text required functions
+//-------------------------------------------------------------------------------
+static Font GetFontDefault(void); // -- GuiLoadStyleDefault()
+static Font LoadFontEx(const char *fileName, int fontSize, int *codepoints, int codepointCount); // -- GuiLoadStyle(), load font
+
+static Texture2D LoadTextureFromImage(Image image); // -- GuiLoadStyle(), required to load texture from embedded font atlas image
+static void SetShapesTexture(Texture2D tex, Rectangle rec); // -- GuiLoadStyle(), required to set shapes rec to font white rec (optimization)
+
+static char *LoadFileText(const char *fileName); // -- GuiLoadStyle(), required to load charset data
+static void UnloadFileText(char *text); // -- GuiLoadStyle(), required to unload charset data
+
+static const char *GetDirectoryPath(const char *filePath); // -- GuiLoadStyle(), required to find charset/font file from text .rgs
+
+static int *LoadCodepoints(const char *text, int *count); // -- GuiLoadStyle(), required to load required font codepoints list
+static void UnloadCodepoints(int *codepoints); // -- GuiLoadStyle(), required to unload codepoints list
+
+static unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize); // -- GuiLoadStyle()
+//-------------------------------------------------------------------------------
+
+// raylib functions already implemented in raygui
+//-------------------------------------------------------------------------------
+static Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value
+static int ColorToInt(Color color); // Returns hexadecimal value for a Color
+static bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
+static const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed'
+static const char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings
+static int TextToInteger(const char *text); // Get integer value from text
+static float TextToFloat(const char *text); // Get float value from text
+
+static int GetCodepointNext(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded text
+static const char *CodepointToUTF8(int codepoint, int *byteSize); // Encode codepoint into UTF-8 text (char array size returned as parameter)
+
+static void DrawRectangleGradientV(int posX, int posY, int width, int height, Color color1, Color color2); // Draw rectangle vertical gradient
+//-------------------------------------------------------------------------------
+
+#endif // RAYGUI_STANDALONE
+
+//----------------------------------------------------------------------------------
+// Module Internal Functions Declaration
+//----------------------------------------------------------------------------------
+static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize); // Load style from memory (binary only)
+
+static int GetTextWidth(const char *text); // Gui get text width using gui font and style
+static Rectangle GetTextBounds(int control, Rectangle bounds); // Get text bounds considering control bounds
+static const char *GetTextIcon(const char *text, int *iconId); // Get text icon if provided and move text cursor
+
+static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, Color tint); // Gui draw text using default font
+static void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor, Color color); // Gui draw rectangle using default raygui style
+
+static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow); // Split controls text into multiple strings
+static Vector3 ConvertHSVtoRGB(Vector3 hsv); // Convert color data from HSV to RGB
+static Vector3 ConvertRGBtoHSV(Vector3 rgb); // Convert color data from RGB to HSV
+
+static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue); // Scroll bar control, used by GuiScrollPanel()
+static void GuiTooltip(Rectangle controlRec); // Draw tooltip using control rec position
+
+static Color GuiFade(Color color, float alpha); // Fade color by an alpha factor
+
+//----------------------------------------------------------------------------------
+// Gui Setup Functions Definition
+//----------------------------------------------------------------------------------
+// Enable gui global state
+// NOTE: We check for STATE_DISABLED to avoid messing custom global state setups
+void GuiEnable(void) { if (guiState == STATE_DISABLED) guiState = STATE_NORMAL; }
+
+// Disable gui global state
+// NOTE: We check for STATE_NORMAL to avoid messing custom global state setups
+void GuiDisable(void) { if (guiState == STATE_NORMAL) guiState = STATE_DISABLED; }
+
+// Lock gui global state
+void GuiLock(void) { guiLocked = true; }
+
+// Unlock gui global state
+void GuiUnlock(void) { guiLocked = false; }
+
+// Check if gui is locked (global state)
+bool GuiIsLocked(void) { return guiLocked; }
+
+// Set gui controls alpha global state
+void GuiSetAlpha(float alpha)
+{
+ if (alpha < 0.0f) alpha = 0.0f;
+ else if (alpha > 1.0f) alpha = 1.0f;
+
+ guiAlpha = alpha;
+}
+
+// Set gui state (global state)
+void GuiSetState(int state) { guiState = (GuiState)state; }
+
+// Get gui state (global state)
+int GuiGetState(void) { return guiState; }
+
+// Set custom gui font
+// NOTE: Font loading/unloading is external to raygui
+void GuiSetFont(Font font)
+{
+ if (font.texture.id > 0)
+ {
+ // NOTE: If we try to setup a font but default style has not been
+ // lazily loaded before, it will be overwritten, so we need to force
+ // default style loading first
+ if (!guiStyleLoaded) GuiLoadStyleDefault();
+
+ guiFont = font;
+ }
+}
+
+// Get custom gui font
+Font GuiGetFont(void)
+{
+ return guiFont;
+}
+
+// Set control style property value
+void GuiSetStyle(int control, int property, int value)
+{
+ if (!guiStyleLoaded) GuiLoadStyleDefault();
+ guiStyle[control*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED) + property] = value;
+
+ // Default properties are propagated to all controls
+ if ((control == 0) && (property < RAYGUI_MAX_PROPS_BASE))
+ {
+ for (int i = 1; i < RAYGUI_MAX_CONTROLS; i++) guiStyle[i*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED) + property] = value;
+ }
+}
+
+// Get control style property value
+int GuiGetStyle(int control, int property)
+{
+ if (!guiStyleLoaded) GuiLoadStyleDefault();
+ return guiStyle[control*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED) + property];
+}
+
+//----------------------------------------------------------------------------------
+// Gui Controls Functions Definition
+//----------------------------------------------------------------------------------
+
+// Window Box control
+int GuiWindowBox(Rectangle bounds, const char *title)
+{
+ // Window title bar height (including borders)
+ // NOTE: This define is also used by GuiMessageBox() and GuiTextInputBox()
+ #if !defined(RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT)
+ #define RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT 24
+ #endif
+
+ int result = 0;
+ //GuiState state = guiState;
+
+ int statusBarHeight = RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT;
+
+ Rectangle statusBar = { bounds.x, bounds.y, bounds.width, (float)statusBarHeight };
+ if (bounds.height < statusBarHeight*2.0f) bounds.height = statusBarHeight*2.0f;
+
+ Rectangle windowPanel = { bounds.x, bounds.y + (float)statusBarHeight - 1, bounds.width, bounds.height - (float)statusBarHeight + 1 };
+ Rectangle closeButtonRec = { statusBar.x + statusBar.width - GuiGetStyle(STATUSBAR, BORDER_WIDTH) - 20,
+ statusBar.y + statusBarHeight/2.0f - 18.0f/2.0f, 18, 18 };
+
+ // Update control
+ //--------------------------------------------------------------------
+ // NOTE: Logic is directly managed by button
+ //--------------------------------------------------------------------
+
+ // Draw control
+ //--------------------------------------------------------------------
+ GuiStatusBar(statusBar, title); // Draw window header as status bar
+ GuiPanel(windowPanel, NULL); // Draw window base
+
+ // Draw window close button
+ int tempBorderWidth = GuiGetStyle(BUTTON, BORDER_WIDTH);
+ int tempTextAlignment = GuiGetStyle(BUTTON, TEXT_ALIGNMENT);
+ GuiSetStyle(BUTTON, BORDER_WIDTH, 1);
+ GuiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER);
+#if defined(RAYGUI_NO_ICONS)
+ result = GuiButton(closeButtonRec, "x");
+#else
+ result = GuiButton(closeButtonRec, GuiIconText(ICON_CROSS_SMALL, NULL));
+#endif
+ GuiSetStyle(BUTTON, BORDER_WIDTH, tempBorderWidth);
+ GuiSetStyle(BUTTON, TEXT_ALIGNMENT, tempTextAlignment);
+ //--------------------------------------------------------------------
+
+ return result; // Window close button clicked: result = 1
+}
+
+// Group Box control with text name
+int GuiGroupBox(Rectangle bounds, const char *text)
+{
+ #if !defined(RAYGUI_GROUPBOX_LINE_THICK)
+ #define RAYGUI_GROUPBOX_LINE_THICK 1
+ #endif
+
+ int result = 0;
+ GuiState state = guiState;
+
+ // Draw control
+ //--------------------------------------------------------------------
+ GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y, RAYGUI_GROUPBOX_LINE_THICK, bounds.height }, 0, BLANK, GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? (int)BORDER_COLOR_DISABLED : (int)LINE_COLOR)));
+ GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + bounds.height - 1, bounds.width, RAYGUI_GROUPBOX_LINE_THICK }, 0, BLANK, GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? (int)BORDER_COLOR_DISABLED : (int)LINE_COLOR)));
+ GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x + bounds.width - 1, bounds.y, RAYGUI_GROUPBOX_LINE_THICK, bounds.height }, 0, BLANK, GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? (int)BORDER_COLOR_DISABLED : (int)LINE_COLOR)));
+
+ GuiLine(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y - GuiGetStyle(DEFAULT, TEXT_SIZE)/2, bounds.width, (float)GuiGetStyle(DEFAULT, TEXT_SIZE) }, text);
+ //--------------------------------------------------------------------
+
+ return result;
+}
+
+// Line control
+int GuiLine(Rectangle bounds, const char *text)
+{
+ #if !defined(RAYGUI_LINE_ORIGIN_SIZE)
+ #define RAYGUI_LINE_MARGIN_TEXT 12
+ #endif
+ #if !defined(RAYGUI_LINE_TEXT_PADDING)
+ #define RAYGUI_LINE_TEXT_PADDING 4
+ #endif
+
+ int result = 0;
+ GuiState state = guiState;
+
+ Color color = GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? (int)BORDER_COLOR_DISABLED : (int)LINE_COLOR));
+
+ // Draw control
+ //--------------------------------------------------------------------
+ if (text == NULL) GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + bounds.height/2, bounds.width, 1 }, 0, BLANK, color);
+ else
+ {
+ Rectangle textBounds = { 0 };
+ textBounds.width = (float)GetTextWidth(text) + 2;
+ textBounds.height = bounds.height;
+ textBounds.x = bounds.x + RAYGUI_LINE_MARGIN_TEXT;
+ textBounds.y = bounds.y;
+
+ // Draw line with embedded text label: "--- text --------------"
+ GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + bounds.height/2, RAYGUI_LINE_MARGIN_TEXT - RAYGUI_LINE_TEXT_PADDING, 1 }, 0, BLANK, color);
+ GuiDrawText(text, textBounds, TEXT_ALIGN_LEFT, color);
+ GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x + 12 + textBounds.width + 4, bounds.y + bounds.height/2, bounds.width - textBounds.width - RAYGUI_LINE_MARGIN_TEXT - RAYGUI_LINE_TEXT_PADDING, 1 }, 0, BLANK, color);
+ }
+ //--------------------------------------------------------------------
+
+ return result;
+}
+
+// Panel control
+int GuiPanel(Rectangle bounds, const char *text)
+{
+ #if !defined(RAYGUI_PANEL_BORDER_WIDTH)
+ #define RAYGUI_PANEL_BORDER_WIDTH 1
+ #endif
+
+ int result = 0;
+ GuiState state = guiState;
+
+ // Text will be drawn as a header bar (if provided)
+ Rectangle statusBar = { bounds.x, bounds.y, bounds.width, (float)RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT };
+ if ((text != NULL) && (bounds.height < RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT*2.0f)) bounds.height = RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT*2.0f;
+
+ if (text != NULL)
+ {
+ // Move panel bounds after the header bar
+ bounds.y += (float)RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - 1;
+ bounds.height -= (float)RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - 1;
+ }
+
+ // Draw control
+ //--------------------------------------------------------------------
+ if (text != NULL) GuiStatusBar(statusBar, text); // Draw panel header as status bar
+
+ GuiDrawRectangle(bounds, RAYGUI_PANEL_BORDER_WIDTH, GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? (int)BORDER_COLOR_DISABLED: (int)LINE_COLOR)),
+ GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? BASE_COLOR_DISABLED : BACKGROUND_COLOR)));
+ //--------------------------------------------------------------------
+
+ return result;
+}
+
+// Tab Bar control
+// NOTE: Using GuiToggle() for the TABS
+int GuiTabBar(Rectangle bounds, const char **text, int count, int *active)
+{
+ #define RAYGUI_TABBAR_ITEM_WIDTH 160
+
+ int result = -1;
+ //GuiState state = guiState;
+
+ Rectangle tabBounds = { bounds.x, bounds.y, RAYGUI_TABBAR_ITEM_WIDTH, bounds.height };
+
+ if (*active < 0) *active = 0;
+ else if (*active > count - 1) *active = count - 1;
+
+ int offsetX = 0; // Required in case tabs go out of screen
+ offsetX = (*active + 2)*RAYGUI_TABBAR_ITEM_WIDTH - GetScreenWidth();
+ if (offsetX < 0) offsetX = 0;
+
+ bool toggle = false; // Required for individual toggles
+
+ // Draw control
+ //--------------------------------------------------------------------
+ for (int i = 0; i < count; i++)
+ {
+ tabBounds.x = bounds.x + (RAYGUI_TABBAR_ITEM_WIDTH + 4)*i - offsetX;
+
+ if (tabBounds.x < GetScreenWidth())
+ {
+ // Draw tabs as toggle controls
+ int textAlignment = GuiGetStyle(TOGGLE, TEXT_ALIGNMENT);
+ int textPadding = GuiGetStyle(TOGGLE, TEXT_PADDING);
+ GuiSetStyle(TOGGLE, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
+ GuiSetStyle(TOGGLE, TEXT_PADDING, 8);
+
+ if (i == (*active))
+ {
+ toggle = true;
+ GuiToggle(tabBounds, GuiIconText(12, text[i]), &toggle);
+ }
+ else
+ {
+ toggle = false;
+ GuiToggle(tabBounds, GuiIconText(12, text[i]), &toggle);
+ if (toggle) *active = i;
+ }
+
+ // Close tab with middle mouse button pressed
+ if (CheckCollisionPointRec(GetMousePosition(), tabBounds) && IsMouseButtonPressed(MOUSE_MIDDLE_BUTTON)) result = i;
+
+ GuiSetStyle(TOGGLE, TEXT_PADDING, textPadding);
+ GuiSetStyle(TOGGLE, TEXT_ALIGNMENT, textAlignment);
+
+ // Draw tab close button
+ // NOTE: Only draw close button for current tab: if (CheckCollisionPointRec(mousePosition, tabBounds))
+ int tempBorderWidth = GuiGetStyle(BUTTON, BORDER_WIDTH);
+ int tempTextAlignment = GuiGetStyle(BUTTON, TEXT_ALIGNMENT);
+ GuiSetStyle(BUTTON, BORDER_WIDTH, 1);
+ GuiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER);
+#if defined(RAYGUI_NO_ICONS)
+ if (GuiButton(RAYGUI_CLITERAL(Rectangle){ tabBounds.x + tabBounds.width - 14 - 5, tabBounds.y + 5, 14, 14 }, "x")) result = i;
+#else
+ if (GuiButton(RAYGUI_CLITERAL(Rectangle){ tabBounds.x + tabBounds.width - 14 - 5, tabBounds.y + 5, 14, 14 }, GuiIconText(ICON_CROSS_SMALL, NULL))) result = i;
+#endif
+ GuiSetStyle(BUTTON, BORDER_WIDTH, tempBorderWidth);
+ GuiSetStyle(BUTTON, TEXT_ALIGNMENT, tempTextAlignment);
+ }
+ }
+
+ // Draw tab-bar bottom line
+ GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + bounds.height - 1, bounds.width, 1 }, 0, BLANK, GetColor(GuiGetStyle(TOGGLE, BORDER_COLOR_NORMAL)));
+ //--------------------------------------------------------------------
+
+ return result; // Return as result the current TAB closing requested
+}
+
+// Scroll Panel control
+int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector2 *scroll, Rectangle *view)
+{
+ #define RAYGUI_MIN_SCROLLBAR_WIDTH 40
+ #define RAYGUI_MIN_SCROLLBAR_HEIGHT 40
+ #define RAYGUI_MIN_MOUSE_WHEEL_SPEED 20
+
+ int result = 0;
+ GuiState state = guiState;
+
+ Rectangle temp = { 0 };
+ if (view == NULL) view = &temp;
+
+ Vector2 scrollPos = { 0.0f, 0.0f };
+ if (scroll != NULL) scrollPos = *scroll;
+
+ // Text will be drawn as a header bar (if provided)
+ Rectangle statusBar = { bounds.x, bounds.y, bounds.width, (float)RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT };
+ if (bounds.height < RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT*2.0f) bounds.height = RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT*2.0f;
+
+ if (text != NULL)
+ {
+ // Move panel bounds after the header bar
+ bounds.y += (float)RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - 1;
+ bounds.height -= (float)RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT + 1;
+ }
+
+ bool hasHorizontalScrollBar = (content.width > bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH))? true : false;
+ bool hasVerticalScrollBar = (content.height > bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH))? true : false;
+
+ // Recheck to account for the other scrollbar being visible
+ if (!hasHorizontalScrollBar) hasHorizontalScrollBar = (hasVerticalScrollBar && (content.width > (bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH))))? true : false;
+ if (!hasVerticalScrollBar) hasVerticalScrollBar = (hasHorizontalScrollBar && (content.height > (bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH))))? true : false;
+
+ int horizontalScrollBarWidth = hasHorizontalScrollBar? GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH) : 0;
+ int verticalScrollBarWidth = hasVerticalScrollBar? GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH) : 0;
+ Rectangle horizontalScrollBar = {
+ (float)((GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)bounds.x + verticalScrollBarWidth : (float)bounds.x) + GuiGetStyle(DEFAULT, BORDER_WIDTH),
+ (float)bounds.y + bounds.height - horizontalScrollBarWidth - GuiGetStyle(DEFAULT, BORDER_WIDTH),
+ (float)bounds.width - verticalScrollBarWidth - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH),
+ (float)horizontalScrollBarWidth
+ };
+ Rectangle verticalScrollBar = {
+ (float)((GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)bounds.x + GuiGetStyle(DEFAULT, BORDER_WIDTH) : (float)bounds.x + bounds.width - verticalScrollBarWidth - GuiGetStyle(DEFAULT, BORDER_WIDTH)),
+ (float)bounds.y + GuiGetStyle(DEFAULT, BORDER_WIDTH),
+ (float)verticalScrollBarWidth,
+ (float)bounds.height - horizontalScrollBarWidth - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH)
+ };
+
+ // Make sure scroll bars have a minimum width/height
+ if (horizontalScrollBar.width < RAYGUI_MIN_SCROLLBAR_WIDTH) horizontalScrollBar.width = RAYGUI_MIN_SCROLLBAR_WIDTH;
+ if (verticalScrollBar.height < RAYGUI_MIN_SCROLLBAR_HEIGHT) verticalScrollBar.height = RAYGUI_MIN_SCROLLBAR_HEIGHT;
+
+ // Calculate view area (area without the scrollbars)
+ *view = (GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)?
+ RAYGUI_CLITERAL(Rectangle){ bounds.x + verticalScrollBarWidth + GuiGetStyle(DEFAULT, BORDER_WIDTH), bounds.y + GuiGetStyle(DEFAULT, BORDER_WIDTH), bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - verticalScrollBarWidth, bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - horizontalScrollBarWidth } :
+ RAYGUI_CLITERAL(Rectangle){ bounds.x + GuiGetStyle(DEFAULT, BORDER_WIDTH), bounds.y + GuiGetStyle(DEFAULT, BORDER_WIDTH), bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - verticalScrollBarWidth, bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - horizontalScrollBarWidth };
+
+ // Clip view area to the actual content size
+ if (view->width > content.width) view->width = content.width;
+ if (view->height > content.height) view->height = content.height;
+
+ float horizontalMin = hasHorizontalScrollBar? ((GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)-verticalScrollBarWidth : 0) - (float)GuiGetStyle(DEFAULT, BORDER_WIDTH) : (((float)GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)-verticalScrollBarWidth : 0) - (float)GuiGetStyle(DEFAULT, BORDER_WIDTH);
+ float horizontalMax = hasHorizontalScrollBar? content.width - bounds.width + (float)verticalScrollBarWidth + GuiGetStyle(DEFAULT, BORDER_WIDTH) - (((float)GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)verticalScrollBarWidth : 0) : (float)-GuiGetStyle(DEFAULT, BORDER_WIDTH);
+ float verticalMin = hasVerticalScrollBar? 0.0f : -1.0f;
+ float verticalMax = hasVerticalScrollBar? content.height - bounds.height + (float)horizontalScrollBarWidth + (float)GuiGetStyle(DEFAULT, BORDER_WIDTH) : (float)-GuiGetStyle(DEFAULT, BORDER_WIDTH);
+
+ // Update control
+ //--------------------------------------------------------------------
+ if ((state != STATE_DISABLED) && !guiLocked)
+ {
+ Vector2 mousePoint = GetMousePosition();
+
+ // Check button state
+ if (CheckCollisionPointRec(mousePoint, bounds))
+ {
+ if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED;
+ else state = STATE_FOCUSED;
+
+#if defined(SUPPORT_SCROLLBAR_KEY_INPUT)
+ if (hasHorizontalScrollBar)
+ {
+ if (IsKeyDown(KEY_RIGHT)) scrollPos.x -= GuiGetStyle(SCROLLBAR, SCROLL_SPEED);
+ if (IsKeyDown(KEY_LEFT)) scrollPos.x += GuiGetStyle(SCROLLBAR, SCROLL_SPEED);
+ }
+
+ if (hasVerticalScrollBar)
+ {
+ if (IsKeyDown(KEY_DOWN)) scrollPos.y -= GuiGetStyle(SCROLLBAR, SCROLL_SPEED);
+ if (IsKeyDown(KEY_UP)) scrollPos.y += GuiGetStyle(SCROLLBAR, SCROLL_SPEED);
+ }
+#endif
+ float wheelMove = GetMouseWheelMove();
+
+ // Set scrolling speed with mouse wheel based on ratio between bounds and content
+ Vector2 mouseWheelSpeed = { content.width/bounds.width, content.height/bounds.height };
+ if (mouseWheelSpeed.x < RAYGUI_MIN_MOUSE_WHEEL_SPEED) mouseWheelSpeed.x = RAYGUI_MIN_MOUSE_WHEEL_SPEED;
+ if (mouseWheelSpeed.y < RAYGUI_MIN_MOUSE_WHEEL_SPEED) mouseWheelSpeed.y = RAYGUI_MIN_MOUSE_WHEEL_SPEED;
+
+ // Horizontal and vertical scrolling with mouse wheel
+ if (hasHorizontalScrollBar && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_LEFT_SHIFT))) scrollPos.x += wheelMove*mouseWheelSpeed.x;
+ else scrollPos.y += wheelMove*mouseWheelSpeed.y; // Vertical scroll
+ }
+ }
+
+ // Normalize scroll values
+ if (scrollPos.x > -horizontalMin) scrollPos.x = -horizontalMin;
+ if (scrollPos.x < -horizontalMax) scrollPos.x = -horizontalMax;
+ if (scrollPos.y > -verticalMin) scrollPos.y = -verticalMin;
+ if (scrollPos.y < -verticalMax) scrollPos.y = -verticalMax;
+ //--------------------------------------------------------------------
+
+ // Draw control
+ //--------------------------------------------------------------------
+ if (text != NULL) GuiStatusBar(statusBar, text); // Draw panel header as status bar
+
+ GuiDrawRectangle(bounds, 0, BLANK, GetColor(GuiGetStyle(DEFAULT, BACKGROUND_COLOR))); // Draw background
+
+ // Save size of the scrollbar slider
+ const int slider = GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE);
+
+ // Draw horizontal scrollbar if visible
+ if (hasHorizontalScrollBar)
+ {
+ // Change scrollbar slider size to show the diff in size between the content width and the widget width
+ GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, (int)(((bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - verticalScrollBarWidth)/(int)content.width)*((int)bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - verticalScrollBarWidth)));
+ scrollPos.x = (float)-GuiScrollBar(horizontalScrollBar, (int)-scrollPos.x, (int)horizontalMin, (int)horizontalMax);
+ }
+ else scrollPos.x = 0.0f;
+
+ // Draw vertical scrollbar if visible
+ if (hasVerticalScrollBar)
+ {
+ // Change scrollbar slider size to show the diff in size between the content height and the widget height
+ GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, (int)(((bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - horizontalScrollBarWidth)/(int)content.height)*((int)bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - horizontalScrollBarWidth)));
+ scrollPos.y = (float)-GuiScrollBar(verticalScrollBar, (int)-scrollPos.y, (int)verticalMin, (int)verticalMax);
+ }
+ else scrollPos.y = 0.0f;
+
+ // Draw detail corner rectangle if both scroll bars are visible
+ if (hasHorizontalScrollBar && hasVerticalScrollBar)
+ {
+ Rectangle corner = { (GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (bounds.x + GuiGetStyle(DEFAULT, BORDER_WIDTH) + 2) : (horizontalScrollBar.x + horizontalScrollBar.width + 2), verticalScrollBar.y + verticalScrollBar.height + 2, (float)horizontalScrollBarWidth - 4, (float)verticalScrollBarWidth - 4 };
+ GuiDrawRectangle(corner, 0, BLANK, GetColor(GuiGetStyle(LISTVIEW, TEXT + (state*3))));
+ }
+
+ // Draw scrollbar lines depending on current state
+ GuiDrawRectangle(bounds, GuiGetStyle(LISTVIEW, BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER + (state*3))), BLANK);
+
+ // Set scrollbar slider size back to the way it was before
+ GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, slider);
+ //--------------------------------------------------------------------
+
+ if (scroll != NULL) *scroll = scrollPos;
+
+ return result;
+}
+
+// Label control
+int GuiLabel(Rectangle bounds, const char *text)
+{
+ int result = 0;
+ GuiState state = guiState;
+
+ // Update control
+ //--------------------------------------------------------------------
+ //...
+ //--------------------------------------------------------------------
+
+ // Draw control
+ //--------------------------------------------------------------------
+ GuiDrawText(text, GetTextBounds(LABEL, bounds), GuiGetStyle(LABEL, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LABEL, TEXT + (state*3))));
+ //--------------------------------------------------------------------
+
+ return result;
+}
+
+// Button control, returns true when clicked
+int GuiButton(Rectangle bounds, const char *text)
+{
+ int result = 0;
+ GuiState state = guiState;
+
+ // Update control
+ //--------------------------------------------------------------------
+ if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode)
+ {
+ Vector2 mousePoint = GetMousePosition();
+
+ // Check button state
+ if (CheckCollisionPointRec(mousePoint, bounds))
+ {
+ if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED;
+ else state = STATE_FOCUSED;
+
+ if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) result = 1;
+ }
+ }
+ //--------------------------------------------------------------------
+
+ // Draw control
+ //--------------------------------------------------------------------
+ GuiDrawRectangle(bounds, GuiGetStyle(BUTTON, BORDER_WIDTH), GetColor(GuiGetStyle(BUTTON, BORDER + (state*3))), GetColor(GuiGetStyle(BUTTON, BASE + (state*3))));
+ GuiDrawText(text, GetTextBounds(BUTTON, bounds), GuiGetStyle(BUTTON, TEXT_ALIGNMENT), GetColor(GuiGetStyle(BUTTON, TEXT + (state*3))));
+
+ if (state == STATE_FOCUSED) GuiTooltip(bounds);
+ //------------------------------------------------------------------
+
+ return result; // Button pressed: result = 1
+}
+
+// Label button control
+int GuiLabelButton(Rectangle bounds, const char *text)
+{
+ GuiState state = guiState;
+ bool pressed = false;
+
+ // NOTE: We force bounds.width to be all text
+ float textWidth = (float)GetTextWidth(text);
+ if ((bounds.width - 2*GuiGetStyle(LABEL, BORDER_WIDTH) - 2*GuiGetStyle(LABEL, TEXT_PADDING)) < textWidth) bounds.width = textWidth + 2*GuiGetStyle(LABEL, BORDER_WIDTH) + 2*GuiGetStyle(LABEL, TEXT_PADDING) + 2;
+
+ // Update control
+ //--------------------------------------------------------------------
+ if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode)
+ {
+ Vector2 mousePoint = GetMousePosition();
+
+ // Check checkbox state
+ if (CheckCollisionPointRec(mousePoint, bounds))
+ {
+ if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED;
+ else state = STATE_FOCUSED;
+
+ if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) pressed = true;
+ }
+ }
+ //--------------------------------------------------------------------
+
+ // Draw control
+ //--------------------------------------------------------------------
+ GuiDrawText(text, GetTextBounds(LABEL, bounds), GuiGetStyle(LABEL, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LABEL, TEXT + (state*3))));
+ //--------------------------------------------------------------------
+
+ return pressed;
+}
+
+// Toggle Button control
+int GuiToggle(Rectangle bounds, const char *text, bool *active)
+{
+ int result = 0;
+ GuiState state = guiState;
+
+ bool temp = false;
+ if (active == NULL) active = &temp;
+
+ // Update control
+ //--------------------------------------------------------------------
+ if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode)
+ {
+ Vector2 mousePoint = GetMousePosition();
+
+ // Check toggle button state
+ if (CheckCollisionPointRec(mousePoint, bounds))
+ {
+ if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED;
+ else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON))
+ {
+ state = STATE_NORMAL;
+ *active = !(*active);
+ }
+ else state = STATE_FOCUSED;
+ }
+ }
+ //--------------------------------------------------------------------
+
+ // Draw control
+ //--------------------------------------------------------------------
+ if (state == STATE_NORMAL)
+ {
+ GuiDrawRectangle(bounds, GuiGetStyle(TOGGLE, BORDER_WIDTH), GetColor(GuiGetStyle(TOGGLE, ((*active)? BORDER_COLOR_PRESSED : (BORDER + state*3)))), GetColor(GuiGetStyle(TOGGLE, ((*active)? BASE_COLOR_PRESSED : (BASE + state*3)))));
+ GuiDrawText(text, GetTextBounds(TOGGLE, bounds), GuiGetStyle(TOGGLE, TEXT_ALIGNMENT), GetColor(GuiGetStyle(TOGGLE, ((*active)? TEXT_COLOR_PRESSED : (TEXT + state*3)))));
+ }
+ else
+ {
+ GuiDrawRectangle(bounds, GuiGetStyle(TOGGLE, BORDER_WIDTH), GetColor(GuiGetStyle(TOGGLE, BORDER + state*3)), GetColor(GuiGetStyle(TOGGLE, BASE + state*3)));
+ GuiDrawText(text, GetTextBounds(TOGGLE, bounds), GuiGetStyle(TOGGLE, TEXT_ALIGNMENT), GetColor(GuiGetStyle(TOGGLE, TEXT + state*3)));
+ }
+
+ if (state == STATE_FOCUSED) GuiTooltip(bounds);
+ //--------------------------------------------------------------------
+
+ return result;
+}
+
+// Toggle Group control
+int GuiToggleGroup(Rectangle bounds, const char *text, int *active)
+{
+ #if !defined(RAYGUI_TOGGLEGROUP_MAX_ITEMS)
+ #define RAYGUI_TOGGLEGROUP_MAX_ITEMS 32
+ #endif
+
+ int result = 0;
+ float initBoundsX = bounds.x;
+
+ int temp = 0;
+ if (active == NULL) active = &temp;
+
+ bool toggle = false; // Required for individual toggles
+
+ // Get substrings items from text (items pointers)
+ int rows[RAYGUI_TOGGLEGROUP_MAX_ITEMS] = { 0 };
+ int itemCount = 0;
+ const char **items = GuiTextSplit(text, ';', &itemCount, rows);
+
+ int prevRow = rows[0];
+
+ for (int i = 0; i < itemCount; i++)
+ {
+ if (prevRow != rows[i])
+ {
+ bounds.x = initBoundsX;
+ bounds.y += (bounds.height + GuiGetStyle(TOGGLE, GROUP_PADDING));
+ prevRow = rows[i];
+ }
+
+ if (i == (*active))
+ {
+ toggle = true;
+ GuiToggle(bounds, items[i], &toggle);
+ }
+ else
+ {
+ toggle = false;
+ GuiToggle(bounds, items[i], &toggle);
+ if (toggle) *active = i;
+ }
+
+ bounds.x += (bounds.width + GuiGetStyle(TOGGLE, GROUP_PADDING));
+ }
+
+ return result;
+}
+
+// Toggle Slider control extended
+int GuiToggleSlider(Rectangle bounds, const char *text, int *active)
+{
+ int result = 0;
+ GuiState state = guiState;
+
+ int temp = 0;
+ if (active == NULL) active = &temp;
+
+ //bool toggle = false; // Required for individual toggles
+
+ // Get substrings items from text (items pointers)
+ int itemCount = 0;
+ const char **items = GuiTextSplit(text, ';', &itemCount, NULL);
+
+ Rectangle slider = {
+ 0, // Calculated later depending on the active toggle
+ bounds.y + GuiGetStyle(SLIDER, BORDER_WIDTH) + GuiGetStyle(SLIDER, SLIDER_PADDING),
+ (bounds.width - 2*GuiGetStyle(SLIDER, BORDER_WIDTH) - (itemCount + 1)*GuiGetStyle(SLIDER, SLIDER_PADDING))/itemCount,
+ bounds.height - 2*GuiGetStyle(SLIDER, BORDER_WIDTH) - 2*GuiGetStyle(SLIDER, SLIDER_PADDING) };
+
+ // Update control
+ //--------------------------------------------------------------------
+ if ((state != STATE_DISABLED) && !guiLocked)
+ {
+ Vector2 mousePoint = GetMousePosition();
+
+ if (CheckCollisionPointRec(mousePoint, bounds))
+ {
+ if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED;
+ else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON))
+ {
+ state = STATE_PRESSED;
+ (*active)++;
+ result = 1;
+ }
+ else state = STATE_FOCUSED;
+ }
+
+ if ((*active) && (state != STATE_FOCUSED)) state = STATE_PRESSED;
+ }
+
+ if (*active >= itemCount) *active = 0;
+ slider.x = bounds.x + GuiGetStyle(SLIDER, BORDER_WIDTH) + (*active + 1)*GuiGetStyle(SLIDER, SLIDER_PADDING) + (*active)*slider.width;
+ //--------------------------------------------------------------------
+
+ // Draw control
+ //--------------------------------------------------------------------
+ GuiDrawRectangle(bounds, GuiGetStyle(SLIDER, BORDER_WIDTH), GetColor(GuiGetStyle(TOGGLE, BORDER + (state*3))),
+ GetColor(GuiGetStyle(TOGGLE, BASE_COLOR_NORMAL)));
+
+ // Draw internal slider
+ if (state == STATE_NORMAL) GuiDrawRectangle(slider, 0, BLANK, GetColor(GuiGetStyle(SLIDER, BASE_COLOR_PRESSED)));
+ else if (state == STATE_FOCUSED) GuiDrawRectangle(slider, 0, BLANK, GetColor(GuiGetStyle(SLIDER, BASE_COLOR_FOCUSED)));
+ else if (state == STATE_PRESSED) GuiDrawRectangle(slider, 0, BLANK, GetColor(GuiGetStyle(SLIDER, BASE_COLOR_PRESSED)));
+
+ // Draw text in slider
+ if (text != NULL)
+ {
+ Rectangle textBounds = { 0 };
+ textBounds.width = (float)GetTextWidth(text);
+ textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
+ textBounds.x = slider.x + slider.width/2 - textBounds.width/2;
+ textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
+
+ GuiDrawText(items[*active], textBounds, GuiGetStyle(TOGGLE, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(TOGGLE, TEXT + (state*3))), guiAlpha));
+ }
+ //--------------------------------------------------------------------
+
+ return result;
+}
+
+// Check Box control, returns 1 when state changed
+int GuiCheckBox(Rectangle bounds, const char *text, bool *checked)
+{
+ int result = 0;
+ GuiState state = guiState;
+
+ bool temp = false;
+ if (checked == NULL) checked = &temp;
+
+ Rectangle textBounds = { 0 };
+
+ if (text != NULL)
+ {
+ textBounds.width = (float)GetTextWidth(text) + 2;
+ textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
+ textBounds.x = bounds.x + bounds.width + GuiGetStyle(CHECKBOX, TEXT_PADDING);
+ textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
+ if (GuiGetStyle(CHECKBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT) textBounds.x = bounds.x - textBounds.width - GuiGetStyle(CHECKBOX, TEXT_PADDING);
+ }
+
+ // Update control
+ //--------------------------------------------------------------------
+ if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode)
+ {
+ Vector2 mousePoint = GetMousePosition();
+
+ Rectangle totalBounds = {
+ (GuiGetStyle(CHECKBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT)? textBounds.x : bounds.x,
+ bounds.y,
+ bounds.width + textBounds.width + GuiGetStyle(CHECKBOX, TEXT_PADDING),
+ bounds.height,
+ };
+
+ // Check checkbox state
+ if (CheckCollisionPointRec(mousePoint, totalBounds))
+ {
+ if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED;
+ else state = STATE_FOCUSED;
+
+ if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON))
+ {
+ *checked = !(*checked);
+ result = 1;
+ }
+ }
+ }
+ //--------------------------------------------------------------------
+
+ // Draw control
+ //--------------------------------------------------------------------
+ GuiDrawRectangle(bounds, GuiGetStyle(CHECKBOX, BORDER_WIDTH), GetColor(GuiGetStyle(CHECKBOX, BORDER + (state*3))), BLANK);
+
+ if (*checked)
+ {
+ Rectangle check = { bounds.x + GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, CHECK_PADDING),
+ bounds.y + GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, CHECK_PADDING),
+ bounds.width - 2*(GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, CHECK_PADDING)),
+ bounds.height - 2*(GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, CHECK_PADDING)) };
+ GuiDrawRectangle(check, 0, BLANK, GetColor(GuiGetStyle(CHECKBOX, TEXT + state*3)));
+ }
+
+ GuiDrawText(text, textBounds, (GuiGetStyle(CHECKBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT)? TEXT_ALIGN_LEFT : TEXT_ALIGN_RIGHT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3))));
+ //--------------------------------------------------------------------
+
+ return result;
+}
+
+// Combo Box control
+int GuiComboBox(Rectangle bounds, const char *text, int *active)
+{
+ int result = 0;
+ GuiState state = guiState;
+
+ int temp = 0;
+ if (active == NULL) active = &temp;
+
+ bounds.width -= (GuiGetStyle(COMBOBOX, COMBO_BUTTON_WIDTH) + GuiGetStyle(COMBOBOX, COMBO_BUTTON_SPACING));
+
+ Rectangle selector = { (float)bounds.x + bounds.width + GuiGetStyle(COMBOBOX, COMBO_BUTTON_SPACING),
+ (float)bounds.y, (float)GuiGetStyle(COMBOBOX, COMBO_BUTTON_WIDTH), (float)bounds.height };
+
+ // Get substrings items from text (items pointers, lengths and count)
+ int itemCount = 0;
+ const char **items = GuiTextSplit(text, ';', &itemCount, NULL);
+
+ if (*active < 0) *active = 0;
+ else if (*active > (itemCount - 1)) *active = itemCount - 1;
+
+ // Update control
+ //--------------------------------------------------------------------
+ if ((state != STATE_DISABLED) && !guiLocked && (itemCount > 1) && !guiControlExclusiveMode)
+ {
+ Vector2 mousePoint = GetMousePosition();
+
+ if (CheckCollisionPointRec(mousePoint, bounds) ||
+ CheckCollisionPointRec(mousePoint, selector))
+ {
+ if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
+ {
+ *active += 1;
+ if (*active >= itemCount) *active = 0; // Cyclic combobox
+ }
+
+ if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED;
+ else state = STATE_FOCUSED;
+ }
+ }
+ //--------------------------------------------------------------------
+
+ // Draw control
+ //--------------------------------------------------------------------
+ // Draw combo box main
+ GuiDrawRectangle(bounds, GuiGetStyle(COMBOBOX, BORDER_WIDTH), GetColor(GuiGetStyle(COMBOBOX, BORDER + (state*3))), GetColor(GuiGetStyle(COMBOBOX, BASE + (state*3))));
+ GuiDrawText(items[*active], GetTextBounds(COMBOBOX, bounds), GuiGetStyle(COMBOBOX, TEXT_ALIGNMENT), GetColor(GuiGetStyle(COMBOBOX, TEXT + (state*3))));
+
+ // Draw selector using a custom button
+ // NOTE: BORDER_WIDTH and TEXT_ALIGNMENT forced values
+ int tempBorderWidth = GuiGetStyle(BUTTON, BORDER_WIDTH);
+ int tempTextAlign = GuiGetStyle(BUTTON, TEXT_ALIGNMENT);
+ GuiSetStyle(BUTTON, BORDER_WIDTH, 1);
+ GuiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER);
+
+ GuiButton(selector, TextFormat("%i/%i", *active + 1, itemCount));
+
+ GuiSetStyle(BUTTON, TEXT_ALIGNMENT, tempTextAlign);
+ GuiSetStyle(BUTTON, BORDER_WIDTH, tempBorderWidth);
+ //--------------------------------------------------------------------
+
+ return result;
+}
+
+// Dropdown Box control
+// NOTE: Returns mouse click
+int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMode)
+{
+ int result = 0;
+ GuiState state = guiState;
+
+ int temp = 0;
+ if (active == NULL) active = &temp;
+
+ int itemSelected = *active;
+ int itemFocused = -1;
+
+ int direction = 0; // Dropdown box open direction: down (default)
+ if (GuiGetStyle(DROPDOWNBOX, DROPDOWN_ROLL_UP) == 1) direction = 1; // Up
+
+ // Get substrings items from text (items pointers, lengths and count)
+ int itemCount = 0;
+ const char **items = GuiTextSplit(text, ';', &itemCount, NULL);
+
+ Rectangle boundsOpen = bounds;
+ boundsOpen.height = (itemCount + 1)*(bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING));
+ if (direction == 1) boundsOpen.y -= itemCount*(bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING)) + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING);
+
+ Rectangle itemBounds = bounds;
+
+ // Update control
+ //--------------------------------------------------------------------
+ if ((state != STATE_DISABLED) && (editMode || !guiLocked) && (itemCount > 1) && !guiControlExclusiveMode)
+ {
+ Vector2 mousePoint = GetMousePosition();
+
+ if (editMode)
+ {
+ state = STATE_PRESSED;
+
+ // Check if mouse has been pressed or released outside limits
+ if (!CheckCollisionPointRec(mousePoint, boundsOpen))
+ {
+ if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON) || IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) result = 1;
+ }
+
+ // Check if already selected item has been pressed again
+ if (CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) result = 1;
+
+ // Check focused and selected item
+ for (int i = 0; i < itemCount; i++)
+ {
+ // Update item rectangle y position for next item
+ if (direction == 0) itemBounds.y += (bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING));
+ else itemBounds.y -= (bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING));
+
+ if (CheckCollisionPointRec(mousePoint, itemBounds))
+ {
+ itemFocused = i;
+ if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON))
+ {
+ itemSelected = i;
+ result = 1; // Item selected
+ }
+ break;
+ }
+ }
+
+ itemBounds = bounds;
+ }
+ else
+ {
+ if (CheckCollisionPointRec(mousePoint, bounds))
+ {
+ if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
+ {
+ result = 1;
+ state = STATE_PRESSED;
+ }
+ else state = STATE_FOCUSED;
+ }
+ }
+ }
+ //--------------------------------------------------------------------
+
+ // Draw control
+ //--------------------------------------------------------------------
+ if (editMode) GuiPanel(boundsOpen, NULL);
+
+ GuiDrawRectangle(bounds, GuiGetStyle(DROPDOWNBOX, BORDER_WIDTH), GetColor(GuiGetStyle(DROPDOWNBOX, BORDER + state*3)), GetColor(GuiGetStyle(DROPDOWNBOX, BASE + state*3)));
+ GuiDrawText(items[itemSelected], GetTextBounds(DROPDOWNBOX, bounds), GuiGetStyle(DROPDOWNBOX, TEXT_ALIGNMENT), GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + state*3)));
+
+ if (editMode)
+ {
+ // Draw visible items
+ for (int i = 0; i < itemCount; i++)
+ {
+ // Update item rectangle y position for next item
+ if (direction == 0) itemBounds.y += (bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING));
+ else itemBounds.y -= (bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING));
+
+ if (i == itemSelected)
+ {
+ GuiDrawRectangle(itemBounds, GuiGetStyle(DROPDOWNBOX, BORDER_WIDTH), GetColor(GuiGetStyle(DROPDOWNBOX, BORDER_COLOR_PRESSED)), GetColor(GuiGetStyle(DROPDOWNBOX, BASE_COLOR_PRESSED)));
+ GuiDrawText(items[i], GetTextBounds(DROPDOWNBOX, itemBounds), GuiGetStyle(DROPDOWNBOX, TEXT_ALIGNMENT), GetColor(GuiGetStyle(DROPDOWNBOX, TEXT_COLOR_PRESSED)));
+ }
+ else if (i == itemFocused)
+ {
+ GuiDrawRectangle(itemBounds, GuiGetStyle(DROPDOWNBOX, BORDER_WIDTH), GetColor(GuiGetStyle(DROPDOWNBOX, BORDER_COLOR_FOCUSED)), GetColor(GuiGetStyle(DROPDOWNBOX, BASE_COLOR_FOCUSED)));
+ GuiDrawText(items[i], GetTextBounds(DROPDOWNBOX, itemBounds), GuiGetStyle(DROPDOWNBOX, TEXT_ALIGNMENT), GetColor(GuiGetStyle(DROPDOWNBOX, TEXT_COLOR_FOCUSED)));
+ }
+ else GuiDrawText(items[i], GetTextBounds(DROPDOWNBOX, itemBounds), GuiGetStyle(DROPDOWNBOX, TEXT_ALIGNMENT), GetColor(GuiGetStyle(DROPDOWNBOX, TEXT_COLOR_NORMAL)));
+ }
+ }
+
+ if (!GuiGetStyle(DROPDOWNBOX, DROPDOWN_ARROW_HIDDEN))
+ {
+ // Draw arrows (using icon if available)
+#if defined(RAYGUI_NO_ICONS)
+ GuiDrawText("v", RAYGUI_CLITERAL(Rectangle){ bounds.x + bounds.width - GuiGetStyle(DROPDOWNBOX, ARROW_PADDING), bounds.y + bounds.height/2 - 2, 10, 10 },
+ TEXT_ALIGN_CENTER, GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + (state*3))));
+#else
+ GuiDrawText(direction? "#121#" : "#120#", RAYGUI_CLITERAL(Rectangle){ bounds.x + bounds.width - GuiGetStyle(DROPDOWNBOX, ARROW_PADDING), bounds.y + bounds.height/2 - 6, 10, 10 },
+ TEXT_ALIGN_CENTER, GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + (state*3)))); // ICON_ARROW_DOWN_FILL
+#endif
+ }
+ //--------------------------------------------------------------------
+
+ *active = itemSelected;
+
+ // TODO: Use result to return more internal states: mouse-press out-of-bounds, mouse-press over selected-item...
+ return result; // Mouse click: result = 1
+}
+
+// Text Box control
+// NOTE: Returns true on ENTER pressed (useful for data validation)
+int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode)
+{
+ #if !defined(RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN)
+ #define RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN 40 // Frames to wait for autocursor movement
+ #endif
+ #if !defined(RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY)
+ #define RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY 1 // Frames delay for autocursor movement
+ #endif
+
+ int result = 0;
+ GuiState state = guiState;
+
+ bool multiline = false; // TODO: Consider multiline text input
+ int wrapMode = GuiGetStyle(DEFAULT, TEXT_WRAP_MODE);
+
+ Rectangle textBounds = GetTextBounds(TEXTBOX, bounds);
+ int textLength = (int)strlen(text); // Get current text length
+ int thisCursorIndex = textBoxCursorIndex;
+ if (thisCursorIndex > textLength) thisCursorIndex = textLength;
+ int textWidth = GetTextWidth(text) - GetTextWidth(text + thisCursorIndex);
+ int textIndexOffset = 0; // Text index offset to start drawing in the box
+
+ // Cursor rectangle
+ // NOTE: Position X value should be updated
+ Rectangle cursor = {
+ textBounds.x + textWidth + GuiGetStyle(DEFAULT, TEXT_SPACING),
+ textBounds.y + textBounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE),
+ 2,
+ (float)GuiGetStyle(DEFAULT, TEXT_SIZE)*2
+ };
+
+ if (cursor.height >= bounds.height) cursor.height = bounds.height - GuiGetStyle(TEXTBOX, BORDER_WIDTH)*2;
+ if (cursor.y < (bounds.y + GuiGetStyle(TEXTBOX, BORDER_WIDTH))) cursor.y = bounds.y + GuiGetStyle(TEXTBOX, BORDER_WIDTH);
+
+ // Mouse cursor rectangle
+ // NOTE: Initialized outside of screen
+ Rectangle mouseCursor = cursor;
+ mouseCursor.x = -1;
+ mouseCursor.width = 1;
+
+ // Auto-cursor movement logic
+ // NOTE: Cursor moves automatically when key down after some time
+ if (IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_UP) || IsKeyDown(KEY_DOWN) || IsKeyDown(KEY_BACKSPACE) || IsKeyDown(KEY_DELETE)) autoCursorCooldownCounter++;
+ else
+ {
+ autoCursorCooldownCounter = 0; // GLOBAL: Cursor cooldown counter
+ autoCursorDelayCounter = 0; // GLOBAL: Cursor delay counter
+ }
+
+ // Blink-cursor frame counter
+ //if (!autoCursorMode) blinkCursorFrameCounter++;
+ //else blinkCursorFrameCounter = 0;
+
+ // Update control
+ //--------------------------------------------------------------------
+ // WARNING: Text editing is only supported under certain conditions:
+ if ((state != STATE_DISABLED) && // Control not disabled
+ !GuiGetStyle(TEXTBOX, TEXT_READONLY) && // TextBox not on read-only mode
+ !guiLocked && // Gui not locked
+ !guiControlExclusiveMode && // No gui slider on dragging
+ (wrapMode == TEXT_WRAP_NONE)) // No wrap mode
+ {
+ Vector2 mousePosition = GetMousePosition();
+
+ if (editMode)
+ {
+ state = STATE_PRESSED;
+
+ if (textBoxCursorIndex > textLength) textBoxCursorIndex = textLength;
+
+ // If text does not fit in the textbox and current cursor position is out of bounds,
+ // we add an index offset to text for drawing only what requires depending on cursor
+ while (textWidth >= textBounds.width)
+ {
+ int nextCodepointSize = 0;
+ GetCodepointNext(text + textIndexOffset, &nextCodepointSize);
+
+ textIndexOffset += nextCodepointSize;
+
+ textWidth = GetTextWidth(text + textIndexOffset) - GetTextWidth(text + textBoxCursorIndex);
+ }
+
+ int codepoint = GetCharPressed(); // Get Unicode codepoint
+ if (multiline && IsKeyPressed(KEY_ENTER)) codepoint = (int)'\n';
+
+ // Encode codepoint as UTF-8
+ int codepointSize = 0;
+ const char *charEncoded = CodepointToUTF8(codepoint, &codepointSize);
+
+ // Add codepoint to text, at current cursor position
+ // NOTE: Make sure we do not overflow buffer size
+ if (((multiline && (codepoint == (int)'\n')) || (codepoint >= 32)) && ((textLength + codepointSize) < textSize))
+ {
+ // Move forward data from cursor position
+ for (int i = (textLength + codepointSize); i > textBoxCursorIndex; i--) text[i] = text[i - codepointSize];
+
+ // Add new codepoint in current cursor position
+ for (int i = 0; i < codepointSize; i++) text[textBoxCursorIndex + i] = charEncoded[i];
+
+ textBoxCursorIndex += codepointSize;
+ textLength += codepointSize;
+
+ // Make sure text last character is EOL
+ text[textLength] = '\0';
+ }
+
+ // Move cursor to start
+ if ((textLength > 0) && IsKeyPressed(KEY_HOME)) textBoxCursorIndex = 0;
+
+ // Move cursor to end
+ if ((textLength > textBoxCursorIndex) && IsKeyPressed(KEY_END)) textBoxCursorIndex = textLength;
+
+ // Delete codepoint from text, after current cursor position
+ if ((textLength > textBoxCursorIndex) && (IsKeyPressed(KEY_DELETE) || (IsKeyDown(KEY_DELETE) && (autoCursorCooldownCounter >= RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN))))
+ {
+ autoCursorDelayCounter++;
+
+ if (IsKeyPressed(KEY_DELETE) || (autoCursorDelayCounter%RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames
+ {
+ int nextCodepointSize = 0;
+ GetCodepointNext(text + textBoxCursorIndex, &nextCodepointSize);
+
+ // Move backward text from cursor position
+ for (int i = textBoxCursorIndex; i < textLength; i++) text[i] = text[i + nextCodepointSize];
+
+ textLength -= codepointSize;
+ if (textBoxCursorIndex > textLength) textBoxCursorIndex = textLength;
+
+ // Make sure text last character is EOL
+ text[textLength] = '\0';
+ }
+ }
+
+ // Delete related codepoints from text, before current cursor position
+ if ((textLength > 0) && IsKeyPressed(KEY_BACKSPACE) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL)))
+ {
+ int i = textBoxCursorIndex - 1;
+ int accCodepointSize = 0;
+
+ // Move cursor to the end of word if on space already
+ while ((i > 0) && isspace(text[i]))
+ {
+ int prevCodepointSize = 0;
+ GetCodepointPrevious(text + i, &prevCodepointSize);
+ i -= prevCodepointSize;
+ accCodepointSize += prevCodepointSize;
+ }
+
+ // Move cursor to the start of the word
+ while ((i > 0) && !isspace(text[i]))
+ {
+ int prevCodepointSize = 0;
+ GetCodepointPrevious(text + i, &prevCodepointSize);
+ i -= prevCodepointSize;
+ accCodepointSize += prevCodepointSize;
+ }
+
+ // Move forward text from cursor position
+ for (int j = (textBoxCursorIndex - accCodepointSize); j < textLength; j++) text[j] = text[j + accCodepointSize];
+
+ // Prevent cursor index from decrementing past 0
+ if (textBoxCursorIndex > 0)
+ {
+ textBoxCursorIndex -= accCodepointSize;
+ textLength -= accCodepointSize;
+ }
+
+ // Make sure text last character is EOL
+ text[textLength] = '\0';
+ }
+ else if ((textLength > 0) && (IsKeyPressed(KEY_BACKSPACE) || (IsKeyDown(KEY_BACKSPACE) && (autoCursorCooldownCounter >= RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN))))
+ {
+ autoCursorDelayCounter++;
+
+ if (IsKeyPressed(KEY_BACKSPACE) || (autoCursorDelayCounter%RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames
+ {
+ int prevCodepointSize = 0;
+
+ // Prevent cursor index from decrementing past 0
+ if (textBoxCursorIndex > 0)
+ {
+ GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize);
+
+ // Move backward text from cursor position
+ for (int i = (textBoxCursorIndex - prevCodepointSize); i < textLength; i++) text[i] = text[i + prevCodepointSize];
+
+ textBoxCursorIndex -= codepointSize;
+ textLength -= codepointSize;
+ }
+
+ // Make sure text last character is EOL
+ text[textLength] = '\0';
+ }
+ }
+
+ // Move cursor position with keys
+ if (IsKeyPressed(KEY_LEFT) || (IsKeyDown(KEY_LEFT) && (autoCursorCooldownCounter > RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN)))
+ {
+ autoCursorDelayCounter++;
+
+ if (IsKeyPressed(KEY_LEFT) || (autoCursorDelayCounter%RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames
+ {
+ int prevCodepointSize = 0;
+ if (textBoxCursorIndex > 0) GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize);
+
+ if (textBoxCursorIndex >= prevCodepointSize) textBoxCursorIndex -= prevCodepointSize;
+ }
+ }
+ else if (IsKeyPressed(KEY_RIGHT) || (IsKeyDown(KEY_RIGHT) && (autoCursorCooldownCounter > RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN)))
+ {
+ autoCursorDelayCounter++;
+
+ if (IsKeyPressed(KEY_RIGHT) || (autoCursorDelayCounter%RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames
+ {
+ int nextCodepointSize = 0;
+ GetCodepointNext(text + textBoxCursorIndex, &nextCodepointSize);
+
+ if ((textBoxCursorIndex + nextCodepointSize) <= textLength) textBoxCursorIndex += nextCodepointSize;
+ }
+ }
+
+ // Move cursor position with mouse
+ if (CheckCollisionPointRec(mousePosition, textBounds)) // Mouse hover text
+ {
+ float scaleFactor = (float)GuiGetStyle(DEFAULT, TEXT_SIZE)/(float)guiFont.baseSize;
+ int codepointIndex = 0;
+ float glyphWidth = 0.0f;
+ float widthToMouseX = 0;
+ int mouseCursorIndex = 0;
+
+ for (int i = textIndexOffset; i < textLength; i++)
+ {
+ codepoint = GetCodepointNext(&text[i], &codepointSize);
+ codepointIndex = GetGlyphIndex(guiFont, codepoint);
+
+ if (guiFont.glyphs[codepointIndex].advanceX == 0) glyphWidth = ((float)guiFont.recs[codepointIndex].width*scaleFactor);
+ else glyphWidth = ((float)guiFont.glyphs[codepointIndex].advanceX*scaleFactor);
+
+ if (mousePosition.x <= (textBounds.x + (widthToMouseX + glyphWidth/2)))
+ {
+ mouseCursor.x = textBounds.x + widthToMouseX;
+ mouseCursorIndex = i;
+ break;
+ }
+
+ widthToMouseX += (glyphWidth + (float)GuiGetStyle(DEFAULT, TEXT_SPACING));
+ }
+
+ // Check if mouse cursor is at the last position
+ int textEndWidth = GetTextWidth(text + textIndexOffset);
+ if (GetMousePosition().x >= (textBounds.x + textEndWidth - glyphWidth/2))
+ {
+ mouseCursor.x = textBounds.x + textEndWidth;
+ mouseCursorIndex = textLength;
+ }
+
+ // Place cursor at required index on mouse click
+ if ((mouseCursor.x >= 0) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
+ {
+ cursor.x = mouseCursor.x;
+ textBoxCursorIndex = mouseCursorIndex;
+ }
+ }
+ else mouseCursor.x = -1;
+
+ // Recalculate cursor position.y depending on textBoxCursorIndex
+ cursor.x = bounds.x + GuiGetStyle(TEXTBOX, TEXT_PADDING) + GetTextWidth(text + textIndexOffset) - GetTextWidth(text + textBoxCursorIndex) + GuiGetStyle(DEFAULT, TEXT_SPACING);
+ //if (multiline) cursor.y = GetTextLines()
+
+ // Finish text editing on ENTER or mouse click outside bounds
+ if ((!multiline && IsKeyPressed(KEY_ENTER)) ||
+ (!CheckCollisionPointRec(mousePosition, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON)))
+ {
+ textBoxCursorIndex = 0; // GLOBAL: Reset the shared cursor index
+ result = 1;
+ }
+ }
+ else
+ {
+ if (CheckCollisionPointRec(mousePosition, bounds))
+ {
+ state = STATE_FOCUSED;
+
+ if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
+ {
+ textBoxCursorIndex = textLength; // GLOBAL: Place cursor index to the end of current text
+ result = 1;
+ }
+ }
+ }
+ }
+ //--------------------------------------------------------------------
+
+ // Draw control
+ //--------------------------------------------------------------------
+ if (state == STATE_PRESSED)
+ {
+ GuiDrawRectangle(bounds, GuiGetStyle(TEXTBOX, BORDER_WIDTH), GetColor(GuiGetStyle(TEXTBOX, BORDER + (state*3))), GetColor(GuiGetStyle(TEXTBOX, BASE_COLOR_PRESSED)));
+ }
+ else if (state == STATE_DISABLED)
+ {
+ GuiDrawRectangle(bounds, GuiGetStyle(TEXTBOX, BORDER_WIDTH), GetColor(GuiGetStyle(TEXTBOX, BORDER + (state*3))), GetColor(GuiGetStyle(TEXTBOX, BASE_COLOR_DISABLED)));
+ }
+ else GuiDrawRectangle(bounds, GuiGetStyle(TEXTBOX, BORDER_WIDTH), GetColor(GuiGetStyle(TEXTBOX, BORDER + (state*3))), BLANK);
+
+ // Draw text considering index offset if required
+ // NOTE: Text index offset depends on cursor position
+ GuiDrawText(text + textIndexOffset, textBounds, GuiGetStyle(TEXTBOX, TEXT_ALIGNMENT), GetColor(GuiGetStyle(TEXTBOX, TEXT + (state*3))));
+
+ // Draw cursor
+ if (editMode && !GuiGetStyle(TEXTBOX, TEXT_READONLY))
+ {
+ //if (autoCursorMode || ((blinkCursorFrameCounter/40)%2 == 0))
+ GuiDrawRectangle(cursor, 0, BLANK, GetColor(GuiGetStyle(TEXTBOX, BORDER_COLOR_PRESSED)));
+
+ // Draw mouse position cursor (if required)
+ if (mouseCursor.x >= 0) GuiDrawRectangle(mouseCursor, 0, BLANK, GetColor(GuiGetStyle(TEXTBOX, BORDER_COLOR_PRESSED)));
+ }
+ else if (state == STATE_FOCUSED) GuiTooltip(bounds);
+ //--------------------------------------------------------------------
+
+ return result; // Mouse button pressed: result = 1
+}
+
+/*
+// Text Box control with multiple lines and word-wrap
+// NOTE: This text-box is readonly, no editing supported by default
+bool GuiTextBoxMulti(Rectangle bounds, char *text, int textSize, bool editMode)
+{
+ bool pressed = false;
+
+ GuiSetStyle(TEXTBOX, TEXT_READONLY, 1);
+ GuiSetStyle(DEFAULT, TEXT_WRAP_MODE, TEXT_WRAP_WORD); // WARNING: If wrap mode enabled, text editing is not supported
+ GuiSetStyle(DEFAULT, TEXT_ALIGNMENT_VERTICAL, TEXT_ALIGN_TOP);
+
+ // TODO: Implement methods to calculate cursor position properly
+ pressed = GuiTextBox(bounds, text, textSize, editMode);
+
+ GuiSetStyle(DEFAULT, TEXT_ALIGNMENT_VERTICAL, TEXT_ALIGN_MIDDLE);
+ GuiSetStyle(DEFAULT, TEXT_WRAP_MODE, TEXT_WRAP_NONE);
+ GuiSetStyle(TEXTBOX, TEXT_READONLY, 0);
+
+ return pressed;
+}
+*/
+
+// Spinner control, returns selected value
+int GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode)
+{
+ int result = 1;
+ GuiState state = guiState;
+
+ int tempValue = *value;
+
+ Rectangle spinner = { bounds.x + GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH) + GuiGetStyle(SPINNER, SPIN_BUTTON_SPACING), bounds.y,
+ bounds.width - 2*(GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH) + GuiGetStyle(SPINNER, SPIN_BUTTON_SPACING)), bounds.height };
+ Rectangle leftButtonBound = { (float)bounds.x, (float)bounds.y, (float)GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH), (float)bounds.height };
+ Rectangle rightButtonBound = { (float)bounds.x + bounds.width - GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH), (float)bounds.y, (float)GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH), (float)bounds.height };
+
+ Rectangle textBounds = { 0 };
+ if (text != NULL)
+ {
+ textBounds.width = (float)GetTextWidth(text) + 2;
+ textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
+ textBounds.x = bounds.x + bounds.width + GuiGetStyle(SPINNER, TEXT_PADDING);
+ textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
+ if (GuiGetStyle(SPINNER, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT) textBounds.x = bounds.x - textBounds.width - GuiGetStyle(SPINNER, TEXT_PADDING);
+ }
+
+ // Update control
+ //--------------------------------------------------------------------
+ if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode)
+ {
+ Vector2 mousePoint = GetMousePosition();
+
+ // Check spinner state
+ if (CheckCollisionPointRec(mousePoint, bounds))
+ {
+ if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED;
+ else state = STATE_FOCUSED;
+ }
+ }
+
+#if defined(RAYGUI_NO_ICONS)
+ if (GuiButton(leftButtonBound, "<")) tempValue--;
+ if (GuiButton(rightButtonBound, ">")) tempValue++;
+#else
+ if (GuiButton(leftButtonBound, GuiIconText(ICON_ARROW_LEFT_FILL, NULL))) tempValue--;
+ if (GuiButton(rightButtonBound, GuiIconText(ICON_ARROW_RIGHT_FILL, NULL))) tempValue++;
+#endif
+
+ if (!editMode)
+ {
+ if (tempValue < minValue) tempValue = minValue;
+ if (tempValue > maxValue) tempValue = maxValue;
+ }
+ //--------------------------------------------------------------------
+
+ // Draw control
+ //--------------------------------------------------------------------
+ result = GuiValueBox(spinner, NULL, &tempValue, minValue, maxValue, editMode);
+
+ // Draw value selector custom buttons
+ // NOTE: BORDER_WIDTH and TEXT_ALIGNMENT forced values
+ int tempBorderWidth = GuiGetStyle(BUTTON, BORDER_WIDTH);
+ int tempTextAlign = GuiGetStyle(BUTTON, TEXT_ALIGNMENT);
+ GuiSetStyle(BUTTON, BORDER_WIDTH, GuiGetStyle(SPINNER, BORDER_WIDTH));
+ GuiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER);
+
+ GuiSetStyle(BUTTON, TEXT_ALIGNMENT, tempTextAlign);
+ GuiSetStyle(BUTTON, BORDER_WIDTH, tempBorderWidth);
+
+ // Draw text label if provided
+ GuiDrawText(text, textBounds, (GuiGetStyle(SPINNER, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT)? TEXT_ALIGN_LEFT : TEXT_ALIGN_RIGHT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3))));
+ //--------------------------------------------------------------------
+
+ *value = tempValue;
+ return result;
+}
+
+// Value Box control, updates input text with numbers
+// NOTE: Requires static variables: frameCounter
+int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode)
+{
+ #if !defined(RAYGUI_VALUEBOX_MAX_CHARS)
+ #define RAYGUI_VALUEBOX_MAX_CHARS 32
+ #endif
+
+ int result = 0;
+ GuiState state = guiState;
+
+ char textValue[RAYGUI_VALUEBOX_MAX_CHARS + 1] = "\0";
+ sprintf(textValue, "%i", *value);
+
+ Rectangle textBounds = { 0 };
+ if (text != NULL)
+ {
+ textBounds.width = (float)GetTextWidth(text) + 2;
+ textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
+ textBounds.x = bounds.x + bounds.width + GuiGetStyle(VALUEBOX, TEXT_PADDING);
+ textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
+ if (GuiGetStyle(VALUEBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT) textBounds.x = bounds.x - textBounds.width - GuiGetStyle(VALUEBOX, TEXT_PADDING);
+ }
+
+ // Update control
+ //--------------------------------------------------------------------
+ if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode)
+ {
+ Vector2 mousePoint = GetMousePosition();
+
+ bool valueHasChanged = false;
+
+ if (editMode)
+ {
+ state = STATE_PRESSED;
+
+ int keyCount = (int)strlen(textValue);
+
+ // Only allow keys in range [48..57]
+ if (keyCount < RAYGUI_VALUEBOX_MAX_CHARS)
+ {
+ if (GetTextWidth(textValue) < bounds.width)
+ {
+ int key = GetCharPressed();
+ if ((key >= 48) && (key <= 57))
+ {
+ textValue[keyCount] = (char)key;
+ keyCount++;
+ valueHasChanged = true;
+ }
+ }
+ }
+
+ // Delete text
+ if (keyCount > 0)
+ {
+ if (IsKeyPressed(KEY_BACKSPACE))
+ {
+ keyCount--;
+ textValue[keyCount] = '\0';
+ valueHasChanged = true;
+ }
+ }
+
+ if (valueHasChanged) *value = TextToInteger(textValue);
+
+ // NOTE: We are not clamp values until user input finishes
+ //if (*value > maxValue) *value = maxValue;
+ //else if (*value < minValue) *value = minValue;
+
+ if ((IsKeyPressed(KEY_ENTER) || IsKeyPressed(KEY_KP_ENTER)) || (!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON)))
+ {
+ if (*value > maxValue) *value = maxValue;
+ else if (*value < minValue) *value = minValue;
+
+ result = 1;
+ }
+ }
+ else
+ {
+ if (*value > maxValue) *value = maxValue;
+ else if (*value < minValue) *value = minValue;
+
+ if (CheckCollisionPointRec(mousePoint, bounds))
+ {
+ state = STATE_FOCUSED;
+ if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) result = 1;
+ }
+ }
+ }
+ //--------------------------------------------------------------------
+
+ // Draw control
+ //--------------------------------------------------------------------
+ Color baseColor = BLANK;
+ if (state == STATE_PRESSED) baseColor = GetColor(GuiGetStyle(VALUEBOX, BASE_COLOR_PRESSED));
+ else if (state == STATE_DISABLED) baseColor = GetColor(GuiGetStyle(VALUEBOX, BASE_COLOR_DISABLED));
+
+ GuiDrawRectangle(bounds, GuiGetStyle(VALUEBOX, BORDER_WIDTH), GetColor(GuiGetStyle(VALUEBOX, BORDER + (state*3))), baseColor);
+ GuiDrawText(textValue, GetTextBounds(VALUEBOX, bounds), TEXT_ALIGN_CENTER, GetColor(GuiGetStyle(VALUEBOX, TEXT + (state*3))));
+
+ // Draw cursor
+ if (editMode)
+ {
+ // NOTE: ValueBox internal text is always centered
+ Rectangle cursor = { bounds.x + GetTextWidth(textValue)/2 + bounds.width/2 + 1, bounds.y + 2*GuiGetStyle(VALUEBOX, BORDER_WIDTH), 4, bounds.height - 4*GuiGetStyle(VALUEBOX, BORDER_WIDTH) };
+ GuiDrawRectangle(cursor, 0, BLANK, GetColor(GuiGetStyle(VALUEBOX, BORDER_COLOR_PRESSED)));
+ }
+
+ // Draw text label if provided
+ GuiDrawText(text, textBounds, (GuiGetStyle(VALUEBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT)? TEXT_ALIGN_LEFT : TEXT_ALIGN_RIGHT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3))));
+ //--------------------------------------------------------------------
+
+ return result;
+}
+
+// Floating point Value Box control, updates input val_str with numbers
+// NOTE: Requires static variables: frameCounter
+int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float *value, bool editMode)
+{
+ #if !defined(RAYGUI_VALUEBOX_MAX_CHARS)
+ #define RAYGUI_VALUEBOX_MAX_CHARS 32
+ #endif
+
+ int result = 0;
+ GuiState state = guiState;
+
+ //char textValue[RAYGUI_VALUEBOX_MAX_CHARS + 1] = "\0";
+ //sprintf(textValue, "%2.2f", *value);
+
+ Rectangle textBounds = {0};
+ if (text != NULL)
+ {
+ textBounds.width = (float)GetTextWidth(text) + 2;
+ textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
+ textBounds.x = bounds.x + bounds.width + GuiGetStyle(VALUEBOX, TEXT_PADDING);
+ textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
+ if (GuiGetStyle(VALUEBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT) textBounds.x = bounds.x - textBounds.width - GuiGetStyle(VALUEBOX, TEXT_PADDING);
+ }
+
+ // Update control
+ //--------------------------------------------------------------------
+ if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode)
+ {
+ Vector2 mousePoint = GetMousePosition();
+
+ bool valueHasChanged = false;
+
+ if (editMode)
+ {
+ state = STATE_PRESSED;
+
+ int keyCount = (int)strlen(textValue);
+
+ // Only allow keys in range [48..57]
+ if (keyCount < RAYGUI_VALUEBOX_MAX_CHARS)
+ {
+ if (GetTextWidth(textValue) < bounds.width)
+ {
+ int key = GetCharPressed();
+ if (((key >= 48) && (key <= 57)) ||
+ (key == '.') ||
+ ((keyCount == 0) && (key == '+')) || // NOTE: Sign can only be in first position
+ ((keyCount == 0) && (key == '-')))
+ {
+ textValue[keyCount] = (char)key;
+ keyCount++;
+
+ valueHasChanged = true;
+ }
+ }
+ }
+
+ // Pressed backspace
+ if (IsKeyPressed(KEY_BACKSPACE))
+ {
+ if (keyCount > 0)
+ {
+ keyCount--;
+ textValue[keyCount] = '\0';
+ valueHasChanged = true;
+ }
+ }
+
+ if (valueHasChanged) *value = TextToFloat(textValue);
+
+ if ((IsKeyPressed(KEY_ENTER) || IsKeyPressed(KEY_KP_ENTER)) || (!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) result = 1;
+ }
+ else
+ {
+ if (CheckCollisionPointRec(mousePoint, bounds))
+ {
+ state = STATE_FOCUSED;
+ if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) result = 1;
+ }
+ }
+ }
+ //--------------------------------------------------------------------
+
+ // Draw control
+ //--------------------------------------------------------------------
+ Color baseColor = BLANK;
+ if (state == STATE_PRESSED) baseColor = GetColor(GuiGetStyle(VALUEBOX, BASE_COLOR_PRESSED));
+ else if (state == STATE_DISABLED) baseColor = GetColor(GuiGetStyle(VALUEBOX, BASE_COLOR_DISABLED));
+
+ GuiDrawRectangle(bounds, GuiGetStyle(VALUEBOX, BORDER_WIDTH), GetColor(GuiGetStyle(VALUEBOX, BORDER + (state*3))), baseColor);
+ GuiDrawText(textValue, GetTextBounds(VALUEBOX, bounds), TEXT_ALIGN_CENTER, GetColor(GuiGetStyle(VALUEBOX, TEXT + (state*3))));
+
+ // Draw cursor
+ if (editMode)
+ {
+ // NOTE: ValueBox internal text is always centered
+ Rectangle cursor = {bounds.x + GetTextWidth(textValue)/2 + bounds.width/2 + 1,
+ bounds.y + 2*GuiGetStyle(VALUEBOX, BORDER_WIDTH), 4,
+ bounds.height - 4*GuiGetStyle(VALUEBOX, BORDER_WIDTH)};
+ GuiDrawRectangle(cursor, 0, BLANK, GetColor(GuiGetStyle(VALUEBOX, BORDER_COLOR_PRESSED)));
+ }
+
+ // Draw text label if provided
+ GuiDrawText(text, textBounds,
+ (GuiGetStyle(VALUEBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT)? TEXT_ALIGN_LEFT : TEXT_ALIGN_RIGHT,
+ GetColor(GuiGetStyle(LABEL, TEXT + (state*3))));
+ //--------------------------------------------------------------------
+
+ return result;
+}
+
+// Slider control with pro parameters
+// NOTE: Other GuiSlider*() controls use this one
+int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue, int sliderWidth)
+{
+ int result = 0;
+ GuiState state = guiState;
+
+ float temp = (maxValue - minValue)/2.0f;
+ if (value == NULL) value = &temp;
+ float oldValue = *value;
+
+ Rectangle slider = { bounds.x, bounds.y + GuiGetStyle(SLIDER, BORDER_WIDTH) + GuiGetStyle(SLIDER, SLIDER_PADDING),
+ 0, bounds.height - 2*GuiGetStyle(SLIDER, BORDER_WIDTH) - 2*GuiGetStyle(SLIDER, SLIDER_PADDING) };
+
+ // Update control
+ //--------------------------------------------------------------------
+ if ((state != STATE_DISABLED) && !guiLocked)
+ {
+ Vector2 mousePoint = GetMousePosition();
+
+ if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds
+ {
+ if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
+ {
+ if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec))
+ {
+ state = STATE_PRESSED;
+ // Get equivalent value and slider position from mousePosition.x
+ *value = (maxValue - minValue)*((mousePoint.x - bounds.x - sliderWidth/2)/(bounds.width-sliderWidth)) + minValue;
+ }
+ }
+ else
+ {
+ guiControlExclusiveMode = false;
+ guiControlExclusiveRec = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 };
+ }
+ }
+ else if (CheckCollisionPointRec(mousePoint, bounds))
+ {
+ if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
+ {
+ state = STATE_PRESSED;
+ guiControlExclusiveMode = true;
+ guiControlExclusiveRec = bounds; // Store bounds as an identifier when dragging starts
+
+ if (!CheckCollisionPointRec(mousePoint, slider))
+ {
+ // Get equivalent value and slider position from mousePosition.x
+ *value = (maxValue - minValue)*((mousePoint.x - bounds.x - sliderWidth/2)/(bounds.width-sliderWidth)) + minValue;
+ }
+ }
+ else state = STATE_FOCUSED;
+ }
+
+ if (*value > maxValue) *value = maxValue;
+ else if (*value < minValue) *value = minValue;
+ }
+
+ // Control value change check
+ if (oldValue == *value) result = 0;
+ else result = 1;
+
+ // Slider bar limits check
+ float sliderValue = (((*value - minValue)/(maxValue - minValue))*(bounds.width - sliderWidth - 2*GuiGetStyle(SLIDER, BORDER_WIDTH)));
+ if (sliderWidth > 0) // Slider
+ {
+ slider.x += sliderValue;
+ slider.width = (float)sliderWidth;
+ if (slider.x <= (bounds.x + GuiGetStyle(SLIDER, BORDER_WIDTH))) slider.x = bounds.x + GuiGetStyle(SLIDER, BORDER_WIDTH);
+ else if ((slider.x + slider.width) >= (bounds.x + bounds.width)) slider.x = bounds.x + bounds.width - slider.width - GuiGetStyle(SLIDER, BORDER_WIDTH);
+ }
+ else if (sliderWidth == 0) // SliderBar
+ {
+ slider.x += GuiGetStyle(SLIDER, BORDER_WIDTH);
+ slider.width = sliderValue;
+ if (slider.width > bounds.width) slider.width = bounds.width - 2*GuiGetStyle(SLIDER, BORDER_WIDTH);
+ }
+ //--------------------------------------------------------------------
+
+ // Draw control
+ //--------------------------------------------------------------------
+ GuiDrawRectangle(bounds, GuiGetStyle(SLIDER, BORDER_WIDTH), GetColor(GuiGetStyle(SLIDER, BORDER + (state*3))), GetColor(GuiGetStyle(SLIDER, (state != STATE_DISABLED)? BASE_COLOR_NORMAL : BASE_COLOR_DISABLED)));
+
+ // Draw slider internal bar (depends on state)
+ if (state == STATE_NORMAL) GuiDrawRectangle(slider, 0, BLANK, GetColor(GuiGetStyle(SLIDER, BASE_COLOR_PRESSED)));
+ else if (state == STATE_FOCUSED) GuiDrawRectangle(slider, 0, BLANK, GetColor(GuiGetStyle(SLIDER, TEXT_COLOR_FOCUSED)));
+ else if (state == STATE_PRESSED) GuiDrawRectangle(slider, 0, BLANK, GetColor(GuiGetStyle(SLIDER, TEXT_COLOR_PRESSED)));
+
+ // Draw left/right text if provided
+ if (textLeft != NULL)
+ {
+ Rectangle textBounds = { 0 };
+ textBounds.width = (float)GetTextWidth(textLeft);
+ textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
+ textBounds.x = bounds.x - textBounds.width - GuiGetStyle(SLIDER, TEXT_PADDING);
+ textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
+
+ GuiDrawText(textLeft, textBounds, TEXT_ALIGN_RIGHT, GetColor(GuiGetStyle(SLIDER, TEXT + (state*3))));
+ }
+
+ if (textRight != NULL)
+ {
+ Rectangle textBounds = { 0 };
+ textBounds.width = (float)GetTextWidth(textRight);
+ textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
+ textBounds.x = bounds.x + bounds.width + GuiGetStyle(SLIDER, TEXT_PADDING);
+ textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
+
+ GuiDrawText(textRight, textBounds, TEXT_ALIGN_LEFT, GetColor(GuiGetStyle(SLIDER, TEXT + (state*3))));
+ }
+ //--------------------------------------------------------------------
+
+ return result;
+}
+
+// Slider control extended, returns selected value and has text
+int GuiSlider(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue)
+{
+ return GuiSliderPro(bounds, textLeft, textRight, value, minValue, maxValue, GuiGetStyle(SLIDER, SLIDER_WIDTH));
+}
+
+// Slider Bar control extended, returns selected value
+int GuiSliderBar(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue)
+{
+ return GuiSliderPro(bounds, textLeft, textRight, value, minValue, maxValue, 0);
+}
+
+// Progress Bar control extended, shows current progress value
+int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue)
+{
+ int result = 0;
+ GuiState state = guiState;
+
+ float temp = (maxValue - minValue)/2.0f;
+ if (value == NULL) value = &temp;
+
+ // Progress bar
+ Rectangle progress = { bounds.x + GuiGetStyle(PROGRESSBAR, BORDER_WIDTH),
+ bounds.y + GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) + GuiGetStyle(PROGRESSBAR, PROGRESS_PADDING), 0,
+ bounds.height - 2*GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) - 2*GuiGetStyle(PROGRESSBAR, PROGRESS_PADDING) };
+
+ // Update control
+ //--------------------------------------------------------------------
+ if (*value > maxValue) *value = maxValue;
+
+ // WARNING: Working with floats could lead to rounding issues
+ if ((state != STATE_DISABLED)) progress.width = (float)(*value/(maxValue - minValue))*bounds.width - ((*value >= maxValue)? (float)(2*GuiGetStyle(PROGRESSBAR, BORDER_WIDTH)) : 0.0f);
+ //--------------------------------------------------------------------
+
+ // Draw control
+ //--------------------------------------------------------------------
+ if (state == STATE_DISABLED)
+ {
+ GuiDrawRectangle(bounds, GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), GetColor(GuiGetStyle(PROGRESSBAR, BORDER + (state*3))), BLANK);
+ }
+ else
+ {
+ if (*value > minValue)
+ {
+ // Draw progress bar with colored border, more visual
+ GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y, (int)progress.width + (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_FOCUSED)));
+ GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + 1, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.height - 2 }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_FOCUSED)));
+ GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + bounds.height - 1, (int)progress.width + (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_FOCUSED)));
+ }
+ else GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.height }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_NORMAL)));
+
+ if (*value >= maxValue) GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x + progress.width + 1, bounds.y, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.height }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_FOCUSED)));
+ else
+ {
+ // Draw borders not yet reached by value
+ GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x + (int)progress.width + 1, bounds.y, bounds.width - (int)progress.width - 1, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_NORMAL)));
+ GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x + (int)progress.width + 1, bounds.y + bounds.height - 1, bounds.width - (int)progress.width - 1, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_NORMAL)));
+ GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x + bounds.width - 1, bounds.y + 1, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.height - 2 }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_NORMAL)));
+ }
+
+ // Draw slider internal progress bar (depends on state)
+ GuiDrawRectangle(progress, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BASE_COLOR_PRESSED)));
+ }
+
+ // Draw left/right text if provided
+ if (textLeft != NULL)
+ {
+ Rectangle textBounds = { 0 };
+ textBounds.width = (float)GetTextWidth(textLeft);
+ textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
+ textBounds.x = bounds.x - textBounds.width - GuiGetStyle(PROGRESSBAR, TEXT_PADDING);
+ textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
+
+ GuiDrawText(textLeft, textBounds, TEXT_ALIGN_RIGHT, GetColor(GuiGetStyle(PROGRESSBAR, TEXT + (state*3))));
+ }
+
+ if (textRight != NULL)
+ {
+ Rectangle textBounds = { 0 };
+ textBounds.width = (float)GetTextWidth(textRight);
+ textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
+ textBounds.x = bounds.x + bounds.width + GuiGetStyle(PROGRESSBAR, TEXT_PADDING);
+ textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
+
+ GuiDrawText(textRight, textBounds, TEXT_ALIGN_LEFT, GetColor(GuiGetStyle(PROGRESSBAR, TEXT + (state*3))));
+ }
+ //--------------------------------------------------------------------
+
+ return result;
+}
+
+// Status Bar control
+int GuiStatusBar(Rectangle bounds, const char *text)
+{
+ int result = 0;
+ GuiState state = guiState;
+
+ // Draw control
+ //--------------------------------------------------------------------
+ GuiDrawRectangle(bounds, GuiGetStyle(STATUSBAR, BORDER_WIDTH), GetColor(GuiGetStyle(STATUSBAR, BORDER + (state*3))), GetColor(GuiGetStyle(STATUSBAR, BASE + (state*3))));
+ GuiDrawText(text, GetTextBounds(STATUSBAR, bounds), GuiGetStyle(STATUSBAR, TEXT_ALIGNMENT), GetColor(GuiGetStyle(STATUSBAR, TEXT + (state*3))));
+ //--------------------------------------------------------------------
+
+ return result;
+}
+
+// Dummy rectangle control, intended for placeholding
+int GuiDummyRec(Rectangle bounds, const char *text)
+{
+ int result = 0;
+ GuiState state = guiState;
+
+ // Update control
+ //--------------------------------------------------------------------
+ if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode)
+ {
+ Vector2 mousePoint = GetMousePosition();
+
+ // Check button state
+ if (CheckCollisionPointRec(mousePoint, bounds))
+ {
+ if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED;
+ else state = STATE_FOCUSED;
+ }
+ }
+ //--------------------------------------------------------------------
+
+ // Draw control
+ //--------------------------------------------------------------------
+ GuiDrawRectangle(bounds, 0, BLANK, GetColor(GuiGetStyle(DEFAULT, (state != STATE_DISABLED)? BASE_COLOR_NORMAL : BASE_COLOR_DISABLED)));
+ GuiDrawText(text, GetTextBounds(DEFAULT, bounds), TEXT_ALIGN_CENTER, GetColor(GuiGetStyle(BUTTON, (state != STATE_DISABLED)? TEXT_COLOR_NORMAL : TEXT_COLOR_DISABLED)));
+ //------------------------------------------------------------------
+
+ return result;
+}
+
+// List View control
+int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *active)
+{
+ int result = 0;
+ int itemCount = 0;
+ const char **items = NULL;
+
+ if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL);
+
+ result = GuiListViewEx(bounds, items, itemCount, scrollIndex, active, NULL);
+
+ return result;
+}
+
+// List View control with extended parameters
+int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus)
+{
+ int result = 0;
+ GuiState state = guiState;
+
+ int itemFocused = (focus == NULL)? -1 : *focus;
+ int itemSelected = (active == NULL)? -1 : *active;
+
+ // Check if we need a scroll bar
+ bool useScrollBar = false;
+ if ((GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT) + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING))*count > bounds.height) useScrollBar = true;
+
+ // Define base item rectangle [0]
+ Rectangle itemBounds = { 0 };
+ itemBounds.x = bounds.x + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING);
+ itemBounds.y = bounds.y + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING) + GuiGetStyle(DEFAULT, BORDER_WIDTH);
+ itemBounds.width = bounds.width - 2*GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING) - GuiGetStyle(DEFAULT, BORDER_WIDTH);
+ itemBounds.height = (float)GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT);
+ if (useScrollBar) itemBounds.width -= GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH);
+
+ // Get items on the list
+ int visibleItems = (int)bounds.height/(GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT) + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING));
+ if (visibleItems > count) visibleItems = count;
+
+ int startIndex = (scrollIndex == NULL)? 0 : *scrollIndex;
+ if ((startIndex < 0) || (startIndex > (count - visibleItems))) startIndex = 0;
+ int endIndex = startIndex + visibleItems;
+
+ // Update control
+ //--------------------------------------------------------------------
+ if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode)
+ {
+ Vector2 mousePoint = GetMousePosition();
+
+ // Check mouse inside list view
+ if (CheckCollisionPointRec(mousePoint, bounds))
+ {
+ state = STATE_FOCUSED;
+
+ // Check focused and selected item
+ for (int i = 0; i < visibleItems; i++)
+ {
+ if (CheckCollisionPointRec(mousePoint, itemBounds))
+ {
+ itemFocused = startIndex + i;
+ if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
+ {
+ if (itemSelected == (startIndex + i)) itemSelected = -1;
+ else itemSelected = startIndex + i;
+ }
+ break;
+ }
+
+ // Update item rectangle y position for next item
+ itemBounds.y += (GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT) + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING));
+ }
+
+ if (useScrollBar)
+ {
+ int wheelMove = (int)GetMouseWheelMove();
+ startIndex -= wheelMove;
+
+ if (startIndex < 0) startIndex = 0;
+ else if (startIndex > (count - visibleItems)) startIndex = count - visibleItems;
+
+ endIndex = startIndex + visibleItems;
+ if (endIndex > count) endIndex = count;
+ }
+ }
+ else itemFocused = -1;
+
+ // Reset item rectangle y to [0]
+ itemBounds.y = bounds.y + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING) + GuiGetStyle(DEFAULT, BORDER_WIDTH);
+ }
+ //--------------------------------------------------------------------
+
+ // Draw control
+ //--------------------------------------------------------------------
+ GuiDrawRectangle(bounds, GuiGetStyle(LISTVIEW, BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER + state*3)), GetColor(GuiGetStyle(DEFAULT, BACKGROUND_COLOR))); // Draw background
+
+ // Draw visible items
+ for (int i = 0; ((i < visibleItems) && (text != NULL)); i++)
+ {
+ GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, LIST_ITEMS_BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_NORMAL)), BLANK);
+
+ if (state == STATE_DISABLED)
+ {
+ if ((startIndex + i) == itemSelected) GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_DISABLED)), GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_DISABLED)));
+
+ GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_DISABLED)));
+ }
+ else
+ {
+ if (((startIndex + i) == itemSelected) && (active != NULL))
+ {
+ // Draw item selected
+ GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_PRESSED)), GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_PRESSED)));
+ GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_PRESSED)));
+ }
+ else if (((startIndex + i) == itemFocused)) // && (focus != NULL)) // NOTE: We want items focused, despite not returned!
+ {
+ // Draw item focused
+ GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_FOCUSED)), GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_FOCUSED)));
+ GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_FOCUSED)));
+ }
+ else
+ {
+ // Draw item normal
+ GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_NORMAL)));
+ }
+ }
+
+ // Update item rectangle y position for next item
+ itemBounds.y += (GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT) + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING));
+ }
+
+ if (useScrollBar)
+ {
+ Rectangle scrollBarBounds = {
+ bounds.x + bounds.width - GuiGetStyle(LISTVIEW, BORDER_WIDTH) - GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH),
+ bounds.y + GuiGetStyle(LISTVIEW, BORDER_WIDTH), (float)GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH),
+ bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH)
+ };
+
+ // Calculate percentage of visible items and apply same percentage to scrollbar
+ float percentVisible = (float)(endIndex - startIndex)/count;
+ float sliderSize = bounds.height*percentVisible;
+
+ int prevSliderSize = GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE); // Save default slider size
+ int prevScrollSpeed = GuiGetStyle(SCROLLBAR, SCROLL_SPEED); // Save default scroll speed
+ GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, (int)sliderSize); // Change slider size
+ GuiSetStyle(SCROLLBAR, SCROLL_SPEED, count - visibleItems); // Change scroll speed
+
+ startIndex = GuiScrollBar(scrollBarBounds, startIndex, 0, count - visibleItems);
+
+ GuiSetStyle(SCROLLBAR, SCROLL_SPEED, prevScrollSpeed); // Reset scroll speed to default
+ GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, prevSliderSize); // Reset slider size to default
+ }
+ //--------------------------------------------------------------------
+
+ if (active != NULL) *active = itemSelected;
+ if (focus != NULL) *focus = itemFocused;
+ if (scrollIndex != NULL) *scrollIndex = startIndex;
+
+ return result;
+}
+
+// Color Panel control - Color (RGBA) variant.
+int GuiColorPanel(Rectangle bounds, const char *text, Color *color)
+{
+ int result = 0;
+
+ Vector3 vcolor = { (float)color->r/255.0f, (float)color->g/255.0f, (float)color->b/255.0f };
+ Vector3 hsv = ConvertRGBtoHSV(vcolor);
+ Vector3 prevHsv = hsv; // workaround to see if GuiColorPanelHSV modifies the hsv.
+
+ GuiColorPanelHSV(bounds, text, &hsv);
+
+ // Check if the hsv was changed, only then change the color.
+ // This is required, because the Color->HSV->Color conversion has precision errors.
+ // Thus the assignment from HSV to Color should only be made, if the HSV has a new user-entered value.
+ // Otherwise GuiColorPanel would often modify it's color without user input.
+ // TODO: GuiColorPanelHSV could return 1 if the slider was dragged, to simplify this check.
+ if (hsv.x != prevHsv.x || hsv.y != prevHsv.y || hsv.z != prevHsv.z)
+ {
+ Vector3 rgb = ConvertHSVtoRGB(hsv);
+
+ // NOTE: Vector3ToColor() only available on raylib 1.8.1
+ *color = RAYGUI_CLITERAL(Color){ (unsigned char)(255.0f*rgb.x),
+ (unsigned char)(255.0f*rgb.y),
+ (unsigned char)(255.0f*rgb.z),
+ color->a };
+ }
+ return result;
+}
+
+// Color Bar Alpha control
+// NOTE: Returns alpha value normalized [0..1]
+int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha)
+{
+ #if !defined(RAYGUI_COLORBARALPHA_CHECKED_SIZE)
+ #define RAYGUI_COLORBARALPHA_CHECKED_SIZE 10
+ #endif
+
+ int result = 0;
+ GuiState state = guiState;
+ Rectangle selector = { (float)bounds.x + (*alpha)*bounds.width - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT)/2, (float)bounds.y - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW), (float)GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT), (float)bounds.height + GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW)*2 };
+
+ // Update control
+ //--------------------------------------------------------------------
+ if ((state != STATE_DISABLED) && !guiLocked)
+ {
+ Vector2 mousePoint = GetMousePosition();
+
+ if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds
+ {
+ if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
+ {
+ if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec))
+ {
+ state = STATE_PRESSED;
+
+ *alpha = (mousePoint.x - bounds.x)/bounds.width;
+ if (*alpha <= 0.0f) *alpha = 0.0f;
+ if (*alpha >= 1.0f) *alpha = 1.0f;
+ }
+ }
+ else
+ {
+ guiControlExclusiveMode = false;
+ guiControlExclusiveRec = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 };
+ }
+ }
+ else if (CheckCollisionPointRec(mousePoint, bounds) || CheckCollisionPointRec(mousePoint, selector))
+ {
+ if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
+ {
+ state = STATE_PRESSED;
+ guiControlExclusiveMode = true;
+ guiControlExclusiveRec = bounds; // Store bounds as an identifier when dragging starts
+
+ *alpha = (mousePoint.x - bounds.x)/bounds.width;
+ if (*alpha <= 0.0f) *alpha = 0.0f;
+ if (*alpha >= 1.0f) *alpha = 1.0f;
+ //selector.x = bounds.x + (int)(((alpha - 0)/(100 - 0))*(bounds.width - 2*GuiGetStyle(SLIDER, BORDER_WIDTH))) - selector.width/2;
+ }
+ else state = STATE_FOCUSED;
+ }
+ }
+ //--------------------------------------------------------------------
+
+ // Draw control
+ //--------------------------------------------------------------------
+
+ // Draw alpha bar: checked background
+ if (state != STATE_DISABLED)
+ {
+ int checksX = (int)bounds.width/RAYGUI_COLORBARALPHA_CHECKED_SIZE;
+ int checksY = (int)bounds.height/RAYGUI_COLORBARALPHA_CHECKED_SIZE;
+
+ for (int x = 0; x < checksX; x++)
+ {
+ for (int y = 0; y < checksY; y++)
+ {
+ Rectangle check = { bounds.x + x*RAYGUI_COLORBARALPHA_CHECKED_SIZE, bounds.y + y*RAYGUI_COLORBARALPHA_CHECKED_SIZE, RAYGUI_COLORBARALPHA_CHECKED_SIZE, RAYGUI_COLORBARALPHA_CHECKED_SIZE };
+ GuiDrawRectangle(check, 0, BLANK, ((x + y)%2)? Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), 0.4f) : Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.4f));
+ }
+ }
+
+ DrawRectangleGradientEx(bounds, RAYGUI_CLITERAL(Color){ 255, 255, 255, 0 }, RAYGUI_CLITERAL(Color){ 255, 255, 255, 0 }, Fade(RAYGUI_CLITERAL(Color){ 0, 0, 0, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 0, 0, 0, 255 }, guiAlpha));
+ }
+ else DrawRectangleGradientEx(bounds, Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.1f), Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.1f), Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), guiAlpha), Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), guiAlpha));
+
+ GuiDrawRectangle(bounds, GuiGetStyle(COLORPICKER, BORDER_WIDTH), GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)), BLANK);
+
+ // Draw alpha bar: selector
+ GuiDrawRectangle(selector, 0, BLANK, GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)));
+ //--------------------------------------------------------------------
+
+ return result;
+}
+
+// Color Bar Hue control
+// Returns hue value normalized [0..1]
+// NOTE: Other similar bars (for reference):
+// Color GuiColorBarSat() [WHITE->color]
+// Color GuiColorBarValue() [BLACK->color], HSV/HSL
+// float GuiColorBarLuminance() [BLACK->WHITE]
+int GuiColorBarHue(Rectangle bounds, const char *text, float *hue)
+{
+ int result = 0;
+ GuiState state = guiState;
+ Rectangle selector = { (float)bounds.x - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW), (float)bounds.y + (*hue)/360.0f*bounds.height - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT)/2, (float)bounds.width + GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW)*2, (float)GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT) };
+
+ // Update control
+ //--------------------------------------------------------------------
+ if ((state != STATE_DISABLED) && !guiLocked)
+ {
+ Vector2 mousePoint = GetMousePosition();
+
+ if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds
+ {
+ if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
+ {
+ if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec))
+ {
+ state = STATE_PRESSED;
+
+ *hue = (mousePoint.y - bounds.y)*360/bounds.height;
+ if (*hue <= 0.0f) *hue = 0.0f;
+ if (*hue >= 359.0f) *hue = 359.0f;
+ }
+ }
+ else
+ {
+ guiControlExclusiveMode = false;
+ guiControlExclusiveRec = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 };
+ }
+ }
+ else if (CheckCollisionPointRec(mousePoint, bounds) || CheckCollisionPointRec(mousePoint, selector))
+ {
+ if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
+ {
+ state = STATE_PRESSED;
+ guiControlExclusiveMode = true;
+ guiControlExclusiveRec = bounds; // Store bounds as an identifier when dragging starts
+
+ *hue = (mousePoint.y - bounds.y)*360/bounds.height;
+ if (*hue <= 0.0f) *hue = 0.0f;
+ if (*hue >= 359.0f) *hue = 359.0f;
+
+ }
+ else state = STATE_FOCUSED;
+
+ /*if (IsKeyDown(KEY_UP))
+ {
+ hue -= 2.0f;
+ if (hue <= 0.0f) hue = 0.0f;
+ }
+ else if (IsKeyDown(KEY_DOWN))
+ {
+ hue += 2.0f;
+ if (hue >= 360.0f) hue = 360.0f;
+ }*/
+ }
+ }
+ //--------------------------------------------------------------------
+
+ // Draw control
+ //--------------------------------------------------------------------
+ if (state != STATE_DISABLED)
+ {
+ // Draw hue bar:color bars
+ // TODO: Use directly DrawRectangleGradientEx(bounds, color1, color2, color2, color1);
+ DrawRectangleGradientV((int)bounds.x, (int)(bounds.y), (int)bounds.width, (int)ceilf(bounds.height/6), Fade(RAYGUI_CLITERAL(Color){ 255, 0, 0, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 255, 255, 0, 255 }, guiAlpha));
+ DrawRectangleGradientV((int)bounds.x, (int)(bounds.y + bounds.height/6), (int)bounds.width, (int)ceilf(bounds.height/6), Fade(RAYGUI_CLITERAL(Color){ 255, 255, 0, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 0, 255, 0, 255 }, guiAlpha));
+ DrawRectangleGradientV((int)bounds.x, (int)(bounds.y + 2*(bounds.height/6)), (int)bounds.width, (int)ceilf(bounds.height/6), Fade(RAYGUI_CLITERAL(Color){ 0, 255, 0, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 0, 255, 255, 255 }, guiAlpha));
+ DrawRectangleGradientV((int)bounds.x, (int)(bounds.y + 3*(bounds.height/6)), (int)bounds.width, (int)ceilf(bounds.height/6), Fade(RAYGUI_CLITERAL(Color){ 0, 255, 255, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 0, 0, 255, 255 }, guiAlpha));
+ DrawRectangleGradientV((int)bounds.x, (int)(bounds.y + 4*(bounds.height/6)), (int)bounds.width, (int)ceilf(bounds.height/6), Fade(RAYGUI_CLITERAL(Color){ 0, 0, 255, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 255, 0, 255, 255 }, guiAlpha));
+ DrawRectangleGradientV((int)bounds.x, (int)(bounds.y + 5*(bounds.height/6)), (int)bounds.width, (int)(bounds.height/6), Fade(RAYGUI_CLITERAL(Color){ 255, 0, 255, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 255, 0, 0, 255 }, guiAlpha));
+ }
+ else DrawRectangleGradientV((int)bounds.x, (int)bounds.y, (int)bounds.width, (int)bounds.height, Fade(Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.1f), guiAlpha), Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), guiAlpha));
+
+ GuiDrawRectangle(bounds, GuiGetStyle(COLORPICKER, BORDER_WIDTH), GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)), BLANK);
+
+ // Draw hue bar: selector
+ GuiDrawRectangle(selector, 0, BLANK, GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)));
+ //--------------------------------------------------------------------
+
+ return result;
+}
+
+// Color Picker control
+// NOTE: It's divided in multiple controls:
+// Color GuiColorPanel(Rectangle bounds, Color color)
+// float GuiColorBarAlpha(Rectangle bounds, float alpha)
+// float GuiColorBarHue(Rectangle bounds, float value)
+// NOTE: bounds define GuiColorPanel() size
+// NOTE: this picker converts RGB to HSV, which can cause the Hue control to jump. If you have this problem, consider using the HSV variant instead
+int GuiColorPicker(Rectangle bounds, const char *text, Color *color)
+{
+ int result = 0;
+
+ Color temp = { 200, 0, 0, 255 };
+ if (color == NULL) color = &temp;
+
+ GuiColorPanel(bounds, NULL, color);
+
+ Rectangle boundsHue = { (float)bounds.x + bounds.width + GuiGetStyle(COLORPICKER, HUEBAR_PADDING), (float)bounds.y, (float)GuiGetStyle(COLORPICKER, HUEBAR_WIDTH), (float)bounds.height };
+ //Rectangle boundsAlpha = { bounds.x, bounds.y + bounds.height + GuiGetStyle(COLORPICKER, BARS_PADDING), bounds.width, GuiGetStyle(COLORPICKER, BARS_THICK) };
+
+ // NOTE: this conversion can cause low hue-resolution, if the r, g and b value are very similar, which causes the hue bar to shift around when only the GuiColorPanel is used.
+ Vector3 hsv = ConvertRGBtoHSV(RAYGUI_CLITERAL(Vector3){ (*color).r/255.0f, (*color).g/255.0f, (*color).b/255.0f });
+
+ GuiColorBarHue(boundsHue, NULL, &hsv.x);
+
+ //color.a = (unsigned char)(GuiColorBarAlpha(boundsAlpha, (float)color.a/255.0f)*255.0f);
+ Vector3 rgb = ConvertHSVtoRGB(hsv);
+
+ *color = RAYGUI_CLITERAL(Color){ (unsigned char)roundf(rgb.x*255.0f), (unsigned char)roundf(rgb.y*255.0f), (unsigned char)roundf(rgb.z*255.0f), (*color).a };
+
+ return result;
+}
+
+// Color Picker control that avoids conversion to RGB and back to HSV on each call, thus avoiding jittering.
+// The user can call ConvertHSVtoRGB() to convert *colorHsv value to RGB.
+// NOTE: It's divided in multiple controls:
+// int GuiColorPanelHSV(Rectangle bounds, const char *text, Vector3 *colorHsv)
+// int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha)
+// float GuiColorBarHue(Rectangle bounds, float value)
+// NOTE: bounds define GuiColorPanelHSV() size
+int GuiColorPickerHSV(Rectangle bounds, const char *text, Vector3 *colorHsv)
+{
+ int result = 0;
+
+ Vector3 tempHsv = { 0 };
+
+ if (colorHsv == NULL)
+ {
+ const Vector3 tempColor = { 200.0f/255.0f, 0.0f, 0.0f };
+ tempHsv = ConvertRGBtoHSV(tempColor);
+ colorHsv = &tempHsv;
+ }
+
+ GuiColorPanelHSV(bounds, NULL, colorHsv);
+
+ const Rectangle boundsHue = { (float)bounds.x + bounds.width + GuiGetStyle(COLORPICKER, HUEBAR_PADDING), (float)bounds.y, (float)GuiGetStyle(COLORPICKER, HUEBAR_WIDTH), (float)bounds.height };
+
+ GuiColorBarHue(boundsHue, NULL, &colorHsv->x);
+
+ return result;
+}
+
+// Color Panel control - HSV variant
+int GuiColorPanelHSV(Rectangle bounds, const char *text, Vector3 *colorHsv)
+{
+ int result = 0;
+ GuiState state = guiState;
+ Vector2 pickerSelector = { 0 };
+
+ const Color colWhite = { 255, 255, 255, 255 };
+ const Color colBlack = { 0, 0, 0, 255 };
+
+ pickerSelector.x = bounds.x + (float)colorHsv->y*bounds.width; // HSV: Saturation
+ pickerSelector.y = bounds.y + (1.0f - (float)colorHsv->z)*bounds.height; // HSV: Value
+
+ Vector3 maxHue = { colorHsv->x, 1.0f, 1.0f };
+ Vector3 rgbHue = ConvertHSVtoRGB(maxHue);
+ Color maxHueCol = { (unsigned char)(255.0f*rgbHue.x),
+ (unsigned char)(255.0f*rgbHue.y),
+ (unsigned char)(255.0f*rgbHue.z), 255 };
+
+ // Update control
+ //--------------------------------------------------------------------
+ if ((state != STATE_DISABLED) && !guiLocked)
+ {
+ Vector2 mousePoint = GetMousePosition();
+
+ if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds
+ {
+ if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
+ {
+ if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec))
+ {
+ pickerSelector = mousePoint;
+
+ if (pickerSelector.x < bounds.x) pickerSelector.x = bounds.x;
+ if (pickerSelector.x > bounds.x + bounds.width) pickerSelector.x = bounds.x + bounds.width;
+ if (pickerSelector.y < bounds.y) pickerSelector.y = bounds.y;
+ if (pickerSelector.y > bounds.y + bounds.height) pickerSelector.y = bounds.y + bounds.height;
+
+ // Calculate color from picker
+ Vector2 colorPick = { pickerSelector.x - bounds.x, pickerSelector.y - bounds.y };
+
+ colorPick.x /= (float)bounds.width; // Get normalized value on x
+ colorPick.y /= (float)bounds.height; // Get normalized value on y
+
+ colorHsv->y = colorPick.x;
+ colorHsv->z = 1.0f - colorPick.y;
+
+ }
+ }
+ else
+ {
+ guiControlExclusiveMode = false;
+ guiControlExclusiveRec = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 };
+ }
+ }
+ else if (CheckCollisionPointRec(mousePoint, bounds))
+ {
+ if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
+ {
+ state = STATE_PRESSED;
+ guiControlExclusiveMode = true;
+ guiControlExclusiveRec = bounds;
+ pickerSelector = mousePoint;
+
+ // Calculate color from picker
+ Vector2 colorPick = { pickerSelector.x - bounds.x, pickerSelector.y - bounds.y };
+
+ colorPick.x /= (float)bounds.width; // Get normalized value on x
+ colorPick.y /= (float)bounds.height; // Get normalized value on y
+
+ colorHsv->y = colorPick.x;
+ colorHsv->z = 1.0f - colorPick.y;
+ }
+ else state = STATE_FOCUSED;
+ }
+ }
+ //--------------------------------------------------------------------
+
+ // Draw control
+ //--------------------------------------------------------------------
+ if (state != STATE_DISABLED)
+ {
+ DrawRectangleGradientEx(bounds, Fade(colWhite, guiAlpha), Fade(colWhite, guiAlpha), Fade(maxHueCol, guiAlpha), Fade(maxHueCol, guiAlpha));
+ DrawRectangleGradientEx(bounds, Fade(colBlack, 0), Fade(colBlack, guiAlpha), Fade(colBlack, guiAlpha), Fade(colBlack, 0));
+
+ // Draw color picker: selector
+ Rectangle selector = { pickerSelector.x - GuiGetStyle(COLORPICKER, COLOR_SELECTOR_SIZE)/2, pickerSelector.y - GuiGetStyle(COLORPICKER, COLOR_SELECTOR_SIZE)/2, (float)GuiGetStyle(COLORPICKER, COLOR_SELECTOR_SIZE), (float)GuiGetStyle(COLORPICKER, COLOR_SELECTOR_SIZE) };
+ GuiDrawRectangle(selector, 0, BLANK, colWhite);
+ }
+ else
+ {
+ DrawRectangleGradientEx(bounds, Fade(Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.1f), guiAlpha), Fade(Fade(colBlack, 0.6f), guiAlpha), Fade(Fade(colBlack, 0.6f), guiAlpha), Fade(Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), 0.6f), guiAlpha));
+ }
+
+ GuiDrawRectangle(bounds, GuiGetStyle(COLORPICKER, BORDER_WIDTH), GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)), BLANK);
+ //--------------------------------------------------------------------
+
+ return result;
+}
+
+// Message Box control
+int GuiMessageBox(Rectangle bounds, const char *title, const char *message, const char *buttons)
+{
+ #if !defined(RAYGUI_MESSAGEBOX_BUTTON_HEIGHT)
+ #define RAYGUI_MESSAGEBOX_BUTTON_HEIGHT 24
+ #endif
+ #if !defined(RAYGUI_MESSAGEBOX_BUTTON_PADDING)
+ #define RAYGUI_MESSAGEBOX_BUTTON_PADDING 12
+ #endif
+
+ int result = -1; // Returns clicked button from buttons list, 0 refers to closed window button
+
+ int buttonCount = 0;
+ const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL);
+ Rectangle buttonBounds = { 0 };
+ buttonBounds.x = bounds.x + RAYGUI_MESSAGEBOX_BUTTON_PADDING;
+ buttonBounds.y = bounds.y + bounds.height - RAYGUI_MESSAGEBOX_BUTTON_HEIGHT - RAYGUI_MESSAGEBOX_BUTTON_PADDING;
+ buttonBounds.width = (bounds.width - RAYGUI_MESSAGEBOX_BUTTON_PADDING*(buttonCount + 1))/buttonCount;
+ buttonBounds.height = RAYGUI_MESSAGEBOX_BUTTON_HEIGHT;
+
+ //int textWidth = GetTextWidth(message) + 2;
+
+ Rectangle textBounds = { 0 };
+ textBounds.x = bounds.x + RAYGUI_MESSAGEBOX_BUTTON_PADDING;
+ textBounds.y = bounds.y + RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT + RAYGUI_MESSAGEBOX_BUTTON_PADDING;
+ textBounds.width = bounds.width - RAYGUI_MESSAGEBOX_BUTTON_PADDING*2;
+ textBounds.height = bounds.height - RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - 3*RAYGUI_MESSAGEBOX_BUTTON_PADDING - RAYGUI_MESSAGEBOX_BUTTON_HEIGHT;
+
+ // Draw control
+ //--------------------------------------------------------------------
+ if (GuiWindowBox(bounds, title)) result = 0;
+
+ int prevTextAlignment = GuiGetStyle(LABEL, TEXT_ALIGNMENT);
+ GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER);
+ GuiLabel(textBounds, message);
+ GuiSetStyle(LABEL, TEXT_ALIGNMENT, prevTextAlignment);
+
+ prevTextAlignment = GuiGetStyle(BUTTON, TEXT_ALIGNMENT);
+ GuiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER);
+
+ for (int i = 0; i < buttonCount; i++)
+ {
+ if (GuiButton(buttonBounds, buttonsText[i])) result = i + 1;
+ buttonBounds.x += (buttonBounds.width + RAYGUI_MESSAGEBOX_BUTTON_PADDING);
+ }
+
+ GuiSetStyle(BUTTON, TEXT_ALIGNMENT, prevTextAlignment);
+ //--------------------------------------------------------------------
+
+ return result;
+}
+
+// Text Input Box control, ask for text
+int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, const char *buttons, char *text, int textMaxSize, bool *secretViewActive)
+{
+ #if !defined(RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT)
+ #define RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT 24
+ #endif
+ #if !defined(RAYGUI_TEXTINPUTBOX_BUTTON_PADDING)
+ #define RAYGUI_TEXTINPUTBOX_BUTTON_PADDING 12
+ #endif
+ #if !defined(RAYGUI_TEXTINPUTBOX_HEIGHT)
+ #define RAYGUI_TEXTINPUTBOX_HEIGHT 26
+ #endif
+
+ // Used to enable text edit mode
+ // WARNING: No more than one GuiTextInputBox() should be open at the same time
+ static bool textEditMode = false;
+
+ int result = -1;
+
+ int buttonCount = 0;
+ const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL);
+ Rectangle buttonBounds = { 0 };
+ buttonBounds.x = bounds.x + RAYGUI_TEXTINPUTBOX_BUTTON_PADDING;
+ buttonBounds.y = bounds.y + bounds.height - RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT - RAYGUI_TEXTINPUTBOX_BUTTON_PADDING;
+ buttonBounds.width = (bounds.width - RAYGUI_TEXTINPUTBOX_BUTTON_PADDING*(buttonCount + 1))/buttonCount;
+ buttonBounds.height = RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT;
+
+ int messageInputHeight = (int)bounds.height - RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - GuiGetStyle(STATUSBAR, BORDER_WIDTH) - RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT - 2*RAYGUI_TEXTINPUTBOX_BUTTON_PADDING;
+
+ Rectangle textBounds = { 0 };
+ if (message != NULL)
+ {
+ int textSize = GetTextWidth(message) + 2;
+
+ textBounds.x = bounds.x + bounds.width/2 - textSize/2;
+ textBounds.y = bounds.y + RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT + messageInputHeight/4 - (float)GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
+ textBounds.width = (float)textSize;
+ textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
+ }
+
+ Rectangle textBoxBounds = { 0 };
+ textBoxBounds.x = bounds.x + RAYGUI_TEXTINPUTBOX_BUTTON_PADDING;
+ textBoxBounds.y = bounds.y + RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - RAYGUI_TEXTINPUTBOX_HEIGHT/2;
+ if (message == NULL) textBoxBounds.y = bounds.y + 24 + RAYGUI_TEXTINPUTBOX_BUTTON_PADDING;
+ else textBoxBounds.y += (messageInputHeight/2 + messageInputHeight/4);
+ textBoxBounds.width = bounds.width - RAYGUI_TEXTINPUTBOX_BUTTON_PADDING*2;
+ textBoxBounds.height = RAYGUI_TEXTINPUTBOX_HEIGHT;
+
+ // Draw control
+ //--------------------------------------------------------------------
+ if (GuiWindowBox(bounds, title)) result = 0;
+
+ // Draw message if available
+ if (message != NULL)
+ {
+ int prevTextAlignment = GuiGetStyle(LABEL, TEXT_ALIGNMENT);
+ GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER);
+ GuiLabel(textBounds, message);
+ GuiSetStyle(LABEL, TEXT_ALIGNMENT, prevTextAlignment);
+ }
+
+ if (secretViewActive != NULL)
+ {
+ static char stars[] = "****************";
+ if (GuiTextBox(RAYGUI_CLITERAL(Rectangle){ textBoxBounds.x, textBoxBounds.y, textBoxBounds.width - 4 - RAYGUI_TEXTINPUTBOX_HEIGHT, textBoxBounds.height },
+ ((*secretViewActive == 1) || textEditMode)? text : stars, textMaxSize, textEditMode)) textEditMode = !textEditMode;
+
+ GuiToggle(RAYGUI_CLITERAL(Rectangle){ textBoxBounds.x + textBoxBounds.width - RAYGUI_TEXTINPUTBOX_HEIGHT, textBoxBounds.y, RAYGUI_TEXTINPUTBOX_HEIGHT, RAYGUI_TEXTINPUTBOX_HEIGHT }, (*secretViewActive == 1)? "#44#" : "#45#", secretViewActive);
+ }
+ else
+ {
+ if (GuiTextBox(textBoxBounds, text, textMaxSize, textEditMode)) textEditMode = !textEditMode;
+ }
+
+ int prevBtnTextAlignment = GuiGetStyle(BUTTON, TEXT_ALIGNMENT);
+ GuiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER);
+
+ for (int i = 0; i < buttonCount; i++)
+ {
+ if (GuiButton(buttonBounds, buttonsText[i])) result = i + 1;
+ buttonBounds.x += (buttonBounds.width + RAYGUI_MESSAGEBOX_BUTTON_PADDING);
+ }
+
+ if (result >= 0) textEditMode = false;
+
+ GuiSetStyle(BUTTON, TEXT_ALIGNMENT, prevBtnTextAlignment);
+ //--------------------------------------------------------------------
+
+ return result; // Result is the pressed button index
+}
+
+// Grid control
+// NOTE: Returns grid mouse-hover selected cell
+// About drawing lines at subpixel spacing, simple put, not easy solution:
+// https://stackoverflow.com/questions/4435450/2d-opengl-drawing-lines-that-dont-exactly-fit-pixel-raster
+int GuiGrid(Rectangle bounds, const char *text, float spacing, int subdivs, Vector2 *mouseCell)
+{
+ // Grid lines alpha amount
+ #if !defined(RAYGUI_GRID_ALPHA)
+ #define RAYGUI_GRID_ALPHA 0.15f
+ #endif
+
+ int result = 0;
+ GuiState state = guiState;
+
+ Vector2 mousePoint = GetMousePosition();
+ Vector2 currentMouseCell = { -1, -1 };
+
+ float spaceWidth = spacing/(float)subdivs;
+ int linesV = (int)(bounds.width/spaceWidth) + 1;
+ int linesH = (int)(bounds.height/spaceWidth) + 1;
+
+ int color = GuiGetStyle(DEFAULT, LINE_COLOR);
+
+ // Update control
+ //--------------------------------------------------------------------
+ if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode)
+ {
+ if (CheckCollisionPointRec(mousePoint, bounds))
+ {
+ // NOTE: Cell values must be the upper left of the cell the mouse is in
+ currentMouseCell.x = floorf((mousePoint.x - bounds.x)/spacing);
+ currentMouseCell.y = floorf((mousePoint.y - bounds.y)/spacing);
+ }
+ }
+ //--------------------------------------------------------------------
+
+ // Draw control
+ //--------------------------------------------------------------------
+ if (state == STATE_DISABLED) color = GuiGetStyle(DEFAULT, BORDER_COLOR_DISABLED);
+
+ if (subdivs > 0)
+ {
+ // Draw vertical grid lines
+ for (int i = 0; i < linesV; i++)
+ {
+ Rectangle lineV = { bounds.x + spacing*i/subdivs, bounds.y, 1, bounds.height + 1 };
+ GuiDrawRectangle(lineV, 0, BLANK, ((i%subdivs) == 0)? GuiFade(GetColor(color), RAYGUI_GRID_ALPHA*4) : GuiFade(GetColor(color), RAYGUI_GRID_ALPHA));
+ }
+
+ // Draw horizontal grid lines
+ for (int i = 0; i < linesH; i++)
+ {
+ Rectangle lineH = { bounds.x, bounds.y + spacing*i/subdivs, bounds.width + 1, 1 };
+ GuiDrawRectangle(lineH, 0, BLANK, ((i%subdivs) == 0)? GuiFade(GetColor(color), RAYGUI_GRID_ALPHA*4) : GuiFade(GetColor(color), RAYGUI_GRID_ALPHA));
+ }
+ }
+
+ if (mouseCell != NULL) *mouseCell = currentMouseCell;
+ return result;
+}
+
+//----------------------------------------------------------------------------------
+// Tooltip management functions
+// NOTE: Tooltips requires some global variables: tooltipPtr
+//----------------------------------------------------------------------------------
+// Enable gui tooltips (global state)
+void GuiEnableTooltip(void) { guiTooltip = true; }
+
+// Disable gui tooltips (global state)
+void GuiDisableTooltip(void) { guiTooltip = false; }
+
+// Set tooltip string
+void GuiSetTooltip(const char *tooltip) { guiTooltipPtr = tooltip; }
+
+//----------------------------------------------------------------------------------
+// Styles loading functions
+//----------------------------------------------------------------------------------
+
+// Load raygui style file (.rgs)
+// NOTE: By default a binary file is expected, that file could contain a custom font,
+// in that case, custom font image atlas is GRAY+ALPHA and pixel data can be compressed (DEFLATE)
+void GuiLoadStyle(const char *fileName)
+{
+ #define MAX_LINE_BUFFER_SIZE 256
+
+ bool tryBinary = false;
+ if (!guiStyleLoaded) GuiLoadStyleDefault();
+
+ // Try reading the files as text file first
+ FILE *rgsFile = fopen(fileName, "rt");
+
+ if (rgsFile != NULL)
+ {
+ char buffer[MAX_LINE_BUFFER_SIZE] = { 0 };
+ fgets(buffer, MAX_LINE_BUFFER_SIZE, rgsFile);
+
+ if (buffer[0] == '#')
+ {
+ int controlId = 0;
+ int propertyId = 0;
+ unsigned int propertyValue = 0;
+
+ while (!feof(rgsFile))
+ {
+ switch (buffer[0])
+ {
+ case 'p':
+ {
+ // Style property: p
+
+ sscanf(buffer, "p %d %d 0x%x", &controlId, &propertyId, &propertyValue);
+ GuiSetStyle(controlId, propertyId, (int)propertyValue);
+
+ } break;
+ case 'f':
+ {
+ // Style font: f
+
+ int fontSize = 0;
+ char charmapFileName[256] = { 0 };
+ char fontFileName[256] = { 0 };
+ sscanf(buffer, "f %d %s %[^\r\n]s", &fontSize, charmapFileName, fontFileName);
+
+ Font font = { 0 };
+ int *codepoints = NULL;
+ int codepointCount = 0;
+
+ if (charmapFileName[0] != '0')
+ {
+ // Load text data from file
+ // NOTE: Expected an UTF-8 array of codepoints, no separation
+ char *textData = LoadFileText(TextFormat("%s/%s", GetDirectoryPath(fileName), charmapFileName));
+ codepoints = LoadCodepoints(textData, &codepointCount);
+ UnloadFileText(textData);
+ }
+
+ if (fontFileName[0] != '\0')
+ {
+ // In case a font is already loaded and it is not default internal font, unload it
+ if (font.texture.id != GetFontDefault().texture.id) UnloadTexture(font.texture);
+
+ if (codepointCount > 0) font = LoadFontEx(TextFormat("%s/%s", GetDirectoryPath(fileName), fontFileName), fontSize, codepoints, codepointCount);
+ else font = LoadFontEx(TextFormat("%s/%s", GetDirectoryPath(fileName), fontFileName), fontSize, NULL, 0); // Default to 95 standard codepoints
+ }
+
+ // If font texture not properly loaded, revert to default font and size/spacing
+ if (font.texture.id == 0)
+ {
+ font = GetFontDefault();
+ GuiSetStyle(DEFAULT, TEXT_SIZE, 10);
+ GuiSetStyle(DEFAULT, TEXT_SPACING, 1);
+ }
+
+ UnloadCodepoints(codepoints);
+
+ if ((font.texture.id > 0) && (font.glyphCount > 0)) GuiSetFont(font);
+
+ } break;
+ default: break;
+ }
+
+ fgets(buffer, MAX_LINE_BUFFER_SIZE, rgsFile);
+ }
+ }
+ else tryBinary = true;
+
+ fclose(rgsFile);
+ }
+
+ if (tryBinary)
+ {
+ rgsFile = fopen(fileName, "rb");
+
+ if (rgsFile != NULL)
+ {
+ fseek(rgsFile, 0, SEEK_END);
+ int fileDataSize = ftell(rgsFile);
+ fseek(rgsFile, 0, SEEK_SET);
+
+ if (fileDataSize > 0)
+ {
+ unsigned char *fileData = (unsigned char *)RAYGUI_MALLOC(fileDataSize*sizeof(unsigned char));
+ fread(fileData, sizeof(unsigned char), fileDataSize, rgsFile);
+
+ GuiLoadStyleFromMemory(fileData, fileDataSize);
+
+ RAYGUI_FREE(fileData);
+ }
+
+ fclose(rgsFile);
+ }
+ }
+}
+
+// Load style default over global style
+void GuiLoadStyleDefault(void)
+{
+ // We set this variable first to avoid cyclic function calls
+ // when calling GuiSetStyle() and GuiGetStyle()
+ guiStyleLoaded = true;
+
+ // Initialize default LIGHT style property values
+ // WARNING: Default value are applied to all controls on set but
+ // they can be overwritten later on for every custom control
+ GuiSetStyle(DEFAULT, BORDER_COLOR_NORMAL, 0x838383ff);
+ GuiSetStyle(DEFAULT, BASE_COLOR_NORMAL, 0xc9c9c9ff);
+ GuiSetStyle(DEFAULT, TEXT_COLOR_NORMAL, 0x686868ff);
+ GuiSetStyle(DEFAULT, BORDER_COLOR_FOCUSED, 0x5bb2d9ff);
+ GuiSetStyle(DEFAULT, BASE_COLOR_FOCUSED, 0xc9effeff);
+ GuiSetStyle(DEFAULT, TEXT_COLOR_FOCUSED, 0x6c9bbcff);
+ GuiSetStyle(DEFAULT, BORDER_COLOR_PRESSED, 0x0492c7ff);
+ GuiSetStyle(DEFAULT, BASE_COLOR_PRESSED, 0x97e8ffff);
+ GuiSetStyle(DEFAULT, TEXT_COLOR_PRESSED, 0x368bafff);
+ GuiSetStyle(DEFAULT, BORDER_COLOR_DISABLED, 0xb5c1c2ff);
+ GuiSetStyle(DEFAULT, BASE_COLOR_DISABLED, 0xe6e9e9ff);
+ GuiSetStyle(DEFAULT, TEXT_COLOR_DISABLED, 0xaeb7b8ff);
+ GuiSetStyle(DEFAULT, BORDER_WIDTH, 1);
+ GuiSetStyle(DEFAULT, TEXT_PADDING, 0);
+ GuiSetStyle(DEFAULT, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER);
+
+ // Initialize default extended property values
+ // NOTE: By default, extended property values are initialized to 0
+ GuiSetStyle(DEFAULT, TEXT_SIZE, 10); // DEFAULT, shared by all controls
+ GuiSetStyle(DEFAULT, TEXT_SPACING, 1); // DEFAULT, shared by all controls
+ GuiSetStyle(DEFAULT, LINE_COLOR, 0x90abb5ff); // DEFAULT specific property
+ GuiSetStyle(DEFAULT, BACKGROUND_COLOR, 0xf5f5f5ff); // DEFAULT specific property
+ GuiSetStyle(DEFAULT, TEXT_LINE_SPACING, 15); // DEFAULT, 15 pixels between lines
+ GuiSetStyle(DEFAULT, TEXT_ALIGNMENT_VERTICAL, TEXT_ALIGN_MIDDLE); // DEFAULT, text aligned vertically to middle of text-bounds
+
+ // Initialize control-specific property values
+ // NOTE: Those properties are in default list but require specific values by control type
+ GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
+ GuiSetStyle(BUTTON, BORDER_WIDTH, 2);
+ GuiSetStyle(SLIDER, TEXT_PADDING, 4);
+ GuiSetStyle(PROGRESSBAR, TEXT_PADDING, 4);
+ GuiSetStyle(CHECKBOX, TEXT_PADDING, 4);
+ GuiSetStyle(CHECKBOX, TEXT_ALIGNMENT, TEXT_ALIGN_RIGHT);
+ GuiSetStyle(DROPDOWNBOX, TEXT_PADDING, 0);
+ GuiSetStyle(DROPDOWNBOX, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER);
+ GuiSetStyle(TEXTBOX, TEXT_PADDING, 4);
+ GuiSetStyle(TEXTBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
+ GuiSetStyle(VALUEBOX, TEXT_PADDING, 0);
+ GuiSetStyle(VALUEBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
+ GuiSetStyle(SPINNER, TEXT_PADDING, 0);
+ GuiSetStyle(SPINNER, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
+ GuiSetStyle(STATUSBAR, TEXT_PADDING, 8);
+ GuiSetStyle(STATUSBAR, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
+
+ // Initialize extended property values
+ // NOTE: By default, extended property values are initialized to 0
+ GuiSetStyle(TOGGLE, GROUP_PADDING, 2);
+ GuiSetStyle(SLIDER, SLIDER_WIDTH, 16);
+ GuiSetStyle(SLIDER, SLIDER_PADDING, 1);
+ GuiSetStyle(PROGRESSBAR, PROGRESS_PADDING, 1);
+ GuiSetStyle(CHECKBOX, CHECK_PADDING, 1);
+ GuiSetStyle(COMBOBOX, COMBO_BUTTON_WIDTH, 32);
+ GuiSetStyle(COMBOBOX, COMBO_BUTTON_SPACING, 2);
+ GuiSetStyle(DROPDOWNBOX, ARROW_PADDING, 16);
+ GuiSetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING, 2);
+ GuiSetStyle(SPINNER, SPIN_BUTTON_WIDTH, 24);
+ GuiSetStyle(SPINNER, SPIN_BUTTON_SPACING, 2);
+ GuiSetStyle(SCROLLBAR, BORDER_WIDTH, 0);
+ GuiSetStyle(SCROLLBAR, ARROWS_VISIBLE, 0);
+ GuiSetStyle(SCROLLBAR, ARROWS_SIZE, 6);
+ GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING, 0);
+ GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, 16);
+ GuiSetStyle(SCROLLBAR, SCROLL_PADDING, 0);
+ GuiSetStyle(SCROLLBAR, SCROLL_SPEED, 12);
+ GuiSetStyle(LISTVIEW, LIST_ITEMS_HEIGHT, 28);
+ GuiSetStyle(LISTVIEW, LIST_ITEMS_SPACING, 2);
+ GuiSetStyle(LISTVIEW, SCROLLBAR_WIDTH, 12);
+ GuiSetStyle(LISTVIEW, SCROLLBAR_SIDE, SCROLLBAR_RIGHT_SIDE);
+ GuiSetStyle(COLORPICKER, COLOR_SELECTOR_SIZE, 8);
+ GuiSetStyle(COLORPICKER, HUEBAR_WIDTH, 16);
+ GuiSetStyle(COLORPICKER, HUEBAR_PADDING, 8);
+ GuiSetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT, 8);
+ GuiSetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW, 2);
+
+ if (guiFont.texture.id != GetFontDefault().texture.id)
+ {
+ // Unload previous font texture
+ UnloadTexture(guiFont.texture);
+ RL_FREE(guiFont.recs);
+ RL_FREE(guiFont.glyphs);
+ guiFont.recs = NULL;
+ guiFont.glyphs = NULL;
+
+ // Setup default raylib font
+ guiFont = GetFontDefault();
+
+ // NOTE: Default raylib font character 95 is a white square
+ Rectangle whiteChar = guiFont.recs[95];
+
+ // NOTE: We set up a 1px padding on char rectangle to avoid pixel bleeding on MSAA filtering
+ SetShapesTexture(guiFont.texture, RAYGUI_CLITERAL(Rectangle){ whiteChar.x + 1, whiteChar.y + 1, whiteChar.width - 2, whiteChar.height - 2 });
+ }
+}
+
+// Get text with icon id prepended
+// NOTE: Useful to add icons by name id (enum) instead of
+// a number that can change between ricon versions
+const char *GuiIconText(int iconId, const char *text)
+{
+#if defined(RAYGUI_NO_ICONS)
+ return NULL;
+#else
+ static char buffer[1024] = { 0 };
+ static char iconBuffer[16] = { 0 };
+
+ if (text != NULL)
+ {
+ memset(buffer, 0, 1024);
+ sprintf(buffer, "#%03i#", iconId);
+
+ for (int i = 5; i < 1024; i++)
+ {
+ buffer[i] = text[i - 5];
+ if (text[i - 5] == '\0') break;
+ }
+
+ return buffer;
+ }
+ else
+ {
+ sprintf(iconBuffer, "#%03i#", iconId);
+
+ return iconBuffer;
+ }
+#endif
+}
+
+#if !defined(RAYGUI_NO_ICONS)
+// Get full icons data pointer
+unsigned int *GuiGetIcons(void) { return guiIconsPtr; }
+
+// Load raygui icons file (.rgi)
+// NOTE: In case nameIds are required, they can be requested with loadIconsName,
+// they are returned as a guiIconsName[iconCount][RAYGUI_ICON_MAX_NAME_LENGTH],
+// WARNING: guiIconsName[]][] memory should be manually freed!
+char **GuiLoadIcons(const char *fileName, bool loadIconsName)
+{
+ // Style File Structure (.rgi)
+ // ------------------------------------------------------
+ // Offset | Size | Type | Description
+ // ------------------------------------------------------
+ // 0 | 4 | char | Signature: "rGI "
+ // 4 | 2 | short | Version: 100
+ // 6 | 2 | short | reserved
+
+ // 8 | 2 | short | Num icons (N)
+ // 10 | 2 | short | Icons size (Options: 16, 32, 64) (S)
+
+ // Icons name id (32 bytes per name id)
+ // foreach (icon)
+ // {
+ // 12+32*i | 32 | char | Icon NameId
+ // }
+
+ // Icons data: One bit per pixel, stored as unsigned int array (depends on icon size)
+ // S*S pixels/32bit per unsigned int = K unsigned int per icon
+ // foreach (icon)
+ // {
+ // ... | K | unsigned int | Icon Data
+ // }
+
+ FILE *rgiFile = fopen(fileName, "rb");
+
+ char **guiIconsName = NULL;
+
+ if (rgiFile != NULL)
+ {
+ char signature[5] = { 0 };
+ short version = 0;
+ short reserved = 0;
+ short iconCount = 0;
+ short iconSize = 0;
+
+ fread(signature, 1, 4, rgiFile);
+ fread(&version, sizeof(short), 1, rgiFile);
+ fread(&reserved, sizeof(short), 1, rgiFile);
+ fread(&iconCount, sizeof(short), 1, rgiFile);
+ fread(&iconSize, sizeof(short), 1, rgiFile);
+
+ if ((signature[0] == 'r') &&
+ (signature[1] == 'G') &&
+ (signature[2] == 'I') &&
+ (signature[3] == ' '))
+ {
+ if (loadIconsName)
+ {
+ guiIconsName = (char **)RAYGUI_MALLOC(iconCount*sizeof(char **));
+ for (int i = 0; i < iconCount; i++)
+ {
+ guiIconsName[i] = (char *)RAYGUI_MALLOC(RAYGUI_ICON_MAX_NAME_LENGTH);
+ fread(guiIconsName[i], 1, RAYGUI_ICON_MAX_NAME_LENGTH, rgiFile);
+ }
+ }
+ else fseek(rgiFile, iconCount*RAYGUI_ICON_MAX_NAME_LENGTH, SEEK_CUR);
+
+ // Read icons data directly over internal icons array
+ fread(guiIconsPtr, sizeof(unsigned int), iconCount*(iconSize*iconSize/32), rgiFile);
+ }
+
+ fclose(rgiFile);
+ }
+
+ return guiIconsName;
+}
+
+// Draw selected icon using rectangles pixel-by-pixel
+void GuiDrawIcon(int iconId, int posX, int posY, int pixelSize, Color color)
+{
+ #define BIT_CHECK(a,b) ((a) & (1u<<(b)))
+
+ for (int i = 0, y = 0; i < RAYGUI_ICON_SIZE*RAYGUI_ICON_SIZE/32; i++)
+ {
+ for (int k = 0; k < 32; k++)
+ {
+ if (BIT_CHECK(guiIconsPtr[iconId*RAYGUI_ICON_DATA_ELEMENTS + i], k))
+ {
+ #if !defined(RAYGUI_STANDALONE)
+ GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ (float)posX + (k%RAYGUI_ICON_SIZE)*pixelSize, (float)posY + y*pixelSize, (float)pixelSize, (float)pixelSize }, 0, BLANK, color);
+ #endif
+ }
+
+ if ((k == 15) || (k == 31)) y++;
+ }
+ }
+}
+
+// Set icon drawing size
+void GuiSetIconScale(int scale)
+{
+ if (scale >= 1) guiIconScale = scale;
+}
+
+#endif // !RAYGUI_NO_ICONS
+
+//----------------------------------------------------------------------------------
+// Module Internal Functions Definition
+//----------------------------------------------------------------------------------
+
+// Load style from memory
+// WARNING: Binary files only
+static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize)
+{
+ unsigned char *fileDataPtr = (unsigned char *)fileData;
+
+ char signature[5] = { 0 };
+ short version = 0;
+ short reserved = 0;
+ int propertyCount = 0;
+
+ memcpy(signature, fileDataPtr, 4);
+ memcpy(&version, fileDataPtr + 4, sizeof(short));
+ memcpy(&reserved, fileDataPtr + 4 + 2, sizeof(short));
+ memcpy(&propertyCount, fileDataPtr + 4 + 2 + 2, sizeof(int));
+ fileDataPtr += 12;
+
+ if ((signature[0] == 'r') &&
+ (signature[1] == 'G') &&
+ (signature[2] == 'S') &&
+ (signature[3] == ' '))
+ {
+ short controlId = 0;
+ short propertyId = 0;
+ unsigned int propertyValue = 0;
+
+ for (int i = 0; i < propertyCount; i++)
+ {
+ memcpy(&controlId, fileDataPtr, sizeof(short));
+ memcpy(&propertyId, fileDataPtr + 2, sizeof(short));
+ memcpy(&propertyValue, fileDataPtr + 2 + 2, sizeof(unsigned int));
+ fileDataPtr += 8;
+
+ if (controlId == 0) // DEFAULT control
+ {
+ // If a DEFAULT property is loaded, it is propagated to all controls
+ // NOTE: All DEFAULT properties should be defined first in the file
+ GuiSetStyle(0, (int)propertyId, propertyValue);
+
+ if (propertyId < RAYGUI_MAX_PROPS_BASE) for (int j = 1; j < RAYGUI_MAX_CONTROLS; j++) GuiSetStyle(j, (int)propertyId, propertyValue);
+ }
+ else GuiSetStyle((int)controlId, (int)propertyId, propertyValue);
+ }
+
+ // Font loading is highly dependant on raylib API to load font data and image
+
+#if !defined(RAYGUI_STANDALONE)
+ // Load custom font if available
+ int fontDataSize = 0;
+ memcpy(&fontDataSize, fileDataPtr, sizeof(int));
+ fileDataPtr += 4;
+
+ if (fontDataSize > 0)
+ {
+ Font font = { 0 };
+ int fontType = 0; // 0-Normal, 1-SDF
+
+ memcpy(&font.baseSize, fileDataPtr, sizeof(int));
+ memcpy(&font.glyphCount, fileDataPtr + 4, sizeof(int));
+ memcpy(&fontType, fileDataPtr + 4 + 4, sizeof(int));
+ fileDataPtr += 12;
+
+ // Load font white rectangle
+ Rectangle fontWhiteRec = { 0 };
+ memcpy(&fontWhiteRec, fileDataPtr, sizeof(Rectangle));
+ fileDataPtr += 16;
+
+ // Load font image parameters
+ int fontImageUncompSize = 0;
+ int fontImageCompSize = 0;
+ memcpy(&fontImageUncompSize, fileDataPtr, sizeof(int));
+ memcpy(&fontImageCompSize, fileDataPtr + 4, sizeof(int));
+ fileDataPtr += 8;
+
+ Image imFont = { 0 };
+ imFont.mipmaps = 1;
+ memcpy(&imFont.width, fileDataPtr, sizeof(int));
+ memcpy(&imFont.height, fileDataPtr + 4, sizeof(int));
+ memcpy(&imFont.format, fileDataPtr + 4 + 4, sizeof(int));
+ fileDataPtr += 12;
+
+ if ((fontImageCompSize > 0) && (fontImageCompSize != fontImageUncompSize))
+ {
+ // Compressed font atlas image data (DEFLATE), it requires DecompressData()
+ int dataUncompSize = 0;
+ unsigned char *compData = (unsigned char *)RAYGUI_MALLOC(fontImageCompSize);
+ memcpy(compData, fileDataPtr, fontImageCompSize);
+ fileDataPtr += fontImageCompSize;
+
+ imFont.data = DecompressData(compData, fontImageCompSize, &dataUncompSize);
+
+ // Security check, dataUncompSize must match the provided fontImageUncompSize
+ if (dataUncompSize != fontImageUncompSize) RAYGUI_LOG("WARNING: Uncompressed font atlas image data could be corrupted");
+
+ RAYGUI_FREE(compData);
+ }
+ else
+ {
+ // Font atlas image data is not compressed
+ imFont.data = (unsigned char *)RAYGUI_MALLOC(fontImageUncompSize);
+ memcpy(imFont.data, fileDataPtr, fontImageUncompSize);
+ fileDataPtr += fontImageUncompSize;
+ }
+
+ if (font.texture.id != GetFontDefault().texture.id) UnloadTexture(font.texture);
+ font.texture = LoadTextureFromImage(imFont);
+
+ RAYGUI_FREE(imFont.data);
+
+ // Validate font atlas texture was loaded correctly
+ if (font.texture.id != 0)
+ {
+ // Load font recs data
+ int recsDataSize = font.glyphCount*sizeof(Rectangle);
+ int recsDataCompressedSize = 0;
+
+ // WARNING: Version 400 adds the compression size parameter
+ if (version >= 400)
+ {
+ // RGS files version 400 support compressed recs data
+ memcpy(&recsDataCompressedSize, fileDataPtr, sizeof(int));
+ fileDataPtr += sizeof(int);
+ }
+
+ if ((recsDataCompressedSize > 0) && (recsDataCompressedSize != recsDataSize))
+ {
+ // Recs data is compressed, uncompress it
+ unsigned char *recsDataCompressed = (unsigned char *)RAYGUI_MALLOC(recsDataCompressedSize);
+
+ memcpy(recsDataCompressed, fileDataPtr, recsDataCompressedSize);
+ fileDataPtr += recsDataCompressedSize;
+
+ int recsDataUncompSize = 0;
+ font.recs = (Rectangle *)DecompressData(recsDataCompressed, recsDataCompressedSize, &recsDataUncompSize);
+
+ // Security check, data uncompressed size must match the expected original data size
+ if (recsDataUncompSize != recsDataSize) RAYGUI_LOG("WARNING: Uncompressed font recs data could be corrupted");
+
+ RAYGUI_FREE(recsDataCompressed);
+ }
+ else
+ {
+ // Recs data is uncompressed
+ font.recs = (Rectangle *)RAYGUI_CALLOC(font.glyphCount, sizeof(Rectangle));
+ for (int i = 0; i < font.glyphCount; i++)
+ {
+ memcpy(&font.recs[i], fileDataPtr, sizeof(Rectangle));
+ fileDataPtr += sizeof(Rectangle);
+ }
+ }
+
+ // Load font glyphs info data
+ int glyphsDataSize = font.glyphCount*16; // 16 bytes data per glyph
+ int glyphsDataCompressedSize = 0;
+
+ // WARNING: Version 400 adds the compression size parameter
+ if (version >= 400)
+ {
+ // RGS files version 400 support compressed glyphs data
+ memcpy(&glyphsDataCompressedSize, fileDataPtr, sizeof(int));
+ fileDataPtr += sizeof(int);
+ }
+
+ // Allocate required glyphs space to fill with data
+ font.glyphs = (GlyphInfo *)RAYGUI_CALLOC(font.glyphCount, sizeof(GlyphInfo));
+
+ if ((glyphsDataCompressedSize > 0) && (glyphsDataCompressedSize != glyphsDataSize))
+ {
+ // Glyphs data is compressed, uncompress it
+ unsigned char *glypsDataCompressed = (unsigned char *)RAYGUI_MALLOC(glyphsDataCompressedSize);
+
+ memcpy(glypsDataCompressed, fileDataPtr, glyphsDataCompressedSize);
+ fileDataPtr += glyphsDataCompressedSize;
+
+ int glyphsDataUncompSize = 0;
+ unsigned char *glyphsDataUncomp = DecompressData(glypsDataCompressed, glyphsDataCompressedSize, &glyphsDataUncompSize);
+
+ // Security check, data uncompressed size must match the expected original data size
+ if (glyphsDataUncompSize != glyphsDataSize) RAYGUI_LOG("WARNING: Uncompressed font glyphs data could be corrupted");
+
+ unsigned char *glyphsDataUncompPtr = glyphsDataUncomp;
+
+ for (int i = 0; i < font.glyphCount; i++)
+ {
+ memcpy(&font.glyphs[i].value, glyphsDataUncompPtr, sizeof(int));
+ memcpy(&font.glyphs[i].offsetX, glyphsDataUncompPtr + 4, sizeof(int));
+ memcpy(&font.glyphs[i].offsetY, glyphsDataUncompPtr + 8, sizeof(int));
+ memcpy(&font.glyphs[i].advanceX, glyphsDataUncompPtr + 12, sizeof(int));
+ glyphsDataUncompPtr += 16;
+ }
+
+ RAYGUI_FREE(glypsDataCompressed);
+ RAYGUI_FREE(glyphsDataUncomp);
+ }
+ else
+ {
+ // Glyphs data is uncompressed
+ for (int i = 0; i < font.glyphCount; i++)
+ {
+ memcpy(&font.glyphs[i].value, fileDataPtr, sizeof(int));
+ memcpy(&font.glyphs[i].offsetX, fileDataPtr + 4, sizeof(int));
+ memcpy(&font.glyphs[i].offsetY, fileDataPtr + 8, sizeof(int));
+ memcpy(&font.glyphs[i].advanceX, fileDataPtr + 12, sizeof(int));
+ fileDataPtr += 16;
+ }
+ }
+ }
+ else font = GetFontDefault(); // Fallback in case of errors loading font atlas texture
+
+ GuiSetFont(font);
+
+ // Set font texture source rectangle to be used as white texture to draw shapes
+ // NOTE: It makes possible to draw shapes and text (full UI) in a single draw call
+ if ((fontWhiteRec.x > 0) &&
+ (fontWhiteRec.y > 0) &&
+ (fontWhiteRec.width > 0) &&
+ (fontWhiteRec.height > 0)) SetShapesTexture(font.texture, fontWhiteRec);
+ }
+#endif
+ }
+}
+
+// Gui get text width considering icon
+static int GetTextWidth(const char *text)
+{
+ #if !defined(ICON_TEXT_PADDING)
+ #define ICON_TEXT_PADDING 4
+ #endif
+
+ Vector2 textSize = { 0 };
+ int textIconOffset = 0;
+
+ if ((text != NULL) && (text[0] != '\0'))
+ {
+ if (text[0] == '#')
+ {
+ for (int i = 1; (i < 5) && (text[i] != '\0'); i++)
+ {
+ if (text[i] == '#')
+ {
+ textIconOffset = i;
+ break;
+ }
+ }
+ }
+
+ text += textIconOffset;
+
+ // Make sure guiFont is set, GuiGetStyle() initializes it lazynessly
+ float fontSize = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
+
+ // Custom MeasureText() implementation
+ if ((guiFont.texture.id > 0) && (text != NULL))
+ {
+ // Get size in bytes of text, considering end of line and line break
+ int size = 0;
+ for (int i = 0; i < MAX_LINE_BUFFER_SIZE; i++)
+ {
+ if ((text[i] != '\0') && (text[i] != '\n')) size++;
+ else break;
+ }
+
+ float scaleFactor = fontSize/(float)guiFont.baseSize;
+ textSize.y = (float)guiFont.baseSize*scaleFactor;
+ float glyphWidth = 0.0f;
+
+ for (int i = 0, codepointSize = 0; i < size; i += codepointSize)
+ {
+ int codepoint = GetCodepointNext(&text[i], &codepointSize);
+ int codepointIndex = GetGlyphIndex(guiFont, codepoint);
+
+ if (guiFont.glyphs[codepointIndex].advanceX == 0) glyphWidth = ((float)guiFont.recs[codepointIndex].width*scaleFactor);
+ else glyphWidth = ((float)guiFont.glyphs[codepointIndex].advanceX*scaleFactor);
+
+ textSize.x += (glyphWidth + (float)GuiGetStyle(DEFAULT, TEXT_SPACING));
+ }
+ }
+
+ if (textIconOffset > 0) textSize.x += (RAYGUI_ICON_SIZE + ICON_TEXT_PADDING);
+ }
+
+ return (int)textSize.x;
+}
+
+// Get text bounds considering control bounds
+static Rectangle GetTextBounds(int control, Rectangle bounds)
+{
+ Rectangle textBounds = bounds;
+
+ textBounds.x = bounds.x + GuiGetStyle(control, BORDER_WIDTH);
+ textBounds.y = bounds.y + GuiGetStyle(control, BORDER_WIDTH) + GuiGetStyle(control, TEXT_PADDING);
+ textBounds.width = bounds.width - 2*GuiGetStyle(control, BORDER_WIDTH) - 2*GuiGetStyle(control, TEXT_PADDING);
+ textBounds.height = bounds.height - 2*GuiGetStyle(control, BORDER_WIDTH) - 2*GuiGetStyle(control, TEXT_PADDING); // NOTE: Text is processed line per line!
+
+ // Depending on control, TEXT_PADDING and TEXT_ALIGNMENT properties could affect the text-bounds
+ switch (control)
+ {
+ case COMBOBOX:
+ case DROPDOWNBOX:
+ case LISTVIEW:
+ // TODO: Special cases (no label): COMBOBOX, DROPDOWNBOX, LISTVIEW
+ case SLIDER:
+ case CHECKBOX:
+ case VALUEBOX:
+ case SPINNER:
+ // TODO: More special cases (label on side): SLIDER, CHECKBOX, VALUEBOX, SPINNER
+ default:
+ {
+ // TODO: WARNING: TEXT_ALIGNMENT is already considered in GuiDrawText()
+ if (GuiGetStyle(control, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT) textBounds.x -= GuiGetStyle(control, TEXT_PADDING);
+ else textBounds.x += GuiGetStyle(control, TEXT_PADDING);
+ }
+ break;
+ }
+
+ return textBounds;
+}
+
+// Get text icon if provided and move text cursor
+// NOTE: We support up to 999 values for iconId
+static const char *GetTextIcon(const char *text, int *iconId)
+{
+#if !defined(RAYGUI_NO_ICONS)
+ *iconId = -1;
+ if (text[0] == '#') // Maybe we have an icon!
+ {
+ char iconValue[4] = { 0 }; // Maximum length for icon value: 3 digits + '\0'
+
+ int pos = 1;
+ while ((pos < 4) && (text[pos] >= '0') && (text[pos] <= '9'))
+ {
+ iconValue[pos - 1] = text[pos];
+ pos++;
+ }
+
+ if (text[pos] == '#')
+ {
+ *iconId = TextToInteger(iconValue);
+
+ // Move text pointer after icon
+ // WARNING: If only icon provided, it could point to EOL character: '\0'
+ if (*iconId >= 0) text += (pos + 1);
+ }
+ }
+#endif
+
+ return text;
+}
+
+// Get text divided into lines (by line-breaks '\n')
+const char **GetTextLines(const char *text, int *count)
+{
+ #define RAYGUI_MAX_TEXT_LINES 128
+
+ static const char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 };
+ for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings
+
+ int textSize = (int)strlen(text);
+
+ lines[0] = text;
+ int len = 0;
+ *count = 1;
+ //int lineSize = 0; // Stores current line size, not returned
+
+ for (int i = 0, k = 0; (i < textSize) && (*count < RAYGUI_MAX_TEXT_LINES); i++)
+ {
+ if (text[i] == '\n')
+ {
+ //lineSize = len;
+ k++;
+ lines[k] = &text[i + 1]; // WARNING: next value is valid?
+ len = 0;
+ *count += 1;
+ }
+ else len++;
+ }
+
+ //lines[*count - 1].size = len;
+
+ return lines;
+}
+
+// Get text width to next space for provided string
+static float GetNextSpaceWidth(const char *text, int *nextSpaceIndex)
+{
+ float width = 0;
+ int codepointByteCount = 0;
+ int codepoint = 0;
+ int index = 0;
+ float glyphWidth = 0;
+ float scaleFactor = (float)GuiGetStyle(DEFAULT, TEXT_SIZE)/guiFont.baseSize;
+
+ for (int i = 0; text[i] != '\0'; i++)
+ {
+ if (text[i] != ' ')
+ {
+ codepoint = GetCodepoint(&text[i], &codepointByteCount);
+ index = GetGlyphIndex(guiFont, codepoint);
+ glyphWidth = (guiFont.glyphs[index].advanceX == 0)? guiFont.recs[index].width*scaleFactor : guiFont.glyphs[index].advanceX*scaleFactor;
+ width += (glyphWidth + (float)GuiGetStyle(DEFAULT, TEXT_SPACING));
+ }
+ else
+ {
+ *nextSpaceIndex = i;
+ break;
+ }
+ }
+
+ return width;
+}
+
+// Gui draw text using default font
+static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, Color tint)
+{
+ #define TEXT_VALIGN_PIXEL_OFFSET(h) ((int)h%2) // Vertical alignment for pixel perfect
+
+ #if !defined(ICON_TEXT_PADDING)
+ #define ICON_TEXT_PADDING 4
+ #endif
+
+ if ((text == NULL) || (text[0] == '\0')) return; // Security check
+
+ // PROCEDURE:
+ // - Text is processed line per line
+ // - For every line, horizontal alignment is defined
+ // - For all text, vertical alignment is defined (multiline text only)
+ // - For every line, wordwrap mode is checked (useful for GuitextBox(), read-only)
+
+ // Get text lines (using '\n' as delimiter) to be processed individually
+ // WARNING: We can't use GuiTextSplit() function because it can be already used
+ // before the GuiDrawText() call and its buffer is static, it would be overriden :(
+ int lineCount = 0;
+ const char **lines = GetTextLines(text, &lineCount);
+
+ // Text style variables
+ //int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT);
+ int alignmentVertical = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT_VERTICAL);
+ int wrapMode = GuiGetStyle(DEFAULT, TEXT_WRAP_MODE); // Wrap-mode only available in read-only mode, no for text editing
+
+ // TODO: WARNING: This totalHeight is not valid for vertical alignment in case of word-wrap
+ float totalHeight = (float)(lineCount*GuiGetStyle(DEFAULT, TEXT_SIZE) + (lineCount - 1)*GuiGetStyle(DEFAULT, TEXT_SIZE)/2);
+ float posOffsetY = 0.0f;
+
+ for (int i = 0; i < lineCount; i++)
+ {
+ int iconId = 0;
+ lines[i] = GetTextIcon(lines[i], &iconId); // Check text for icon and move cursor
+
+ // Get text position depending on alignment and iconId
+ //---------------------------------------------------------------------------------
+ Vector2 textBoundsPosition = { textBounds.x, textBounds.y };
+ float textBoundsWidthOffset = 0.0f;
+
+ // NOTE: We get text size after icon has been processed
+ // WARNING: GetTextWidth() also processes text icon to get width! -> Really needed?
+ int textSizeX = GetTextWidth(lines[i]);
+
+ // If text requires an icon, add size to measure
+ if (iconId >= 0)
+ {
+ textSizeX += RAYGUI_ICON_SIZE*guiIconScale;
+
+ // WARNING: If only icon provided, text could be pointing to EOF character: '\0'
+#if !defined(RAYGUI_NO_ICONS)
+ if ((lines[i] != NULL) && (lines[i][0] != '\0')) textSizeX += ICON_TEXT_PADDING;
+#endif
+ }
+
+ // Check guiTextAlign global variables
+ switch (alignment)
+ {
+ case TEXT_ALIGN_LEFT: textBoundsPosition.x = textBounds.x; break;
+ case TEXT_ALIGN_CENTER: textBoundsPosition.x = textBounds.x + textBounds.width/2 - textSizeX/2; break;
+ case TEXT_ALIGN_RIGHT: textBoundsPosition.x = textBounds.x + textBounds.width - textSizeX; break;
+ default: break;
+ }
+
+ if (textSizeX > textBounds.width && (lines[i] != NULL) && (lines[i][0] != '\0')) textBoundsPosition.x = textBounds.x;
+
+ switch (alignmentVertical)
+ {
+ // Only valid in case of wordWrap = 0;
+ case TEXT_ALIGN_TOP: textBoundsPosition.y = textBounds.y + posOffsetY; break;
+ case TEXT_ALIGN_MIDDLE: textBoundsPosition.y = textBounds.y + posOffsetY + textBounds.height/2 - totalHeight/2 + TEXT_VALIGN_PIXEL_OFFSET(textBounds.height); break;
+ case TEXT_ALIGN_BOTTOM: textBoundsPosition.y = textBounds.y + posOffsetY + textBounds.height - totalHeight + TEXT_VALIGN_PIXEL_OFFSET(textBounds.height); break;
+ default: break;
+ }
+
+ // NOTE: Make sure we get pixel-perfect coordinates,
+ // In case of decimals we got weird text positioning
+ textBoundsPosition.x = (float)((int)textBoundsPosition.x);
+ textBoundsPosition.y = (float)((int)textBoundsPosition.y);
+ //---------------------------------------------------------------------------------
+
+ // Draw text (with icon if available)
+ //---------------------------------------------------------------------------------
+#if !defined(RAYGUI_NO_ICONS)
+ if (iconId >= 0)
+ {
+ // NOTE: We consider icon height, probably different than text size
+ GuiDrawIcon(iconId, (int)textBoundsPosition.x, (int)(textBounds.y + textBounds.height/2 - RAYGUI_ICON_SIZE*guiIconScale/2 + TEXT_VALIGN_PIXEL_OFFSET(textBounds.height)), guiIconScale, tint);
+ textBoundsPosition.x += (float)(RAYGUI_ICON_SIZE*guiIconScale + ICON_TEXT_PADDING);
+ textBoundsWidthOffset = (float)(RAYGUI_ICON_SIZE*guiIconScale + ICON_TEXT_PADDING);
+ }
+#endif
+ // Get size in bytes of text,
+ // considering end of line and line break
+ int lineSize = 0;
+ for (int c = 0; (lines[i][c] != '\0') && (lines[i][c] != '\n') && (lines[i][c] != '\r'); c++, lineSize++){ }
+ float scaleFactor = (float)GuiGetStyle(DEFAULT, TEXT_SIZE)/guiFont.baseSize;
+
+ int lastSpaceIndex = 0;
+ bool tempWrapCharMode = false;
+
+ int textOffsetY = 0;
+ float textOffsetX = 0.0f;
+ float glyphWidth = 0;
+
+ int ellipsisWidth = GetTextWidth("...");
+ bool textOverflow = false;
+ for (int c = 0, codepointSize = 0; c < lineSize; c += codepointSize)
+ {
+ int codepoint = GetCodepointNext(&lines[i][c], &codepointSize);
+ int index = GetGlyphIndex(guiFont, codepoint);
+
+ // NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
+ // but we need to draw all of the bad bytes using the '?' symbol moving one byte
+ if (codepoint == 0x3f) codepointSize = 1; // TODO: Review not recognized codepoints size
+
+ // Get glyph width to check if it goes out of bounds
+ if (guiFont.glyphs[index].advanceX == 0) glyphWidth = ((float)guiFont.recs[index].width*scaleFactor);
+ else glyphWidth = (float)guiFont.glyphs[index].advanceX*scaleFactor;
+
+ // Wrap mode text measuring, to validate if
+ // it can be drawn or a new line is required
+ if (wrapMode == TEXT_WRAP_CHAR)
+ {
+ // Jump to next line if current character reach end of the box limits
+ if ((textOffsetX + glyphWidth) > textBounds.width - textBoundsWidthOffset)
+ {
+ textOffsetX = 0.0f;
+ textOffsetY += GuiGetStyle(DEFAULT, TEXT_LINE_SPACING);
+
+ if (tempWrapCharMode) // Wrap at char level when too long words
+ {
+ wrapMode = TEXT_WRAP_WORD;
+ tempWrapCharMode = false;
+ }
+ }
+ }
+ else if (wrapMode == TEXT_WRAP_WORD)
+ {
+ if (codepoint == 32) lastSpaceIndex = c;
+
+ // Get width to next space in line
+ int nextSpaceIndex = 0;
+ float nextSpaceWidth = GetNextSpaceWidth(lines[i] + c, &nextSpaceIndex);
+
+ int nextSpaceIndex2 = 0;
+ float nextWordSize = GetNextSpaceWidth(lines[i] + lastSpaceIndex + 1, &nextSpaceIndex2);
+
+ if (nextWordSize > textBounds.width - textBoundsWidthOffset)
+ {
+ // Considering the case the next word is longer than bounds
+ tempWrapCharMode = true;
+ wrapMode = TEXT_WRAP_CHAR;
+ }
+ else if ((textOffsetX + nextSpaceWidth) > textBounds.width - textBoundsWidthOffset)
+ {
+ textOffsetX = 0.0f;
+ textOffsetY += GuiGetStyle(DEFAULT, TEXT_LINE_SPACING);
+ }
+ }
+
+ if (codepoint == '\n') break; // WARNING: Lines are already processed manually, no need to keep drawing after this codepoint
+ else
+ {
+ // TODO: There are multiple types of spaces in Unicode,
+ // maybe it's a good idea to add support for more: http://jkorpela.fi/chars/spaces.html
+ if ((codepoint != ' ') && (codepoint != '\t')) // Do not draw codepoints with no glyph
+ {
+ if (wrapMode == TEXT_WRAP_NONE)
+ {
+ // Draw only required text glyphs fitting the textBounds.width
+ if (textSizeX > textBounds.width)
+ {
+ if (textOffsetX <= (textBounds.width - glyphWidth - textBoundsWidthOffset - ellipsisWidth))
+ {
+ DrawTextCodepoint(guiFont, codepoint, RAYGUI_CLITERAL(Vector2){ textBoundsPosition.x + textOffsetX, textBoundsPosition.y + textOffsetY }, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), GuiFade(tint, guiAlpha));
+ }
+ else if (!textOverflow)
+ {
+ textOverflow = true;
+
+ for (int j = 0; j < ellipsisWidth; j += ellipsisWidth/3)
+ {
+ DrawTextCodepoint(guiFont, '.', RAYGUI_CLITERAL(Vector2){ textBoundsPosition.x + textOffsetX + j, textBoundsPosition.y + textOffsetY }, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), GuiFade(tint, guiAlpha));
+ }
+ }
+ }
+ else
+ {
+ DrawTextCodepoint(guiFont, codepoint, RAYGUI_CLITERAL(Vector2){ textBoundsPosition.x + textOffsetX, textBoundsPosition.y + textOffsetY }, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), GuiFade(tint, guiAlpha));
+ }
+ }
+ else if ((wrapMode == TEXT_WRAP_CHAR) || (wrapMode == TEXT_WRAP_WORD))
+ {
+ // Draw only glyphs inside the bounds
+ if ((textBoundsPosition.y + textOffsetY) <= (textBounds.y + textBounds.height - GuiGetStyle(DEFAULT, TEXT_SIZE)))
+ {
+ DrawTextCodepoint(guiFont, codepoint, RAYGUI_CLITERAL(Vector2){ textBoundsPosition.x + textOffsetX, textBoundsPosition.y + textOffsetY }, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), GuiFade(tint, guiAlpha));
+ }
+ }
+ }
+
+ if (guiFont.glyphs[index].advanceX == 0) textOffsetX += ((float)guiFont.recs[index].width*scaleFactor + (float)GuiGetStyle(DEFAULT, TEXT_SPACING));
+ else textOffsetX += ((float)guiFont.glyphs[index].advanceX*scaleFactor + (float)GuiGetStyle(DEFAULT, TEXT_SPACING));
+ }
+ }
+
+ if (wrapMode == TEXT_WRAP_NONE) posOffsetY += (float)GuiGetStyle(DEFAULT, TEXT_LINE_SPACING);
+ else if ((wrapMode == TEXT_WRAP_CHAR) || (wrapMode == TEXT_WRAP_WORD)) posOffsetY += (textOffsetY + (float)GuiGetStyle(DEFAULT, TEXT_LINE_SPACING));
+ //---------------------------------------------------------------------------------
+ }
+
+#if defined(RAYGUI_DEBUG_TEXT_BOUNDS)
+ GuiDrawRectangle(textBounds, 0, WHITE, Fade(BLUE, 0.4f));
+#endif
+}
+
+// Gui draw rectangle using default raygui plain style with borders
+static void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor, Color color)
+{
+ if (color.a > 0)
+ {
+ // Draw rectangle filled with color
+ DrawRectangle((int)rec.x, (int)rec.y, (int)rec.width, (int)rec.height, GuiFade(color, guiAlpha));
+ }
+
+ if (borderWidth > 0)
+ {
+ // Draw rectangle border lines with color
+ DrawRectangle((int)rec.x, (int)rec.y, (int)rec.width, borderWidth, GuiFade(borderColor, guiAlpha));
+ DrawRectangle((int)rec.x, (int)rec.y + borderWidth, borderWidth, (int)rec.height - 2*borderWidth, GuiFade(borderColor, guiAlpha));
+ DrawRectangle((int)rec.x + (int)rec.width - borderWidth, (int)rec.y + borderWidth, borderWidth, (int)rec.height - 2*borderWidth, GuiFade(borderColor, guiAlpha));
+ DrawRectangle((int)rec.x, (int)rec.y + (int)rec.height - borderWidth, (int)rec.width, borderWidth, GuiFade(borderColor, guiAlpha));
+ }
+
+#if defined(RAYGUI_DEBUG_RECS_BOUNDS)
+ DrawRectangle((int)rec.x, (int)rec.y, (int)rec.width, (int)rec.height, Fade(RED, 0.4f));
+#endif
+}
+
+// Draw tooltip using control bounds
+static void GuiTooltip(Rectangle controlRec)
+{
+ if (!guiLocked && guiTooltip && (guiTooltipPtr != NULL) && !guiControlExclusiveMode)
+ {
+ Vector2 textSize = MeasureTextEx(GuiGetFont(), guiTooltipPtr, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), (float)GuiGetStyle(DEFAULT, TEXT_SPACING));
+
+ if ((controlRec.x + textSize.x + 16) > GetScreenWidth()) controlRec.x -= (textSize.x + 16 - controlRec.width);
+
+ GuiPanel(RAYGUI_CLITERAL(Rectangle){ controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, GuiGetStyle(DEFAULT, TEXT_SIZE) + 8.f }, NULL);
+
+ int textPadding = GuiGetStyle(LABEL, TEXT_PADDING);
+ int textAlignment = GuiGetStyle(LABEL, TEXT_ALIGNMENT);
+ GuiSetStyle(LABEL, TEXT_PADDING, 0);
+ GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER);
+ GuiLabel(RAYGUI_CLITERAL(Rectangle){ controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, GuiGetStyle(DEFAULT, TEXT_SIZE) + 8.f }, guiTooltipPtr);
+ GuiSetStyle(LABEL, TEXT_ALIGNMENT, textAlignment);
+ GuiSetStyle(LABEL, TEXT_PADDING, textPadding);
+ }
+}
+
+// Split controls text into multiple strings
+// Also check for multiple columns (required by GuiToggleGroup())
+static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow)
+{
+ // NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter)
+ // inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated,
+ // all used memory is static... it has some limitations:
+ // 1. Maximum number of possible split strings is set by RAYGUI_TEXTSPLIT_MAX_ITEMS
+ // 2. Maximum size of text to split is RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE
+ // NOTE: Those definitions could be externally provided if required
+
+ // TODO: HACK: GuiTextSplit() - Review how textRows are returned to user
+ // textRow is an externally provided array of integers that stores row number for every splitted string
+
+ #if !defined(RAYGUI_TEXTSPLIT_MAX_ITEMS)
+ #define RAYGUI_TEXTSPLIT_MAX_ITEMS 128
+ #endif
+ #if !defined(RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE)
+ #define RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE 1024
+ #endif
+
+ static const char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data)
+ static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; // Buffer data (text input copy with '\0' added)
+ memset(buffer, 0, RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE);
+
+ result[0] = buffer;
+ int counter = 1;
+
+ if (textRow != NULL) textRow[0] = 0;
+
+ // Count how many substrings we have on text and point to every one
+ for (int i = 0; i < RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE; i++)
+ {
+ buffer[i] = text[i];
+ if (buffer[i] == '\0') break;
+ else if ((buffer[i] == delimiter) || (buffer[i] == '\n'))
+ {
+ result[counter] = buffer + i + 1;
+
+ if (textRow != NULL)
+ {
+ if (buffer[i] == '\n') textRow[counter] = textRow[counter - 1] + 1;
+ else textRow[counter] = textRow[counter - 1];
+ }
+
+ buffer[i] = '\0'; // Set an end of string at this point
+
+ counter++;
+ if (counter > RAYGUI_TEXTSPLIT_MAX_ITEMS) break;
+ }
+ }
+
+ *count = counter;
+
+ return result;
+}
+
+// Convert color data from RGB to HSV
+// NOTE: Color data should be passed normalized
+static Vector3 ConvertRGBtoHSV(Vector3 rgb)
+{
+ Vector3 hsv = { 0 };
+ float min = 0.0f;
+ float max = 0.0f;
+ float delta = 0.0f;
+
+ min = (rgb.x < rgb.y)? rgb.x : rgb.y;
+ min = (min < rgb.z)? min : rgb.z;
+
+ max = (rgb.x > rgb.y)? rgb.x : rgb.y;
+ max = (max > rgb.z)? max : rgb.z;
+
+ hsv.z = max; // Value
+ delta = max - min;
+
+ if (delta < 0.00001f)
+ {
+ hsv.y = 0.0f;
+ hsv.x = 0.0f; // Undefined, maybe NAN?
+ return hsv;
+ }
+
+ if (max > 0.0f)
+ {
+ // NOTE: If max is 0, this divide would cause a crash
+ hsv.y = (delta/max); // Saturation
+ }
+ else
+ {
+ // NOTE: If max is 0, then r = g = b = 0, s = 0, h is undefined
+ hsv.y = 0.0f;
+ hsv.x = 0.0f; // Undefined, maybe NAN?
+ return hsv;
+ }
+
+ // NOTE: Comparing float values could not work properly
+ if (rgb.x >= max) hsv.x = (rgb.y - rgb.z)/delta; // Between yellow & magenta
+ else
+ {
+ if (rgb.y >= max) hsv.x = 2.0f + (rgb.z - rgb.x)/delta; // Between cyan & yellow
+ else hsv.x = 4.0f + (rgb.x - rgb.y)/delta; // Between magenta & cyan
+ }
+
+ hsv.x *= 60.0f; // Convert to degrees
+
+ if (hsv.x < 0.0f) hsv.x += 360.0f;
+
+ return hsv;
+}
+
+// Convert color data from HSV to RGB
+// NOTE: Color data should be passed normalized
+static Vector3 ConvertHSVtoRGB(Vector3 hsv)
+{
+ Vector3 rgb = { 0 };
+ float hh = 0.0f, p = 0.0f, q = 0.0f, t = 0.0f, ff = 0.0f;
+ long i = 0;
+
+ // NOTE: Comparing float values could not work properly
+ if (hsv.y <= 0.0f)
+ {
+ rgb.x = hsv.z;
+ rgb.y = hsv.z;
+ rgb.z = hsv.z;
+ return rgb;
+ }
+
+ hh = hsv.x;
+ if (hh >= 360.0f) hh = 0.0f;
+ hh /= 60.0f;
+
+ i = (long)hh;
+ ff = hh - i;
+ p = hsv.z*(1.0f - hsv.y);
+ q = hsv.z*(1.0f - (hsv.y*ff));
+ t = hsv.z*(1.0f - (hsv.y*(1.0f - ff)));
+
+ switch (i)
+ {
+ case 0:
+ {
+ rgb.x = hsv.z;
+ rgb.y = t;
+ rgb.z = p;
+ } break;
+ case 1:
+ {
+ rgb.x = q;
+ rgb.y = hsv.z;
+ rgb.z = p;
+ } break;
+ case 2:
+ {
+ rgb.x = p;
+ rgb.y = hsv.z;
+ rgb.z = t;
+ } break;
+ case 3:
+ {
+ rgb.x = p;
+ rgb.y = q;
+ rgb.z = hsv.z;
+ } break;
+ case 4:
+ {
+ rgb.x = t;
+ rgb.y = p;
+ rgb.z = hsv.z;
+ } break;
+ case 5:
+ default:
+ {
+ rgb.x = hsv.z;
+ rgb.y = p;
+ rgb.z = q;
+ } break;
+ }
+
+ return rgb;
+}
+
+// Scroll bar control (used by GuiScrollPanel())
+static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue)
+{
+ GuiState state = guiState;
+
+ // Is the scrollbar horizontal or vertical?
+ bool isVertical = (bounds.width > bounds.height)? false : true;
+
+ // The size (width or height depending on scrollbar type) of the spinner buttons
+ const int spinnerSize = GuiGetStyle(SCROLLBAR, ARROWS_VISIBLE)?
+ (isVertical? (int)bounds.width - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH) :
+ (int)bounds.height - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH)) : 0;
+
+ // Arrow buttons [<] [>] [∧] [∨]
+ Rectangle arrowUpLeft = { 0 };
+ Rectangle arrowDownRight = { 0 };
+
+ // Actual area of the scrollbar excluding the arrow buttons
+ Rectangle scrollbar = { 0 };
+
+ // Slider bar that moves --[///]-----
+ Rectangle slider = { 0 };
+
+ // Normalize value
+ if (value > maxValue) value = maxValue;
+ if (value < minValue) value = minValue;
+
+ int valueRange = maxValue - minValue;
+ if (valueRange <= 0) valueRange = 1;
+
+ int sliderSize = GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE);
+ if (sliderSize < 1) sliderSize = 1; // TODO: Consider a minimum slider size
+
+ // Calculate rectangles for all of the components
+ arrowUpLeft = RAYGUI_CLITERAL(Rectangle){
+ (float)bounds.x + GuiGetStyle(SCROLLBAR, BORDER_WIDTH),
+ (float)bounds.y + GuiGetStyle(SCROLLBAR, BORDER_WIDTH),
+ (float)spinnerSize, (float)spinnerSize };
+
+ if (isVertical)
+ {
+ arrowDownRight = RAYGUI_CLITERAL(Rectangle){ (float)bounds.x + GuiGetStyle(SCROLLBAR, BORDER_WIDTH), (float)bounds.y + bounds.height - spinnerSize - GuiGetStyle(SCROLLBAR, BORDER_WIDTH), (float)spinnerSize, (float)spinnerSize };
+ scrollbar = RAYGUI_CLITERAL(Rectangle){ bounds.x + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_PADDING), arrowUpLeft.y + arrowUpLeft.height, bounds.width - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_PADDING)), bounds.height - arrowUpLeft.height - arrowDownRight.height - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH) };
+
+ // Make sure the slider won't get outside of the scrollbar
+ sliderSize = (sliderSize >= scrollbar.height)? ((int)scrollbar.height - 2) : sliderSize;
+ slider = RAYGUI_CLITERAL(Rectangle){
+ bounds.x + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING),
+ scrollbar.y + (int)(((float)(value - minValue)/valueRange)*(scrollbar.height - sliderSize)),
+ bounds.width - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING)),
+ (float)sliderSize };
+ }
+ else // horizontal
+ {
+ arrowDownRight = RAYGUI_CLITERAL(Rectangle){ (float)bounds.x + bounds.width - spinnerSize - GuiGetStyle(SCROLLBAR, BORDER_WIDTH), (float)bounds.y + GuiGetStyle(SCROLLBAR, BORDER_WIDTH), (float)spinnerSize, (float)spinnerSize };
+ scrollbar = RAYGUI_CLITERAL(Rectangle){ arrowUpLeft.x + arrowUpLeft.width, bounds.y + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_PADDING), bounds.width - arrowUpLeft.width - arrowDownRight.width - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH), bounds.height - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_PADDING)) };
+
+ // Make sure the slider won't get outside of the scrollbar
+ sliderSize = (sliderSize >= scrollbar.width)? ((int)scrollbar.width - 2) : sliderSize;
+ slider = RAYGUI_CLITERAL(Rectangle){
+ scrollbar.x + (int)(((float)(value - minValue)/valueRange)*(scrollbar.width - sliderSize)),
+ bounds.y + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING),
+ (float)sliderSize,
+ bounds.height - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING)) };
+ }
+
+ // Update control
+ //--------------------------------------------------------------------
+ if ((state != STATE_DISABLED) && !guiLocked)
+ {
+ Vector2 mousePoint = GetMousePosition();
+
+ if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds
+ {
+ if (IsMouseButtonDown(MOUSE_LEFT_BUTTON) &&
+ !CheckCollisionPointRec(mousePoint, arrowUpLeft) &&
+ !CheckCollisionPointRec(mousePoint, arrowDownRight))
+ {
+ if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec))
+ {
+ state = STATE_PRESSED;
+
+ if (isVertical) value = (int)(((float)(mousePoint.y - scrollbar.y - slider.height/2)*valueRange)/(scrollbar.height - slider.height) + minValue);
+ else value = (int)(((float)(mousePoint.x - scrollbar.x - slider.width/2)*valueRange)/(scrollbar.width - slider.width) + minValue);
+ }
+ }
+ else
+ {
+ guiControlExclusiveMode = false;
+ guiControlExclusiveRec = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 };
+ }
+ }
+ else if (CheckCollisionPointRec(mousePoint, bounds))
+ {
+ state = STATE_FOCUSED;
+
+ // Handle mouse wheel
+ int wheel = (int)GetMouseWheelMove();
+ if (wheel != 0) value += wheel;
+
+ // Handle mouse button down
+ if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
+ {
+ guiControlExclusiveMode = true;
+ guiControlExclusiveRec = bounds; // Store bounds as an identifier when dragging starts
+
+ // Check arrows click
+ if (CheckCollisionPointRec(mousePoint, arrowUpLeft)) value -= valueRange/GuiGetStyle(SCROLLBAR, SCROLL_SPEED);
+ else if (CheckCollisionPointRec(mousePoint, arrowDownRight)) value += valueRange/GuiGetStyle(SCROLLBAR, SCROLL_SPEED);
+ else if (!CheckCollisionPointRec(mousePoint, slider))
+ {
+ // If click on scrollbar position but not on slider, place slider directly on that position
+ if (isVertical) value = (int)(((float)(mousePoint.y - scrollbar.y - slider.height/2)*valueRange)/(scrollbar.height - slider.height) + minValue);
+ else value = (int)(((float)(mousePoint.x - scrollbar.x - slider.width/2)*valueRange)/(scrollbar.width - slider.width) + minValue);
+ }
+
+ state = STATE_PRESSED;
+ }
+
+ // Keyboard control on mouse hover scrollbar
+ /*
+ if (isVertical)
+ {
+ if (IsKeyDown(KEY_DOWN)) value += 5;
+ else if (IsKeyDown(KEY_UP)) value -= 5;
+ }
+ else
+ {
+ if (IsKeyDown(KEY_RIGHT)) value += 5;
+ else if (IsKeyDown(KEY_LEFT)) value -= 5;
+ }
+ */
+ }
+
+ // Normalize value
+ if (value > maxValue) value = maxValue;
+ if (value < minValue) value = minValue;
+ }
+ //--------------------------------------------------------------------
+
+ // Draw control
+ //--------------------------------------------------------------------
+ GuiDrawRectangle(bounds, GuiGetStyle(SCROLLBAR, BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER + state*3)), GetColor(GuiGetStyle(DEFAULT, BORDER_COLOR_DISABLED))); // Draw the background
+
+ GuiDrawRectangle(scrollbar, 0, BLANK, GetColor(GuiGetStyle(BUTTON, BASE_COLOR_NORMAL))); // Draw the scrollbar active area background
+ GuiDrawRectangle(slider, 0, BLANK, GetColor(GuiGetStyle(SLIDER, BORDER + state*3))); // Draw the slider bar
+
+ // Draw arrows (using icon if available)
+ if (GuiGetStyle(SCROLLBAR, ARROWS_VISIBLE))
+ {
+#if defined(RAYGUI_NO_ICONS)
+ GuiDrawText(isVertical? "^" : "<",
+ RAYGUI_CLITERAL(Rectangle){ arrowUpLeft.x, arrowUpLeft.y, isVertical? bounds.width : bounds.height, isVertical? bounds.width : bounds.height },
+ TEXT_ALIGN_CENTER, GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + (state*3))));
+ GuiDrawText(isVertical? "v" : ">",
+ RAYGUI_CLITERAL(Rectangle){ arrowDownRight.x, arrowDownRight.y, isVertical? bounds.width : bounds.height, isVertical? bounds.width : bounds.height },
+ TEXT_ALIGN_CENTER, GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + (state*3))));
+#else
+ GuiDrawText(isVertical? "#121#" : "#118#",
+ RAYGUI_CLITERAL(Rectangle){ arrowUpLeft.x, arrowUpLeft.y, isVertical? bounds.width : bounds.height, isVertical? bounds.width : bounds.height },
+ TEXT_ALIGN_CENTER, GetColor(GuiGetStyle(SCROLLBAR, TEXT + state*3))); // ICON_ARROW_UP_FILL / ICON_ARROW_LEFT_FILL
+ GuiDrawText(isVertical? "#120#" : "#119#",
+ RAYGUI_CLITERAL(Rectangle){ arrowDownRight.x, arrowDownRight.y, isVertical? bounds.width : bounds.height, isVertical? bounds.width : bounds.height },
+ TEXT_ALIGN_CENTER, GetColor(GuiGetStyle(SCROLLBAR, TEXT + state*3))); // ICON_ARROW_DOWN_FILL / ICON_ARROW_RIGHT_FILL
+#endif
+ }
+ //--------------------------------------------------------------------
+
+ return value;
+}
+
+// Color fade-in or fade-out, alpha goes from 0.0f to 1.0f
+// WARNING: It multiplies current alpha by alpha scale factor
+static Color GuiFade(Color color, float alpha)
+{
+ if (alpha < 0.0f) alpha = 0.0f;
+ else if (alpha > 1.0f) alpha = 1.0f;
+
+ Color result = { color.r, color.g, color.b, (unsigned char)(color.a*alpha) };
+
+ return result;
+}
+
+#if defined(RAYGUI_STANDALONE)
+// Returns a Color struct from hexadecimal value
+static Color GetColor(int hexValue)
+{
+ Color color;
+
+ color.r = (unsigned char)(hexValue >> 24) & 0xFF;
+ color.g = (unsigned char)(hexValue >> 16) & 0xFF;
+ color.b = (unsigned char)(hexValue >> 8) & 0xFF;
+ color.a = (unsigned char)hexValue & 0xFF;
+
+ return color;
+}
+
+// Returns hexadecimal value for a Color
+static int ColorToInt(Color color)
+{
+ return (((int)color.r << 24) | ((int)color.g << 16) | ((int)color.b << 8) | (int)color.a);
+}
+
+// Check if point is inside rectangle
+static bool CheckCollisionPointRec(Vector2 point, Rectangle rec)
+{
+ bool collision = false;
+
+ if ((point.x >= rec.x) && (point.x <= (rec.x + rec.width)) &&
+ (point.y >= rec.y) && (point.y <= (rec.y + rec.height))) collision = true;
+
+ return collision;
+}
+
+// Formatting of text with variables to 'embed'
+static const char *TextFormat(const char *text, ...)
+{
+ #if !defined(RAYGUI_TEXTFORMAT_MAX_SIZE)
+ #define RAYGUI_TEXTFORMAT_MAX_SIZE 256
+ #endif
+
+ static char buffer[RAYGUI_TEXTFORMAT_MAX_SIZE];
+
+ va_list args;
+ va_start(args, text);
+ vsprintf(buffer, text, args);
+ va_end(args);
+
+ return buffer;
+}
+
+// Draw rectangle with vertical gradient fill color
+// NOTE: This function is only used by GuiColorPicker()
+static void DrawRectangleGradientV(int posX, int posY, int width, int height, Color color1, Color color2)
+{
+ Rectangle bounds = { (float)posX, (float)posY, (float)width, (float)height };
+ DrawRectangleGradientEx(bounds, color1, color2, color2, color1);
+}
+
+// Split string into multiple strings
+const char **TextSplit(const char *text, char delimiter, int *count)
+{
+ // NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter)
+ // inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated,
+ // all used memory is static... it has some limitations:
+ // 1. Maximum number of possible split strings is set by RAYGUI_TEXTSPLIT_MAX_ITEMS
+ // 2. Maximum size of text to split is RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE
+
+ #if !defined(RAYGUI_TEXTSPLIT_MAX_ITEMS)
+ #define RAYGUI_TEXTSPLIT_MAX_ITEMS 128
+ #endif
+ #if !defined(RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE)
+ #define RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE 1024
+ #endif
+
+ static const char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL };
+ static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 };
+ memset(buffer, 0, RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE);
+
+ result[0] = buffer;
+ int counter = 0;
+
+ if (text != NULL)
+ {
+ counter = 1;
+
+ // Count how many substrings we have on text and point to every one
+ for (int i = 0; i < RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE; i++)
+ {
+ buffer[i] = text[i];
+ if (buffer[i] == '\0') break;
+ else if (buffer[i] == delimiter)
+ {
+ buffer[i] = '\0'; // Set an end of string at this point
+ result[counter] = buffer + i + 1;
+ counter++;
+
+ if (counter == RAYGUI_TEXTSPLIT_MAX_ITEMS) break;
+ }
+ }
+ }
+
+ *count = counter;
+ return result;
+}
+
+// Get integer value from text
+// NOTE: This function replaces atoi() [stdlib.h]
+static int TextToInteger(const char *text)
+{
+ int value = 0;
+ int sign = 1;
+
+ if ((text[0] == '+') || (text[0] == '-'))
+ {
+ if (text[0] == '-') sign = -1;
+ text++;
+ }
+
+ for (int i = 0; ((text[i] >= '0') && (text[i] <= '9')); ++i) value = value*10 + (int)(text[i] - '0');
+
+ return value*sign;
+}
+
+// Get float value from text
+// NOTE: This function replaces atof() [stdlib.h]
+// WARNING: Only '.' character is understood as decimal point
+static float TextToFloat(const char *text)
+{
+ float value = 0.0f;
+ float sign = 1.0f;
+
+ if ((text[0] == '+') || (text[0] == '-'))
+ {
+ if (text[0] == '-') sign = -1.0f;
+ text++;
+ }
+
+ int i = 0;
+ for (; ((text[i] >= '0') && (text[i] <= '9')); i++) value = value*10.0f + (float)(text[i] - '0');
+
+ if (text[i++] != '.') value *= sign;
+ else
+ {
+ float divisor = 10.0f;
+ for (; ((text[i] >= '0') && (text[i] <= '9')); i++)
+ {
+ value += ((float)(text[i] - '0'))/divisor;
+ divisor = divisor*10.0f;
+ }
+ }
+
+ return value;
+}
+
+// Encode codepoint into UTF-8 text (char array size returned as parameter)
+static const char *CodepointToUTF8(int codepoint, int *byteSize)
+{
+ static char utf8[6] = { 0 };
+ int size = 0;
+
+ if (codepoint <= 0x7f)
+ {
+ utf8[0] = (char)codepoint;
+ size = 1;
+ }
+ else if (codepoint <= 0x7ff)
+ {
+ utf8[0] = (char)(((codepoint >> 6) & 0x1f) | 0xc0);
+ utf8[1] = (char)((codepoint & 0x3f) | 0x80);
+ size = 2;
+ }
+ else if (codepoint <= 0xffff)
+ {
+ utf8[0] = (char)(((codepoint >> 12) & 0x0f) | 0xe0);
+ utf8[1] = (char)(((codepoint >> 6) & 0x3f) | 0x80);
+ utf8[2] = (char)((codepoint & 0x3f) | 0x80);
+ size = 3;
+ }
+ else if (codepoint <= 0x10ffff)
+ {
+ utf8[0] = (char)(((codepoint >> 18) & 0x07) | 0xf0);
+ utf8[1] = (char)(((codepoint >> 12) & 0x3f) | 0x80);
+ utf8[2] = (char)(((codepoint >> 6) & 0x3f) | 0x80);
+ utf8[3] = (char)((codepoint & 0x3f) | 0x80);
+ size = 4;
+ }
+
+ *byteSize = size;
+
+ return utf8;
+}
+
+// Get next codepoint in a UTF-8 encoded text, scanning until '\0' is found
+// When a invalid UTF-8 byte is encountered we exit as soon as possible and a '?'(0x3f) codepoint is returned
+// Total number of bytes processed are returned as a parameter
+// NOTE: the standard says U+FFFD should be returned in case of errors
+// but that character is not supported by the default font in raylib
+static int GetCodepointNext(const char *text, int *codepointSize)
+{
+ const char *ptr = text;
+ int codepoint = 0x3f; // Codepoint (defaults to '?')
+ *codepointSize = 1;
+
+ // Get current codepoint and bytes processed
+ if (0xf0 == (0xf8 & ptr[0]))
+ {
+ // 4 byte UTF-8 codepoint
+ if (((ptr[1] & 0xC0) ^ 0x80) || ((ptr[2] & 0xC0) ^ 0x80) || ((ptr[3] & 0xC0) ^ 0x80)) { return codepoint; } //10xxxxxx checks
+ codepoint = ((0x07 & ptr[0]) << 18) | ((0x3f & ptr[1]) << 12) | ((0x3f & ptr[2]) << 6) | (0x3f & ptr[3]);
+ *codepointSize = 4;
+ }
+ else if (0xe0 == (0xf0 & ptr[0]))
+ {
+ // 3 byte UTF-8 codepoint */
+ if (((ptr[1] & 0xC0) ^ 0x80) || ((ptr[2] & 0xC0) ^ 0x80)) { return codepoint; } //10xxxxxx checks
+ codepoint = ((0x0f & ptr[0]) << 12) | ((0x3f & ptr[1]) << 6) | (0x3f & ptr[2]);
+ *codepointSize = 3;
+ }
+ else if (0xc0 == (0xe0 & ptr[0]))
+ {
+ // 2 byte UTF-8 codepoint
+ if ((ptr[1] & 0xC0) ^ 0x80) { return codepoint; } //10xxxxxx checks
+ codepoint = ((0x1f & ptr[0]) << 6) | (0x3f & ptr[1]);
+ *codepointSize = 2;
+ }
+ else if (0x00 == (0x80 & ptr[0]))
+ {
+ // 1 byte UTF-8 codepoint
+ codepoint = ptr[0];
+ *codepointSize = 1;
+ }
+
+ return codepoint;
+}
+#endif // RAYGUI_STANDALONE
+
+#endif // RAYGUI_IMPLEMENTATION
diff --git a/examples/examples_list.txt b/examples/examples_list.txt
index 50643bf2b..b86a4bc02 100644
--- a/examples/examples_list.txt
+++ b/examples/examples_list.txt
@@ -47,6 +47,7 @@ core;core_high_dpi;★★☆☆;5.0;5.5;2025;2025;"Jonathan Marler";@marler8997
core;core_render_texture;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5
core;core_undo_redo;★★★☆;5.5;5.6;2025;2025;"Ramon Santamaria";@raysan5
core;core_input_actions;★★☆☆;5.5;5.6;2025;2025;"Jett";@JettMonstersGoBoom
+core;core_directory_files;★☆☆☆;5.5;5.6;2025;2025;"Hugo ARNAL";@hugoarnal
shapes;shapes_basic_shapes;★☆☆☆;1.0;4.2;2014;2025;"Ramon Santamaria";@raysan5
shapes;shapes_bouncing_ball;★☆☆☆;2.5;2.5;2013;2025;"Ramon Santamaria";@raysan5
shapes;shapes_bullet_hell;★☆☆☆;5.6;5.6;2025;2025;"Zero";@zerohorsepower
@@ -60,6 +61,7 @@ shapes;shapes_following_eyes;★★☆☆;2.5;2.5;2013;2025;"Ramon Santamaria";@
shapes;shapes_easings_ball;★★☆☆;2.5;2.5;2014;2025;"Ramon Santamaria";@raysan5
shapes;shapes_easings_box;★★☆☆;2.5;2.5;2014;2025;"Ramon Santamaria";@raysan5
shapes;shapes_easings_rectangles;★★★☆;2.0;2.5;2014;2025;"Ramon Santamaria";@raysan5
+shapes;shapes_recursive_tree;★★★☆;5.6-dev;5.6-dev;2025;2025;"Jopestpe";@jopestpe
shapes;shapes_ring_drawing;★★★☆;2.5;2.5;2018;2025;"Vlad Adrian";@demizdor
shapes;shapes_circle_sector_drawing;★★★☆;2.5;2.5;2018;2025;"Vlad Adrian";@demizdor
shapes;shapes_rounded_rectangle_drawing;★★★☆;2.5;2.5;2018;2025;"Vlad Adrian";@demizdor
@@ -69,7 +71,9 @@ shapes;shapes_splines_drawing;★★★☆;5.0;5.0;2023;2025;"Ramon Santamaria";
shapes;shapes_digital_clock;★★★★;5.5;5.6;2025;2025;"Hamza RAHAL";@hmz-rhl
shapes;shapes_double_pendulum;★★☆☆;5.5;5.5;2025;2025;"JoeCheong";@Joecheong2006
shapes;shapes_dashed_line;★☆☆☆;5.5;5.5;2025;2025;"Luís Almeida";@luis605
+shapes;shapes_triangle_strip;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Jopestpe";@jopestpe
shapes;shapes_vector_angle;★★☆☆;1.0;5.0;2023;2025;"Ramon Santamaria";@raysan5
+shapes;shapes_pie_chart;★☆☆☆;5.5;5.6;2025;2025;"Gideon Serfontein";@GideonSerf
textures;textures_logo_raylib;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
textures;textures_srcrec_dstrec;★★★☆;1.3;1.3;2015;2025;"Ramon Santamaria";@raysan5
textures;textures_image_drawing;★★☆☆;1.4;1.4;2016;2025;"Ramon Santamaria";@raysan5
@@ -106,10 +110,11 @@ text;text_input_box;★★☆☆;1.7;3.5;2017;2025;"Ramon Santamaria";@raysan5
text;text_writing_anim;★★☆☆;1.4;1.4;2016;2025;"Ramon Santamaria";@raysan5
text;text_rectangle_bounds;★★★★;2.5;4.0;2018;2025;"Vlad Adrian";@demizdor
text;text_unicode_emojis;★★★★;2.5;4.0;2019;2025;"Vlad Adrian";@demizdor
-text;text_unicode_ranges;★★★★;5.5;5.6;2025;2025;"Vlad Adrian";@demizdor
+text;text_unicode_ranges;★★★★;5.5;5.6;2025;2025;"Vadim Gunko";@GuvaCode
text;text_3d_drawing;★★★★;3.5;4.0;2021;2025;"Vlad Adrian";@demizdor
text;text_codepoints_loading;★★★☆;4.2;4.2;2022;2025;"Ramon Santamaria";@raysan5
text;text_inline_styling;★★★☆;5.6-dev;5.6-dev;2025;2025;"Wagner Barongello";@SultansOfCode
+text;text_words_alignment;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates
models;models_animation_playing;★★☆☆;2.5;3.5;2019;2025;"Culacant";@culacant
models;models_billboard_rendering;★★★☆;1.3;3.5;2015;2025;"Ramon Santamaria";@raysan5
models;models_box_collisions;★☆☆☆;1.3;3.5;2015;2025;"Ramon Santamaria";@raysan5
@@ -179,3 +184,9 @@ others;easings_testbed;★★★☆;2.5;3.0;2019;2025;"Juan Miguel López";@flas
others;raylib_opengl_interop;★★★★;3.8;4.0;2021;2025;"Stephan Soller";@arkanis
others;embedded_files_loading;★★☆☆;3.0;3.5;2020;2025;"Kristian Holmgren";@defutura
others;web_basic_window;★☆☆☆;5.6-dev;5.6-dev;2014;2025;"Ramon Santamaria";@raysan5
+shapes;shapes_kaleidoscope;★★☆☆;5.5;5.6;2025;2025;"Hugo ARNAL";@hugoarnal
+core;core_clipboard_text;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Robin";@RobinsAviary
+shapes;shapes_clock_of_clocks;★★☆☆;5.5;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates
+shapes;shapes_mouse_trail;★☆☆☆;5.6;5.6-dev;2024;2024;"[Balamurugan R]";@[Bala050814]
+shapes;shapes_simple_particles;★☆☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
+shapes;shapes_starfield;★☆☆☆;5.5;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates
diff --git a/examples/models/models_basic_voxel.c b/examples/models/models_basic_voxel.c
index 8df15d73d..a70da1822 100644
--- a/examples/models/models_basic_voxel.c
+++ b/examples/models/models_basic_voxel.c
@@ -88,7 +88,7 @@ int main(void)
if (!voxels[x][y][z]) continue; // Skip empty voxels
// Build a bounding box for this voxel
- Vector3 position = { x, y, z };
+ Vector3 position = { (float)x, (float)y, (float)z };
BoundingBox box = {
(Vector3){ position.x - 0.5f, position.y - 0.5f, position.z - 0.5f },
(Vector3){ position.x + 0.5f, position.y + 0.5f, position.z + 0.5f }
@@ -126,7 +126,7 @@ int main(void)
{
if (!voxels[x][y][z]) continue;
- Vector3 position = { x, y, z };
+ Vector3 position = { (float)x, (float)y, (float)z };
DrawModel(cubeModel, position, 1.0f, BEIGE);
DrawCubeWires(position, 1.0f, 1.0f, 1.0f, BLACK);
}
diff --git a/examples/models/models_geometry_textures_cube.c b/examples/models/models_geometry_textures_cube.c
index f8236f36d..9441c7fd4 100644
--- a/examples/models/models_geometry_textures_cube.c
+++ b/examples/models/models_geometry_textures_cube.c
@@ -40,7 +40,7 @@ int main(void)
// Load image to create texture for the cube
Model model = LoadModelFromMesh(GenMeshCube(1.0f, 1.0f, 1.0f));
Image img = LoadImage("resources/cubicmap_atlas.png");
- Image crop = ImageFromImage(img, (Rectangle){0, img.height/2, img.width/2, img.height/2});
+ Image crop = ImageFromImage(img, (Rectangle){0, img.height/2.0f, img.width/2.0f, img.height/2.0f});
Texture2D texture = LoadTextureFromImage(crop);
UnloadImage(img);
UnloadImage(crop);
diff --git a/examples/models/models_tesseract_view.c b/examples/models/models_tesseract_view.c
index 97a02ca8e..1544873fb 100644
--- a/examples/models/models_tesseract_view.c
+++ b/examples/models/models_tesseract_view.c
@@ -65,7 +65,7 @@ int main(void)
{
// Update
//----------------------------------------------------------------------------------
- rotation = DEG2RAD*45.0f*GetTime();
+ rotation = DEG2RAD*45.0f*(float)GetTime();
for (int i = 0; i < 16; i++)
{
diff --git a/examples/others/rlgl_compute_shader.c b/examples/others/rlgl_compute_shader.c
index 4704b4a7c..14a2b32cd 100644
--- a/examples/others/rlgl_compute_shader.c
+++ b/examples/others/rlgl_compute_shader.c
@@ -59,7 +59,7 @@ int main(void)
InitWindow(screenWidth, screenHeight, "raylib [others] example - compute shader");
- const Vector2 resolution = { screenWidth, screenHeight };
+ const Vector2 resolution = { (float)screenWidth, (float)screenHeight };
unsigned int brushSize = 8;
// Game of Life logic compute shader
diff --git a/examples/shaders/shaders_basic_pbr.c b/examples/shaders/shaders_basic_pbr.c
index 75dacd5aa..6fb15a607 100644
--- a/examples/shaders/shaders_basic_pbr.c
+++ b/examples/shaders/shaders_basic_pbr.c
@@ -252,7 +252,11 @@ int main()
// Draw spheres to show the lights positions
for (int i = 0; i < MAX_LIGHTS; i++)
{
- Color lightColor = (Color){ lights[i].color[0]*255, lights[i].color[1]*255, lights[i].color[2]*255, lights[i].color[3]*255 };
+ Color lightColor = (Color){
+ (unsigned char)(lights[i].color[0]*255),
+ (unsigned char)(lights[i].color[1] * 255),
+ (unsigned char)(lights[i].color[2] * 255),
+ (unsigned char)(lights[i].color[3] * 255) };
if (lights[i].enabled) DrawSphereEx(lights[i].position, 0.2f, 8, 8, lightColor);
else DrawSphereWires(lights[i].position, 0.2f, 8, 8, ColorAlpha(lightColor, 0.3f));
diff --git a/examples/shaders/shaders_lightmap_rendering.c b/examples/shaders/shaders_lightmap_rendering.c
index 232e0901b..e269aada2 100644
--- a/examples/shaders/shaders_lightmap_rendering.c
+++ b/examples/shaders/shaders_lightmap_rendering.c
@@ -102,7 +102,7 @@ int main(void)
BeginBlendMode(BLEND_ADDITIVE);
DrawTexturePro(
light,
- (Rectangle){ 0, 0, light.width, light.height },
+ (Rectangle){ 0, 0, (float)light.width, (float)light.height },
(Rectangle){ 0, 0, 20, 20 },
(Vector2){ 10.0, 10.0 },
0.0,
@@ -110,7 +110,7 @@ int main(void)
);
DrawTexturePro(
light,
- (Rectangle){ 0, 0, light.width, light.height },
+ (Rectangle){ 0, 0, (float)light.width, (float)light.height },
(Rectangle){ 8, 4, 20, 20 },
(Vector2){ 10.0, 10.0 },
0.0,
@@ -118,7 +118,7 @@ int main(void)
);
DrawTexturePro(
light,
- (Rectangle){ 0, 0, light.width, light.height },
+ (Rectangle){ 0, 0, (float)light.width, (float)light.height },
(Rectangle){ 8, 8, 10, 10 },
(Vector2){ 5.0, 5.0 },
0.0,
@@ -152,7 +152,7 @@ int main(void)
DrawTexturePro(
lightmap.texture,
(Rectangle){ 0, 0, -MAP_SIZE, -MAP_SIZE },
- (Rectangle){ GetRenderWidth() - MAP_SIZE*8 - 10, 10, MAP_SIZE*8, MAP_SIZE*8 },
+ (Rectangle){ (float)GetRenderWidth() - MAP_SIZE*8 - 10, 10, (float)MAP_SIZE*8, (float)MAP_SIZE*8 },
(Vector2){ 0.0, 0.0 },
0.0,
WHITE);
diff --git a/examples/shaders/shaders_normalmap_rendering.c b/examples/shaders/shaders_normalmap_rendering.c
index e66362c07..4859ec813 100644
--- a/examples/shaders/shaders_normalmap_rendering.c
+++ b/examples/shaders/shaders_normalmap_rendering.c
@@ -113,7 +113,7 @@ int main(void)
if (IsKeyPressed(KEY_N)) useNormalMap = !useNormalMap;
// Spin plane model at a constant rate
- plane.transform = MatrixRotateY(GetTime()*0.5f);
+ plane.transform = MatrixRotateY((float)GetTime()*0.5f);
// Update shader values
float lightPos[3] = {lightPosition.x, lightPosition.y, lightPosition.z};
diff --git a/examples/shapes/shapes_bullet_hell.c b/examples/shapes/shapes_bullet_hell.c
index 8eaddfbfe..235df4d16 100644
--- a/examples/shapes/shapes_bullet_hell.c
+++ b/examples/shapes/shapes_bullet_hell.c
@@ -68,8 +68,8 @@ int main(void)
// Draw circle to bullet texture, then draw bullet using DrawTexture()
// NOTE: This is done to improve the performance, since DrawCircle() is very slow
BeginTextureMode(bulletTexture);
- DrawCircle(12, 12, bulletRadius, WHITE);
- DrawCircleLines(12, 12, bulletRadius, BLACK);
+ DrawCircle(12, 12, (float)bulletRadius, WHITE);
+ DrawCircleLines(12, 12, (float)bulletRadius, BLACK);
EndTextureMode();
bool drawInPerformanceMode = true; // Switch between DrawCircle() and DrawTexture()
@@ -192,8 +192,8 @@ int main(void)
if (!bullets[i].disabled)
{
DrawTexture(bulletTexture.texture,
- bullets[i].position.x - bulletTexture.texture.width*0.5f,
- bullets[i].position.y - bulletTexture.texture.height*0.5f,
+ (int)(bullets[i].position.x - bulletTexture.texture.width*0.5f),
+ (int)(bullets[i].position.y - bulletTexture.texture.height*0.5f),
bullets[i].color);
}
}
@@ -206,8 +206,8 @@ int main(void)
// Do not draw disabled bullets (out of screen)
if (!bullets[i].disabled)
{
- DrawCircleV(bullets[i].position, bulletRadius, bullets[i].color);
- DrawCircleLinesV(bullets[i].position, bulletRadius, BLACK);
+ DrawCircleV(bullets[i].position, (float)bulletRadius, bullets[i].color);
+ DrawCircleLinesV(bullets[i].position, (float)bulletRadius, BLACK);
}
}
}
diff --git a/examples/shapes/shapes_clock_of_clocks.c b/examples/shapes/shapes_clock_of_clocks.c
new file mode 100644
index 000000000..493e53b5e
--- /dev/null
+++ b/examples/shapes/shapes_clock_of_clocks.c
@@ -0,0 +1,227 @@
+/*******************************************************************************************
+*
+* raylib [shapes] example - clock of clocks
+*
+* Example complexity rating: [★★☆☆] 2/4
+*
+* Example originally created with raylib 5.5, last time updated with raylib 5.6-dev
+*
+* Example contributed by JP Mortiboys (@themushroompirates) 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) 2025 JP Mortiboys (@themushroompirates)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#include "raymath.h" // Required for: Lerp()
+#include // Required for: time(), localtime()
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ SetConfigFlags(FLAG_MSAA_4X_HINT);
+ InitWindow(screenWidth, screenHeight, "raylib [shapes] example - clock of clocks");
+
+ const Color bgColor = ColorLerp(DARKBLUE, BLACK, 0.75f);
+ const Color handsColor = ColorLerp(YELLOW, RAYWHITE, .25f);
+
+ const float clockFaceSize = 24;
+ const float clockFaceSpacing = 8.0f;
+ const float sectionSpacing = 16.0f;
+
+ const Vector2 TL = (Vector2){ 0.0f, 90.0f }; // Top-left corner
+ const Vector2 TR = (Vector2){ 90.0f, 180.0f }; // Top-right corner
+ const Vector2 BR = (Vector2){ 180.0f, 270.0f }; // Bottom-right corner
+ const Vector2 BL = (Vector2){ 0.0f, 270.0f }; // Bottom-left corner
+ const Vector2 HH = (Vector2){ 0.0f, 180.0f }; // Horizontal line
+ const Vector2 VV = (Vector2){ 90.0f, 270.0f }; // Vertical line
+ const Vector2 ZZ = (Vector2){ 135.0f, 135.0f }; // Not relevant
+
+ const Vector2 digitAngles[10][24] = {
+ /* 0 */ { TL,HH,HH,TR, /* */ VV,TL,TR,VV,/* */ VV,VV,VV,VV,/* */ VV,VV,VV,VV,/* */ VV,BL,BR,VV,/* */ BL,HH,HH,BR },
+ /* 1 */ { TL,HH,TR,ZZ, /* */ BL,TR,VV,ZZ,/* */ ZZ,VV,VV,ZZ,/* */ ZZ,VV,VV,ZZ,/* */ TL,BR,BL,TR,/* */ BL,HH,HH,BR },
+ /* 2 */ { TL,HH,HH,TR, /* */ BL,HH,TR,VV,/* */ TL,HH,BR,VV,/* */ VV,TL,HH,BR,/* */ VV,BL,HH,TR,/* */ BL,HH,HH,BR },
+ /* 3 */ { TL,HH,HH,TR, /* */ BL,HH,TR,VV,/* */ TL,HH,BR,VV,/* */ BL,HH,TR,VV,/* */ TL,HH,BR,VV,/* */ BL,HH,HH,BR },
+ /* 4 */ { TL,TR,TL,TR, /* */ VV,VV,VV,VV,/* */ VV,BL,BR,VV,/* */ BL,HH,TR,VV,/* */ ZZ,ZZ,VV,VV,/* */ ZZ,ZZ,BL,BR },
+ /* 5 */ { TL,HH,HH,TR, /* */ VV,TL,HH,BR,/* */ VV,BL,HH,TR,/* */ BL,HH,TR,VV,/* */ TL,HH,BR,VV,/* */ BL,HH,HH,BR },
+ /* 6 */ { TL,HH,HH,TR, /* */ VV,TL,HH,BR,/* */ VV,BL,HH,TR,/* */ VV,TL,TR,VV,/* */ VV,BL,BR,VV,/* */ BL,HH,HH,BR },
+ /* 7 */ { TL,HH,HH,TR, /* */ BL,HH,TR,VV,/* */ ZZ,ZZ,VV,VV,/* */ ZZ,ZZ,VV,VV,/* */ ZZ,ZZ,VV,VV,/* */ ZZ,ZZ,BL,BR },
+ /* 8 */ { TL,HH,HH,TR, /* */ VV,TL,TR,VV,/* */ VV,BL,BR,VV,/* */ VV,TL,TR,VV,/* */ VV,BL,BR,VV,/* */ BL,HH,HH,BR },
+ /* 9 */ { TL,HH,HH,TR, /* */ VV,TL,TR,VV,/* */ VV,BL,BR,VV,/* */ BL,HH,TR,VV,/* */ TL,HH,BR,VV,/* */ BL,HH,HH,BR },
+ };
+ // Time for the hands to move to the new position (in seconds); this must be <1s
+ const float handsMoveDuration = .5f;
+
+ // We store the previous seconds value so we can see if the time has changed
+ int prevSeconds = -1;
+
+ // This represents the real position where the hands are right now
+ Vector2 currentAngles[6][24] = { 0 };
+
+ // This is the position where the hands were moving from
+ Vector2 srcAngles[6][24] = { 0 };
+ // This is the position where the hands are moving to
+ Vector2 dstAngles[6][24] = { 0 };
+
+ // Current animation timer
+ float handsMoveTimer = 0.0f;
+
+ // 12 or 24 hour mode
+ int hourMode = 24;
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+
+ // Get the current time
+ time_t rawtime;
+ struct tm *timeinfo;
+
+ time(&rawtime);
+ timeinfo = localtime(&rawtime);
+
+ if (timeinfo->tm_sec != prevSeconds) {
+ // The time has changed, so we need to move the hands to the new positions
+ prevSeconds = timeinfo->tm_sec;
+
+ // Format the current time so we can access the individual digits
+ const char *clockDigits = TextFormat("%02d%02d%02d", timeinfo->tm_hour % hourMode, timeinfo->tm_min, timeinfo->tm_sec);
+
+ // Fetch where we want all the hands to be
+ for (int digit = 0; digit < 6; digit++) {
+ for (int cell = 0; cell < 24; cell++) {
+ srcAngles[digit][cell] = currentAngles[digit][cell];
+ dstAngles[digit][cell] = digitAngles[ clockDigits[digit] - '0' ][cell];
+
+ // Quick exception for 12h mode
+ if (digit == 0 && hourMode == 12 && clockDigits[0] == '0') {
+ dstAngles[digit][cell] = ZZ;
+ }
+
+ if (srcAngles[digit][cell].x > dstAngles[digit][cell].x) {
+ srcAngles[digit][cell].x -= 360.0f;
+ }
+ if (srcAngles[digit][cell].y > dstAngles[digit][cell].y) {
+ srcAngles[digit][cell].y -= 360.0f;
+ }
+ }
+ }
+
+ // Reset the timer
+ handsMoveTimer = -GetFrameTime();
+ }
+
+ // Now let's animate all the hands if we need to
+ if (handsMoveTimer < handsMoveDuration) {
+ // Increase the timer but don't go above the maximum
+ handsMoveTimer = Clamp(handsMoveTimer + GetFrameTime(), 0, handsMoveDuration);
+
+ // Calculate the % completion of the animation
+ float t = handsMoveTimer / handsMoveDuration;
+
+ // A little cheeky smoothstep
+ t = t * t * (3.0f - 2.0f * t);
+
+ for (int digit = 0; digit < 6; digit++) {
+ for (int cell = 0; cell < 24; cell++) {
+ currentAngles[digit][cell].x = Lerp(srcAngles[digit][cell].x, dstAngles[digit][cell].x, t);
+ currentAngles[digit][cell].y = Lerp(srcAngles[digit][cell].y, dstAngles[digit][cell].y, t);
+ }
+ }
+
+ if (handsMoveTimer == handsMoveDuration) {
+ // The animation has now finished
+ }
+ }
+
+ // Handle input
+
+ // Toggle between 12 and 24 hour mode with space
+ if (IsKeyPressed(KEY_SPACE)) {
+ hourMode = 36 - hourMode;
+ }
+
+
+
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(bgColor);
+
+ DrawText(TextFormat("%d-h mode, space to change", hourMode), 10, 30, 20, RAYWHITE);
+
+ float xOffset = 4.0f;
+
+ for (int digit = 0; digit < 6; digit++) {
+
+ for (int row = 0; row < 6; row++) {
+ for (int col = 0; col < 4; col++) {
+ Vector2 centre = (Vector2){
+ xOffset + col*(clockFaceSize+clockFaceSpacing) + clockFaceSize * .5f,
+ 100 + row*(clockFaceSize+clockFaceSpacing) + clockFaceSize * .5f
+ };
+ DrawRing(centre, clockFaceSize * 0.5f - 2.0f, clockFaceSize * 0.5f, 0, 360, 24, DARKGRAY);
+
+ // Big hand
+ DrawRectanglePro(
+ (Rectangle){centre.x, centre.y, clockFaceSize*.5f+4.0f, 4.0f},
+ (Vector2){ 2.0f, 2.0f },
+ currentAngles[digit][row*4+col].x,
+ handsColor
+ );
+
+ // Little hand
+ DrawRectanglePro(
+ (Rectangle){centre.x, centre.y, clockFaceSize*.5f+2.0f, 4.0f},
+ (Vector2){ 2.0f, 2.0f },
+ currentAngles[digit][row*4+col].y,
+ handsColor
+ );
+ }
+ }
+
+ xOffset += (clockFaceSize+clockFaceSpacing) * 4;
+ if (digit % 2 == 1) {
+
+ DrawRing((Vector2){xOffset + 4.0f, 160.0f}, 6.0f, 8.0f, 0.0f, 360.0f, 24, handsColor);
+ DrawRing((Vector2){xOffset + 4.0f, 225.0f}, 6.0f, 8.0f, 0.0f, 360.0f, 24, handsColor);
+
+ xOffset += sectionSpacing;
+
+ }
+ }
+
+ DrawFPS(10, 10);
+
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
\ No newline at end of file
diff --git a/examples/shapes/shapes_clock_of_clocks.png b/examples/shapes/shapes_clock_of_clocks.png
new file mode 100644
index 000000000..fb91d7263
Binary files /dev/null and b/examples/shapes/shapes_clock_of_clocks.png differ
diff --git a/examples/shapes/shapes_dashed_line.c b/examples/shapes/shapes_dashed_line.c
index 7a6bf3eee..2a11bf64a 100644
--- a/examples/shapes/shapes_dashed_line.c
+++ b/examples/shapes/shapes_dashed_line.c
@@ -68,7 +68,7 @@ int main(void)
ClearBackground(RAYWHITE);
// Draw the dashed line with the current properties
- DrawLineDashed(lineStartPosition, lineEndPosition, dashLength, blankLength, lineColors[colorIndex]);
+ DrawLineDashed(lineStartPosition, lineEndPosition, (int)dashLength, (int)blankLength, lineColors[colorIndex]);
// Draw UI and Instructions
DrawRectangle(5, 5, 265, 95, Fade(SKYBLUE, 0.5f));
diff --git a/examples/shapes/shapes_digital_clock.c b/examples/shapes/shapes_digital_clock.c
index 3317202b8..77b020704 100644
--- a/examples/shapes/shapes_digital_clock.c
+++ b/examples/shapes/shapes_digital_clock.c
@@ -15,6 +15,8 @@
*
********************************************************************************************/
+#define _CRT_SECURE_NO_WARNINGS // Disable some Visual Studio warnings
+
#include "raylib.h"
#include // Required for: cosf(), sinf()
@@ -158,7 +160,7 @@ static void UpdateClock(Clock *clock)
clock->minute.value = timeinfo->tm_min;
clock->hour.value = timeinfo->tm_hour;
- clock->hour.angle = (timeinfo->tm_hour%12)*180.0/6.0f;
+ clock->hour.angle = (timeinfo->tm_hour%12)*180.0f/6.0f;
clock->hour.angle += (timeinfo->tm_min%60)*30/60.0f;
clock->hour.angle -= 90;
@@ -175,8 +177,8 @@ static void UpdateClock(Clock *clock)
static void DrawClockAnalog(Clock clock, Vector2 position)
{
// Draw clock base
- DrawCircleV(position, clock.second.length + 40, LIGHTGRAY);
- DrawCircleV(position, 12, GRAY);
+ DrawCircleV(position, clock.second.length + 40.0f, LIGHTGRAY);
+ DrawCircleV(position, 12.0f, GRAY);
// Draw clock minutes/seconds lines
for (int i = 0; i < 60; i++)
@@ -192,15 +194,15 @@ static void DrawClockAnalog(Clock clock, Vector2 position)
}
// Draw hand seconds
- DrawRectanglePro((Rectangle){ position.x, position.y, clock.second.length, clock.second.thickness },
+ DrawRectanglePro((Rectangle){ position.x, position.y, (float)clock.second.length, (float)clock.second.thickness },
(Vector2){ 0.0f, clock.second.thickness/2.0f }, clock.second.angle, clock.second.color);
// Draw hand minutes
- DrawRectanglePro((Rectangle){ position.x, position.y, clock.minute.length, clock.minute.thickness },
+ DrawRectanglePro((Rectangle){ position.x, position.y, (float)clock.minute.length, (float)clock.minute.thickness },
(Vector2){ 0.0f, clock.minute.thickness/2.0f }, clock.minute.angle, clock.minute.color);
// Draw hand hours
- DrawRectanglePro((Rectangle){ position.x, position.y, clock.hour.length, clock.hour.thickness },
+ DrawRectanglePro((Rectangle){ position.x, position.y, (float)clock.hour.length, (float)clock.hour.thickness },
(Vector2){ 0.0f, clock.hour.thickness/2.0f }, clock.hour.angle, clock.hour.color);
}
@@ -212,14 +214,14 @@ static void DrawClockDigital(Clock clock, Vector2 position)
DrawDisplayValue((Vector2){ position.x, position.y }, clock.hour.value/10, RED, Fade(LIGHTGRAY, 0.3f));
DrawDisplayValue((Vector2){ position.x + 120, position.y }, clock.hour.value%10, RED, Fade(LIGHTGRAY, 0.3f));
- DrawCircle(position.x + 240, position.y + 70, 12, (clock.second.value%2)? RED : Fade(LIGHTGRAY, 0.3f));
- DrawCircle(position.x + 240, position.y + 150, 12, (clock.second.value%2)? RED : Fade(LIGHTGRAY, 0.3f));
+ DrawCircle((int)position.x + 240, (int)position.y + 70, 12, (clock.second.value%2)? RED : Fade(LIGHTGRAY, 0.3f));
+ DrawCircle((int)position.x + 240, (int)position.y + 150, 12, (clock.second.value%2)? RED : Fade(LIGHTGRAY, 0.3f));
DrawDisplayValue((Vector2){ position.x + 260, position.y }, clock.minute.value/10, RED, Fade(LIGHTGRAY, 0.3f));
DrawDisplayValue((Vector2){ position.x + 380, position.y }, clock.minute.value%10, RED, Fade(LIGHTGRAY, 0.3f));
- DrawCircle(position.x + 500, position.y + 70, 12, (clock.second.value%2)? RED : Fade(LIGHTGRAY, 0.3f));
- DrawCircle(position.x + 500, position.y + 150, 12, (clock.second.value%2)? RED : Fade(LIGHTGRAY, 0.3f));
+ DrawCircle((int)position.x + 500, (int)position.y + 70, 12, (clock.second.value%2)? RED : Fade(LIGHTGRAY, 0.3f));
+ DrawCircle((int)position.x + 500, (int)position.y + 150, 12, (clock.second.value%2)? RED : Fade(LIGHTGRAY, 0.3f));
DrawDisplayValue((Vector2){ position.x + 520, position.y }, clock.second.value/10, RED, Fade(LIGHTGRAY, 0.3f));
DrawDisplayValue((Vector2){ position.x + 640, position.y }, clock.second.value%10, RED, Fade(LIGHTGRAY, 0.3f));
diff --git a/examples/shapes/shapes_double_pendulum.c b/examples/shapes/shapes_double_pendulum.c
index 200f9ad7e..4bcac02f9 100644
--- a/examples/shapes/shapes_double_pendulum.c
+++ b/examples/shapes/shapes_double_pendulum.c
@@ -21,7 +21,7 @@
// Constant for Simulation
#define SIMULATION_STEPS 30
-#define G 9.81
+#define G 9.81f
//----------------------------------------------------------------------------------
// Module Functions Declaration
@@ -43,9 +43,9 @@ int main(void)
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - double pendulum");
// Simulation Paramters
- float l1 = 15, m1 = 0.2, theta1 = DEG2RAD*170, w1 = 0;
- float l2 = 15, m2 = 0.1, theta2 = DEG2RAD*0, w2 = 0;
- float lengthScaler = 0.1;
+ float l1 = 15.0f, m1 = 0.2f, theta1 = DEG2RAD*170, w1 = 0;
+ float l2 = 15.0f, m2 = 0.1f, theta2 = DEG2RAD*0, w2 = 0;
+ float lengthScaler = 0.1f;
float totalM = m1 + m2;
Vector2 previousPosition = CalculateDoublePendulumEndPoint(l1, theta1, l2, theta2);
@@ -57,8 +57,8 @@ int main(void)
float L2 = l2*lengthScaler;
// Draw parameters
- int lineThick = 20, trailThick = 2;
- float fateAlpha = 0.01;
+ float lineThick = 20, trailThick = 2;
+ float fateAlpha = 0.01f;
// Create framebuffer
RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight);
@@ -129,15 +129,15 @@ int main(void)
ClearBackground(BLACK);
// Draw trails texture
- DrawTextureRec(target.texture, (Rectangle){ 0, 0, target.texture.width, -target.texture.height }, (Vector2){ 0, 0 }, WHITE);
+ DrawTextureRec(target.texture, (Rectangle){ 0, 0, (float)target.texture.width, (float)-target.texture.height }, (Vector2){ 0, 0 }, WHITE);
// Draw double pendulum
- DrawRectanglePro((Rectangle){ screenWidth/2, screenHeight/2 - 100, 10*l1, lineThick },
- (Vector2){0, lineThick*0.5}, 90 - RAD2DEG*theta1, RAYWHITE);
+ DrawRectanglePro((Rectangle){ screenWidth/2.0f, screenHeight/2.0f - 100, 10*l1, lineThick },
+ (Vector2){0, lineThick*0.5f}, 90 - RAD2DEG*theta1, RAYWHITE);
Vector2 endpoint1 = CalculatePendulumEndPoint(l1, theta1);
- DrawRectanglePro((Rectangle){ screenWidth/2 + endpoint1.x, screenHeight/2 - 100 + endpoint1.y, 10*l2, lineThick },
- (Vector2){0, lineThick*0.5}, 90 - RAD2DEG*theta2, RAYWHITE);
+ DrawRectanglePro((Rectangle){ screenWidth/2.0f + endpoint1.x, screenHeight/2.0f - 100 + endpoint1.y, 10*l2, lineThick },
+ (Vector2){0, lineThick*0.5f}, 90 - RAD2DEG*theta2, RAYWHITE);
EndDrawing();
//----------------------------------------------------------------------------------
@@ -159,7 +159,7 @@ int main(void)
// Calculate pendulum end point
static Vector2 CalculatePendulumEndPoint(float l, float theta)
{
- return (Vector2){ 10*l*sin(theta), 10*l*cos(theta) };
+ return (Vector2){ 10*l*sinf(theta), 10*l*cosf(theta) };
}
// Calculate double pendulum end point
diff --git a/examples/shapes/shapes_kaleidoscope.c b/examples/shapes/shapes_kaleidoscope.c
new file mode 100644
index 000000000..07c96344c
--- /dev/null
+++ b/examples/shapes/shapes_kaleidoscope.c
@@ -0,0 +1,92 @@
+/*******************************************************************************************
+*
+* raylib [shapes] example - kaleidoscope
+*
+* Example complexity rating: [★★☆☆] 2/4
+*
+* Example originally created with raylib 5.5, last time updated with raylib 5.6
+*
+* Example contributed by Hugo ARNAL (@hugoarnal) 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) 2025 Hugo ARNAL (@hugoarnal)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+#include "raymath.h"
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [shapes] example - kaleidoscope");
+
+ int symmetry = 6;
+ float angle = 360.0f/(float)symmetry;
+ float thickness = 3.0f;
+ Vector2 prevMousePos = { 0 };
+
+ SetTargetFPS(60);
+ ClearBackground(BLACK);
+
+ Vector2 offset = { (float)screenWidth/2.0f, (float)screenHeight/2.0f };
+ Camera2D camera = { 0 };
+ camera.target = (Vector2){ 0 };
+ camera.offset = offset;
+ camera.rotation = 0.0f;
+ camera.zoom = 1.0f;
+
+ Vector2 scaleVector = { 1.0f, -1.0f };
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ Vector2 mousePos = GetMousePosition();
+ Vector2 lineStart = Vector2Subtract(mousePos, offset);
+ Vector2 lineEnd = Vector2Subtract(prevMousePos, offset);
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+ BeginMode2D(camera);
+ if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) {
+ for (int i = 0; i < symmetry; i++) {
+ lineStart = Vector2Rotate(lineStart, angle*DEG2RAD);
+ lineEnd = Vector2Rotate(lineEnd, angle*DEG2RAD);
+
+ DrawLineEx(lineStart, lineEnd, thickness, WHITE);
+
+ Vector2 reflectLineStart = Vector2Multiply(lineStart, scaleVector);
+ Vector2 reflectLineEnd = Vector2Multiply(lineEnd, scaleVector);
+
+ DrawLineEx(reflectLineStart, reflectLineEnd, thickness, WHITE);
+ }
+ }
+
+ prevMousePos = mousePos;
+ EndMode2D();
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
diff --git a/examples/shapes/shapes_kaleidoscope.png b/examples/shapes/shapes_kaleidoscope.png
new file mode 100644
index 000000000..d14571ab7
Binary files /dev/null and b/examples/shapes/shapes_kaleidoscope.png differ
diff --git a/examples/shapes/shapes_mouse_trail.c b/examples/shapes/shapes_mouse_trail.c
new file mode 100644
index 000000000..88a7c0ce5
--- /dev/null
+++ b/examples/shapes/shapes_mouse_trail.c
@@ -0,0 +1,106 @@
+#include "raylib.h"
+#include "raymath.h"
+
+/*******************************************************************************************
+*
+* raylib [shapes] example - Draw a mouse trail (position history)
+*
+* Example complexity rating: [★☆☆☆] 1/4
+*
+* Example originally created with raylib 5.6
+*
+* Example contributed by [Balamurugan R] (@[Bala050814]]) and reviewed by [Ray] (@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 [Balamurugan R] (@[Bala050814])
+*
+********************************************************************************************/
+
+// Define the maximum number of positions to store in the trail
+#define MAX_TRAIL_LENGTH 30
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [shapes] example - mouse trail");
+
+ // Array to store the history of mouse positions (our fixed-size queue)
+ Vector2 trailPositions[MAX_TRAIL_LENGTH] = { 0 };
+
+ SetTargetFPS(60);
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ Vector2 mousePosition = GetMousePosition();
+
+ // 1. Shift all existing positions backward by one slot in the array
+ // The last element (the oldest position) is dropped.
+ for (int i = MAX_TRAIL_LENGTH - 1; i > 0; i--)
+ {
+ trailPositions[i] = trailPositions[i - 1];
+ }
+
+ // 2. Store the new, current mouse position at the start of the array (Index 0)
+ trailPositions[0] = mousePosition;
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ // Use BLACK for a darker background to make the colored trail pop
+ ClearBackground(BLACK);
+
+ // 3. Draw the trail by looping through the history array
+ for (int i = 0; i < MAX_TRAIL_LENGTH; i++)
+ {
+ // Ensure we skip drawing if the array hasn't been fully filled on startup
+ if (trailPositions[i].x != 0.0f || trailPositions[i].y != 0.0f)
+ {
+ // Calculate relative trail strength (ratio is near 1.0 for new, near 0.0 for old)
+ float ratio = (float)(MAX_TRAIL_LENGTH - i) / MAX_TRAIL_LENGTH;
+
+ // Fade effect: oldest positions are more transparent
+ // Fade (color, alpha) - alpha is 0.5 to 1.0 based on ratio
+ Color trailColor = Fade(SKYBLUE, ratio * 0.5f + 0.5f);
+
+ // Size effect: oldest positions are smaller
+ float trailRadius = 15.0f * ratio;
+
+ DrawCircleV(trailPositions[i], trailRadius, trailColor);
+ }
+ }
+
+ // Draw a distinct white circle for the current mouse position (Index 0)
+ DrawCircleV(mousePosition, 15.0f, WHITE);
+
+ DrawText("Move the mouse to see the trail effect!",
+ 10, screenHeight - 30, 20, LIGHTGRAY);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+
+ // No resources loaded, nothing to unload.
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
\ No newline at end of file
diff --git a/examples/shapes/shapes_mouse_trail.png b/examples/shapes/shapes_mouse_trail.png
new file mode 100644
index 000000000..aa64efcdf
Binary files /dev/null and b/examples/shapes/shapes_mouse_trail.png differ
diff --git a/examples/shapes/shapes_pie_chart.c b/examples/shapes/shapes_pie_chart.c
new file mode 100644
index 000000000..35250c5be
--- /dev/null
+++ b/examples/shapes/shapes_pie_chart.c
@@ -0,0 +1,224 @@
+/*******************************************************************************************
+*
+* raylib [shapes] example - pie chart
+*
+* Example complexity rating: [★☆☆☆] 1/4
+*
+* Example originally created with raylib 5.5, last time updated with raylib 5.6
+*
+* Example contributed by Gideon Serfontein (@GideonSerf) 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) 2025 Gideon Serfontein (@GideonSerf)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+#include
+#include
+
+#define RAYGUI_IMPLEMENTATION
+#include "raygui.h"
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [shapes] example - pie chart");
+
+ #define MAX_SLICES 10
+ int sliceCount = 7;
+ float values[MAX_SLICES] = {300.0f, 100.0f, 450.0f, 350.0f, 600.0f, 380.0f, 750.0f}; //initial slice values
+ char labels[MAX_SLICES][32];
+ bool editingLabel[MAX_SLICES] = {false};
+
+ for (int i = 0; i < MAX_SLICES; i++)
+ snprintf(labels[i], 32, "Slice %i", i + 1);
+
+ bool showValues = true;
+ bool showPercentages = false;
+ int hoveredSlice = -1;
+ Rectangle scrollPanelBounds = {0};
+ Vector2 scrollContentOffset = {0};
+ Rectangle view = {0};
+
+ SetTargetFPS(60);
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose())
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ //UI layout parameters
+ const int panelWidth = 270;
+ const int panelMargin = 5;
+
+ // UI Panel top-left anchor
+ const Vector2 panelPos = {
+ (float)screenWidth - panelMargin - panelWidth,
+ (float)panelMargin
+ };
+
+ // UI Panel rectangle
+ const Rectangle panelRect = {
+ panelPos.x, panelPos.y,
+ (float)panelWidth,
+ (float)screenHeight - 2.0f*panelMargin
+ };
+
+ // Pie chart geometry
+ const Rectangle canvas = { 0, 0, panelPos.x, (float)screenHeight };
+ const Vector2 center = {canvas.width / 2.0f, canvas.height / 2.0f};
+ const float radius = 205.0f;
+
+ // Calculate total value for percentage calculations
+ float totalValue = 0.0f;
+ for (int i = 0; i < sliceCount; i++)
+ totalValue += values[i];
+
+ // Check for mouse hover over slices
+ hoveredSlice = -1; // Reset hovered slice
+ Vector2 mousePos = GetMousePosition();
+ if (CheckCollisionPointRec(mousePos, canvas)) // Only check if mouse is inside the canvas
+ {
+ float dx = mousePos.x - center.x;
+ float dy = mousePos.y - center.y;
+ float distance = sqrtf(dx * dx + dy * dy);
+
+ if (distance <= radius) // Inside the pie radius
+ {
+ float angle = atan2f(dy, dx) * RAD2DEG;
+ if (angle < 0)
+ angle += 360;
+
+ float currentAngle = 0.0f;
+ for (int i = 0; i < sliceCount; i++)
+ {
+ float sweep = (totalValue > 0) ? (values[i] / totalValue) * 360.0f : 0.0f;
+ if (angle >= currentAngle && angle < (currentAngle + sweep))
+ {
+ hoveredSlice = i;
+ break;
+ }
+ currentAngle += sweep;
+ }
+ }
+ }
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+ ClearBackground(RAYWHITE);
+
+ // Draw the pie chart on the canvas
+ //------------------------------------------------------------------------------
+ float startAngle = 0.0f;
+ for (int i = 0; i < sliceCount; i++)
+ {
+ float sweepAngle = (totalValue > 0) ? (values[i] / totalValue) * 360.0f : 0.0f;
+ float midAngle = startAngle + sweepAngle / 2.0f; // Middle angle for label positioning
+
+ Color color = ColorFromHSV((float)i / sliceCount * 360.0f, 0.75f, 0.9f);
+ float currentRadius = radius;
+
+ // Make the hovered slice pop out by adding 5 pixels to its radius
+ if (i == hoveredSlice)
+ currentRadius += 5.0f;
+
+ // Draw the pie slice using raylib's DrawCircleSector function
+ DrawCircleSector(center, currentRadius, startAngle, startAngle + sweepAngle, 120, color);
+
+ // Draw the label for the current slice
+ if (values[i] > 0)
+ {
+ char labelText[64];
+ if (showValues && showPercentages)
+ snprintf(labelText, 64, "%.1f (%.0f%%)", values[i], (values[i] / totalValue) * 100.0f);
+ else if (showValues)
+ snprintf(labelText, 64, "%.1f", values[i]);
+ else if (showPercentages)
+ snprintf(labelText, 64, "%.0f%%", (values[i] / totalValue) * 100.0f);
+ else
+ labelText[0] = '\0';
+
+ Vector2 textSize = MeasureTextEx(GetFontDefault(), labelText, 18, 1);
+ float labelRadius = radius * 0.7f;
+ Vector2 labelPos = {
+ center.x + cosf(midAngle * DEG2RAD) * labelRadius - textSize.x / 2,
+ center.y + sinf(midAngle * DEG2RAD) * labelRadius - textSize.y / 2};
+ DrawText(labelText, (int)labelPos.x, (int)labelPos.y, 18, WHITE);
+ }
+
+ startAngle += sweepAngle;
+ }
+ //------------------------------------------------------------------------------
+
+ // UI control panel
+ //------------------------------------------------------------------------------
+ DrawRectangleRec(panelRect, Fade(LIGHTGRAY, 0.5f));
+ DrawRectangleLinesEx(panelRect, 1.0f, GRAY);
+
+ int currentY = (int)panelPos.y + 12; // Start a bit lower for margin
+
+ GuiSpinner((Rectangle){ panelPos.x + 95, (float)currentY, 125, 25 }, "Slices ", &sliceCount, 1, MAX_SLICES, false);
+ currentY += 40;
+
+ GuiCheckBox((Rectangle){ panelPos.x + 20, (float)currentY, 20, 20 }, "Show Values", &showValues);
+ currentY += 30;
+
+ GuiCheckBox((Rectangle){ panelPos.x + 20, (float)currentY, 20, 20 }, "Show Percentages", &showPercentages);
+ currentY += 40;
+
+ GuiLine((Rectangle){ panelPos.x + 10, (float)currentY, panelRect.width - 20, 1 }, NULL);
+ currentY += 20;
+
+ // Scrollable area for slice editors
+ scrollPanelBounds = (Rectangle){ panelPos.x+panelMargin, (float)currentY, panelRect.width-panelMargin*2, panelRect.y + panelRect.height - currentY - panelMargin };
+ int contentHeight = sliceCount * 35;
+
+ GuiScrollPanel(scrollPanelBounds, NULL,
+ (Rectangle){ 0, 0, panelRect.width - 20, (float)contentHeight },
+ &scrollContentOffset, &view);
+
+ const float contentX = view.x + scrollContentOffset.x; // left of content
+ const float contentY = view.y + scrollContentOffset.y; // top of content
+
+ BeginScissorMode((int)view.x, (int)view.y, (int)view.width, (int)view.height);
+ for (int i = 0; i < sliceCount; i++)
+ {
+ const int rowY = (int)(contentY + 5 + i * 35);
+
+ // Color indicator
+ Color color = ColorFromHSV((float)i / sliceCount * 360.0f, 0.75f, 0.9f);
+ DrawRectangle((int)(contentX + 15), rowY + 5, 20, 20, color);
+
+ // Label textbox
+ if (GuiTextBox((Rectangle){contentX + 45, (float)rowY, 75, 30}, labels[i], 32, editingLabel[i]))
+ editingLabel[i] = !editingLabel[i];
+
+ GuiSliderBar((Rectangle){contentX + 130, (float)rowY, 110, 30},
+ NULL, NULL, &values[i], 0.0f, 1000.0f);
+ }
+ EndScissorMode();
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
\ No newline at end of file
diff --git a/examples/shapes/shapes_pie_chart.png b/examples/shapes/shapes_pie_chart.png
new file mode 100644
index 000000000..bad7960f4
Binary files /dev/null and b/examples/shapes/shapes_pie_chart.png differ
diff --git a/examples/shapes/shapes_recursive_tree.c b/examples/shapes/shapes_recursive_tree.c
new file mode 100644
index 000000000..4d0042419
--- /dev/null
+++ b/examples/shapes/shapes_recursive_tree.c
@@ -0,0 +1,141 @@
+/*******************************************************************************************
+*
+* raylib [shapes] example - recursive tree
+*
+* Example complexity rating: [★★★☆] 3/4
+*
+* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
+*
+* Example contributed by Jopestpe (@jopestpe)
+*
+* 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) 2025 Jopestpe (@jopestpe)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+#include
+
+#define RAYGUI_IMPLEMENTATION
+#include "raygui.h" // Required for GUI controls
+
+//----------------------------------------------------------------------------------
+// Types and Structures Definition
+//----------------------------------------------------------------------------------
+typedef struct {
+ Vector2 start;
+ Vector2 end;
+ float angle;
+ float length;
+} Branch;
+
+//----------------------------------------------------------------------------------
+// Module Functions Declaration
+//----------------------------------------------------------------------------------
+static Vector2 CalculateBranchEnd(Vector2 start, float angle, float length);
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [shapes] example - recursive tree");
+
+ Vector2 start = { (screenWidth/2.0f) - 125.0f, (float)screenHeight };
+ float angle = 40.0f;
+ float thick = 1.0f;
+ float treeDepth = 10.0f;
+ float branchDecay = 0.66f;
+ float length = 120.0f;
+ bool bezier = false;
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+
+ float theta = angle*DEG2RAD;
+ int maxBranches = (int)(powf(2, floorf(treeDepth)));
+ Branch branches[1024] = { 0 };
+ int count = 0;
+
+ Vector2 initialEnd = CalculateBranchEnd(start, 0.0f, length);
+ branches[count++] = (Branch){start, initialEnd, 0.0f, length};
+
+ for (int i = 0; i < count; i++)
+ {
+ Branch branch = branches[i];
+ if (branch.length < 2) continue;
+
+ float nextLength = branch.length*branchDecay;
+
+ if (count < maxBranches && nextLength >= 2)
+ {
+ Vector2 branchStart = branch.end;
+
+ Vector2 branchEnd1 = CalculateBranchEnd(branchStart, branch.angle + theta, nextLength);
+ Vector2 branchEnd2 = CalculateBranchEnd(branchStart, branch.angle - theta, nextLength);
+
+ branches[count++] = (Branch){branchStart, branchEnd1, branch.angle + theta, nextLength};
+ branches[count++] = (Branch){branchStart, branchEnd2, branch.angle - theta, nextLength};
+ }
+ }
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ for (int i = 0; i < count; i++)
+ {
+ Branch branch = branches[i];
+ if (branch.length >= 2)
+ {
+ if (!bezier) DrawLineEx(branch.start, branch.end, thick, RED);
+ else DrawLineBezier(branch.start, branch.end, thick, RED);
+ }
+ }
+
+ DrawLine(580, 0, 580, GetScreenHeight(), (Color){ 218, 218, 218, 255 });
+ DrawRectangle(580, 0, GetScreenWidth(), GetScreenHeight(), (Color){ 232, 232, 232, 255 });
+
+ // Draw GUI controls
+ //------------------------------------------------------------------------------
+ GuiSliderBar((Rectangle){ 640, 40, 120, 20}, "Angle", TextFormat("%.0f", angle), &angle, 0, 180);
+ GuiSliderBar((Rectangle){ 640, 70, 120, 20 }, "Length", TextFormat("%.0f", length), &length, 12.0f, 240.0f);
+ GuiSliderBar((Rectangle){ 640, 100, 120, 20}, "Decay", TextFormat("%.2f", branchDecay), &branchDecay, 0.1f, 0.78f);
+ GuiSliderBar((Rectangle){ 640, 130, 120, 20 }, "Depth", TextFormat("%.0f", treeDepth), &treeDepth, 1.0f, 10.f);
+ GuiSliderBar((Rectangle){ 640, 160, 120, 20}, "Thick", TextFormat("%.0f", thick), &thick, 1, 8);
+ GuiCheckBox((Rectangle){ 640, 190, 20, 20 }, "Bezier", &bezier);
+ //------------------------------------------------------------------------------
+
+ DrawFPS(10, 10);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
+
+static Vector2 CalculateBranchEnd(Vector2 start, float angle, float length)
+{
+ return (Vector2){ start.x + length*sinf(angle), start.y - length*cosf(angle) };
+}
\ No newline at end of file
diff --git a/examples/shapes/shapes_recursive_tree.png b/examples/shapes/shapes_recursive_tree.png
new file mode 100644
index 000000000..88932c204
Binary files /dev/null and b/examples/shapes/shapes_recursive_tree.png differ
diff --git a/examples/shapes/shapes_simple_particles.c b/examples/shapes/shapes_simple_particles.c
new file mode 100644
index 000000000..5bef0917a
--- /dev/null
+++ b/examples/shapes/shapes_simple_particles.c
@@ -0,0 +1,276 @@
+/*******************************************************************************************
+*
+* raylib [shapes] example - simple particles
+*
+* Example complexity rating: [★☆☆☆] 1/4
+*
+* Example originally created with raylib 5.6, last time updated with raylib 5.6
+*
+* Example contributed by Jordi Santonja (@JordSant)
+*
+* 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) 2025 Jordi Santonja (@JordSant)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#include // Required for: calloc(), free()
+#include // Required for: cosf(), sinf()
+
+#define MAX_PARTICLES 3000 // Max number particles
+
+//----------------------------------------------------------------------------------
+// Types and Structures Definition
+//----------------------------------------------------------------------------------
+typedef enum ParticleType {
+ WATER = 0,
+ SMOKE,
+ FIRE
+} ParticleType;
+
+static const char particleTypeNames[3][10] = { "WATER", "SMOKE", "FIRE" };
+
+typedef struct Particle {
+ ParticleType type; // Particle type (WATER, SMOKE, FIRE)
+ Vector2 position; // Particle position on screen
+ Vector2 velocity; // Particle current speed and direction
+ float radius; // Particle radius
+ Color color; // Particle color
+
+ float lifeTime; // Particle life time
+ bool alive; // Particle alive: inside screen and life time
+} Particle;
+
+typedef struct CircularBuffer {
+ int head; // Index for the next write
+ int tail; // Index for the next read
+ Particle *buffer; // Particle buffer array
+} CircularBuffer;
+
+//----------------------------------------------------------------------------------
+// Module Functions Declaration
+//----------------------------------------------------------------------------------
+static void EmitParticle(CircularBuffer *circularBuffer, Vector2 emitterPosition, ParticleType type);
+static Particle *AddToCircularBuffer(CircularBuffer *circularBuffer);
+static void UpdateParticles(CircularBuffer *circularBuffer, int screenWidth, int screenHeight);
+static void UpdateCircularBuffer(CircularBuffer *circularBuffer);
+static void DrawParticles(CircularBuffer *circularBuffer);
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [shapes] example - simple particles");
+
+ // Definition of particles
+ Particle *particles = (Particle*)RL_CALLOC(MAX_PARTICLES, sizeof(Particle)); // Particle array
+ CircularBuffer circularBuffer = { 0, 0, particles };
+
+ // Particle emitter parameters
+ int emissionRate = -2; // Negative: on average every -X frames. Positive: particles per frame
+ ParticleType currentType = WATER;
+ Vector2 emitterPosition = { screenWidth/2.0f, screenHeight/2.0f };
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ // Emit new particles: when emissionRate is 1, emit every frame
+ if (emissionRate < 0)
+ {
+ if (rand()%(-emissionRate) == 0) EmitParticle(&circularBuffer, emitterPosition, currentType);
+ }
+ else
+ {
+ for (int i = 0; i <= emissionRate; ++i) EmitParticle(&circularBuffer, emitterPosition, currentType);
+ }
+
+ // Update the parameters of each particle
+ UpdateParticles(&circularBuffer, screenWidth, screenHeight);
+ // Remove dead particles from the circular buffer
+ UpdateCircularBuffer(&circularBuffer);
+
+ // Change Particle Emission Rate (UP/DOWN arrows)
+ if (IsKeyPressed(KEY_UP)) emissionRate++;
+ if (IsKeyPressed(KEY_DOWN)) emissionRate--;
+
+ // Change Particle Type (LEFT/RIGHT arrows)
+ if (IsKeyPressed(KEY_RIGHT)) (currentType == FIRE)? (currentType = WATER) : currentType++;
+ if (IsKeyPressed(KEY_LEFT)) (currentType == WATER)? (currentType = FIRE) : currentType--;
+
+ if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) emitterPosition = GetMousePosition();
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ // Call the function with a loop to draw all particles
+ DrawParticles(&circularBuffer);
+
+ // Draw UI and Instructions
+ DrawRectangle(5, 5, 315, 75, Fade(SKYBLUE, 0.5f));
+ DrawRectangleLines(5, 5, 315, 75, BLUE);
+
+ DrawText("CONTROLS:", 15, 15, 10, BLACK);
+ DrawText("UP/DOWN: Change Particle Emission Rate", 15, 35, 10, BLACK);
+ DrawText("LEFT/RIGHT: Change Particle Type (Water, Smoke, Fire)", 15, 55, 10, BLACK);
+
+ if (emissionRate < 0) DrawText(TextFormat("Particles every %d frames | Type: %s", -emissionRate, particleTypeNames[currentType]), 15, 95, 10, DARKGRAY);
+ else DrawText(TextFormat("%d Particles per frame | Type: %s", emissionRate + 1, particleTypeNames[currentType]), 15, 95, 10, DARKGRAY);
+
+ DrawFPS(screenWidth - 80, 10);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ RL_FREE(particles); // Free particles array data
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
+
+//----------------------------------------------------------------------------------
+// Module Functions Definition
+//----------------------------------------------------------------------------------
+static void EmitParticle(CircularBuffer *circularBuffer, Vector2 emitterPosition, ParticleType type)
+{
+ Particle *newParticle = AddToCircularBuffer(circularBuffer);
+
+ // If buffer is full, newParticle is NULL
+ if (newParticle != NULL)
+ {
+ // Fill particle properties
+ newParticle->position = emitterPosition;
+ newParticle->alive = true;
+ newParticle->lifeTime = 0.0f;
+ newParticle->type = type;
+ float speed = (float)(rand()%10)/5.0f;
+ switch (type)
+ {
+ case WATER:
+ {
+ newParticle->radius = 5.0f;
+ newParticle->color = BLUE;
+ } break;
+ case SMOKE:
+ {
+ newParticle->radius = 7.0f;
+ newParticle->color = GRAY;
+ } break;
+ case FIRE:
+ {
+ newParticle->radius = 10.0f;
+ newParticle->color = YELLOW;
+ speed /= 10.0f;
+ } break;
+ default: break;
+ }
+
+ float direction = (float)(rand()%360);
+ newParticle->velocity = (Vector2){ speed*cosf(direction*DEG2RAD), speed*sinf(direction*DEG2RAD) };
+ }
+}
+
+static Particle *AddToCircularBuffer(CircularBuffer *circularBuffer)
+{
+ Particle *particle = NULL;
+
+ // Check if buffer full
+ if (((circularBuffer->head + 1)%MAX_PARTICLES) != circularBuffer->tail)
+ {
+ // Add new particle to the head position and advance head
+ particle = &circularBuffer->buffer[circularBuffer->head];
+ circularBuffer->head = (circularBuffer->head + 1)%MAX_PARTICLES;
+ }
+
+ return particle;
+}
+
+static void UpdateParticles(CircularBuffer *circularBuffer, int screenWidth, int screenHeight)
+{
+ for (int i = circularBuffer->tail; i != circularBuffer->head; i = (i + 1)%MAX_PARTICLES)
+ {
+ // Update particle life and positions
+ circularBuffer->buffer[i].lifeTime += 1.0f/60.0f; // 60 FPS -> 1/60 seconds per frame
+
+ switch (circularBuffer->buffer[i].type)
+ {
+ case WATER:
+ circularBuffer->buffer[i].position.x += circularBuffer->buffer[i].velocity.x;
+ circularBuffer->buffer[i].velocity.y += 0.2f; // Gravity
+ circularBuffer->buffer[i].position.y += circularBuffer->buffer[i].velocity.y;
+ break;
+ case SMOKE:
+ circularBuffer->buffer[i].position.x += circularBuffer->buffer[i].velocity.x;
+ circularBuffer->buffer[i].velocity.y -= 0.05f; // Upwards
+ circularBuffer->buffer[i].position.y += circularBuffer->buffer[i].velocity.y;
+ circularBuffer->buffer[i].radius += 0.5f; // Increment radius: smoke expands
+ circularBuffer->buffer[i].color.a -= 4; // Decrement alpha: smoke fades
+ if (circularBuffer->buffer[i].color.a < 4) // If alpha transparent, particle dies
+ circularBuffer->buffer[i].alive = false;
+ break;
+ case FIRE:
+ // Add a little horizontal oscillation to fire particles
+ circularBuffer->buffer[i].position.x += circularBuffer->buffer[i].velocity.x + cosf(circularBuffer->buffer[i].lifeTime*215.0f);
+ circularBuffer->buffer[i].velocity.y -= 0.05f; // Upwards
+ circularBuffer->buffer[i].position.y += circularBuffer->buffer[i].velocity.y;
+ circularBuffer->buffer[i].radius -= 0.15f; // Decrement radius: fire shrinks
+ circularBuffer->buffer[i].color.g -= 3; // Decrement green: fire turns reddish starting from yellow
+ if (circularBuffer->buffer[i].radius <= 0.02f) // If radius too small, particle dies
+ circularBuffer->buffer[i].alive = false;
+ break;
+ default: break;
+ }
+
+ // Disable particle when out of screen
+ Vector2 center = circularBuffer->buffer[i].position;
+ float radius = circularBuffer->buffer[i].radius;
+ if ((center.x < -radius) || (center.x > screenWidth + radius) ||
+ (center.y < -radius) || (center.y > screenHeight + radius))
+ circularBuffer->buffer[i].alive = false;
+ }
+}
+
+static void UpdateCircularBuffer(CircularBuffer *circularBuffer)
+{
+ // Update circular buffer: advance tail over dead particles
+ while ((circularBuffer->tail != circularBuffer->head) &&
+ !circularBuffer->buffer[circularBuffer->tail].alive)
+ {
+ circularBuffer->tail = (circularBuffer->tail + 1)%MAX_PARTICLES;
+ }
+}
+
+static void DrawParticles(CircularBuffer *circularBuffer)
+{
+ for (int i = circularBuffer->tail; i != circularBuffer->head; i = (i + 1)%MAX_PARTICLES)
+ {
+ if (circularBuffer->buffer[i].alive)
+ {
+ DrawCircleV(circularBuffer->buffer[i].position,
+ circularBuffer->buffer[i].radius,
+ circularBuffer->buffer[i].color);
+ }
+ }
+}
diff --git a/examples/shapes/shapes_simple_particles.png b/examples/shapes/shapes_simple_particles.png
new file mode 100644
index 000000000..78abece57
Binary files /dev/null and b/examples/shapes/shapes_simple_particles.png differ
diff --git a/examples/shapes/shapes_starfield.c b/examples/shapes/shapes_starfield.c
new file mode 100644
index 000000000..df543d066
--- /dev/null
+++ b/examples/shapes/shapes_starfield.c
@@ -0,0 +1,143 @@
+/*******************************************************************************************
+*
+* raylib [shapes] example - starfield
+*
+* Example complexity rating: [★☆☆☆] 1/4
+*
+* Example originally created with raylib 5.5, last time updated with raylib 5.6-dev
+*
+* Example contributed by JP Mortiboys (@themushroompirates) 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) 2025 JP Mortiboys (@themushroompirates)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#include "raymath.h" // Required for: Lerp()
+
+#define STAR_COUNT 420
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [shapes] example - starfield");
+
+ Color bgColor = ColorLerp(DARKBLUE, BLACK, 0.69f);
+
+ // Speed at which we fly forward
+ float speed = 10.0f/9.0f;
+
+ // We're either drawing lines or circles
+ bool drawLines = true;
+
+ Vector3 stars[STAR_COUNT] = { 0 };
+ Vector2 starsScreenPos[STAR_COUNT] = { 0 };
+
+ // Setup the stars with a random position
+ for (int i = 0; i < STAR_COUNT; i++) {
+ stars[i].x = GetRandomValue(-screenWidth*.5, screenWidth*.5);
+ stars[i].y = GetRandomValue(-screenHeight*.5, screenHeight*.5);
+ stars[i].z = 1.0f;
+ }
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+
+ // Change speed based on number keys
+ for (int i = 0; i <= 9; i++) {
+ if (IsKeyPressed(KEY_ZERO + i)) {
+ speed = 2.0f * (float)i / 9.0f;
+ }
+ }
+
+ // Toggle lines / points with space bar
+ if (IsKeyPressed(KEY_SPACE)) {
+ drawLines = !drawLines;
+ }
+
+ float dt = GetFrameTime();
+ for (int i = 0; i < STAR_COUNT; i++) {
+ // Update star's timer
+ stars[i].z -= dt * speed;
+ // Calculate the screen position
+ starsScreenPos[i] = (Vector2) {
+ screenWidth*.5f + stars[i].x / stars[i].z,
+ screenHeight*.5f + stars[i].y / stars[i].z,
+ };
+ // If the star is too old, or offscreen, it dies and we make a new random one
+ if (stars[i].z < 0.0f
+ || starsScreenPos[i].x < 0 || starsScreenPos[i].y < 0.0f
+ || starsScreenPos[i].x > screenWidth || starsScreenPos[i].y > screenHeight) {
+ stars[i].x = GetRandomValue(-screenWidth*.5, screenWidth*.5);
+ stars[i].y = GetRandomValue(-screenHeight*.5, screenHeight*.5);
+ stars[i].z = 1.0f;
+ }
+ }
+
+
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(bgColor);
+
+ for (int i = 0; i < STAR_COUNT; i++) {
+ if (drawLines) {
+ // Get the time a little while ago for this star, but clamp it
+ float t = Clamp(stars[i].z + 1.0f/32.0f, 0.0f, 1.0f);
+ // If it's different enough from the current time, we proceed
+ if (t - stars[i].z > 1e-3) {
+ // Calculate the screen position of the old point
+ Vector2 startPos = (Vector2) {
+ screenWidth*.5f + stars[i].x / t,
+ screenHeight*.5f + stars[i].y / t,
+ };
+ // Draw a line connecting the old point to the current point
+ DrawLineV(startPos, starsScreenPos[i], RAYWHITE);
+ }
+ }
+ else {
+ // Make the radius grow as the star ages
+ float radius = Lerp(stars[i].z, 1.0f, 5.0f);
+ // Draw the circle
+ DrawCircleV(starsScreenPos[i], radius, RAYWHITE);
+ }
+ }
+
+ DrawFPS(10, 10);
+
+ DrawText(TextFormat("Current Speed: %.0f [Number keys to change]", 9.0f * speed / 2.0f), 10, 30, 20, RAYWHITE);
+ DrawText(TextFormat("Drawing %s [Space to change]", drawLines ? "Lines" : "Circles"), 10, 50, 20, RAYWHITE);
+
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
\ No newline at end of file
diff --git a/examples/shapes/shapes_starfield.png b/examples/shapes/shapes_starfield.png
new file mode 100644
index 000000000..6903f222b
Binary files /dev/null and b/examples/shapes/shapes_starfield.png differ
diff --git a/examples/shapes/shapes_triangle_strip.c b/examples/shapes/shapes_triangle_strip.c
new file mode 100644
index 000000000..d8b5faeea
--- /dev/null
+++ b/examples/shapes/shapes_triangle_strip.c
@@ -0,0 +1,106 @@
+/*******************************************************************************************
+*
+* raylib [shapes] example - triangle strip
+*
+* Example complexity rating: [★★☆☆] 2/4
+*
+* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
+*
+* Example contributed by Jopestpe (@jopestpe)
+*
+* 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) 2025 Jopestpe (@jopestpe)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+#include
+
+#define RAYGUI_IMPLEMENTATION
+#include "raygui.h" // Required for GUI controls
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [shapes] example - triangle strip");
+
+ Vector2 points[120] = { 0 };
+ Vector2 center = { (screenWidth/2.0f) - 125.f, screenHeight/2.0f };
+ float segments = 6.0f;
+ float insideRadius = 100.0f;
+ float outsideRadius = 150.0f;
+ bool outline = true;
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ int pointCount = (int)(segments);
+ float angleStep = (360.0f/pointCount)*DEG2RAD;
+
+ for (int i = 0, i2 = 0; i < pointCount; i++, i2 += 2)
+ {
+ float angle1 = i*angleStep;
+ points[i2] = (Vector2){ center.x + cosf(angle1)*insideRadius, center.y + sinf(angle1)*insideRadius };
+ float angle2 = angle1 + angleStep/2.0f;
+ points[i2 + 1] = (Vector2){ center.x + cosf(angle2)*outsideRadius, center.y + sinf(angle2)*outsideRadius };
+ }
+
+ points[pointCount*2] = points[0];
+ points[pointCount*2 + 1] = points[1];
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ for (int i = 0, i2 = 0; i < pointCount; i++, i2 += 2)
+ {
+ float angle1 = i*angleStep;
+ Color color = ColorFromHSV(angle1*RAD2DEG, 1.0f, 1.0f);
+ DrawTriangle(points[i2 + 2], points[i2 + 1], points[i2], color);
+ if (outline) DrawTriangleLines(points[i2], points[i2 + 1], points[i2 + 2], BLACK);
+
+ float angle2 = angle1 + angleStep/2.0f;
+ color = ColorFromHSV(angle2*RAD2DEG, 1.0f, 1.0f);
+ DrawTriangle(points[i2 + 3], points[i2 + 1], points[i2 + 2], color);
+ if (outline) DrawTriangleLines(points[i2 + 2], points[i2 + 1], points[i2 + 3], BLACK);
+ }
+
+ DrawLine(580, 0, 580, GetScreenHeight(), (Color){ 218, 218, 218, 255 });
+ DrawRectangle(580, 0, GetScreenWidth(), GetScreenHeight(), (Color){ 232, 232, 232, 255 });
+
+ // Draw GUI controls
+ //------------------------------------------------------------------------------
+ GuiSliderBar((Rectangle){ 640, 40, 120, 20}, "Segments", TextFormat("%.0f", segments), &segments, 6.0f, 60.f);
+ GuiCheckBox((Rectangle){ 640, 70, 20, 20 }, "Outline", &outline);
+ //------------------------------------------------------------------------------
+
+ DrawFPS(10, 10);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
\ No newline at end of file
diff --git a/examples/shapes/shapes_triangle_strip.png b/examples/shapes/shapes_triangle_strip.png
new file mode 100644
index 000000000..c291a0849
Binary files /dev/null and b/examples/shapes/shapes_triangle_strip.png differ
diff --git a/examples/shapes/shapes_vector_angle.c b/examples/shapes/shapes_vector_angle.c
index 7de296dcb..b5faf4c78 100644
--- a/examples/shapes/shapes_vector_angle.c
+++ b/examples/shapes/shapes_vector_angle.c
@@ -30,7 +30,7 @@ int main(void)
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - vector angle");
- Vector2 v0 = { screenWidth/2, screenHeight/2 };
+ Vector2 v0 = { screenWidth/2.0f, screenHeight/2.0f };
Vector2 v1 = Vector2Add(v0, (Vector2){ 100.0f, 80.0f });
Vector2 v2 = { 0 }; // Updated with mouse position
@@ -97,17 +97,17 @@ int main(void)
DrawCircleSector(v0, 40.0f, startangle, startangle - angle, 32, Fade(GREEN, 0.6f));
}
- DrawText("v0", v0.x, v0.y, 10, DARKGRAY);
+ DrawText("v0", (int)v0.x, (int)v0.y, 10, DARKGRAY);
// If the line from v0 to v1 would overlap the text, move it's position up 10
- if (angleMode == 0 && Vector2Subtract(v0, v1).y > 0.0f) DrawText("v1", v1.x, v1.y-10.0f, 10, DARKGRAY);
- if (angleMode == 0 && Vector2Subtract(v0, v1).y < 0.0f) DrawText("v1", v1.x, v1.y, 10, DARKGRAY);
+ if (angleMode == 0 && Vector2Subtract(v0, v1).y > 0.0f) DrawText("v1", (int)v1.x, (int)v1.y-10, 10, DARKGRAY);
+ if (angleMode == 0 && Vector2Subtract(v0, v1).y < 0.0f) DrawText("v1", (int)v1.x, (int)v1.y, 10, DARKGRAY);
// If angle mode 1, use v1 to emphasize the horizontal line
- if (angleMode == 1) DrawText("v1", v0.x + 40.0f, v0.y, 10, DARKGRAY);
+ if (angleMode == 1) DrawText("v1", (int)v0.x + 40, (int)v0.y, 10, DARKGRAY);
// position adjusted by -10 so it isn't hidden by cursor
- DrawText("v2", v2.x-10.0f, v2.y-10.0f, 10, DARKGRAY);
+ DrawText("v2", (int)v2.x-10, (int)v2.y-10, 10, DARKGRAY);
DrawText("Press SPACE to change MODE", 460, 10, 20, DARKGRAY);
DrawText(TextFormat("ANGLE: %2.2f", angle), 10, 70, 20, LIME);
diff --git a/examples/text/text_inline_styling.c b/examples/text/text_inline_styling.c
index 865b1c5d0..b221c7e6f 100644
--- a/examples/text/text_inline_styling.c
+++ b/examples/text/text_inline_styling.c
@@ -86,7 +86,7 @@ int main(void)
DrawTextStyled(GetFontDefault(), text, (Vector2){ 100, 220 }, 40.0f, 2.0f, BLACK);
textSize = MeasureTextStyled(GetFontDefault(), text, 40.0f, 2.0f);
- DrawRectangleLines(100, 220, textSize.x, textSize.y, GREEN);
+ DrawRectangleLines(100, 220, (int)textSize.x, (int)textSize.y, GREEN);
EndDrawing();
//----------------------------------------------------------------------------------
@@ -154,7 +154,7 @@ static void DrawTextStyled(Font font, const char *text, Vector2 position, float
// Parse following color
char colHexText[9] = { 0 };
- char *textPtr = &text[i]; // Color should start here, let's see...
+ const char *textPtr = &text[i]; // Color should start here, let's see...
int colHexCount = 0;
while ((textPtr != NULL) && (textPtr[colHexCount] != '\0') && (textPtr[colHexCount] != ']'))
@@ -186,7 +186,7 @@ static void DrawTextStyled(Font font, const char *text, Vector2 position, float
else increaseX += ((float)font.glyphs[index].advanceX*scaleFactor + spacing);
// Draw background rectangle color (if required)
- if (colBack.a > 0) DrawRectangle(position.x + textOffsetX, position.y + textOffsetY - backRecPadding, increaseX, fontSize + 2*backRecPadding, colBack);
+ if (colBack.a > 0) DrawRectangleRec((Rectangle) { position.x + textOffsetX, position.y + textOffsetY - backRecPadding, increaseX, fontSize + 2 * backRecPadding }, colBack);
if ((codepoint != ' ') && (codepoint != '\t'))
{
@@ -236,7 +236,7 @@ static Vector2 MeasureTextStyled(Font font, const char *text, float fontSize, fl
{
i += 2; // Skip "[c" or "[b" to start parsing color
- char *textPtr = &text[i]; // Color should start here, let's see...
+ const char *textPtr = &text[i]; // Color should start here, let's see...
int colHexCount = 0;
while ((textPtr != NULL) && (textPtr[colHexCount] != '\0') && (textPtr[colHexCount] != ']'))
diff --git a/examples/text/text_unicode_ranges.c b/examples/text/text_unicode_ranges.c
index 473bee64f..e54c052b1 100644
--- a/examples/text/text_unicode_ranges.c
+++ b/examples/text/text_unicode_ranges.c
@@ -6,12 +6,12 @@
*
* Example originally created with raylib 5.5, last time updated with raylib 5.6
*
-* Example contributed by Vlad Adrian (@demizdor) and reviewed by Ramon Santamaria (@raysan5)
+* Example contributed by Vadim Gunko (@GuvaCode) 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) 2025 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5)
+* Copyright (c) 2025 Vadim Gunko (@GuvaCode) and Ramon Santamaria (@raysan5)
*
********************************************************************************************/
@@ -144,9 +144,9 @@ int main(void)
// Draw font texture scaled to screen
float atlasScale = 380.0f/font.texture.width;
- DrawRectangle(400, 16, font.texture.width*atlasScale, font.texture.height*atlasScale, BLACK);
- DrawTexturePro(font.texture, (Rectangle){ 0, 0, font.texture.width, font.texture.height },
- (Rectangle){ 400, 16, font.texture.width*atlasScale, font.texture.height*atlasScale }, (Vector2){ 0, 0 }, 0.0f, WHITE);
+ DrawRectangleRec((Rectangle) { 400.0f, 16.0f, font.texture.width* atlasScale, font.texture.height* atlasScale }, BLACK);
+ DrawTexturePro(font.texture, (Rectangle){ 0, 0, (float)font.texture.width, (float)font.texture.height },
+ (Rectangle){ 400.0f, 16.0f, font.texture.width*atlasScale, font.texture.height*atlasScale }, (Vector2){ 0, 0 }, 0.0f, WHITE);
DrawRectangleLines(400, 16, 380, 380, RED);
DrawText(TextFormat("ATLAS SIZE: %ix%i px (x%02.2f)", font.texture.width, font.texture.height, atlasScale), 20, 380, 20, BLUE);
diff --git a/examples/text/text_words_alignment.c b/examples/text/text_words_alignment.c
new file mode 100644
index 000000000..352b3cd37
--- /dev/null
+++ b/examples/text/text_words_alignment.c
@@ -0,0 +1,130 @@
+/*******************************************************************************************
+*
+* raylib [text] example - words alignment
+*
+* Example complexity rating: [★☆☆☆] 1/4
+*
+* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
+*
+* Example contributed by JP Mortiboys (@themushroompirates) 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) 2025 JP Mortiboys (@themushroompirates)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#include "raymath.h" // Required for: Lerp()
+
+typedef enum TextAlignment {
+ TEXT_ALIGN_LEFT = 0,
+ TEXT_ALIGN_TOP = 0,
+ TEXT_ALIGN_CENTRE = 1,
+ TEXT_ALIGN_MIDDLE = 1,
+ TEXT_ALIGN_RIGHT = 2,
+ TEXT_ALIGN_BOTTOM = 2
+} TextAlignment;
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [text] example - words alignment");
+
+ // Define the rectangle we will draw the text in
+ Rectangle textContainerRect = (Rectangle){ screenWidth/2-screenWidth/4, screenHeight/2-screenHeight/3, screenWidth/2, screenHeight*2/3 };
+
+ // Some text to display the current alignment
+ const char *textAlignNameH[] = { "Left", "Centre", "Right" };
+ const char *textAlignNameV[] = { "Top", "Middle", "Bottom" };
+
+ // Define the text we're going to draw in the rectangle
+ int wordIndex = 0;
+ int wordCount = 0;
+ char **words = TextSplit("raylib is a simple and easy-to-use library to enjoy videogames programming", ' ', &wordCount);
+
+ // Initialize the font size we're going to use
+ int fontSize = 40;
+
+ // And of course the font...
+ Font font = GetFontDefault();
+
+ // Intialize the alignment variables
+ TextAlignment hAlign = TEXT_ALIGN_CENTRE;
+ TextAlignment vAlign = TEXT_ALIGN_MIDDLE;
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+
+ if (IsKeyPressed(KEY_LEFT)) {
+ hAlign = hAlign - 1;
+ if (hAlign < 0) hAlign = 0;
+ }
+ if (IsKeyPressed(KEY_RIGHT)) {
+ hAlign = hAlign + 1;
+ if (hAlign > 2) hAlign = 2;
+ }
+ if (IsKeyPressed(KEY_UP)) {
+ vAlign = vAlign - 1;
+ if (vAlign < 0) vAlign = 0;
+ }
+ if (IsKeyPressed(KEY_DOWN)) {
+ vAlign = vAlign + 1;
+ if (vAlign > 2) vAlign = 2;
+ }
+
+ // One word per second
+ wordIndex = (int)GetTime() % wordCount;
+
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(DARKBLUE);
+
+ DrawText("Use Arrow Keys to change the text alignment", 20, 20, 20, LIGHTGRAY);
+ DrawText(TextFormat("Alignment: Horizontal = %s, Vertical = %s", textAlignNameH[hAlign], textAlignNameV[vAlign]), 20, 40, 20, LIGHTGRAY);
+
+ DrawRectangleRec(textContainerRect, BLUE);
+
+ // Get the size of the text to draw
+ Vector2 textSize = MeasureTextEx(font, words[wordIndex], fontSize, fontSize*.1f);
+
+ // Calculate the top-left text position based on the rectangle and alignment
+ Vector2 textPos = (Vector2) {
+ textContainerRect.x + Lerp(0.0f, textContainerRect.width - textSize.x, ((float)hAlign) * 0.5f),
+ textContainerRect.y + Lerp(0.0f, textContainerRect.height - textSize.y, ((float)vAlign) * 0.5f)
+ };
+
+ // Draw the text
+ DrawTextEx(font, words[wordIndex], textPos, fontSize, fontSize*.1f, RAYWHITE);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
\ No newline at end of file
diff --git a/examples/text/text_words_alignment.png b/examples/text/text_words_alignment.png
new file mode 100644
index 000000000..ae0892381
Binary files /dev/null and b/examples/text/text_words_alignment.png differ
diff --git a/examples/textures/textures_image_channel.c b/examples/textures/textures_image_channel.c
index 29622b74d..e512af366 100644
--- a/examples/textures/textures_image_channel.c
+++ b/examples/textures/textures_image_channel.c
@@ -61,13 +61,13 @@ int main(void)
UnloadImage(imageBlue);
UnloadImage(backgroundImage);
- Rectangle fudesumiRec = {0, 0, fudesumiImage.width, fudesumiImage.height};
+ Rectangle fudesumiRec = {0, 0, (float)fudesumiImage.width, (float)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 };
+ Rectangle redPos = { 410, 10, fudesumiPos.width/2.0f, fudesumiPos.height/2.0f };
+ Rectangle greenPos = { 600, 10, fudesumiPos.width/2.0f, fudesumiPos.height/2.0f };
+ Rectangle bluePos = { 410, 230, fudesumiPos.width/2.0f, fudesumiPos.height/2.0f };
+ Rectangle alphaPos = { 600, 230, fudesumiPos.width/2.0f, fudesumiPos.height/2.0f };
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
diff --git a/projects/VS2022/examples/core_clipboard_text.vcxproj b/projects/VS2022/examples/core_clipboard_text.vcxproj
new file mode 100644
index 000000000..5b0b3e16f
--- /dev/null
+++ b/projects/VS2022/examples/core_clipboard_text.vcxproj
@@ -0,0 +1,569 @@
+
+
+
+
+ Debug.DLL
+ ARM64
+
+
+ Debug.DLL
+ Win32
+
+
+ Debug.DLL
+ x64
+
+
+ Debug
+ ARM64
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release.DLL
+ ARM64
+
+
+ Release.DLL
+ Win32
+
+
+ Release.DLL
+ x64
+
+
+ Release
+ ARM64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {124935CC-73BB-489E-92E8-4F922A85DB5D}
+ Win32Proj
+ core_clipboard_text
+ 10.0
+ core_clipboard_text
+
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ /FS %(AdditionalOptions)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;shcore.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ /FS %(AdditionalOptions)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+
+
+
+
+
+
+ {e89d61ac-55de-4482-afd4-df7242ebc859}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/VS2022/examples/core_delta_time.vcxproj b/projects/VS2022/examples/core_delta_time.vcxproj
index 3d31afa42..1c488bb6f 100644
--- a/projects/VS2022/examples/core_delta_time.vcxproj
+++ b/projects/VS2022/examples/core_delta_time.vcxproj
@@ -51,7 +51,7 @@
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}
+ {19CA0070-B4B2-4394-90B7-D0C259AA35BA}
Win32Proj
core_delta_time
10.0
diff --git a/projects/VS2022/examples/core_directory_files.vcxproj b/projects/VS2022/examples/core_directory_files.vcxproj
new file mode 100644
index 000000000..426fbfca8
--- /dev/null
+++ b/projects/VS2022/examples/core_directory_files.vcxproj
@@ -0,0 +1,569 @@
+
+
+
+
+ Debug.DLL
+ ARM64
+
+
+ Debug.DLL
+ Win32
+
+
+ Debug.DLL
+ x64
+
+
+ Debug
+ ARM64
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release.DLL
+ ARM64
+
+
+ Release.DLL
+ Win32
+
+
+ Release.DLL
+ x64
+
+
+ Release
+ ARM64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {7467E9AE-844F-444D-8A3F-17397544BA21}
+ Win32Proj
+ core_directory_files
+ 10.0
+ core_directory_files
+
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ /FS %(AdditionalOptions)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ /FS %(AdditionalOptions)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+
+
+
+
+
+
+ {e89d61ac-55de-4482-afd4-df7242ebc859}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/VS2022/examples/core_monitor_change.vcxproj b/projects/VS2022/examples/core_monitor_change.vcxproj
index e372a68d0..07921bef3 100644
--- a/projects/VS2022/examples/core_monitor_change.vcxproj
+++ b/projects/VS2022/examples/core_monitor_change.vcxproj
@@ -51,7 +51,7 @@
- {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}
+ {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}
Win32Proj
core_monitor_change
10.0
diff --git a/projects/VS2022/examples/models_geometry_textures_cube.vcxproj b/projects/VS2022/examples/models_geometry_textures_cube.vcxproj
index 5c8452472..77fcd94d4 100644
--- a/projects/VS2022/examples/models_geometry_textures_cube.vcxproj
+++ b/projects/VS2022/examples/models_geometry_textures_cube.vcxproj
@@ -51,7 +51,7 @@
- {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}
+ {A4662163-83E7-4309-8CAA-B0BF13655FE6}
Win32Proj
models_geometry_textures_cube
10.0
diff --git a/projects/VS2022/examples/shaders_ascii_rendering.vcxproj b/projects/VS2022/examples/shaders_ascii_rendering.vcxproj
index 49ee10790..0bb37c6d8 100644
--- a/projects/VS2022/examples/shaders_ascii_rendering.vcxproj
+++ b/projects/VS2022/examples/shaders_ascii_rendering.vcxproj
@@ -51,7 +51,7 @@
- {9DB1F875-6E65-4195-B23F-ED8095C0B99C}
+ {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}
Win32Proj
shaders_ascii_rendering
10.0
diff --git a/projects/VS2022/examples/shapes_clock_of_clocks.vcxproj b/projects/VS2022/examples/shapes_clock_of_clocks.vcxproj
new file mode 100644
index 000000000..94b1713ec
--- /dev/null
+++ b/projects/VS2022/examples/shapes_clock_of_clocks.vcxproj
@@ -0,0 +1,569 @@
+
+
+
+
+ Debug.DLL
+ ARM64
+
+
+ Debug.DLL
+ Win32
+
+
+ Debug.DLL
+ x64
+
+
+ Debug
+ ARM64
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release.DLL
+ ARM64
+
+
+ Release.DLL
+ Win32
+
+
+ Release.DLL
+ x64
+
+
+ Release
+ ARM64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}
+ Win32Proj
+ shapes_clock_of_clocks
+ 10.0
+ shapes_clock_of_clocks
+
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ /FS %(AdditionalOptions)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;shcore.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ /FS %(AdditionalOptions)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+
+
+
+
+
+
+ {e89d61ac-55de-4482-afd4-df7242ebc859}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/VS2022/examples/shapes_dashed_line.vcxproj b/projects/VS2022/examples/shapes_dashed_line.vcxproj
index 4a4b86ef3..a5d4c3e1a 100644
--- a/projects/VS2022/examples/shapes_dashed_line.vcxproj
+++ b/projects/VS2022/examples/shapes_dashed_line.vcxproj
@@ -51,7 +51,7 @@
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}
+ {8E132D5A-2C00-48D0-8747-97E41356F26F}
Win32Proj
shapes_dashed_line
10.0
diff --git a/projects/VS2022/examples/shapes_digital_clock.vcxproj b/projects/VS2022/examples/shapes_digital_clock.vcxproj
index e361eb190..c2a201a12 100644
--- a/projects/VS2022/examples/shapes_digital_clock.vcxproj
+++ b/projects/VS2022/examples/shapes_digital_clock.vcxproj
@@ -292,7 +292,7 @@
Level3
Disabled
- WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ _CRT_SECURE_NO_WARNING;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
CompileAsC
$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
@@ -309,7 +309,7 @@
Level3
Disabled
- WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ _CRT_SECURE_NO_WARNING;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
CompileAsC
$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
/FS %(AdditionalOptions)
@@ -345,7 +345,7 @@
Level3
Disabled
- WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ _CRT_SECURE_NO_WARNING;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
CompileAsC
$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
@@ -366,7 +366,7 @@
Level3
Disabled
- WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ _CRT_SECURE_NO_WARNING;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
CompileAsC
$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
@@ -410,7 +410,7 @@
MaxSpeed
true
true
- WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ _CRT_SECURE_NO_WARNING;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
CompileAsC
true
@@ -432,7 +432,7 @@
MaxSpeed
true
true
- WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ _CRT_SECURE_NO_WARNING;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
CompileAsC
true
@@ -476,7 +476,7 @@
MaxSpeed
true
true
- WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ _CRT_SECURE_NO_WARNING;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
CompileAsC
true
@@ -504,7 +504,7 @@
MaxSpeed
true
true
- WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ _CRT_SECURE_NO_WARNING;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
CompileAsC
true
diff --git a/projects/VS2022/examples/shapes_kaleidoscope.vcxproj b/projects/VS2022/examples/shapes_kaleidoscope.vcxproj
new file mode 100644
index 000000000..52fa68e53
--- /dev/null
+++ b/projects/VS2022/examples/shapes_kaleidoscope.vcxproj
@@ -0,0 +1,569 @@
+
+
+
+
+ Debug.DLL
+ ARM64
+
+
+ Debug.DLL
+ Win32
+
+
+ Debug.DLL
+ x64
+
+
+ Debug
+ ARM64
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release.DLL
+ ARM64
+
+
+ Release.DLL
+ Win32
+
+
+ Release.DLL
+ x64
+
+
+ Release
+ ARM64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {0C442799-B09C-4CD1-9538-711B6E85E9BF}
+ Win32Proj
+ shapes_kaleidoscope
+ 10.0
+ shapes_kaleidoscope
+
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ /FS %(AdditionalOptions)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ /FS %(AdditionalOptions)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+
+
+
+
+
+
+ {e89d61ac-55de-4482-afd4-df7242ebc859}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/VS2022/examples/shapes_mouse_trail.vcxproj b/projects/VS2022/examples/shapes_mouse_trail.vcxproj
new file mode 100644
index 000000000..edc65c027
--- /dev/null
+++ b/projects/VS2022/examples/shapes_mouse_trail.vcxproj
@@ -0,0 +1,569 @@
+
+
+
+
+ Debug.DLL
+ ARM64
+
+
+ Debug.DLL
+ Win32
+
+
+ Debug.DLL
+ x64
+
+
+ Debug
+ ARM64
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release.DLL
+ ARM64
+
+
+ Release.DLL
+ Win32
+
+
+ Release.DLL
+ x64
+
+
+ Release
+ ARM64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}
+ Win32Proj
+ shapes_mouse_trail
+ 10.0
+ shapes_mouse_trail
+
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ /FS %(AdditionalOptions)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;shcore.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ /FS %(AdditionalOptions)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+
+
+
+
+
+
+ {e89d61ac-55de-4482-afd4-df7242ebc859}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/VS2022/examples/shapes_pie_chart.vcxproj b/projects/VS2022/examples/shapes_pie_chart.vcxproj
new file mode 100644
index 000000000..ad1cf93d1
--- /dev/null
+++ b/projects/VS2022/examples/shapes_pie_chart.vcxproj
@@ -0,0 +1,569 @@
+
+
+
+
+ Debug.DLL
+ ARM64
+
+
+ Debug.DLL
+ Win32
+
+
+ Debug.DLL
+ x64
+
+
+ Debug
+ ARM64
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release.DLL
+ ARM64
+
+
+ Release.DLL
+ Win32
+
+
+ Release.DLL
+ x64
+
+
+ Release
+ ARM64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}
+ Win32Proj
+ shapes_pie_chart
+ 10.0
+ shapes_pie_chart
+
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ /FS %(AdditionalOptions)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ /FS %(AdditionalOptions)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+
+
+
+
+
+
+ {e89d61ac-55de-4482-afd4-df7242ebc859}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/VS2022/examples/shapes_recursive_tree.vcxproj b/projects/VS2022/examples/shapes_recursive_tree.vcxproj
new file mode 100644
index 000000000..771860844
--- /dev/null
+++ b/projects/VS2022/examples/shapes_recursive_tree.vcxproj
@@ -0,0 +1,569 @@
+
+
+
+
+ Debug.DLL
+ ARM64
+
+
+ Debug.DLL
+ Win32
+
+
+ Debug.DLL
+ x64
+
+
+ Debug
+ ARM64
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release.DLL
+ ARM64
+
+
+ Release.DLL
+ Win32
+
+
+ Release.DLL
+ x64
+
+
+ Release
+ ARM64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {DFB40A10-F8B7-412A-BCC3-5EE49294D816}
+ Win32Proj
+ shapes_recursive_tree
+ 10.0
+ shapes_recursive_tree
+
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+
+
+
+ Level3
+ Disabled
+ _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ /FS %(AdditionalOptions)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;shcore.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ /FS %(AdditionalOptions)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+
+
+ Level3
+ Disabled
+ _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+
+
+
+
+
+
+ {e89d61ac-55de-4482-afd4-df7242ebc859}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/VS2022/examples/shapes_simple_particles.vcxproj b/projects/VS2022/examples/shapes_simple_particles.vcxproj
new file mode 100644
index 000000000..8a5270503
--- /dev/null
+++ b/projects/VS2022/examples/shapes_simple_particles.vcxproj
@@ -0,0 +1,569 @@
+
+
+
+
+ Debug.DLL
+ ARM64
+
+
+ Debug.DLL
+ Win32
+
+
+ Debug.DLL
+ x64
+
+
+ Debug
+ ARM64
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release.DLL
+ ARM64
+
+
+ Release.DLL
+ Win32
+
+
+ Release.DLL
+ x64
+
+
+ Release
+ ARM64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {497FDF54-9762-4048-A833-61CC3980A0FB}
+ Win32Proj
+ shapes_simple_particles
+ 10.0
+ shapes_simple_particles
+
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ /FS %(AdditionalOptions)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;shcore.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ /FS %(AdditionalOptions)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+
+
+
+
+
+
+ {e89d61ac-55de-4482-afd4-df7242ebc859}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/VS2022/examples/shapes_starfield.vcxproj b/projects/VS2022/examples/shapes_starfield.vcxproj
new file mode 100644
index 000000000..5cfc0a6d3
--- /dev/null
+++ b/projects/VS2022/examples/shapes_starfield.vcxproj
@@ -0,0 +1,569 @@
+
+
+
+
+ Debug.DLL
+ ARM64
+
+
+ Debug.DLL
+ Win32
+
+
+ Debug.DLL
+ x64
+
+
+ Debug
+ ARM64
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release.DLL
+ ARM64
+
+
+ Release.DLL
+ Win32
+
+
+ Release.DLL
+ x64
+
+
+ Release
+ ARM64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}
+ Win32Proj
+ shapes_starfield
+ 10.0
+ shapes_starfield
+
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ /FS %(AdditionalOptions)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;shcore.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ /FS %(AdditionalOptions)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+
+
+
+
+
+
+ {e89d61ac-55de-4482-afd4-df7242ebc859}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/VS2022/examples/shapes_triangle_strip.vcxproj b/projects/VS2022/examples/shapes_triangle_strip.vcxproj
new file mode 100644
index 000000000..b128c0ff6
--- /dev/null
+++ b/projects/VS2022/examples/shapes_triangle_strip.vcxproj
@@ -0,0 +1,569 @@
+
+
+
+
+ Debug.DLL
+ ARM64
+
+
+ Debug.DLL
+ Win32
+
+
+ Debug.DLL
+ x64
+
+
+ Debug
+ ARM64
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release.DLL
+ ARM64
+
+
+ Release.DLL
+ Win32
+
+
+ Release.DLL
+ x64
+
+
+ Release
+ ARM64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {BB58A5FB-1A35-4471-86D0-A5189EC541B3}
+ Win32Proj
+ shapes_triangle_strip
+ 10.0
+ shapes_triangle_strip
+
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shapes
+ WindowsLocalDebugger
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ /FS %(AdditionalOptions)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;shcore.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ /FS %(AdditionalOptions)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+
+
+
+
+
+
+ {e89d61ac-55de-4482-afd4-df7242ebc859}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/VS2022/examples/text_words_alignment.vcxproj b/projects/VS2022/examples/text_words_alignment.vcxproj
new file mode 100644
index 000000000..be9c1614e
--- /dev/null
+++ b/projects/VS2022/examples/text_words_alignment.vcxproj
@@ -0,0 +1,569 @@
+
+
+
+
+ Debug.DLL
+ ARM64
+
+
+ Debug.DLL
+ Win32
+
+
+ Debug.DLL
+ x64
+
+
+ Debug
+ ARM64
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release.DLL
+ ARM64
+
+
+ Release.DLL
+ Win32
+
+
+ Release.DLL
+ x64
+
+
+ Release
+ ARM64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {29B00F47-BE91-4A1F-B87D-B1302F038316}
+ Win32Proj
+ text_words_alignment
+ 10.0
+ text_words_alignment
+
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ $(SolutionDir)..\..\examples\text
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\text
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\text
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\text
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\text
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\text
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\text
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\text
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\text
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\text
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\text
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\text
+ WindowsLocalDebugger
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ /FS %(AdditionalOptions)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;shcore.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ /FS %(AdditionalOptions)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+
+
+
+
+
+
+ {e89d61ac-55de-4482-afd4-df7242ebc859}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/VS2022/examples/web_basic_window.vcxproj b/projects/VS2022/examples/web_basic_window.vcxproj
index e36012ac6..6c0c7ab1f 100644
--- a/projects/VS2022/examples/web_basic_window.vcxproj
+++ b/projects/VS2022/examples/web_basic_window.vcxproj
@@ -51,7 +51,7 @@
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}
+ {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}
Win32Proj
web_basic_window
10.0
diff --git a/projects/VS2022/raylib.sln b/projects/VS2022/raylib.sln
index 0d7019b61..5a784adbe 100644
--- a/projects/VS2022/raylib.sln
+++ b/projects/VS2022/raylib.sln
@@ -347,7 +347,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_undo_redo", "examples\
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_input_actions", "examples\core_input_actions.vcxproj", "{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_delta_time", "examples\core_delta_time.vcxproj", "{6B1A933E-71B8-4C1F-9E79-02D98830E671}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_delta_time", "examples\core_delta_time.vcxproj", "{19CA0070-B4B2-4394-90B7-D0C259AA35BA}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_bullet_hell", "examples\shapes_bullet_hell.vcxproj", "{2CCCD9E4-9058-4291-BD89-39C979F0CA1E}"
EndProject
@@ -355,15 +355,37 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_vector_angle", "exam
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_basic_voxel", "examples\models_basic_voxel.vcxproj", "{52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_dashed_line", "examples\shapes_dashed_line.vcxproj", "{6B1A933E-71B8-4C1F-9E79-02D98830E671}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_dashed_line", "examples\shapes_dashed_line.vcxproj", "{8E132D5A-2C00-48D0-8747-97E41356F26F}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_geometry_textures_cube", "examples\models_geometry_textures_cube.vcxproj", "{2CCCD9E4-9058-4291-BD89-39C979F0CA1E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_geometry_textures_cube", "examples\models_geometry_textures_cube.vcxproj", "{A4662163-83E7-4309-8CAA-B0BF13655FE6}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_ascii_rendering", "examples\shaders_ascii_rendering.vcxproj", "{9DB1F875-6E65-4195-B23F-ED8095C0B99C}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_ascii_rendering", "examples\shaders_ascii_rendering.vcxproj", "{5F4B766F-DD52-4B53-B6C3-BC7611E17F20}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_monitor_change", "examples\core_monitor_change.vcxproj", "{52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_monitor_change", "examples\core_monitor_change.vcxproj", "{FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "web_basic_window", "examples\web_basic_window.vcxproj", "{6B1A933E-71B8-4C1F-9E79-02D98830E671}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "web_basic_window", "examples\web_basic_window.vcxproj", "{A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_kaleidoscope", "examples\shapes_kaleidoscope.vcxproj", "{0C442799-B09C-4CD1-9538-711B6E85E9BF}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_recursive_tree", "examples\shapes_recursive_tree.vcxproj", "{DFB40A10-F8B7-412A-BCC3-5EE49294D816}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_triangle_strip", "examples\shapes_triangle_strip.vcxproj", "{BB58A5FB-1A35-4471-86D0-A5189EC541B3}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_pie_chart", "examples\shapes_pie_chart.vcxproj", "{61997220-5383-4AE5-ABD4-5F45AE1B0F2A}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_directory_files", "examples\core_directory_files.vcxproj", "{7467E9AE-844F-444D-8A3F-17397544BA21}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_simple_particles", "examples\shapes_simple_particles.vcxproj", "{497FDF54-9762-4048-A833-61CC3980A0FB}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_words_alignment", "examples\text_words_alignment.vcxproj", "{29B00F47-BE91-4A1F-B87D-B1302F038316}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_clipboard_text", "examples\core_clipboard_text.vcxproj", "{124935CC-73BB-489E-92E8-4F922A85DB5D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_clock_of_clocks", "examples\shapes_clock_of_clocks.vcxproj", "{AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_mouse_trail", "examples\shapes_mouse_trail.vcxproj", "{0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_starfield", "examples\shapes_starfield.vcxproj", "{EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -4291,30 +4313,30 @@ Global
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release|x64.Build.0 = Release|x64
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release|x86.ActiveCfg = Release|Win32
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release|x86.Build.0 = Release|Win32
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|ARM64.ActiveCfg = Debug|ARM64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|ARM64.Build.0 = Debug|ARM64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x64.ActiveCfg = Debug|x64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x64.Build.0 = Debug|x64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x86.ActiveCfg = Debug|Win32
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x86.Build.0 = Debug|Win32
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x64.Build.0 = Release.DLL|x64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x86.Build.0 = Release.DLL|Win32
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|ARM64.ActiveCfg = Release|ARM64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|ARM64.Build.0 = Release|ARM64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x64.ActiveCfg = Release|x64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x64.Build.0 = Release|x64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x86.ActiveCfg = Release|Win32
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x86.Build.0 = Release|Win32
+ {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
+ {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
+ {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug|ARM64.Build.0 = Debug|ARM64
+ {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug|x64.ActiveCfg = Debug|x64
+ {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug|x64.Build.0 = Debug|x64
+ {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug|x86.ActiveCfg = Debug|Win32
+ {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug|x86.Build.0 = Debug|Win32
+ {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
+ {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
+ {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release|ARM64.ActiveCfg = Release|ARM64
+ {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release|ARM64.Build.0 = Release|ARM64
+ {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release|x64.ActiveCfg = Release|x64
+ {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release|x64.Build.0 = Release|x64
+ {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release|x86.ActiveCfg = Release|Win32
+ {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release|x86.Build.0 = Release|Win32
{2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
{2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
{2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
@@ -4387,126 +4409,390 @@ Global
{52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release|x64.Build.0 = Release|x64
{52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release|x86.ActiveCfg = Release|Win32
{52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release|x86.Build.0 = Release|Win32
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|ARM64.ActiveCfg = Debug|ARM64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|ARM64.Build.0 = Debug|ARM64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x64.ActiveCfg = Debug|x64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x64.Build.0 = Debug|x64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x86.ActiveCfg = Debug|Win32
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x86.Build.0 = Debug|Win32
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x64.Build.0 = Release.DLL|x64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x86.Build.0 = Release.DLL|Win32
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|ARM64.ActiveCfg = Release|ARM64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|ARM64.Build.0 = Release|ARM64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x64.ActiveCfg = Release|x64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x64.Build.0 = Release|x64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x86.ActiveCfg = Release|Win32
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x86.Build.0 = Release|Win32
- {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
- {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
- {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
- {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
- {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
- {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
- {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|ARM64.ActiveCfg = Debug|ARM64
- {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|ARM64.Build.0 = Debug|ARM64
- {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|x64.ActiveCfg = Debug|x64
- {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|x64.Build.0 = Debug|x64
- {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|x86.ActiveCfg = Debug|Win32
- {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|x86.Build.0 = Debug|Win32
- {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
- {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
- {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
- {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|x64.Build.0 = Release.DLL|x64
- {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
- {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|x86.Build.0 = Release.DLL|Win32
- {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|ARM64.ActiveCfg = Release|ARM64
- {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|ARM64.Build.0 = Release|ARM64
- {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|x64.ActiveCfg = Release|x64
- {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|x64.Build.0 = Release|x64
- {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|x86.ActiveCfg = Release|Win32
- {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|x86.Build.0 = Release|Win32
- {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
- {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
- {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
- {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
- {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
- {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
- {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug|ARM64.ActiveCfg = Debug|ARM64
- {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug|ARM64.Build.0 = Debug|ARM64
- {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug|x64.ActiveCfg = Debug|x64
- {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug|x64.Build.0 = Debug|x64
- {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug|x86.ActiveCfg = Debug|Win32
- {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug|x86.Build.0 = Debug|Win32
- {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
- {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
- {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
- {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release.DLL|x64.Build.0 = Release.DLL|x64
- {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
- {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release.DLL|x86.Build.0 = Release.DLL|Win32
- {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release|ARM64.ActiveCfg = Release|ARM64
- {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release|ARM64.Build.0 = Release|ARM64
- {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release|x64.ActiveCfg = Release|x64
- {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release|x64.Build.0 = Release|x64
- {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release|x86.ActiveCfg = Release|Win32
- {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release|x86.Build.0 = Release|Win32
- {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
- {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
- {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
- {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
- {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
- {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
- {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug|ARM64.ActiveCfg = Debug|ARM64
- {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug|ARM64.Build.0 = Debug|ARM64
- {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug|x64.ActiveCfg = Debug|x64
- {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug|x64.Build.0 = Debug|x64
- {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug|x86.ActiveCfg = Debug|Win32
- {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug|x86.Build.0 = Debug|Win32
- {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
- {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
- {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
- {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release.DLL|x64.Build.0 = Release.DLL|x64
- {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
- {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release.DLL|x86.Build.0 = Release.DLL|Win32
- {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release|ARM64.ActiveCfg = Release|ARM64
- {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release|ARM64.Build.0 = Release|ARM64
- {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release|x64.ActiveCfg = Release|x64
- {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release|x64.Build.0 = Release|x64
- {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release|x86.ActiveCfg = Release|Win32
- {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release|x86.Build.0 = Release|Win32
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|ARM64.ActiveCfg = Debug|ARM64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|ARM64.Build.0 = Debug|ARM64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x64.ActiveCfg = Debug|x64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x64.Build.0 = Debug|x64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x86.ActiveCfg = Debug|Win32
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x86.Build.0 = Debug|Win32
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x64.Build.0 = Release.DLL|x64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x86.Build.0 = Release.DLL|Win32
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|ARM64.ActiveCfg = Release|ARM64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|ARM64.Build.0 = Release|ARM64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x64.ActiveCfg = Release|x64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x64.Build.0 = Release|x64
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x86.ActiveCfg = Release|Win32
- {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x86.Build.0 = Release|Win32
+ {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
+ {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
+ {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug|ARM64.Build.0 = Debug|ARM64
+ {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug|x64.ActiveCfg = Debug|x64
+ {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug|x64.Build.0 = Debug|x64
+ {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug|x86.ActiveCfg = Debug|Win32
+ {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug|x86.Build.0 = Debug|Win32
+ {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
+ {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
+ {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release|ARM64.ActiveCfg = Release|ARM64
+ {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release|ARM64.Build.0 = Release|ARM64
+ {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release|x64.ActiveCfg = Release|x64
+ {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release|x64.Build.0 = Release|x64
+ {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release|x86.ActiveCfg = Release|Win32
+ {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release|x86.Build.0 = Release|Win32
+ {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
+ {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
+ {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug|ARM64.Build.0 = Debug|ARM64
+ {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug|x64.ActiveCfg = Debug|x64
+ {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug|x64.Build.0 = Debug|x64
+ {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug|x86.ActiveCfg = Debug|Win32
+ {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug|x86.Build.0 = Debug|Win32
+ {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
+ {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
+ {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release|ARM64.ActiveCfg = Release|ARM64
+ {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release|ARM64.Build.0 = Release|ARM64
+ {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release|x64.ActiveCfg = Release|x64
+ {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release|x64.Build.0 = Release|x64
+ {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release|x86.ActiveCfg = Release|Win32
+ {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release|x86.Build.0 = Release|Win32
+ {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
+ {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
+ {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug|ARM64.Build.0 = Debug|ARM64
+ {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug|x64.ActiveCfg = Debug|x64
+ {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug|x64.Build.0 = Debug|x64
+ {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug|x86.ActiveCfg = Debug|Win32
+ {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug|x86.Build.0 = Debug|Win32
+ {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
+ {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
+ {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release|ARM64.ActiveCfg = Release|ARM64
+ {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release|ARM64.Build.0 = Release|ARM64
+ {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release|x64.ActiveCfg = Release|x64
+ {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release|x64.Build.0 = Release|x64
+ {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release|x86.ActiveCfg = Release|Win32
+ {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release|x86.Build.0 = Release|Win32
+ {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
+ {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
+ {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug|ARM64.Build.0 = Debug|ARM64
+ {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug|x64.ActiveCfg = Debug|x64
+ {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug|x64.Build.0 = Debug|x64
+ {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug|x86.ActiveCfg = Debug|Win32
+ {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug|x86.Build.0 = Debug|Win32
+ {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
+ {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
+ {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release|ARM64.ActiveCfg = Release|ARM64
+ {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release|ARM64.Build.0 = Release|ARM64
+ {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release|x64.ActiveCfg = Release|x64
+ {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release|x64.Build.0 = Release|x64
+ {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release|x86.ActiveCfg = Release|Win32
+ {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release|x86.Build.0 = Release|Win32
+ {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
+ {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
+ {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug|ARM64.Build.0 = Debug|ARM64
+ {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug|x64.ActiveCfg = Debug|x64
+ {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug|x64.Build.0 = Debug|x64
+ {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug|x86.ActiveCfg = Debug|Win32
+ {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug|x86.Build.0 = Debug|Win32
+ {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
+ {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
+ {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release|ARM64.ActiveCfg = Release|ARM64
+ {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release|ARM64.Build.0 = Release|ARM64
+ {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release|x64.ActiveCfg = Release|x64
+ {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release|x64.Build.0 = Release|x64
+ {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release|x86.ActiveCfg = Release|Win32
+ {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release|x86.Build.0 = Release|Win32
+ {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
+ {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
+ {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug|ARM64.Build.0 = Debug|ARM64
+ {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug|x64.ActiveCfg = Debug|x64
+ {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug|x64.Build.0 = Debug|x64
+ {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug|x86.ActiveCfg = Debug|Win32
+ {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug|x86.Build.0 = Debug|Win32
+ {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
+ {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
+ {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release|ARM64.ActiveCfg = Release|ARM64
+ {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release|ARM64.Build.0 = Release|ARM64
+ {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release|x64.ActiveCfg = Release|x64
+ {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release|x64.Build.0 = Release|x64
+ {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release|x86.ActiveCfg = Release|Win32
+ {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release|x86.Build.0 = Release|Win32
+ {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
+ {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
+ {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug|ARM64.Build.0 = Debug|ARM64
+ {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug|x64.ActiveCfg = Debug|x64
+ {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug|x64.Build.0 = Debug|x64
+ {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug|x86.ActiveCfg = Debug|Win32
+ {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug|x86.Build.0 = Debug|Win32
+ {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
+ {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
+ {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release|ARM64.ActiveCfg = Release|ARM64
+ {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release|ARM64.Build.0 = Release|ARM64
+ {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release|x64.ActiveCfg = Release|x64
+ {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release|x64.Build.0 = Release|x64
+ {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release|x86.ActiveCfg = Release|Win32
+ {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release|x86.Build.0 = Release|Win32
+ {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
+ {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
+ {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug|ARM64.Build.0 = Debug|ARM64
+ {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug|x64.ActiveCfg = Debug|x64
+ {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug|x64.Build.0 = Debug|x64
+ {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug|x86.ActiveCfg = Debug|Win32
+ {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug|x86.Build.0 = Debug|Win32
+ {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
+ {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
+ {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release|ARM64.ActiveCfg = Release|ARM64
+ {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release|ARM64.Build.0 = Release|ARM64
+ {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release|x64.ActiveCfg = Release|x64
+ {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release|x64.Build.0 = Release|x64
+ {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release|x86.ActiveCfg = Release|Win32
+ {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release|x86.Build.0 = Release|Win32
+ {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
+ {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
+ {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug|ARM64.Build.0 = Debug|ARM64
+ {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug|x64.ActiveCfg = Debug|x64
+ {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug|x64.Build.0 = Debug|x64
+ {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug|x86.ActiveCfg = Debug|Win32
+ {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug|x86.Build.0 = Debug|Win32
+ {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
+ {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
+ {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release|ARM64.ActiveCfg = Release|ARM64
+ {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release|ARM64.Build.0 = Release|ARM64
+ {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release|x64.ActiveCfg = Release|x64
+ {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release|x64.Build.0 = Release|x64
+ {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release|x86.ActiveCfg = Release|Win32
+ {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release|x86.Build.0 = Release|Win32
+ {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
+ {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
+ {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug|ARM64.Build.0 = Debug|ARM64
+ {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug|x64.ActiveCfg = Debug|x64
+ {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug|x64.Build.0 = Debug|x64
+ {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug|x86.ActiveCfg = Debug|Win32
+ {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug|x86.Build.0 = Debug|Win32
+ {7467E9AE-844F-444D-8A3F-17397544BA21}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
+ {7467E9AE-844F-444D-8A3F-17397544BA21}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
+ {7467E9AE-844F-444D-8A3F-17397544BA21}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {7467E9AE-844F-444D-8A3F-17397544BA21}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {7467E9AE-844F-444D-8A3F-17397544BA21}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {7467E9AE-844F-444D-8A3F-17397544BA21}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {7467E9AE-844F-444D-8A3F-17397544BA21}.Release|ARM64.ActiveCfg = Release|ARM64
+ {7467E9AE-844F-444D-8A3F-17397544BA21}.Release|ARM64.Build.0 = Release|ARM64
+ {7467E9AE-844F-444D-8A3F-17397544BA21}.Release|x64.ActiveCfg = Release|x64
+ {7467E9AE-844F-444D-8A3F-17397544BA21}.Release|x64.Build.0 = Release|x64
+ {7467E9AE-844F-444D-8A3F-17397544BA21}.Release|x86.ActiveCfg = Release|Win32
+ {7467E9AE-844F-444D-8A3F-17397544BA21}.Release|x86.Build.0 = Release|Win32
+ {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
+ {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
+ {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug|ARM64.Build.0 = Debug|ARM64
+ {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug|x64.ActiveCfg = Debug|x64
+ {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug|x64.Build.0 = Debug|x64
+ {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug|x86.ActiveCfg = Debug|Win32
+ {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug|x86.Build.0 = Debug|Win32
+ {497FDF54-9762-4048-A833-61CC3980A0FB}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
+ {497FDF54-9762-4048-A833-61CC3980A0FB}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
+ {497FDF54-9762-4048-A833-61CC3980A0FB}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {497FDF54-9762-4048-A833-61CC3980A0FB}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {497FDF54-9762-4048-A833-61CC3980A0FB}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {497FDF54-9762-4048-A833-61CC3980A0FB}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {497FDF54-9762-4048-A833-61CC3980A0FB}.Release|ARM64.ActiveCfg = Release|ARM64
+ {497FDF54-9762-4048-A833-61CC3980A0FB}.Release|ARM64.Build.0 = Release|ARM64
+ {497FDF54-9762-4048-A833-61CC3980A0FB}.Release|x64.ActiveCfg = Release|x64
+ {497FDF54-9762-4048-A833-61CC3980A0FB}.Release|x64.Build.0 = Release|x64
+ {497FDF54-9762-4048-A833-61CC3980A0FB}.Release|x86.ActiveCfg = Release|Win32
+ {497FDF54-9762-4048-A833-61CC3980A0FB}.Release|x86.Build.0 = Release|Win32
+ {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
+ {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
+ {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug|ARM64.Build.0 = Debug|ARM64
+ {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug|x64.ActiveCfg = Debug|x64
+ {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug|x64.Build.0 = Debug|x64
+ {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug|x86.ActiveCfg = Debug|Win32
+ {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug|x86.Build.0 = Debug|Win32
+ {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
+ {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
+ {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release|ARM64.ActiveCfg = Release|ARM64
+ {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release|ARM64.Build.0 = Release|ARM64
+ {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release|x64.ActiveCfg = Release|x64
+ {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release|x64.Build.0 = Release|x64
+ {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release|x86.ActiveCfg = Release|Win32
+ {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release|x86.Build.0 = Release|Win32
+ {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
+ {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
+ {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug|ARM64.Build.0 = Debug|ARM64
+ {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug|x64.ActiveCfg = Debug|x64
+ {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug|x64.Build.0 = Debug|x64
+ {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug|x86.ActiveCfg = Debug|Win32
+ {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug|x86.Build.0 = Debug|Win32
+ {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
+ {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
+ {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release|ARM64.ActiveCfg = Release|ARM64
+ {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release|ARM64.Build.0 = Release|ARM64
+ {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release|x64.ActiveCfg = Release|x64
+ {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release|x64.Build.0 = Release|x64
+ {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release|x86.ActiveCfg = Release|Win32
+ {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release|x86.Build.0 = Release|Win32
+ {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
+ {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
+ {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug|ARM64.Build.0 = Debug|ARM64
+ {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug|x64.ActiveCfg = Debug|x64
+ {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug|x64.Build.0 = Debug|x64
+ {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug|x86.ActiveCfg = Debug|Win32
+ {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug|x86.Build.0 = Debug|Win32
+ {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
+ {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
+ {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release|ARM64.ActiveCfg = Release|ARM64
+ {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release|ARM64.Build.0 = Release|ARM64
+ {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release|x64.ActiveCfg = Release|x64
+ {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release|x64.Build.0 = Release|x64
+ {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release|x86.ActiveCfg = Release|Win32
+ {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release|x86.Build.0 = Release|Win32
+ {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
+ {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
+ {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug|ARM64.Build.0 = Debug|ARM64
+ {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug|x64.ActiveCfg = Debug|x64
+ {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug|x64.Build.0 = Debug|x64
+ {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug|x86.ActiveCfg = Debug|Win32
+ {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug|x86.Build.0 = Debug|Win32
+ {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
+ {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
+ {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release|ARM64.ActiveCfg = Release|ARM64
+ {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release|ARM64.Build.0 = Release|ARM64
+ {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release|x64.ActiveCfg = Release|x64
+ {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release|x64.Build.0 = Release|x64
+ {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release|x86.ActiveCfg = Release|Win32
+ {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release|x86.Build.0 = Release|Win32
+ {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
+ {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
+ {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug|ARM64.Build.0 = Debug|ARM64
+ {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug|x64.ActiveCfg = Debug|x64
+ {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug|x64.Build.0 = Debug|x64
+ {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug|x86.ActiveCfg = Debug|Win32
+ {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug|x86.Build.0 = Debug|Win32
+ {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
+ {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
+ {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release|ARM64.ActiveCfg = Release|ARM64
+ {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release|ARM64.Build.0 = Release|ARM64
+ {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release|x64.ActiveCfg = Release|x64
+ {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release|x64.Build.0 = Release|x64
+ {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release|x86.ActiveCfg = Release|Win32
+ {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -4674,7 +4960,7 @@ Global
{C54703BF-D68A-480D-BE27-49B62E45D582} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9}
{9CD8BCAD-F212-4BCC-BA98-899743CE3279} = {CC132A4D-D081-4C26-BFB9-AB11984054F8}
{0981CA28-E4A5-4DF1-987F-A41D09131EFC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
- {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A}
{6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9}
{6777EC3C-077C-42FC-B4AD-B799CE55CCE4} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A}
{A61DAD9C-271C-4E95-81AA-DB4CD58564D4} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
@@ -4682,14 +4968,26 @@ Global
{D496308F-3C3C-40B3-A3ED-EA327D244B3E} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A}
{3B27F358-2679-4F38-B297-17B536F580BB} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
- {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
- {2CCCD9E4-9058-4291-BD89-39C979F0CA1E} = {278D8859-20B1-428F-8448-064F46E1F021}
+ {19CA0070-B4B2-4394-90B7-D0C259AA35BA} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
+ {2CCCD9E4-9058-4291-BD89-39C979F0CA1E} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
{9DB1F875-6E65-4195-B23F-ED8095C0B99C} = {278D8859-20B1-428F-8448-064F46E1F021}
- {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}
- {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {278D8859-20B1-428F-8448-064F46E1F021}
- {2CCCD9E4-9058-4291-BD89-39C979F0CA1E} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}
- {9DB1F875-6E65-4195-B23F-ED8095C0B99C} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9}
- {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
+ {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F} = {278D8859-20B1-428F-8448-064F46E1F021}
+ {8E132D5A-2C00-48D0-8747-97E41356F26F} = {278D8859-20B1-428F-8448-064F46E1F021}
+ {A4662163-83E7-4309-8CAA-B0BF13655FE6} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}
+ {5F4B766F-DD52-4B53-B6C3-BC7611E17F20} = {278D8859-20B1-428F-8448-064F46E1F021}
+ {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
+ {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC} = {E9D708A5-9C1F-4B84-A795-C5F191801762}
+ {0C442799-B09C-4CD1-9538-711B6E85E9BF} = {278D8859-20B1-428F-8448-064F46E1F021}
+ {DFB40A10-F8B7-412A-BCC3-5EE49294D816} = {278D8859-20B1-428F-8448-064F46E1F021}
+ {BB58A5FB-1A35-4471-86D0-A5189EC541B3} = {278D8859-20B1-428F-8448-064F46E1F021}
+ {61997220-5383-4AE5-ABD4-5F45AE1B0F2A} = {278D8859-20B1-428F-8448-064F46E1F021}
+ {7467E9AE-844F-444D-8A3F-17397544BA21} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
+ {497FDF54-9762-4048-A833-61CC3980A0FB} = {278D8859-20B1-428F-8448-064F46E1F021}
+ {29B00F47-BE91-4A1F-B87D-B1302F038316} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A}
+ {124935CC-73BB-489E-92E8-4F922A85DB5D} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
+ {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F} = {278D8859-20B1-428F-8448-064F46E1F021}
+ {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2} = {278D8859-20B1-428F-8448-064F46E1F021}
+ {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91} = {278D8859-20B1-428F-8448-064F46E1F021}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29}
diff --git a/src/Makefile b/src/Makefile
index e767d21d0..0d4ca9ac7 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -519,7 +519,7 @@ endif
#------------------------------------------------------------------------------------------------
LDFLAGS = $(CUSTOM_LDFLAGS) -L. -L$(RAYLIB_RELEASE_PATH)
-ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
+ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW PLATFORM_DESKTOP_SDL PLATFORM_DESKTOP_RGFW))
ifeq ($(PLATFORM_OS),WINDOWS)
ifneq ($(CC), tcc)
LDFLAGS += -Wl,--out-implib,$(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME)dll.a
@@ -536,7 +536,6 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
endif
endif
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_SDL)
- LDFLAGS += -Wl,-soname,lib$(RAYLIB_LIB_NAME).so.$(RAYLIB_API_VERSION)
LDFLAGS += -L$(SDL_LIBRARY_PATH)
endif
ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW))
diff --git a/src/external/RGFW.h b/src/external/RGFW.h
index 8bd9b5709..7205bf9d8 100644
--- a/src/external/RGFW.h
+++ b/src/external/RGFW.h
@@ -7727,8 +7727,8 @@ RGFW_bool RGFW_monitor_requestMode(RGFW_monitor mon, RGFW_monitorMode mode, RGFW
dm.dmBitsPerPel = (DWORD)(mode.red + mode.green + mode.blue);
}
- if (ChangeDisplaySettingsEx(dd.DeviceName, &dm, NULL, CDS_TEST, NULL) == DISP_CHANGE_SUCCESSFUL) {
- if (ChangeDisplaySettingsEx(dd.DeviceName, &dm, NULL, CDS_UPDATEREGISTRY, NULL) == DISP_CHANGE_SUCCESSFUL)
+ if (ChangeDisplaySettingsExA((LPCSTR)dd.DeviceName, (DEVMODE *)&dm, NULL, CDS_TEST, NULL) == DISP_CHANGE_SUCCESSFUL) {
+ if (ChangeDisplaySettingsExA((LPCSTR)dd.DeviceName, (DEVMODE *)&dm, NULL, CDS_UPDATEREGISTRY, NULL) == DISP_CHANGE_SUCCESSFUL)
return RGFW_TRUE;
return RGFW_FALSE;
} else return RGFW_FALSE;
diff --git a/src/external/glfw/src/context.c b/src/external/glfw/src/context.c
index cc1fac4f3..bcb2b51b8 100644
--- a/src/external/glfw/src/context.c
+++ b/src/external/glfw/src/context.c
@@ -359,7 +359,7 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
window->context.source = ctxconfig->source;
window->context.client = GLFW_OPENGL_API;
- previous = _glfwPlatformGetTls(&_glfw.contextSlot);
+ previous = (_GLFWwindow *)_glfwPlatformGetTls(&_glfw.contextSlot);
glfwMakeContextCurrent((GLFWwindow*) window);
if (_glfwPlatformGetTls(&_glfw.contextSlot) != window)
return GLFW_FALSE;
@@ -615,12 +615,12 @@ GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions
GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle)
{
- _GLFWwindow* window = (_GLFWwindow*) handle;
+ _GLFWwindow* window = (_GLFWwindow *) handle;
_GLFWwindow* previous;
_GLFW_REQUIRE_INIT();
- previous = _glfwPlatformGetTls(&_glfw.contextSlot);
+ previous = (_GLFWwindow *)_glfwPlatformGetTls(&_glfw.contextSlot);
if (window && window->context.client == GLFW_NO_API)
{
@@ -642,12 +642,12 @@ GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle)
GLFWAPI GLFWwindow* glfwGetCurrentContext(void)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
- return _glfwPlatformGetTls(&_glfw.contextSlot);
+ return (GLFWwindow *)_glfwPlatformGetTls(&_glfw.contextSlot);
}
GLFWAPI void glfwSwapBuffers(GLFWwindow* handle)
{
- _GLFWwindow* window = (_GLFWwindow*) handle;
+ _GLFWwindow* window = (_GLFWwindow *) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
@@ -668,7 +668,7 @@ GLFWAPI void glfwSwapInterval(int interval)
_GLFW_REQUIRE_INIT();
- window = _glfwPlatformGetTls(&_glfw.contextSlot);
+ window = (_GLFWwindow *)_glfwPlatformGetTls(&_glfw.contextSlot);
if (!window)
{
_glfwInputError(GLFW_NO_CURRENT_CONTEXT,
@@ -686,7 +686,7 @@ GLFWAPI int glfwExtensionSupported(const char* extension)
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
- window = _glfwPlatformGetTls(&_glfw.contextSlot);
+ window = (_GLFWwindow *)_glfwPlatformGetTls(&_glfw.contextSlot);
if (!window)
{
_glfwInputError(GLFW_NO_CURRENT_CONTEXT,
@@ -752,7 +752,7 @@ GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
- window = _glfwPlatformGetTls(&_glfw.contextSlot);
+ window = (_GLFWwindow *)_glfwPlatformGetTls(&_glfw.contextSlot);
if (!window)
{
_glfwInputError(GLFW_NO_CURRENT_CONTEXT,
@@ -762,4 +762,3 @@ GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
return window->context.getProcAddress(procname);
}
-
diff --git a/src/external/glfw/src/egl_context.c b/src/external/glfw/src/egl_context.c
index ef65dd350..19ab3dfbe 100644
--- a/src/external/glfw/src/egl_context.c
+++ b/src/external/glfw/src/egl_context.c
@@ -118,10 +118,10 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
return GLFW_FALSE;
}
- nativeConfigs = _glfw_calloc(nativeCount, sizeof(EGLConfig));
+ nativeConfigs = (EGLConfig *)_glfw_calloc(nativeCount, sizeof(EGLConfig));
eglGetConfigs(_glfw.egl.display, nativeConfigs, nativeCount, &nativeCount);
- usableConfigs = _glfw_calloc(nativeCount, sizeof(_GLFWfbconfig));
+ usableConfigs = (_GLFWfbconfig *)_glfw_calloc(nativeCount, sizeof(_GLFWfbconfig));
usableCount = 0;
for (i = 0; i < nativeCount; i++)
@@ -308,7 +308,7 @@ static int extensionSupportedEGL(const char* extension)
static GLFWglproc getProcAddressEGL(const char* procname)
{
- _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
+ _GLFWwindow* window = (_GLFWwindow *)_glfwPlatformGetTls(&_glfw.contextSlot);
assert(window != NULL);
if (window->context.egl.client)
@@ -883,7 +883,7 @@ GLFWAPI EGLDisplay glfwGetEGLDisplay(void)
GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* handle)
{
- _GLFWwindow* window = (_GLFWwindow*) handle;
+ _GLFWwindow* window = (_GLFWwindow *) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_CONTEXT);
if (window->context.source != GLFW_EGL_CONTEXT_API)
@@ -897,7 +897,7 @@ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* handle)
GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle)
{
- _GLFWwindow* window = (_GLFWwindow*) handle;
+ _GLFWwindow* window = (_GLFWwindow *) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_SURFACE);
if (window->context.source != GLFW_EGL_CONTEXT_API)
@@ -908,4 +908,3 @@ GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle)
return window->context.egl.surface;
}
-
diff --git a/src/external/jar_mod.h b/src/external/jar_mod.h
index 2a220f8af..7ecf9f437 100644
--- a/src/external/jar_mod.h
+++ b/src/external/jar_mod.h
@@ -1148,7 +1148,7 @@ static bool jar_mod_load( jar_mod_context_t * modctx, void * mod_data, int mod_d
{
// 15 Samples modules support
// Shift the whole datas to make it look likes a standard 4 channels mod.
- memcopy(&(modctx->song.signature), "M.K.", 4);
+ memcopy(&(modctx->song.signature), (void *)"M.K.", 4);
memcopy(&(modctx->song.length), &(modctx->song.samples[15]), 130);
memclear(&(modctx->song.samples[15]), 0, 480);
modmemory += 600;
@@ -1535,13 +1535,13 @@ mulong jar_mod_load_file(jar_mod_context_t * modctx, const char* filename)
if(fsize && fsize < 32*1024*1024)
{
- modctx->modfile = JARMOD_MALLOC(fsize);
+ modctx->modfile = (muchar *) JARMOD_MALLOC(fsize);
modctx->modfilesize = fsize;
memset(modctx->modfile, 0, fsize);
fread(modctx->modfile, fsize, 1, f);
fclose(f);
-
- if(!jar_mod_load(modctx, (void*)modctx->modfile, fsize)) fsize = 0;
+
+ if(!jar_mod_load(modctx, (void *)modctx->modfile, fsize)) fsize = 0;
} else fsize = 0;
}
return fsize;
diff --git a/src/external/jar_xm.h b/src/external/jar_xm.h
index 174c1704c..849fe62f4 100644
--- a/src/external/jar_xm.h
+++ b/src/external/jar_xm.h
@@ -123,7 +123,7 @@ void jar_xm_generate_samples(jar_xm_context_t* ctx, float* output, size_t numsam
// * @param output buffer of 2*numsamples elements (A left and right value for each sample)
// * @param numsamples number of samples to generate
void jar_xm_generate_samples_16bit(jar_xm_context_t* ctx, short* output, size_t numsamples) {
- float* musicBuffer = JARXM_MALLOC((2*numsamples)*sizeof(float));
+ float* musicBuffer = (float *)JARXM_MALLOC((2*numsamples)*sizeof(float));
jar_xm_generate_samples(ctx, musicBuffer, numsamples);
if(output){
@@ -136,7 +136,7 @@ void jar_xm_generate_samples_16bit(jar_xm_context_t* ctx, short* output, size_t
// * @param output buffer of 2*numsamples elements (A left and right value for each sample)
// * @param numsamples number of samples to generate
void jar_xm_generate_samples_8bit(jar_xm_context_t* ctx, char* output, size_t numsamples) {
- float* musicBuffer = JARXM_MALLOC((2*numsamples)*sizeof(float));
+ float* musicBuffer = (float *)JARXM_MALLOC((2*numsamples)*sizeof(float));
jar_xm_generate_samples(ctx, musicBuffer, numsamples);
if(output){
@@ -543,7 +543,7 @@ int jar_xm_create_context_safe(jar_xm_context_t** ctxp, const char* moddata, siz
#endif
bytes_needed = jar_xm_get_memory_needed_for_context(moddata, moddata_length);
- mempool = JARXM_MALLOC(bytes_needed);
+ mempool = (char *)JARXM_MALLOC(bytes_needed);
if(mempool == NULL && bytes_needed > 0) { /* JARXM_MALLOC() failed, trouble ahead */
DEBUG("call to JARXM_MALLOC() failed, returned %p", (void*)mempool);
return 2;
@@ -558,11 +558,11 @@ int jar_xm_create_context_safe(jar_xm_context_t** ctxp, const char* moddata, siz
ctx->rate = rate;
mempool = jar_xm_load_module(ctx, moddata, moddata_length, mempool);
- mempool = ALIGN_PTR(mempool, 16);
+ mempool = (char *)ALIGN_PTR(mempool, 16);
ctx->channels = (jar_xm_channel_context_t*)mempool;
mempool += ctx->module.num_channels * sizeof(jar_xm_channel_context_t);
- mempool = ALIGN_PTR(mempool, 16);
+ mempool = (char *)ALIGN_PTR(mempool, 16);
ctx->default_global_volume = 1.f;
ctx->global_volume = ctx->default_global_volume;
@@ -583,7 +583,7 @@ int jar_xm_create_context_safe(jar_xm_context_t** ctxp, const char* moddata, siz
ch->actual_panning = .5f;
}
- mempool = ALIGN_PTR(mempool, 16);
+ mempool = (char *)ALIGN_PTR(mempool, 16);
ctx->row_loop_count = (uint8_t *)mempool;
mempool += MAX_NUM_ROWS * sizeof(uint8_t);
@@ -681,14 +681,14 @@ uint64_t jar_xm_get_latest_trigger_of_channel(jar_xm_context_t *ctx, uint16_t ch
//* Bound reader macros.
//* If we attempt to read the buffer out-of-bounds, pretend that the buffer is infinitely padded with zeroes.
-#define READ_U8(offset) (((offset) < moddata_length) ? (*(uint8_t*)(moddata + (offset))) : 0)
+#define READ_U8(offset) (((offset) < moddata_length) ? (*(uint8_t *)(moddata + (offset))) : 0)
#define READ_U16(offset) ((uint16_t)READ_U8(offset) | ((uint16_t)READ_U8((offset) + 1) << 8))
#define READ_U32(offset) ((uint32_t)READ_U16(offset) | ((uint32_t)READ_U16((offset) + 2) << 16))
#define READ_MEMCPY(ptr, offset, length) memcpy_pad(ptr, length, moddata, moddata_length, offset)
static void memcpy_pad(void *dst, size_t dst_len, const void *src, size_t src_len, size_t offset) {
- uint8_t *dst_c = dst;
- const uint8_t *src_c = src;
+ uint8_t *dst_c = (uint8_t *)dst;
+ const uint8_t *src_c = (uint8_t *)src;
/* how many bytes can be copied without overrunning `src` */
size_t copy_bytes = (src_len >= offset) ? (src_len - offset) : 0;
@@ -808,10 +808,10 @@ char* jar_xm_load_module(jar_xm_context_t* ctx, const char* moddata, size_t modd
mod->linear_interpolation = 1; // Linear interpolation can be set after loading
mod->ramping = 1; // ramping can be set after loading
mempool += mod->num_patterns * sizeof(jar_xm_pattern_t);
- mempool = ALIGN_PTR(mempool, 16);
+ mempool = (char *)ALIGN_PTR(mempool, 16);
mod->instruments = (jar_xm_instrument_t*)mempool;
mempool += mod->num_instruments * sizeof(jar_xm_instrument_t);
- mempool = ALIGN_PTR(mempool, 16);
+ mempool = (char *)ALIGN_PTR(mempool, 16);
uint16_t flags = READ_U32(offset + 14);
mod->frequency_type = (flags & (1 << 0)) ? jar_xm_LINEAR_FREQUENCIES : jar_xm_AMIGA_FREQUENCIES;
ctx->default_tempo = READ_U16(offset + 16);
@@ -884,7 +884,7 @@ char* jar_xm_load_module(jar_xm_context_t* ctx, const char* moddata, size_t modd
offset += packed_patterndata_size;
}
- mempool = ALIGN_PTR(mempool, 16);
+ mempool = (char *)ALIGN_PTR(mempool, 16);
/* Read instruments */
for(uint16_t i = 0; i < ctx->module.num_instruments; ++i) {
@@ -928,11 +928,11 @@ char* jar_xm_load_module(jar_xm_context_t* ctx, const char* moddata, size_t modd
instr->panning_envelope.enabled = flags & (1 << 0);
instr->panning_envelope.sustain_enabled = flags & (1 << 1);
instr->panning_envelope.loop_enabled = flags & (1 << 2);
- instr->vibrato_type = READ_U8(offset + 235);
+ instr->vibrato_type = (jar_xm_waveform_type_t)READ_U8(offset + 235);
if(instr->vibrato_type == 2) {
- instr->vibrato_type = 1;
+ instr->vibrato_type = (jar_xm_waveform_type_t)1;
} else if(instr->vibrato_type == 1) {
- instr->vibrato_type = 2;
+ instr->vibrato_type = (jar_xm_waveform_type_t)2;
}
instr->vibrato_sweep = READ_U8(offset + 236);
instr->vibrato_depth = READ_U8(offset + 237);
@@ -976,7 +976,7 @@ char* jar_xm_load_module(jar_xm_context_t* ctx, const char* moddata, size_t modd
sample->panning = (float)READ_U8(offset + 15) / 255.f;
sample->relative_note = (int8_t)READ_U8(offset + 16);
READ_MEMCPY(sample->name, 18, SAMPLE_NAME_LENGTH);
- sample->data = (float*)mempool;
+ sample->data = (float *)mempool;
if(sample->bits == 16) {
/* 16 bit sample */
mempool += sample->length * (sizeof(float) >> 1);
@@ -1475,7 +1475,7 @@ static void jar_xm_handle_note_and_instrument(jar_xm_context_t* ctx, jar_xm_chan
jar_xm_pitch_slide(ctx, ch, ch->fine_portamento_down_param);
break;
case 4: /* E4y: Set vibrato control */
- ch->vibrato_waveform = s->effect_param & 3;
+ ch->vibrato_waveform = (jar_xm_waveform_type_t)(s->effect_param & 3);
ch->vibrato_waveform_retrigger = !((s->effect_param >> 2) & 1);
break;
case 5: /* E5y: Set finetune */
@@ -1502,7 +1502,7 @@ static void jar_xm_handle_note_and_instrument(jar_xm_context_t* ctx, jar_xm_chan
}
break;
case 7: /* E7y: Set tremolo control */
- ch->tremolo_waveform = s->effect_param & 3;
+ ch->tremolo_waveform = (jar_xm_waveform_type_t)(s->effect_param & 3);
ch->tremolo_waveform_retrigger = !((s->effect_param >> 2) & 1);
break;
case 0xA: /* EAy: Fine volume slide up */
@@ -2223,7 +2223,7 @@ int jar_xm_create_context_from_file(jar_xm_context_t** ctx, uint32_t rate, const
return 4;
}
- char* data = JARXM_MALLOC(size + 1);
+ char* data = (char *)JARXM_MALLOC(size + 1);
if(!data || fread(data, 1, size, xmf) < size) {
fclose(xmf);
DEBUG_ERR(data ? "fread() failed" : "JARXM_MALLOC() failed");
diff --git a/src/external/miniaudio.h b/src/external/miniaudio.h
index c74bebeb3..b7e7a54dd 100644
--- a/src/external/miniaudio.h
+++ b/src/external/miniaudio.h
@@ -1,6 +1,6 @@
/*
Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file.
-miniaudio - v0.11.22 - 2025-02-24
+miniaudio - v0.11.23 - 2025-09-11
David Reid - mackron@gmail.com
@@ -12,18 +12,10 @@ GitHub: https://github.com/mackron/miniaudio
/*
1. Introduction
===============
-To use miniaudio, include "miniaudio.h":
-
- ```c
- #include "miniaudio.h"
- ```
-
-The implementation is contained in "miniaudio.c". Just compile this like any other source file. You
-can include miniaudio.c if you want to compile your project as a single translation unit:
-
- ```c
- #include "miniaudio.c"
- ```
+To use miniaudio, just include "miniaudio.h" like any other header and add "miniaudio.c" to your
+source tree. If you don't want to add it to your source tree you can compile and link to it like
+any other library. Note that ABI compatibility is not guaranteed between versions, even with bug
+fix releases, so take care if compiling as a shared object.
miniaudio includes both low level and high level APIs. The low level API is good for those who want
to do all of their mixing themselves and only require a light weight interface to the underlying
@@ -303,7 +295,7 @@ The engine encapsulates both the resource manager and the node graph to create a
use high level API. The resource manager and node graph APIs are covered in more later sections of
this manual.
-The code below shows how you can initialize an engine using it's default configuration.
+The code below shows how you can initialize an engine using its default configuration.
```c
ma_result result;
@@ -391,7 +383,7 @@ Sounds are not started by default. Start a sound with `ma_sound_start()` and sto
`ma_sound_stop()`. When a sound is stopped, it is not rewound to the start. Use
`ma_sound_seek_to_pcm_frame(&sound, 0)` to seek back to the start of a sound. By default, starting
and stopping sounds happens immediately, but sometimes it might be convenient to schedule the sound
-the be started and/or stopped at a specific time. This can be done with the following functions:
+to be started and/or stopped at a specific time. This can be done with the following functions:
```c
ma_sound_set_start_time_in_pcm_frames()
@@ -463,6 +455,11 @@ is at the end, use `ma_sound_at_end()`. Looping of a sound can be controlled wit
miniaudio should work cleanly out of the box without the need to download or install any
dependencies. See below for platform-specific details.
+This library has been designed to be added directly to your source tree which is the preferred way
+of using it, but you can compile it as a normal library if that's your preference. Be careful if
+compiling as a shared object because miniaudio is not ABI compatible between any release, including
+bug fix releases. It's recommended you link statically.
+
Note that GCC and Clang require `-msse2`, `-mavx2`, etc. for SIMD optimizations.
If you get errors about undefined references to `__sync_val_compare_and_swap_8`, `__atomic_load_8`,
@@ -532,7 +529,7 @@ you'll need to disable run-time linking with `MA_NO_RUNTIME_LINKING` and link wi
The Emscripten build emits Web Audio JavaScript directly and should compile cleanly out of the box.
You cannot use `-std=c*` compiler flags, nor `-ansi`.
-You can enable the use of AudioWorkets by defining `MA_ENABLE_AUDIO_WORKLETS` and then compiling
+You can enable the use of AudioWorklets by defining `MA_ENABLE_AUDIO_WORKLETS` and then compiling
with the following options:
-sAUDIO_WORKLET=1 -sWASM_WORKERS=1 -sASYNCIFY
@@ -881,7 +878,7 @@ read data within a certain range of the underlying data. To do this you can use
This is useful if you have a sound bank where many sounds are stored in the same file and you want
the data source to only play one of those sub-sounds. Note that once the range is set, everything
-that takes a position, such as cursors and loop points, should always be relatvie to the start of
+that takes a position, such as cursors and loop points, should always be relative to the start of
the range. When the range is set, any previously defined loop point will be reset.
Custom loop points can also be used with data sources. By default, data sources will loop after
@@ -889,7 +886,7 @@ they reach the end of the data source, but if you need to loop at a specific loc
the following:
```c
- result = ma_data_set_loop_point_in_pcm_frames(pDataSource, loopBegInFrames, loopEndInFrames);
+ result = ma_data_source_set_loop_point_in_pcm_frames(pDataSource, loopBegInFrames, loopEndInFrames);
if (result != MA_SUCCESS) {
return result; // Failed to set the loop point.
}
@@ -3750,7 +3747,7 @@ extern "C" {
#define MA_VERSION_MAJOR 0
#define MA_VERSION_MINOR 11
-#define MA_VERSION_REVISION 22
+#define MA_VERSION_REVISION 23
#define MA_VERSION_STRING MA_XSTRINGIFY(MA_VERSION_MAJOR) "." MA_XSTRINGIFY(MA_VERSION_MINOR) "." MA_XSTRINGIFY(MA_VERSION_REVISION)
#if defined(_MSC_VER) && !defined(__clang__)
@@ -3857,6 +3854,8 @@ typedef ma_uint16 wchar_t;
#define MA_SIZE_MAX 0xFFFFFFFF /* When SIZE_MAX is not defined by the standard library just default to the maximum 32-bit unsigned integer. */
#endif
+#define MA_UINT64_MAX (((ma_uint64)0xFFFFFFFF << 32) | (ma_uint64)0xFFFFFFFF) /* Weird shifting syntax is for VC6 compatibility. */
+
/* Platform/backend detection. */
#if defined(_WIN32) || defined(__COSMOPOLITAN__)
@@ -3865,29 +3864,55 @@ typedef ma_uint16 wchar_t;
#define MA_WIN32_UWP
#elif defined(WINAPI_FAMILY) && (defined(WINAPI_FAMILY_GAMES) && WINAPI_FAMILY == WINAPI_FAMILY_GAMES)
#define MA_WIN32_GDK
+ #elif defined(NXDK)
+ #define MA_WIN32_NXDK
#else
#define MA_WIN32_DESKTOP
#endif
+
+ /* The original Xbox. */
+ #if defined(NXDK) /* <-- Add other Xbox compiler toolchains here, and then add a toolchain-specific define in case we need to discriminate between them later. */
+ #define MA_XBOX
+
+ #if defined(NXDK)
+ #define MA_XBOX_NXDK
+ #endif
+ #endif
#endif
-#if !defined(_WIN32) /* If it's not Win32, assume POSIX. */
+#if defined(__MSDOS__) || defined(MSDOS) || defined(_MSDOS) || defined(__DOS__)
+ #define MA_DOS
+
+ /* No threading allowed on DOS. */
+ #ifndef MA_NO_THREADING
+ #define MA_NO_THREADING
+ #endif
+
+ /* No runtime linking allowed on DOS. */
+ #ifndef MA_NO_RUNTIME_LINKING
+ #define MA_NO_RUNTIME_LINKING
+ #endif
+#endif
+#if !defined(MA_WIN32) && !defined(MA_DOS) /* If it's not Win32, assume POSIX. */
#define MA_POSIX
- /*
- Use the MA_NO_PTHREAD_IN_HEADER option at your own risk. This is intentionally undocumented.
- You can use this to avoid including pthread.h in the header section. The downside is that it
- results in some fixed sized structures being declared for the various types that are used in
- miniaudio. The risk here is that these types might be too small for a given platform. This
- risk is yours to take and no support will be offered if you enable this option.
- */
- #ifndef MA_NO_PTHREAD_IN_HEADER
- #include /* Unfortunate #include, but needed for pthread_t, pthread_mutex_t and pthread_cond_t types. */
- typedef pthread_t ma_pthread_t;
- typedef pthread_mutex_t ma_pthread_mutex_t;
- typedef pthread_cond_t ma_pthread_cond_t;
- #else
- typedef ma_uintptr ma_pthread_t;
- typedef union ma_pthread_mutex_t { char __data[40]; ma_uint64 __alignment; } ma_pthread_mutex_t;
- typedef union ma_pthread_cond_t { char __data[48]; ma_uint64 __alignment; } ma_pthread_cond_t;
+ #if !defined(MA_NO_THREADING)
+ /*
+ Use the MA_NO_PTHREAD_IN_HEADER option at your own risk. This is intentionally undocumented.
+ You can use this to avoid including pthread.h in the header section. The downside is that it
+ results in some fixed sized structures being declared for the various types that are used in
+ miniaudio. The risk here is that these types might be too small for a given platform. This
+ risk is yours to take and no support will be offered if you enable this option.
+ */
+ #ifndef MA_NO_PTHREAD_IN_HEADER
+ #include /* Unfortunate #include, but needed for pthread_t, pthread_mutex_t and pthread_cond_t types. */
+ typedef pthread_t ma_pthread_t;
+ typedef pthread_mutex_t ma_pthread_mutex_t;
+ typedef pthread_cond_t ma_pthread_cond_t;
+ #else
+ typedef ma_uintptr ma_pthread_t;
+ typedef union ma_pthread_mutex_t { char __data[40]; ma_uint64 __alignment; } ma_pthread_mutex_t;
+ typedef union ma_pthread_cond_t { char __data[48]; ma_uint64 __alignment; } ma_pthread_cond_t;
+ #endif
#endif
#if defined(__unix__)
@@ -3914,8 +3939,11 @@ typedef ma_uint16 wchar_t;
#if defined(__PROSPERO__)
#define MA_PROSPERO
#endif
- #if defined(__NX__)
- #define MA_NX
+ #if defined(__3DS__)
+ #define MA_3DS
+ #endif
+ #if defined(__SWITCH__) || defined(__NX__)
+ #define MA_SWITCH
#endif
#if defined(__BEOS__) || defined(__HAIKU__)
#define MA_BEOS
@@ -3925,12 +3953,13 @@ typedef ma_uint16 wchar_t;
#endif
#endif
-#if defined(__has_c_attribute)
- #if __has_c_attribute(fallthrough)
- #define MA_FALLTHROUGH [[fallthrough]]
- #endif
+#if !defined(MA_FALLTHROUGH) && defined(__cplusplus) && __cplusplus >= 201703L
+ #define MA_FALLTHROUGH [[fallthrough]]
#endif
-#if !defined(MA_FALLTHROUGH) && defined(__has_attribute) && (defined(__clang__) || defined(__GNUC__))
+#if !defined(MA_FALLTHROUGH) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L
+ #define MA_FALLTHROUGH [[fallthrough]]
+#endif
+#if !defined(MA_FALLTHROUGH) && defined(__has_attribute)
#if __has_attribute(fallthrough)
#define MA_FALLTHROUGH __attribute__((fallthrough))
#endif
@@ -3967,7 +3996,7 @@ typedef ma_uint16 wchar_t;
#define MA_NO_INLINE __attribute__((noinline))
#else
#define MA_INLINE MA_GNUC_INLINE_HINT
- #define MA_NO_INLINE __attribute__((noinline))
+ #define MA_NO_INLINE
#endif
#elif defined(__WATCOMC__)
#define MA_INLINE __inline
@@ -4350,7 +4379,7 @@ typedef struct
typedef struct
{
- ma_int32 state;
+ ma_uint32 state;
} ma_lcg;
@@ -6569,7 +6598,7 @@ This section contains the APIs for device playback and capture. Here is where yo
************************************************************************************************************************************************************/
#ifndef MA_NO_DEVICE_IO
/* Some backends are only supported on certain platforms. */
-#if defined(MA_WIN32)
+#if defined(MA_WIN32) && !defined(MA_XBOX)
#define MA_SUPPORT_WASAPI
#if defined(MA_WIN32_DESKTOP) /* DirectSound and WinMM backends are only supported on desktops. */
@@ -7426,6 +7455,7 @@ struct ma_context
ma_proc snd_pcm_hw_params_set_rate_resample;
ma_proc snd_pcm_hw_params_set_rate;
ma_proc snd_pcm_hw_params_set_rate_near;
+ ma_proc snd_pcm_hw_params_set_rate_minmax;
ma_proc snd_pcm_hw_params_set_buffer_size_near;
ma_proc snd_pcm_hw_params_set_periods_near;
ma_proc snd_pcm_hw_params_set_access;
@@ -7986,6 +8016,7 @@ struct ma_device
/*AAudioStream**/ ma_ptr pStreamPlayback;
/*AAudioStream**/ ma_ptr pStreamCapture;
ma_mutex rerouteLock;
+ ma_atomic_bool32 isTearingDown;
ma_aaudio_usage usage;
ma_aaudio_content_type contentType;
ma_aaudio_input_preset inputPreset;
@@ -11255,7 +11286,7 @@ typedef struct
ma_log* pLog; /* When set to NULL, will use the context's log. */
ma_uint32 listenerCount; /* Must be between 1 and MA_ENGINE_MAX_LISTENERS. */
ma_uint32 channels; /* The number of channels to use when mixing and spatializing. When set to 0, will use the native channel count of the device. */
- ma_uint32 sampleRate; /* The sample rate. When set to 0 will use the native channel count of the device. */
+ ma_uint32 sampleRate; /* The sample rate. When set to 0 will use the native sample rate of the device. */
ma_uint32 periodSizeInFrames; /* If set to something other than 0, updates will always be exactly this size. The underlying device may be a different size, but from the perspective of the mixer that won't matter.*/
ma_uint32 periodSizeInMilliseconds; /* Used if periodSizeInFrames is unset. */
ma_uint32 gainSmoothTimeInFrames; /* The number of frames to interpolate the gain of spatialized sounds across. If set to 0, will use gainSmoothTimeInMilliseconds. */
@@ -11419,11 +11450,11 @@ MA_API ma_bool32 ma_sound_is_looping(const ma_sound* pSound);
MA_API ma_bool32 ma_sound_at_end(const ma_sound* pSound);
MA_API ma_result ma_sound_seek_to_pcm_frame(ma_sound* pSound, ma_uint64 frameIndex); /* Just a wrapper around ma_data_source_seek_to_pcm_frame(). */
MA_API ma_result ma_sound_seek_to_second(ma_sound* pSound, float seekPointInSeconds); /* Abstraction to ma_sound_seek_to_pcm_frame() */
-MA_API ma_result ma_sound_get_data_format(ma_sound* pSound, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
-MA_API ma_result ma_sound_get_cursor_in_pcm_frames(ma_sound* pSound, ma_uint64* pCursor);
-MA_API ma_result ma_sound_get_length_in_pcm_frames(ma_sound* pSound, ma_uint64* pLength);
-MA_API ma_result ma_sound_get_cursor_in_seconds(ma_sound* pSound, float* pCursor);
-MA_API ma_result ma_sound_get_length_in_seconds(ma_sound* pSound, float* pLength);
+MA_API ma_result ma_sound_get_data_format(const ma_sound* pSound, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
+MA_API ma_result ma_sound_get_cursor_in_pcm_frames(const ma_sound* pSound, ma_uint64* pCursor);
+MA_API ma_result ma_sound_get_length_in_pcm_frames(const ma_sound* pSound, ma_uint64* pLength);
+MA_API ma_result ma_sound_get_cursor_in_seconds(const ma_sound* pSound, float* pCursor);
+MA_API ma_result ma_sound_get_length_in_seconds(const ma_sound* pSound, float* pLength);
MA_API ma_result ma_sound_set_end_callback(ma_sound* pSound, ma_sound_end_proc callback, void* pUserData);
MA_API ma_result ma_sound_group_init(ma_engine* pEngine, ma_uint32 flags, ma_sound_group* pParentGroup, ma_sound_group* pGroup);
@@ -11544,17 +11575,23 @@ IMPLEMENTATION
#endif
#if !defined(MA_WIN32)
-#include
-#include /* select() (used for ma_sleep()). */
-#include
+ #if !defined(MA_NO_THREADING)
+ #include
+ #include /* For pthreads. */
+ #endif
+
+ #include /* select() (used for ma_sleep()). */
+ #include /* For nanosleep() */
+ #include
#endif
-#ifdef MA_NX
-#include /* For nanosleep() */
+/* For fstat(), etc. */
+#if defined(MA_XBOX_NXDK)
+ #include /* Suggestion for NXDK: Add a sys/stat.h wrapper for compatibility. */
+#else
+ #include
#endif
-#include /* For fstat(), etc. */
-
#ifdef MA_EMSCRIPTEN
#include
#endif
@@ -11861,7 +11898,7 @@ static MA_INLINE ma_bool32 ma_has_neon(void)
#endif
#ifndef MA_RESTRICT
- #if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
+ #if defined(__clang__) || defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)))
#define MA_RESTRICT __restrict
#else
#define MA_RESTRICT
@@ -11955,7 +11992,7 @@ static void ma_sleep__posix(ma_uint32 milliseconds)
(void)milliseconds;
MA_ASSERT(MA_FALSE); /* The Emscripten build should never sleep. */
#else
- #if (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L) || defined(MA_NX)
+ #if (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L) || defined(MA_SWITCH)
struct timespec ts;
ts.tv_sec = milliseconds / 1000;
ts.tv_nsec = milliseconds % 1000 * 1000000;
@@ -11997,7 +12034,7 @@ static MA_INLINE void ma_yield(void)
#endif
#endif
#else
- __asm__ __volatile__ ("pause");
+ __asm__ __volatile__ ("rep; nop");
#endif
#elif (defined(__arm__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7) || defined(_M_ARM64) || (defined(_M_ARM) && _M_ARM >= 7) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__)
/* ARM */
@@ -12020,7 +12057,7 @@ static MA_INLINE unsigned int ma_disable_denormals(void)
{
unsigned int prevState;
- #if defined(_MSC_VER)
+ #if defined(_MSC_VER) && !defined(MA_XBOX_NXDK)
{
/*
Older versions of Visual Studio don't support the "safe" versions of _controlfp_s(). I don't
@@ -12043,7 +12080,7 @@ static MA_INLINE unsigned int ma_disable_denormals(void)
}
#elif defined(MA_X86) || defined(MA_X64)
{
- #if defined(__SSE2__) && !(defined(__TINYC__) || defined(__WATCOMC__) || defined(__COSMOPOLITAN__)) /* <-- Add compilers that lack support for _mm_getcsr() and _mm_setcsr() to this list. */
+ #if defined(MA_SUPPORT_SSE2) && defined(__SSE2__) && !(defined(__TINYC__) || defined(__WATCOMC__) || defined(__COSMOPOLITAN__)) /* <-- Add compilers that lack support for _mm_getcsr() and _mm_setcsr() to this list. */
{
prevState = _mm_getcsr();
_mm_setcsr(prevState | MA_MM_DENORMALS_ZERO_MASK | MA_MM_FLUSH_ZERO_MASK);
@@ -12067,7 +12104,7 @@ static MA_INLINE unsigned int ma_disable_denormals(void)
static MA_INLINE void ma_restore_denormals(unsigned int prevState)
{
- #if defined(_MSC_VER)
+ #if defined(_MSC_VER) && !defined(MA_XBOX_NXDK)
{
/* Older versions of Visual Studio do not support _controlfp_s(). See ma_disable_denormals(). */
#if _MSC_VER <= 1200
@@ -12083,7 +12120,7 @@ static MA_INLINE void ma_restore_denormals(unsigned int prevState)
}
#elif defined(MA_X86) || defined(MA_X64)
{
- #if defined(__SSE2__) && !(defined(__TINYC__) || defined(__WATCOMC__) || defined(__COSMOPOLITAN__)) /* <-- Add compilers that lack support for _mm_getcsr() and _mm_setcsr() to this list. */
+ #if defined(MA_SUPPORT_SSE2) && defined(__SSE2__) && !(defined(__TINYC__) || defined(__WATCOMC__) || defined(__COSMOPOLITAN__)) /* <-- Add compilers that lack support for _mm_getcsr() and _mm_setcsr() to this list. */
{
_mm_setcsr(prevState);
}
@@ -12719,6 +12756,29 @@ MA_API MA_NO_INLINE int ma_strcmp(const char* str1, const char* str2)
return ((unsigned char*)str1)[0] - ((unsigned char*)str2)[0];
}
+MA_API MA_NO_INLINE int ma_wcscmp(const wchar_t* str1, const wchar_t* str2)
+{
+ if (str1 == str2) return 0;
+
+ /* These checks differ from the standard implementation. It's not important, but I prefer it just for sanity. */
+ if (str1 == NULL) return -1;
+ if (str2 == NULL) return 1;
+
+ for (;;) {
+ if (str1[0] == L'\0') {
+ break;
+ }
+ if (str1[0] != str2[0]) {
+ break;
+ }
+
+ str1 += 1;
+ str2 += 1;
+ }
+
+ return ((unsigned short*)str1)[0] - ((unsigned short*)str2)[0];
+}
+
MA_API MA_NO_INLINE int ma_strappend(char* dst, size_t dstSize, const char* srcA, const char* srcB)
{
int result;
@@ -12736,6 +12796,22 @@ MA_API MA_NO_INLINE int ma_strappend(char* dst, size_t dstSize, const char* srcA
return result;
}
+MA_API MA_NO_INLINE size_t ma_wcslen(const wchar_t* str)
+{
+ const wchar_t* end;
+
+ if (str == NULL) {
+ return 0;
+ }
+
+ end = str;
+ while (end[0] != '\0') {
+ end += 1;
+ }
+
+ return end - str;
+}
+
MA_API MA_NO_INLINE char* ma_copy_string(const char* src, const ma_allocation_callbacks* pAllocationCallbacks)
{
size_t sz;
@@ -12758,7 +12834,7 @@ MA_API MA_NO_INLINE char* ma_copy_string(const char* src, const ma_allocation_ca
MA_API MA_NO_INLINE wchar_t* ma_copy_string_w(const wchar_t* src, const ma_allocation_callbacks* pAllocationCallbacks)
{
- size_t sz = wcslen(src)+1;
+ size_t sz = ma_wcslen(src)+1;
wchar_t* dst = (wchar_t*)ma_malloc(sz * sizeof(*dst), pAllocationCallbacks);
if (dst == NULL) {
return NULL;
@@ -13189,7 +13265,7 @@ MA_API ma_result ma_fopen(FILE** ppFile, const char* pFilePath, const char* pOpe
return MA_INVALID_ARGS;
}
-#if defined(_MSC_VER) && _MSC_VER >= 1400
+#if (defined(_MSC_VER) && _MSC_VER >= 1400) && !defined(MA_XBOX_NXDK)
err = fopen_s(ppFile, pFilePath, pOpenMode);
if (err != 0) {
return ma_result_from_errno(err);
@@ -13231,7 +13307,7 @@ _wfopen() isn't always available in all compilation environments.
This can be reviewed as compatibility issues arise. The preference is to use _wfopen_s() and _wfopen() as opposed to the wcsrtombs()
fallback, so if you notice your compiler not detecting this properly I'm happy to look at adding support.
*/
-#if defined(_WIN32)
+#if defined(_WIN32) && !defined(MA_XBOX_NXDK)
#if defined(_MSC_VER) || defined(__MINGW64__) || (!defined(__STRICT_ANSI__) && !defined(_NO_EXT_KEYS))
#define MA_HAS_WFOPEN
#endif
@@ -13247,29 +13323,34 @@ MA_API ma_result ma_wfopen(FILE** ppFile, const wchar_t* pFilePath, const wchar_
return MA_INVALID_ARGS;
}
-#if defined(MA_HAS_WFOPEN)
+ #if defined(MA_HAS_WFOPEN)
{
/* Use _wfopen() on Windows. */
- #if defined(_MSC_VER) && _MSC_VER >= 1400
- errno_t err = _wfopen_s(ppFile, pFilePath, pOpenMode);
- if (err != 0) {
- return ma_result_from_errno(err);
+ #if defined(_MSC_VER) && _MSC_VER >= 1400
+ {
+ errno_t err = _wfopen_s(ppFile, pFilePath, pOpenMode);
+ if (err != 0) {
+ return ma_result_from_errno(err);
+ }
}
- #else
- *ppFile = _wfopen(pFilePath, pOpenMode);
- if (*ppFile == NULL) {
- return ma_result_from_errno(errno);
+ #else
+ {
+ *ppFile = _wfopen(pFilePath, pOpenMode);
+ if (*ppFile == NULL) {
+ return ma_result_from_errno(errno);
+ }
}
- #endif
+ #endif
+
(void)pAllocationCallbacks;
}
-#else
- /*
- Use fopen() on anything other than Windows. Requires a conversion. This is annoying because fopen() is locale specific. The only real way I can
- think of to do this is with wcsrtombs(). Note that wcstombs() is apparently not thread-safe because it uses a static global mbstate_t object for
- maintaining state. I've checked this with -std=c89 and it works, but if somebody get's a compiler error I'll look into improving compatibility.
- */
+ #elif !defined(MA_XBOX_NXDK) && !defined(MA_DOS) /* If your compiler does not support wcsrtombs(), add it here. */
{
+ /*
+ Use fopen() on anything other than Windows. Requires a conversion. This is annoying because fopen() is locale specific. The only real way I can
+ think of to do this is with wcsrtombs(). Note that wcstombs() is apparently not thread-safe because it uses a static global mbstate_t object for
+ maintaining state. I've checked this with -std=c89 and it works, but if somebody get's a compiler error I'll look into improving compatibility.
+ */
mbstate_t mbs;
size_t lenMB;
const wchar_t* pFilePathTemp = pFilePath;
@@ -13310,11 +13391,16 @@ MA_API ma_result ma_wfopen(FILE** ppFile, const wchar_t* pFilePath, const wchar_
ma_free(pFilePathMB, pAllocationCallbacks);
}
+ #else
+ {
+ /* Getting here means there is no way to open the file with a wide character string. */
+ *ppFile = NULL;
+ }
+ #endif
if (*ppFile == NULL) {
return MA_ERROR;
}
-#endif
return MA_SUCCESS;
}
@@ -13323,7 +13409,7 @@ MA_API ma_result ma_wfopen(FILE** ppFile, const wchar_t* pFilePath, const wchar_
static MA_INLINE void ma_copy_memory_64(void* dst, const void* src, ma_uint64 sizeInBytes)
{
-#if 0xFFFFFFFFFFFFFFFF <= MA_SIZE_MAX
+#if MA_SIZE_MAX > 0xFFFFFFFF
MA_COPY_MEMORY(dst, src, (size_t)sizeInBytes);
#else
while (sizeInBytes > 0) {
@@ -13343,7 +13429,7 @@ static MA_INLINE void ma_copy_memory_64(void* dst, const void* src, ma_uint64 si
static MA_INLINE void ma_zero_memory_64(void* dst, ma_uint64 sizeInBytes)
{
-#if 0xFFFFFFFFFFFFFFFF <= MA_SIZE_MAX
+#if MA_SIZE_MAX > 0xFFFFFFFF
MA_ZERO_MEMORY(dst, (size_t)sizeInBytes);
#else
while (sizeInBytes > 0) {
@@ -13472,6 +13558,18 @@ static ma_result ma_allocation_callbacks_init_copy(ma_allocation_callbacks* pDst
Logging
**************************************************************************************************************************************************************/
+#ifndef ma_va_copy
+ #if !defined(_MSC_VER) || _MSC_VER >= 1800
+ #if (defined(__GNUC__) && __GNUC__ < 3)
+ #define ma_va_copy(dst, src) ((dst) = (src)) /* This is untested. Not sure if this is correct for old GCC. */
+ #else
+ #define ma_va_copy(dst, src) va_copy((dst), (src))
+ #endif
+ #else
+ #define ma_va_copy(dst, src) ((dst) = (src))
+ #endif
+#endif
+
MA_API const char* ma_log_level_to_string(ma_uint32 logLevel)
{
switch (logLevel)
@@ -13712,9 +13810,15 @@ MA_API ma_result ma_log_postv(ma_log* pLog, ma_uint32 level, const char* pFormat
int length;
char pFormattedMessageStack[1024];
char* pFormattedMessageHeap = NULL;
+ va_list args2;
/* First try formatting into our fixed sized stack allocated buffer. If this is too small we'll fallback to a heap allocation. */
- length = vsnprintf(pFormattedMessageStack, sizeof(pFormattedMessageStack), pFormat, args);
+ ma_va_copy(args2, args);
+ {
+ length = vsnprintf(pFormattedMessageStack, sizeof(pFormattedMessageStack), pFormat, args2);
+ }
+ va_end(args2);
+
if (length < 0) {
return MA_INVALID_OPERATION; /* An error occurred when trying to convert the buffer. */
}
@@ -13755,17 +13859,10 @@ MA_API ma_result ma_log_postv(ma_log* pLog, ma_uint32 level, const char* pFormat
char* pFormattedMessage = NULL;
va_list args2;
- #if _MSC_VER >= 1800
+ ma_va_copy(args2, args);
{
- va_copy(args2, args);
+ formattedLen = ma_vscprintf(&pLog->allocationCallbacks, pFormat, args2);
}
- #else
- {
- args2 = args;
- }
- #endif
-
- formattedLen = ma_vscprintf(&pLog->allocationCallbacks, pFormat, args2);
va_end(args2);
if (formattedLen <= 0) {
@@ -13964,7 +14061,7 @@ miniaudio's purposes.
#define MA_LCG_A 48271
#define MA_LCG_C 0
-static ma_lcg g_maLCG = {MA_DEFAULT_LCG_SEED}; /* Non-zero initial seed. Use ma_seed() to use an explicit seed. */
+static ma_lcg g_maLCG = {MA_DEFAULT_LCG_SEED}; /* Non-zero initial seed. Use ma_lcg_seed() to use an explicit seed. */
static MA_INLINE void ma_lcg_seed(ma_lcg* pLCG, ma_int32 seed)
{
@@ -14013,7 +14110,7 @@ static MA_INLINE ma_int32 ma_lcg_rand_range_s32(ma_lcg* pLCG, ma_int32 lo, ma_in
}
-
+#if 0 /* Currently unused. */
static MA_INLINE void ma_seed(ma_int32 seed)
{
ma_lcg_seed(&g_maLCG, seed);
@@ -14038,6 +14135,7 @@ static MA_INLINE float ma_rand_f32(void)
{
return ma_lcg_rand_f32(&g_maLCG);
}
+#endif
static MA_INLINE float ma_rand_range_f32(float lo, float hi)
{
@@ -14097,6 +14195,7 @@ Atomics
**************************************************************************************************************************************************************/
/* c89atomic.h begin */
#ifndef ma_atomic_h
+#define ma_atomic_h
#if defined(__cplusplus)
extern "C" {
#endif
@@ -14108,11 +14207,40 @@ extern "C" {
#endif
#endif
typedef int ma_atomic_memory_order;
-#define MA_ATOMIC_HAS_8
-#define MA_ATOMIC_HAS_16
-#define MA_ATOMIC_HAS_32
-#define MA_ATOMIC_HAS_64
-#if (defined(_MSC_VER) ) || defined(__WATCOMC__) || defined(__DMC__)
+#if !defined(MA_ATOMIC_MODERN_MSVC) && \
+ !defined(MA_ATOMIC_LEGACY_MSVC) && \
+ !defined(MA_ATOMIC_LEGACY_MSVC_ASM) && \
+ !defined(MA_ATOMIC_MODERN_GCC) && \
+ !defined(MA_ATOMIC_LEGACY_GCC) && \
+ !defined(MA_ATOMIC_LEGACY_GCC_ASM)
+ #if defined(_MSC_VER) || defined(__WATCOMC__) || defined(__DMC__) || defined(__BORLANDC__)
+ #if (defined(_MSC_VER) && _MSC_VER > 1600)
+ #define MA_ATOMIC_MODERN_MSVC
+ #else
+ #if defined(MA_X64)
+ #define MA_ATOMIC_LEGACY_MSVC
+ #else
+ #define MA_ATOMIC_LEGACY_MSVC_ASM
+ #endif
+ #endif
+ #elif (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))) || defined(__clang__)
+ #define MA_ATOMIC_MODERN_GCC
+ #else
+ #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))
+ #define MA_ATOMIC_LEGACY_GCC
+ #else
+ #define MA_ATOMIC_LEGACY_GCC_ASM
+ #endif
+ #endif
+#endif
+#if defined(MA_ATOMIC_MODERN_MSVC) || defined(MA_ATOMIC_LEGACY_MSVC)
+ #include
+ #define ma_atomic_memory_order_relaxed 1
+ #define ma_atomic_memory_order_consume 2
+ #define ma_atomic_memory_order_acquire 3
+ #define ma_atomic_memory_order_release 4
+ #define ma_atomic_memory_order_acq_rel 5
+ #define ma_atomic_memory_order_seq_cst 6
#define MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, intrin, ma_atomicType, msvcType) \
ma_atomicType result; \
switch (order) \
@@ -14138,720 +14266,1501 @@ typedef int ma_atomic_memory_order;
} break; \
} \
return result;
- #define MA_ATOMIC_MSVC_ARM_INTRINSIC_COMPARE_EXCHANGE(ptr, expected, desired, order, intrin, ma_atomicType, msvcType) \
+ typedef ma_uint32 ma_atomic_flag;
+ static MA_INLINE ma_atomic_flag ma_atomic_flag_test_and_set_explicit(volatile ma_atomic_flag* dst, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ARM)
+ {
+ MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, 1, order, _InterlockedExchange, ma_atomic_flag, long);
+ }
+ #else
+ {
+ (void)order;
+ return (ma_atomic_flag)_InterlockedExchange((volatile long*)dst, (long)1);
+ }
+ #endif
+ }
+ static MA_INLINE void ma_atomic_flag_clear_explicit(volatile ma_atomic_flag* dst, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ARM)
+ {
+ MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, 0, order, _InterlockedExchange, ma_atomic_flag, long);
+ }
+ #else
+ {
+ (void)order;
+ _InterlockedExchange((volatile long*)dst, (long)0);
+ }
+ #endif
+ }
+ static MA_INLINE ma_atomic_flag ma_atomic_flag_load_explicit(volatile const ma_atomic_flag* dst, ma_atomic_memory_order order)
+ {
+ (void)order;
+ return (ma_uint32)_InterlockedCompareExchange((volatile long*)dst, 0, 0);
+ }
+#endif
+#if defined(MA_ATOMIC_LEGACY_MSVC_ASM)
+ #define ma_atomic_memory_order_relaxed 1
+ #define ma_atomic_memory_order_consume 2
+ #define ma_atomic_memory_order_acquire 3
+ #define ma_atomic_memory_order_release 4
+ #define ma_atomic_memory_order_acq_rel 5
+ #define ma_atomic_memory_order_seq_cst 6
+ typedef ma_uint32 ma_atomic_flag;
+ static MA_INLINE ma_atomic_flag ma_atomic_flag_test_and_set_explicit(volatile ma_atomic_flag* dst, ma_atomic_memory_order order)
+ {
+ ma_atomic_flag result = 0;
+ (void)order;
+ __asm {
+ mov ecx, dst
+ mov eax, 1
+ xchg [ecx], eax
+ mov result, eax
+ }
+ return result;
+ }
+ static MA_INLINE void ma_atomic_flag_clear_explicit(volatile ma_atomic_flag* dst, ma_atomic_memory_order order)
+ {
+ if (order == ma_atomic_memory_order_relaxed) {
+ __asm {
+ mov esi, dst
+ mov dword ptr [esi], 0
+ }
+ } else {
+ __asm {
+ mov esi, dst
+ mov eax, 0
+ xchg [esi], eax
+ }
+ }
+ }
+ static MA_INLINE ma_atomic_flag ma_atomic_flag_load_explicit(volatile const ma_atomic_flag* dst, ma_atomic_memory_order order)
+ {
+ ma_atomic_flag result = 0;
+ if (order == ma_atomic_memory_order_relaxed) {
+ __asm {
+ mov esi, dst
+ mov eax, [esi]
+ mov result, eax
+ }
+ } else if (order <= ma_atomic_memory_order_release) {
+ __asm {
+ mov esi, dst
+ mov eax, [esi]
+ lock add dword ptr [esp], 0
+ mov result, eax
+ }
+ } else {
+ __asm {
+ lock add dword ptr [esp], 0
+ mov esi, dst
+ mov eax, [esi]
+ mov result, eax
+ lock add dword ptr [esp], 0
+ }
+ }
+ return result;
+ }
+#endif
+#if defined(MA_ATOMIC_MODERN_GCC)
+ #define ma_atomic_memory_order_relaxed __ATOMIC_RELAXED
+ #define ma_atomic_memory_order_consume __ATOMIC_CONSUME
+ #define ma_atomic_memory_order_acquire __ATOMIC_ACQUIRE
+ #define ma_atomic_memory_order_release __ATOMIC_RELEASE
+ #define ma_atomic_memory_order_acq_rel __ATOMIC_ACQ_REL
+ #define ma_atomic_memory_order_seq_cst __ATOMIC_SEQ_CST
+ typedef ma_uint32 ma_atomic_flag;
+ #define ma_atomic_flag_test_and_set_explicit(dst, order) __atomic_exchange_n(dst, 1, order)
+ #define ma_atomic_flag_clear_explicit(dst, order) __atomic_store_n(dst, 0, order)
+ #define ma_atomic_flag_load_explicit(dst, order) __atomic_load_n(dst, order)
+#endif
+#if defined(MA_ATOMIC_LEGACY_GCC)
+ #define ma_atomic_memory_order_relaxed 1
+ #define ma_atomic_memory_order_consume 2
+ #define ma_atomic_memory_order_acquire 3
+ #define ma_atomic_memory_order_release 4
+ #define ma_atomic_memory_order_acq_rel 5
+ #define ma_atomic_memory_order_seq_cst 6
+ typedef ma_uint32 ma_atomic_flag;
+ static MA_INLINE ma_atomic_flag ma_atomic_flag_test_and_set_explicit(volatile ma_atomic_flag* dst, ma_atomic_memory_order order)
+ {
+ if (order > ma_atomic_memory_order_acquire) {
+ __sync_synchronize();
+ }
+ return __sync_lock_test_and_set(dst, 1);
+ }
+ static MA_INLINE void ma_atomic_flag_clear_explicit(volatile ma_atomic_flag* dst, ma_atomic_memory_order order)
+ {
+ if (order > ma_atomic_memory_order_release) {
+ __sync_synchronize();
+ }
+ __sync_lock_release(dst);
+ }
+ static MA_INLINE ma_atomic_flag ma_atomic_flag_load_explicit(volatile const ma_atomic_flag* dst, ma_atomic_memory_order order)
+ {
+ (void)order;
+ return __sync_val_compare_and_swap((ma_atomic_flag*)dst, 0, 0);
+ }
+#endif
+#if defined(MA_ATOMIC_LEGACY_GCC_ASM)
+ #define ma_atomic_memory_order_relaxed 1
+ #define ma_atomic_memory_order_consume 2
+ #define ma_atomic_memory_order_acquire 3
+ #define ma_atomic_memory_order_release 4
+ #define ma_atomic_memory_order_acq_rel 5
+ #define ma_atomic_memory_order_seq_cst 6
+ #if defined(MA_X86)
+ #define ma_atomic_thread_fence(order) __asm__ __volatile__("lock; addl $0, (%%esp)" ::: "memory")
+ #elif defined(MA_X64)
+ #define ma_atomic_thread_fence(order) __asm__ __volatile__("lock; addq $0, (%%rsp)" ::: "memory")
+ #else
+ #error Unsupported architecture.
+ #endif
+ #define MA_ATOMIC_XCHG_GCC_X86(instructionSizeSuffix, result, dst, src) \
+ __asm__ __volatile__( \
+ "xchg"instructionSizeSuffix" %0, %1" \
+ : "=r"(result), \
+ "=m"(*dst) \
+ : "0"(src), \
+ "m"(*dst) \
+ : "memory" \
+ )
+ #define MA_ATOMIC_LOAD_RELAXED_GCC_X86(instructionSizeSuffix, result, dst) \
+ __asm__ __volatile__( \
+ "mov"instructionSizeSuffix" %1, %0" \
+ : "=r"(result) \
+ : "m"(*dst) \
+ )
+ #define MA_ATOMIC_LOAD_RELEASE_GCC_X86(instructionSizeSuffix, result, dst) \
+ ma_atomic_thread_fence(ma_atomic_memory_order_release); \
+ __asm__ __volatile__( \
+ "mov"instructionSizeSuffix" %1, %0" \
+ : "=r"(result) \
+ : "m"(*dst) \
+ : "memory" \
+ )
+ #define MA_ATOMIC_LOAD_SEQ_CST_GCC_X86(instructionSizeSuffix, result, dst) \
+ ma_atomic_thread_fence(ma_atomic_memory_order_seq_cst); \
+ __asm__ __volatile__( \
+ "mov"instructionSizeSuffix" %1, %0" \
+ : "=r"(result) \
+ : "m"(*dst) \
+ : "memory" \
+ ); \
+ ma_atomic_thread_fence(ma_atomic_memory_order_seq_cst)
+ typedef ma_uint32 ma_atomic_flag;
+ static MA_INLINE ma_atomic_flag ma_atomic_flag_test_and_set_explicit(volatile ma_atomic_flag* dst, ma_atomic_memory_order order)
+ {
+ ma_atomic_flag result;
+ #if defined(MA_X86) || defined(MA_X64)
+ {
+ (void)order;
+ MA_ATOMIC_XCHG_GCC_X86("l", result, dst, 1);
+ }
+ #else
+ {
+ #error Unsupported architecture.
+ }
+ #endif
+ return result;
+ }
+ static MA_INLINE void ma_atomic_flag_clear_explicit(volatile ma_atomic_flag* dst, ma_atomic_memory_order order)
+ {
+ #if defined(MA_X86) || defined(MA_X64)
+ {
+ if (order == ma_atomic_memory_order_relaxed) {
+ __asm__ __volatile__(
+ "movl $0, %0"
+ : "=m"(*dst)
+ );
+ } else if (order == ma_atomic_memory_order_release) {
+ __asm__ __volatile__(
+ "movl $0, %0"
+ : "=m"(*dst)
+ :
+ : "memory"
+ );
+ } else {
+ ma_atomic_flag tmp = 0;
+ __asm__ __volatile__(
+ "xchgl %0, %1"
+ : "=r"(tmp),
+ "=m"(*dst)
+ : "0"(tmp),
+ "m"(*dst)
+ : "memory"
+ );
+ }
+ }
+ #else
+ {
+ #error Unsupported architecture.
+ }
+ #endif
+ }
+ static MA_INLINE ma_atomic_flag ma_atomic_flag_load_explicit(volatile const ma_atomic_flag* dst, ma_atomic_memory_order order)
+ {
+ #if defined(MA_X86) || defined(MA_X64)
+ {
+ ma_atomic_flag result;
+ if (order == ma_atomic_memory_order_relaxed) {
+ MA_ATOMIC_LOAD_RELAXED_GCC_X86("l", result, dst);
+ } else if (order <= ma_atomic_memory_order_release) {
+ MA_ATOMIC_LOAD_RELEASE_GCC_X86("l", result, dst);
+ } else {
+ MA_ATOMIC_LOAD_SEQ_CST_GCC_X86("l", result, dst);
+ }
+ return result;
+ }
+ #else
+ {
+ #error Unsupported architecture.
+ }
+ #endif
+ }
+#endif
+#define ma_atomic_flag_test_and_set(dst) ma_atomic_flag_test_and_set_explicit(dst, ma_atomic_memory_order_acquire)
+#define ma_atomic_flag_clear(dst) ma_atomic_flag_clear_explicit(dst, ma_atomic_memory_order_release)
+typedef ma_atomic_flag ma_atomic_spinlock;
+static MA_INLINE void ma_atomic_spinlock_lock(volatile ma_atomic_spinlock* pSpinlock)
+{
+ for (;;) {
+ if (ma_atomic_flag_test_and_set_explicit(pSpinlock, ma_atomic_memory_order_acquire) == 0) {
+ break;
+ }
+ while (ma_atomic_flag_load_explicit(pSpinlock, ma_atomic_memory_order_relaxed) == 1) {
+ }
+ }
+}
+static MA_INLINE void ma_atomic_spinlock_unlock(volatile ma_atomic_spinlock* pSpinlock)
+{
+ ma_atomic_flag_clear_explicit(pSpinlock, ma_atomic_memory_order_release);
+}
+ma_atomic_spinlock ma_atomic_global_lock;
+#if defined(MA_ATOMIC_MODERN_MSVC) || defined(MA_ATOMIC_LEGACY_MSVC) || defined(MA_ATOMIC_LEGACY_MSVC_ASM) || defined(MA_ATOMIC_LEGACY_GCC) || defined(MA_ATOMIC_LEGACY_GCC_ASM)
+ #if defined(MA_X64) || (defined(MA_X86) && ((defined(__GNUC__) && defined(__i486__)) || (defined(_M_IX86) && _M_IX86 >= 400)))
+ #if defined(MA_ATOMIC_LEGACY_MSVC) && defined(MA_X64)
+ #else
+ #define MA_ATOMIC_IS_LOCK_FREE_8 1
+ #define MA_ATOMIC_IS_LOCK_FREE_16 1
+ #endif
+ #define MA_ATOMIC_IS_LOCK_FREE_32 1
+ #if defined(MA_X64) || (defined(MA_X86) && ((defined(__GNUC__) && defined(__i586__)) || (defined(_M_IX86) && _M_IX86 >= 500)))
+ #define MA_ATOMIC_IS_LOCK_FREE_64 1
+ #else
+ #endif
+ #else
+ #endif
+ #if defined(MA_ARM32) || defined(MA_ARM64)
+ #define MA_ATOMIC_IS_LOCK_FREE_8 1
+ #define MA_ATOMIC_IS_LOCK_FREE_16 1
+ #define MA_ATOMIC_IS_LOCK_FREE_32 1
+ #if defined(MA_ARM64) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__)
+ #define MA_ATOMIC_IS_LOCK_FREE_64 1
+ #endif
+ #endif
+ #if defined(MA_ATOMIC_PPC32) || defined(MA_ATOMIC_PPC64)
+ #if (defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7))) && !defined(__clang__)
+ #else
+ #define MA_ATOMIC_IS_LOCK_FREE_8 1
+ #define MA_ATOMIC_IS_LOCK_FREE_16 1
+ #endif
+ #define MA_ATOMIC_IS_LOCK_FREE_32 1
+ #if defined(MA_ATOMIC_PPC64)
+ #define MA_ATOMIC_IS_LOCK_FREE_64 1
+ #endif
+ #endif
+ static MA_INLINE ma_bool32 ma_atomic_is_lock_free_8(volatile void* ptr)
+ {
+ (void)ptr;
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_8)
+ return 1;
+ #else
+ return 0;
+ #endif
+ }
+ static MA_INLINE ma_bool32 ma_atomic_is_lock_free_16(volatile void* ptr)
+ {
+ (void)ptr;
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_16)
+ return 1;
+ #else
+ return 0;
+ #endif
+ }
+ static MA_INLINE ma_bool32 ma_atomic_is_lock_free_32(volatile void* ptr)
+ {
+ (void)ptr;
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_32)
+ return 1;
+ #else
+ return 0;
+ #endif
+ }
+ static MA_INLINE ma_bool32 ma_atomic_is_lock_free_64(volatile void* ptr)
+ {
+ (void)ptr;
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_64)
+ return 1;
+ #else
+ return 0;
+ #endif
+ }
+#endif
+#define MA_ATOMIC_COMPARE_AND_SWAP_LOCK(sizeInBits, dst, expected, replacement) \
+ ma_uint##sizeInBits result; \
+ ma_atomic_spinlock_lock(&ma_atomic_global_lock); \
+ { \
+ result = *dst; \
+ if (result == expected) { \
+ *dst = replacement; \
+ } \
+ } \
+ ma_atomic_spinlock_unlock(&ma_atomic_global_lock); \
+ return result
+#define MA_ATOMIC_LOAD_EXPLICIT_LOCK(sizeInBits, ptr, order) \
+ ma_uint##sizeInBits result; \
+ ma_atomic_spinlock_lock(&ma_atomic_global_lock); \
+ { \
+ result = *ptr; \
+ (void)order; \
+ } \
+ ma_atomic_spinlock_unlock(&ma_atomic_global_lock); \
+ return result
+#define MA_ATOMIC_STORE_EXPLICIT_LOCK(sizeInBits, dst, src, order) \
+ ma_atomic_spinlock_lock(&ma_atomic_global_lock); \
+ { \
+ *dst = src; \
+ (void)order; \
+ } \
+ ma_atomic_spinlock_unlock(&ma_atomic_global_lock)
+#define MA_ATOMIC_STORE_EXPLICIT_CAS(sizeInBits, dst, src, order) \
+ ma_uint##sizeInBits oldValue; \
+ do { \
+ oldValue = ma_atomic_load_explicit_##sizeInBits(dst, ma_atomic_memory_order_relaxed); \
+ } while (ma_atomic_compare_and_swap_##sizeInBits(dst, oldValue, src) != oldValue); \
+ (void)order
+#define MA_ATOMIC_EXCHANGE_EXPLICIT_LOCK(sizeInBits, dst, src, order) \
+ ma_uint##sizeInBits result; \
+ ma_atomic_spinlock_lock(&ma_atomic_global_lock); \
+ { \
+ result = *dst; \
+ *dst = src; \
+ (void)order; \
+ } \
+ ma_atomic_spinlock_unlock(&ma_atomic_global_lock); \
+ return result
+#define MA_ATOMIC_EXCHANGE_EXPLICIT_CAS(sizeInBits, dst, src, order) \
+ ma_uint##sizeInBits oldValue; \
+ do { \
+ oldValue = ma_atomic_load_explicit_##sizeInBits(dst, ma_atomic_memory_order_relaxed); \
+ } while (ma_atomic_compare_and_swap_##sizeInBits(dst, oldValue, src) != oldValue); \
+ (void)order; \
+ return oldValue
+#define MA_ATOMIC_FETCH_ADD_LOCK(sizeInBits, dst, src, order) \
+ ma_uint##sizeInBits result; \
+ ma_atomic_spinlock_lock(&ma_atomic_global_lock); \
+ { \
+ result = *dst; \
+ *dst += src; \
+ (void)order; \
+ } \
+ ma_atomic_spinlock_unlock(&ma_atomic_global_lock); \
+ return result
+#define MA_ATOMIC_FETCH_ADD_CAS(sizeInBits, dst, src, order) \
+ ma_uint##sizeInBits oldValue; \
+ ma_uint##sizeInBits newValue; \
+ do { \
+ oldValue = ma_atomic_load_explicit_##sizeInBits(dst, ma_atomic_memory_order_relaxed); \
+ newValue = oldValue + src; \
+ } while (ma_atomic_compare_and_swap_##sizeInBits(dst, oldValue, newValue) != oldValue); \
+ (void)order; \
+ return oldValue
+#define MA_ATOMIC_FETCH_AND_CAS(sizeInBits, dst, src, order) \
+ ma_uint##sizeInBits oldValue; \
+ ma_uint##sizeInBits newValue; \
+ do { \
+ oldValue = ma_atomic_load_explicit_##sizeInBits(dst, ma_atomic_memory_order_relaxed); \
+ newValue = (ma_uint##sizeInBits)(oldValue & src); \
+ } while (ma_atomic_compare_and_swap_##sizeInBits(dst, oldValue, newValue) != oldValue); \
+ (void)order; \
+ return oldValue
+#define MA_ATOMIC_FETCH_OR_CAS(sizeInBits, dst, src, order) \
+ ma_uint##sizeInBits oldValue; \
+ ma_uint##sizeInBits newValue; \
+ do { \
+ oldValue = ma_atomic_load_explicit_##sizeInBits(dst, ma_atomic_memory_order_relaxed); \
+ newValue = (ma_uint##sizeInBits)(oldValue | src); \
+ } while (ma_atomic_compare_and_swap_##sizeInBits(dst, oldValue, newValue) != oldValue); \
+ (void)order; \
+ return oldValue
+#define MA_ATOMIC_FETCH_XOR_CAS(sizeInBits, dst, src, order) \
+ ma_uint##sizeInBits oldValue; \
+ ma_uint##sizeInBits newValue; \
+ do { \
+ oldValue = ma_atomic_load_explicit_##sizeInBits(dst, ma_atomic_memory_order_relaxed); \
+ newValue = (ma_uint##sizeInBits)(oldValue ^ src); \
+ } while (ma_atomic_compare_and_swap_##sizeInBits(dst, oldValue, newValue) != oldValue); \
+ (void)order; \
+ return oldValue
+#if defined(MA_ATOMIC_MODERN_MSVC) || defined(MA_ATOMIC_LEGACY_MSVC)
+ #define MA_ATOMIC_MSVC_ARM_INTRINSIC_COMPARE_EXCHANGE(ptr, expected, replacement, order, intrin, ma_atomicType, msvcType) \
ma_atomicType result; \
switch (order) \
{ \
case ma_atomic_memory_order_relaxed: \
{ \
- result = (ma_atomicType)intrin##_nf((volatile msvcType*)ptr, (msvcType)expected, (msvcType)desired); \
+ result = (ma_atomicType)intrin##_nf((volatile msvcType*)ptr, (msvcType)expected, (msvcType)replacement); \
} break; \
case ma_atomic_memory_order_consume: \
case ma_atomic_memory_order_acquire: \
{ \
- result = (ma_atomicType)intrin##_acq((volatile msvcType*)ptr, (msvcType)expected, (msvcType)desired); \
+ result = (ma_atomicType)intrin##_acq((volatile msvcType*)ptr, (msvcType)expected, (msvcType)replacement); \
} break; \
case ma_atomic_memory_order_release: \
{ \
- result = (ma_atomicType)intrin##_rel((volatile msvcType*)ptr, (msvcType)expected, (msvcType)desired); \
+ result = (ma_atomicType)intrin##_rel((volatile msvcType*)ptr, (msvcType)expected, (msvcType)replacement); \
} break; \
case ma_atomic_memory_order_acq_rel: \
case ma_atomic_memory_order_seq_cst: \
default: \
{ \
- result = (ma_atomicType)intrin((volatile msvcType*)ptr, (msvcType)expected, (msvcType)desired); \
+ result = (ma_atomicType)intrin((volatile msvcType*)ptr, (msvcType)expected, (msvcType)replacement); \
} break; \
} \
return result;
- #define ma_atomic_memory_order_relaxed 0
- #define ma_atomic_memory_order_consume 1
- #define ma_atomic_memory_order_acquire 2
- #define ma_atomic_memory_order_release 3
- #define ma_atomic_memory_order_acq_rel 4
- #define ma_atomic_memory_order_seq_cst 5
- #if _MSC_VER < 1600 && defined(MA_X86)
- #define MA_ATOMIC_MSVC_USE_INLINED_ASSEMBLY
- #endif
- #if _MSC_VER < 1600
- #undef MA_ATOMIC_HAS_8
- #undef MA_ATOMIC_HAS_16
- #endif
- #if !defined(MA_ATOMIC_MSVC_USE_INLINED_ASSEMBLY)
- #include
- #endif
- #if defined(MA_ATOMIC_MSVC_USE_INLINED_ASSEMBLY)
- #if defined(MA_ATOMIC_HAS_8)
- static MA_INLINE ma_uint8 __stdcall ma_atomic_compare_and_swap_8(volatile ma_uint8* dst, ma_uint8 expected, ma_uint8 desired)
- {
- ma_uint8 result = 0;
- __asm {
- mov ecx, dst
- mov al, expected
- mov dl, desired
- lock cmpxchg [ecx], dl
- mov result, al
- }
- return result;
- }
- #endif
- #if defined(MA_ATOMIC_HAS_16)
- static MA_INLINE ma_uint16 __stdcall ma_atomic_compare_and_swap_16(volatile ma_uint16* dst, ma_uint16 expected, ma_uint16 desired)
- {
- ma_uint16 result = 0;
- __asm {
- mov ecx, dst
- mov ax, expected
- mov dx, desired
- lock cmpxchg [ecx], dx
- mov result, ax
- }
- return result;
- }
- #endif
- #if defined(MA_ATOMIC_HAS_32)
- static MA_INLINE ma_uint32 __stdcall ma_atomic_compare_and_swap_32(volatile ma_uint32* dst, ma_uint32 expected, ma_uint32 desired)
- {
- ma_uint32 result = 0;
- __asm {
- mov ecx, dst
- mov eax, expected
- mov edx, desired
- lock cmpxchg [ecx], edx
- mov result, eax
- }
- return result;
- }
- #endif
- #if defined(MA_ATOMIC_HAS_64)
- static MA_INLINE ma_uint64 __stdcall ma_atomic_compare_and_swap_64(volatile ma_uint64* dst, ma_uint64 expected, ma_uint64 desired)
- {
- ma_uint32 resultEAX = 0;
- ma_uint32 resultEDX = 0;
- __asm {
- mov esi, dst
- mov eax, dword ptr expected
- mov edx, dword ptr expected + 4
- mov ebx, dword ptr desired
- mov ecx, dword ptr desired + 4
- lock cmpxchg8b qword ptr [esi]
- mov resultEAX, eax
- mov resultEDX, edx
- }
- return ((ma_uint64)resultEDX << 32) | resultEAX;
- }
- #endif
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_8)
+ #define ma_atomic_compare_and_swap_8( dst, expected, replacement) (ma_uint8 )_InterlockedCompareExchange8((volatile char*)dst, (char)replacement, (char)expected)
#else
- #if defined(MA_ATOMIC_HAS_8)
- #define ma_atomic_compare_and_swap_8( dst, expected, desired) (ma_uint8 )_InterlockedCompareExchange8((volatile char*)dst, (char)desired, (char)expected)
- #endif
- #if defined(MA_ATOMIC_HAS_16)
- #define ma_atomic_compare_and_swap_16(dst, expected, desired) (ma_uint16)_InterlockedCompareExchange16((volatile short*)dst, (short)desired, (short)expected)
- #endif
- #if defined(MA_ATOMIC_HAS_32)
- #define ma_atomic_compare_and_swap_32(dst, expected, desired) (ma_uint32)_InterlockedCompareExchange((volatile long*)dst, (long)desired, (long)expected)
- #endif
- #if defined(MA_ATOMIC_HAS_64)
- #define ma_atomic_compare_and_swap_64(dst, expected, desired) (ma_uint64)_InterlockedCompareExchange64((volatile ma_int64*)dst, (ma_int64)desired, (ma_int64)expected)
- #endif
+ static MA_INLINE ma_uint8 __stdcall ma_atomic_compare_and_swap_8(volatile ma_uint8* dst, ma_uint8 expected, ma_uint8 replacement)
+ {
+ MA_ATOMIC_COMPARE_AND_SWAP_LOCK(8, dst, expected, replacement);
+ }
#endif
- #if defined(MA_ATOMIC_MSVC_USE_INLINED_ASSEMBLY)
- #if defined(MA_ATOMIC_HAS_8)
- static MA_INLINE ma_uint8 __stdcall ma_atomic_exchange_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
- {
- ma_uint8 result = 0;
- (void)order;
- __asm {
- mov ecx, dst
- mov al, src
- lock xchg [ecx], al
- mov result, al
- }
- return result;
- }
- #endif
- #if defined(MA_ATOMIC_HAS_16)
- static MA_INLINE ma_uint16 __stdcall ma_atomic_exchange_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
- {
- ma_uint16 result = 0;
- (void)order;
- __asm {
- mov ecx, dst
- mov ax, src
- lock xchg [ecx], ax
- mov result, ax
- }
- return result;
- }
- #endif
- #if defined(MA_ATOMIC_HAS_32)
- static MA_INLINE ma_uint32 __stdcall ma_atomic_exchange_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
- {
- ma_uint32 result = 0;
- (void)order;
- __asm {
- mov ecx, dst
- mov eax, src
- lock xchg [ecx], eax
- mov result, eax
- }
- return result;
- }
- #endif
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_16)
+ #define ma_atomic_compare_and_swap_16(dst, expected, replacement) (ma_uint16)_InterlockedCompareExchange16((volatile short*)dst, (short)replacement, (short)expected)
#else
- #if defined(MA_ATOMIC_HAS_8)
- static MA_INLINE ma_uint8 __stdcall ma_atomic_exchange_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
- {
+ static MA_INLINE ma_uint16 __stdcall ma_atomic_compare_and_swap_16(volatile ma_uint16* dst, ma_uint16 expected, ma_uint16 replacement)
+ {
+ MA_ATOMIC_COMPARE_AND_SWAP_LOCK(16, dst, expected, replacement);
+ }
+ #endif
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_32)
+ #define ma_atomic_compare_and_swap_32(dst, expected, replacement) (ma_uint32)_InterlockedCompareExchange((volatile long*)dst, (long)replacement, (long)expected)
+ #else
+ static MA_INLINE ma_uint32 __stdcall ma_atomic_compare_and_swap_32(volatile ma_uint32* dst, ma_uint32 expected, ma_uint32 replacement)
+ {
+ MA_ATOMIC_COMPARE_AND_SWAP_LOCK(32, dst, expected, replacement);
+ }
+ #endif
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_32)
+ #define ma_atomic_compare_and_swap_64(dst, expected, replacement) (ma_uint64)_InterlockedCompareExchange64((volatile ma_int64*)dst, (ma_int64)replacement, (ma_int64)expected)
+ #else
+ static MA_INLINE ma_uint64 __stdcall ma_atomic_compare_and_swap_64(volatile ma_uint64* dst, ma_uint64 expected, ma_uint64 replacement)
+ {
+ MA_ATOMIC_COMPARE_AND_SWAP_LOCK(64, dst, expected, replacement);
+ }
+ #endif
+ static MA_INLINE ma_uint8 ma_atomic_load_explicit_8(volatile const ma_uint8* ptr, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_8)
+ {
#if defined(MA_ARM)
- MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedExchange8, ma_uint8, char);
+ {
+ MA_ATOMIC_MSVC_ARM_INTRINSIC_COMPARE_EXCHANGE(ptr, 0, 0, order, _InterlockedCompareExchange8, ma_uint8, char);
+ }
#else
+ {
+ (void)order;
+ return ma_atomic_compare_and_swap_8((volatile ma_uint8*)ptr, 0, 0);
+ }
+ #endif
+ }
+ #else
+ {
+ MA_ATOMIC_LOAD_EXPLICIT_LOCK(8, ptr, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint16 ma_atomic_load_explicit_16(volatile const ma_uint16* ptr, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_16)
+ {
+ #if defined(MA_ARM)
+ {
+ MA_ATOMIC_MSVC_ARM_INTRINSIC_COMPARE_EXCHANGE(ptr, 0, 0, order, _InterlockedCompareExchange16, ma_uint16, short);
+ }
+ #else
+ {
+ (void)order;
+ return ma_atomic_compare_and_swap_16((volatile ma_uint16*)ptr, 0, 0);
+ }
+ #endif
+ }
+ #else
+ {
+ MA_ATOMIC_LOAD_EXPLICIT_LOCK(16, ptr, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint32 ma_atomic_load_explicit_32(volatile const ma_uint32* ptr, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_32)
+ {
+ #if defined(MA_ARM)
+ {
+ MA_ATOMIC_MSVC_ARM_INTRINSIC_COMPARE_EXCHANGE(ptr, 0, 0, order, _InterlockedCompareExchange, ma_uint32, long);
+ }
+ #else
+ {
+ (void)order;
+ return ma_atomic_compare_and_swap_32((volatile ma_uint32*)ptr, 0, 0);
+ }
+ #endif
+ }
+ #else
+ {
+ MA_ATOMIC_LOAD_EXPLICIT_LOCK(32, ptr, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint64 ma_atomic_load_explicit_64(volatile const ma_uint64* ptr, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_32)
+ {
+ #if defined(MA_ARM)
+ {
+ MA_ATOMIC_MSVC_ARM_INTRINSIC_COMPARE_EXCHANGE(ptr, 0, 0, order, _InterlockedCompareExchange64, ma_uint64, long long);
+ }
+ #else
+ {
+ (void)order;
+ return ma_atomic_compare_and_swap_64((volatile ma_uint64*)ptr, 0, 0);
+ }
+ #endif
+ }
+ #else
+ {
+ MA_ATOMIC_LOAD_EXPLICIT_LOCK(64, ptr, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint8 __stdcall ma_atomic_exchange_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_8)
+ {
+ #if defined(MA_ARM)
+ {
+ MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedExchange8, ma_uint8, char);
+ }
+ #else
+ {
(void)order;
return (ma_uint8)_InterlockedExchange8((volatile char*)dst, (char)src);
- #endif
}
+ #endif
+ }
+ #else
+ {
+ MA_ATOMIC_EXCHANGE_EXPLICIT_LOCK(8, dst, src, order);
+ }
#endif
- #if defined(MA_ATOMIC_HAS_16)
- static MA_INLINE ma_uint16 __stdcall ma_atomic_exchange_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
- {
+ }
+ static MA_INLINE ma_uint16 __stdcall ma_atomic_exchange_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_16)
+ {
#if defined(MA_ARM)
+ {
MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedExchange16, ma_uint16, short);
+ }
#else
+ {
(void)order;
return (ma_uint16)_InterlockedExchange16((volatile short*)dst, (short)src);
- #endif
}
+ #endif
+ }
+ #else
+ {
+ MA_ATOMIC_EXCHANGE_EXPLICIT_LOCK(16, dst, src, order);
+ }
#endif
- #if defined(MA_ATOMIC_HAS_32)
- static MA_INLINE ma_uint32 __stdcall ma_atomic_exchange_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
- {
+ }
+ static MA_INLINE ma_uint32 __stdcall ma_atomic_exchange_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_32)
+ {
#if defined(MA_ARM)
+ {
MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedExchange, ma_uint32, long);
+ }
#else
+ {
(void)order;
return (ma_uint32)_InterlockedExchange((volatile long*)dst, (long)src);
- #endif
}
- #endif
- #if defined(MA_ATOMIC_HAS_64) && defined(MA_64BIT)
- static MA_INLINE ma_uint64 __stdcall ma_atomic_exchange_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
- {
- #if defined(MA_ARM)
- MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedExchange64, ma_uint64, long long);
- #else
- (void)order;
- return (ma_uint64)_InterlockedExchange64((volatile long long*)dst, (long long)src);
#endif
- }
- #else
- #endif
- #endif
- #if defined(MA_ATOMIC_HAS_64) && !defined(MA_64BIT)
- static MA_INLINE ma_uint64 __stdcall ma_atomic_exchange_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
- {
- ma_uint64 oldValue;
- do {
- oldValue = *dst;
- } while (ma_atomic_compare_and_swap_64(dst, oldValue, src) != oldValue);
- (void)order;
- return oldValue;
}
- #endif
- #if defined(MA_ATOMIC_MSVC_USE_INLINED_ASSEMBLY)
- #if defined(MA_ATOMIC_HAS_8)
- static MA_INLINE ma_uint8 __stdcall ma_atomic_fetch_add_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
- {
- ma_uint8 result = 0;
- (void)order;
- __asm {
- mov ecx, dst
- mov al, src
- lock xadd [ecx], al
- mov result, al
- }
- return result;
- }
+ #else
+ {
+ MA_ATOMIC_EXCHANGE_EXPLICIT_LOCK(32, dst, src, order);
+ }
#endif
- #if defined(MA_ATOMIC_HAS_16)
- static MA_INLINE ma_uint16 __stdcall ma_atomic_fetch_add_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
+ }
+ static MA_INLINE ma_uint64 __stdcall ma_atomic_exchange_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_64)
+ {
+ #if defined(MA_32BIT)
{
- ma_uint16 result = 0;
- (void)order;
- __asm {
- mov ecx, dst
- mov ax, src
- lock xadd [ecx], ax
- mov result, ax
- }
- return result;
+ MA_ATOMIC_EXCHANGE_EXPLICIT_CAS(64, dst, src, order);
}
- #endif
- #if defined(MA_ATOMIC_HAS_32)
- static MA_INLINE ma_uint32 __stdcall ma_atomic_fetch_add_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
- {
- ma_uint32 result = 0;
- (void)order;
- __asm {
- mov ecx, dst
- mov eax, src
- lock xadd [ecx], eax
- mov result, eax
- }
- return result;
- }
- #endif
- #else
- #if defined(MA_ATOMIC_HAS_8)
- static MA_INLINE ma_uint8 __stdcall ma_atomic_fetch_add_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
- {
- #if defined(MA_ARM)
- MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedExchangeAdd8, ma_uint8, char);
#else
+ {
+ #if defined(MA_ARM)
+ {
+ MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedExchange64, ma_uint64, long long);
+ }
+ #else
+ {
+ (void)order;
+ return (ma_uint64)_InterlockedExchange64((volatile long long*)dst, (long long)src);
+ }
+ #endif
+ }
+ #endif
+ }
+ #else
+ {
+ MA_ATOMIC_EXCHANGE_EXPLICIT_LOCK(64, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint8 __stdcall ma_atomic_fetch_add_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_8)
+ {
+ #if defined(MA_ARM)
+ {
+ MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedExchangeAdd8, ma_uint8, char);
+ }
+ #else
+ {
(void)order;
return (ma_uint8)_InterlockedExchangeAdd8((volatile char*)dst, (char)src);
- #endif
}
+ #endif
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_ADD_LOCK(8, dst, src, order);
+ }
#endif
- #if defined(MA_ATOMIC_HAS_16)
- static MA_INLINE ma_uint16 __stdcall ma_atomic_fetch_add_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
- {
+ }
+ static MA_INLINE ma_uint16 __stdcall ma_atomic_fetch_add_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_16)
+ {
#if defined(MA_ARM)
+ {
MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedExchangeAdd16, ma_uint16, short);
+ }
#else
+ {
(void)order;
return (ma_uint16)_InterlockedExchangeAdd16((volatile short*)dst, (short)src);
- #endif
}
+ #endif
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_ADD_LOCK(16, dst, src, order);
+ }
#endif
- #if defined(MA_ATOMIC_HAS_32)
- static MA_INLINE ma_uint32 __stdcall ma_atomic_fetch_add_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
- {
+ }
+ static MA_INLINE ma_uint32 __stdcall ma_atomic_fetch_add_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_32)
+ {
#if defined(MA_ARM)
+ {
MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedExchangeAdd, ma_uint32, long);
+ }
#else
+ {
(void)order;
return (ma_uint32)_InterlockedExchangeAdd((volatile long*)dst, (long)src);
- #endif
}
- #endif
- #if defined(MA_ATOMIC_HAS_64) && defined(MA_64BIT)
- static MA_INLINE ma_uint64 __stdcall ma_atomic_fetch_add_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
- {
- #if defined(MA_ARM)
- MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedExchangeAdd64, ma_uint64, long long);
- #else
- (void)order;
- return (ma_uint64)_InterlockedExchangeAdd64((volatile long long*)dst, (long long)src);
#endif
- }
+ }
#else
- #endif
- #endif
- #if defined(MA_ATOMIC_HAS_64) && !defined(MA_64BIT)
- static MA_INLINE ma_uint64 __stdcall ma_atomic_fetch_add_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
{
- ma_uint64 oldValue;
- ma_uint64 newValue;
- do {
- oldValue = *dst;
- newValue = oldValue + src;
- } while (ma_atomic_compare_and_swap_64(dst, oldValue, newValue) != oldValue);
- (void)order;
- return oldValue;
+ MA_ATOMIC_FETCH_ADD_LOCK(32, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint64 __stdcall ma_atomic_fetch_add_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_64)
+ {
+ #if defined(MA_32BIT)
+ {
+ MA_ATOMIC_FETCH_ADD_CAS(64, dst, src, order);
+ }
+ #else
+ {
+ #if defined(MA_ARM)
+ {
+ MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedExchangeAdd64, ma_uint64, long long);
+ }
+ #else
+ {
+ (void)order;
+ return (ma_uint64)_InterlockedExchangeAdd64((volatile long long*)dst, (long long)src);
+ }
+ #endif
+ }
+ #endif
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_ADD_LOCK(64, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint8 __stdcall ma_atomic_fetch_sub_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
+ {
+ return ma_atomic_fetch_add_explicit_8(dst, (ma_uint8)(-(ma_int8)src), order);
+ }
+ static MA_INLINE ma_uint16 __stdcall ma_atomic_fetch_sub_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
+ {
+ return ma_atomic_fetch_add_explicit_16(dst, (ma_uint16)(-(ma_int16)src), order);
+ }
+ static MA_INLINE ma_uint32 __stdcall ma_atomic_fetch_sub_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
+ {
+ return ma_atomic_fetch_add_explicit_32(dst, (ma_uint32)(-(ma_int32)src), order);
+ }
+ static MA_INLINE ma_uint64 __stdcall ma_atomic_fetch_sub_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
+ {
+ return ma_atomic_fetch_add_explicit_64(dst, (ma_uint64)(-(ma_int64)src), order);
+ }
+ static MA_INLINE ma_uint8 __stdcall ma_atomic_fetch_and_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ARM)
+ {
+ MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedAnd8, ma_uint8, char);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_AND_CAS(8, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint16 __stdcall ma_atomic_fetch_and_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ARM)
+ {
+ MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedAnd16, ma_uint16, short);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_AND_CAS(16, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint32 __stdcall ma_atomic_fetch_and_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ARM)
+ {
+ MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedAnd, ma_uint32, long);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_AND_CAS(32, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint64 __stdcall ma_atomic_fetch_and_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ARM)
+ {
+ MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedAnd64, ma_uint64, long long);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_AND_CAS(64, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint8 __stdcall ma_atomic_fetch_or_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ARM)
+ {
+ MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedOr8, ma_uint8, char);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_OR_CAS(8, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint16 __stdcall ma_atomic_fetch_or_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ARM)
+ {
+ MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedOr16, ma_uint16, short);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_OR_CAS(16, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint32 __stdcall ma_atomic_fetch_or_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ARM)
+ {
+ MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedOr, ma_uint32, long);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_OR_CAS(32, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint64 __stdcall ma_atomic_fetch_or_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ARM)
+ {
+ MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedOr64, ma_uint64, long long);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_OR_CAS(64, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint8 __stdcall ma_atomic_fetch_xor_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ARM)
+ {
+ MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedXor8, ma_uint8, char);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_XOR_CAS(8, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint16 __stdcall ma_atomic_fetch_xor_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ARM)
+ {
+ MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedXor16, ma_uint16, short);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_XOR_CAS(16, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint32 __stdcall ma_atomic_fetch_xor_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ARM)
+ {
+ MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedXor, ma_uint32, long);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_XOR_CAS(32, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint64 __stdcall ma_atomic_fetch_xor_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ARM)
+ {
+ MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedXor64, ma_uint64, long long);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_XOR_CAS(64, dst, src, order);
+ }
+ #endif
+ }
+ #define ma_atomic_store_explicit_8( dst, src, order) (void)ma_atomic_exchange_explicit_8 (dst, src, order)
+ #define ma_atomic_store_explicit_16(dst, src, order) (void)ma_atomic_exchange_explicit_16(dst, src, order)
+ #define ma_atomic_store_explicit_32(dst, src, order) (void)ma_atomic_exchange_explicit_32(dst, src, order)
+ #define ma_atomic_store_explicit_64(dst, src, order) (void)ma_atomic_exchange_explicit_64(dst, src, order)
+ #if defined(MA_X64)
+ #define ma_atomic_thread_fence(order) __faststorefence(), (void)order
+ #elif defined(MA_ARM64)
+ #define ma_atomic_thread_fence(order) __dmb(_ARM64_BARRIER_ISH), (void)order
+ #else
+ static MA_INLINE void ma_atomic_thread_fence(ma_atomic_memory_order order)
+ {
+ volatile ma_uint32 barrier = 0;
+ ma_atomic_fetch_add_explicit_32(&barrier, 0, order);
}
#endif
- #if defined(MA_ATOMIC_MSVC_USE_INLINED_ASSEMBLY)
- static MA_INLINE void __stdcall ma_atomic_thread_fence(ma_atomic_memory_order order)
+ #define ma_atomic_signal_fence(order) _ReadWriteBarrier(), (void)order
+#endif
+#if defined(MA_ATOMIC_LEGACY_MSVC_ASM)
+ static MA_INLINE ma_uint8 __stdcall ma_atomic_compare_and_swap_8(volatile ma_uint8* dst, ma_uint8 expected, ma_uint8 replacement)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_8)
{
+ ma_uint8 result = 0;
+ __asm {
+ mov ecx, dst
+ mov al, expected
+ mov dl, replacement
+ lock cmpxchg [ecx], dl
+ mov result, al
+ }
+ return result;
+ }
+ #else
+ {
+ MA_ATOMIC_COMPARE_AND_SWAP_LOCK(8, dst, expected, replacement);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint16 __stdcall ma_atomic_compare_and_swap_16(volatile ma_uint16* dst, ma_uint16 expected, ma_uint16 replacement)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_16)
+ {
+ ma_uint16 result = 0;
+ __asm {
+ mov ecx, dst
+ mov ax, expected
+ mov dx, replacement
+ lock cmpxchg [ecx], dx
+ mov result, ax
+ }
+ return result;
+ }
+ #else
+ {
+ MA_ATOMIC_COMPARE_AND_SWAP_LOCK(16, dst, expected, replacement);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint32 __stdcall ma_atomic_compare_and_swap_32(volatile ma_uint32* dst, ma_uint32 expected, ma_uint32 replacement)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_32)
+ {
+ ma_uint32 result = 0;
+ __asm {
+ mov ecx, dst
+ mov eax, expected
+ mov edx, replacement
+ lock cmpxchg [ecx], edx
+ mov result, eax
+ }
+ return result;
+ }
+ #else
+ {
+ MA_ATOMIC_COMPARE_AND_SWAP_LOCK(32, dst, expected, replacement);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint64 __stdcall ma_atomic_compare_and_swap_64(volatile ma_uint64* dst, ma_uint64 expected, ma_uint64 replacement)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_64)
+ {
+ ma_uint32 resultEAX = 0;
+ ma_uint32 resultEDX = 0;
+ __asm {
+ mov esi, dst
+ mov eax, dword ptr expected
+ mov edx, dword ptr expected + 4
+ mov ebx, dword ptr replacement
+ mov ecx, dword ptr replacement + 4
+ lock cmpxchg8b qword ptr [esi]
+ mov resultEAX, eax
+ mov resultEDX, edx
+ }
+ return ((ma_uint64)resultEDX << 32) | resultEAX;
+ }
+ #else
+ {
+ MA_ATOMIC_COMPARE_AND_SWAP_LOCK(64, dst, expected, replacement);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint8 ma_atomic_load_explicit_8(volatile const ma_uint8* dst, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_8)
+ {
+ ma_uint8 result = 0;
+ if (order == ma_atomic_memory_order_relaxed) {
+ __asm {
+ mov esi, dst
+ mov al, [esi]
+ mov result, al
+ }
+ } else if (order <= ma_atomic_memory_order_release) {
+ __asm {
+ mov esi, dst
+ mov al, [esi]
+ lock add dword ptr [esp], 0
+ mov result, al
+ }
+ } else {
+ __asm {
+ lock add dword ptr [esp], 0
+ mov esi, dst
+ mov al, [esi]
+ mov result, al
+ lock add dword ptr [esp], 0
+ }
+ }
+ return result;
+ }
+ #else
+ {
+ MA_ATOMIC_LOAD_EXPLICIT_LOCK(8, dst, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint16 ma_atomic_load_explicit_16(volatile const ma_uint16* dst, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_16)
+ {
+ ma_uint16 result = 0;
+ if (order == ma_atomic_memory_order_relaxed) {
+ __asm {
+ mov esi, dst
+ mov ax, [esi]
+ mov result, ax
+ }
+ } else if (order <= ma_atomic_memory_order_release) {
+ __asm {
+ mov esi, dst
+ mov ax, [esi]
+ lock add dword ptr [esp], 0
+ mov result, ax
+ }
+ } else {
+ __asm {
+ lock add dword ptr [esp], 0
+ mov esi, dst
+ mov ax, [esi]
+ mov result, ax
+ lock add dword ptr [esp], 0
+ }
+ }
+ return result;
+ }
+ #else
+ {
+ MA_ATOMIC_LOAD_EXPLICIT_LOCK(16, dst, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint32 ma_atomic_load_explicit_32(volatile const ma_uint32* dst, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_32)
+ {
+ ma_uint32 result = 0;
+ if (order == ma_atomic_memory_order_relaxed) {
+ __asm {
+ mov esi, dst
+ mov eax, [esi]
+ mov result, eax
+ }
+ } else if (order <= ma_atomic_memory_order_release) {
+ __asm {
+ mov esi, dst
+ mov eax, [esi]
+ lock add dword ptr [esp], 0
+ mov result, eax
+ }
+ } else {
+ __asm {
+ lock add dword ptr [esp], 0
+ mov esi, dst
+ mov eax, [esi]
+ mov result, eax
+ lock add dword ptr [esp], 0
+ }
+ }
+ return result;
+ }
+ #else
+ {
+ MA_ATOMIC_LOAD_EXPLICIT_LOCK(32, dst, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint64 ma_atomic_load_explicit_64(volatile const ma_uint64* dst, ma_atomic_memory_order order)
+ {
+ (void)order;
+ return ma_atomic_compare_and_swap_64((volatile ma_uint64*)dst, 0, 0);
+ }
+ static MA_INLINE void __stdcall ma_atomic_store_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
+ {
+ if (order == ma_atomic_memory_order_relaxed) {
+ __asm {
+ mov esi, dst
+ mov al, src
+ mov [esi], al
+ }
+ } else {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_8)
+ {
+ __asm {
+ mov esi, dst
+ mov al, src
+ xchg [esi], al
+ }
+ }
+ #else
+ {
+ MA_ATOMIC_STORE_EXPLICIT_LOCK(8, dst, src, order);
+ }
+ #endif
+ }
+ }
+ static MA_INLINE void __stdcall ma_atomic_store_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
+ {
+ if (order == ma_atomic_memory_order_relaxed) {
+ __asm {
+ mov esi, dst
+ mov ax, src
+ mov [esi], ax
+ }
+ } else {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_16)
+ {
+ __asm {
+ mov esi, dst
+ mov ax, src
+ xchg [esi], ax
+ }
+ }
+ #else
+ {
+ MA_ATOMIC_STORE_EXPLICIT_LOCK(16, dst, src, order);
+ }
+ #endif
+ }
+ }
+ static MA_INLINE void __stdcall ma_atomic_store_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
+ {
+ if (order == ma_atomic_memory_order_relaxed) {
+ __asm {
+ mov esi, dst
+ mov eax, src
+ mov [esi], eax
+ }
+ } else {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_32)
+ {
+ __asm {
+ mov esi, dst
+ mov eax, src
+ xchg [esi], eax
+ }
+ }
+ #else
+ {
+ MA_ATOMIC_STORE_EXPLICIT_LOCK(32, dst, src, order);
+ }
+ #endif
+ }
+ }
+ static MA_INLINE void __stdcall ma_atomic_store_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_64)
+ {
+ MA_ATOMIC_STORE_EXPLICIT_CAS(64, dst, src, order);
+ }
+ #else
+ {
+ MA_ATOMIC_STORE_EXPLICIT_LOCK(64, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint8 __stdcall ma_atomic_exchange_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_8)
+ {
+ ma_uint8 result = 0;
(void)order;
__asm {
- lock add [esp], 0
+ mov ecx, dst
+ mov al, src
+ lock xchg [ecx], al
+ mov result, al
}
+ return result;
}
- #else
- #if defined(MA_X64)
- #define ma_atomic_thread_fence(order) __faststorefence(), (void)order
- #elif defined(MA_ARM64)
- #define ma_atomic_thread_fence(order) __dmb(_ARM64_BARRIER_ISH), (void)order
#else
- static MA_INLINE void ma_atomic_thread_fence(ma_atomic_memory_order order)
- {
- volatile ma_uint32 barrier = 0;
- ma_atomic_fetch_add_explicit_32(&barrier, 0, order);
+ {
+ MA_ATOMIC_EXCHANGE_EXPLICIT_LOCK(8, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint16 __stdcall ma_atomic_exchange_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_16)
+ {
+ ma_uint16 result = 0;
+ (void)order;
+ __asm {
+ mov ecx, dst
+ mov ax, src
+ lock xchg [ecx], ax
+ mov result, ax
}
- #endif
- #endif
- #define ma_atomic_compiler_fence() ma_atomic_thread_fence(ma_atomic_memory_order_seq_cst)
- #define ma_atomic_signal_fence(order) ma_atomic_thread_fence(order)
- #if defined(MA_ATOMIC_HAS_8)
- static MA_INLINE ma_uint8 ma_atomic_load_explicit_8(volatile const ma_uint8* ptr, ma_atomic_memory_order order)
- {
- #if defined(MA_ARM)
- MA_ATOMIC_MSVC_ARM_INTRINSIC_COMPARE_EXCHANGE(ptr, 0, 0, order, _InterlockedCompareExchange8, ma_uint8, char);
+ return result;
+ }
#else
- (void)order;
- return ma_atomic_compare_and_swap_8((volatile ma_uint8*)ptr, 0, 0);
- #endif
- }
- #endif
- #if defined(MA_ATOMIC_HAS_16)
- static MA_INLINE ma_uint16 ma_atomic_load_explicit_16(volatile const ma_uint16* ptr, ma_atomic_memory_order order)
{
- #if defined(MA_ARM)
- MA_ATOMIC_MSVC_ARM_INTRINSIC_COMPARE_EXCHANGE(ptr, 0, 0, order, _InterlockedCompareExchange16, ma_uint16, short);
+ MA_ATOMIC_EXCHANGE_EXPLICIT_LOCK(16, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint32 __stdcall ma_atomic_exchange_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_32)
+ {
+ ma_uint32 result = 0;
+ (void)order;
+ __asm {
+ mov ecx, dst
+ mov eax, src
+ xchg [ecx], eax
+ mov result, eax
+ }
+ return result;
+ }
#else
- (void)order;
- return ma_atomic_compare_and_swap_16((volatile ma_uint16*)ptr, 0, 0);
- #endif
- }
- #endif
- #if defined(MA_ATOMIC_HAS_32)
- static MA_INLINE ma_uint32 ma_atomic_load_explicit_32(volatile const ma_uint32* ptr, ma_atomic_memory_order order)
{
- #if defined(MA_ARM)
- MA_ATOMIC_MSVC_ARM_INTRINSIC_COMPARE_EXCHANGE(ptr, 0, 0, order, _InterlockedCompareExchange, ma_uint32, long);
+ MA_ATOMIC_EXCHANGE_EXPLICIT_LOCK(32, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint64 __stdcall ma_atomic_exchange_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_64)
+ {
+ MA_ATOMIC_EXCHANGE_EXPLICIT_CAS(64, dst, src, order);
+ }
#else
- (void)order;
- return ma_atomic_compare_and_swap_32((volatile ma_uint32*)ptr, 0, 0);
- #endif
- }
- #endif
- #if defined(MA_ATOMIC_HAS_64)
- static MA_INLINE ma_uint64 ma_atomic_load_explicit_64(volatile const ma_uint64* ptr, ma_atomic_memory_order order)
{
- #if defined(MA_ARM)
- MA_ATOMIC_MSVC_ARM_INTRINSIC_COMPARE_EXCHANGE(ptr, 0, 0, order, _InterlockedCompareExchange64, ma_uint64, long long);
+ MA_ATOMIC_EXCHANGE_EXPLICIT_LOCK(64, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint8 __stdcall ma_atomic_fetch_add_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_8)
+ {
+ ma_uint8 result = 0;
+ (void)order;
+ __asm {
+ mov ecx, dst
+ mov al, src
+ lock xadd [ecx], al
+ mov result, al
+ }
+ return result;
+ }
#else
- (void)order;
- return ma_atomic_compare_and_swap_64((volatile ma_uint64*)ptr, 0, 0);
+ {
+ MA_ATOMIC_FETCH_ADD_LOCK(8, dst, src, order);
+ }
#endif
- }
- #endif
- #if defined(MA_ATOMIC_HAS_8)
- #define ma_atomic_store_explicit_8( dst, src, order) (void)ma_atomic_exchange_explicit_8 (dst, src, order)
- #endif
- #if defined(MA_ATOMIC_HAS_16)
- #define ma_atomic_store_explicit_16(dst, src, order) (void)ma_atomic_exchange_explicit_16(dst, src, order)
- #endif
- #if defined(MA_ATOMIC_HAS_32)
- #define ma_atomic_store_explicit_32(dst, src, order) (void)ma_atomic_exchange_explicit_32(dst, src, order)
- #endif
- #if defined(MA_ATOMIC_HAS_64)
- #define ma_atomic_store_explicit_64(dst, src, order) (void)ma_atomic_exchange_explicit_64(dst, src, order)
- #endif
- #if defined(MA_ATOMIC_HAS_8)
- static MA_INLINE ma_uint8 __stdcall ma_atomic_fetch_sub_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
+ }
+ static MA_INLINE ma_uint16 __stdcall ma_atomic_fetch_add_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_16)
{
- ma_uint8 oldValue;
- ma_uint8 newValue;
- do {
- oldValue = *dst;
- newValue = (ma_uint8)(oldValue - src);
- } while (ma_atomic_compare_and_swap_8(dst, oldValue, newValue) != oldValue);
+ ma_uint16 result = 0;
(void)order;
- return oldValue;
+ __asm {
+ mov ecx, dst
+ mov ax, src
+ lock xadd [ecx], ax
+ mov result, ax
+ }
+ return result;
}
- #endif
- #if defined(MA_ATOMIC_HAS_16)
- static MA_INLINE ma_uint16 __stdcall ma_atomic_fetch_sub_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
- {
- ma_uint16 oldValue;
- ma_uint16 newValue;
- do {
- oldValue = *dst;
- newValue = (ma_uint16)(oldValue - src);
- } while (ma_atomic_compare_and_swap_16(dst, oldValue, newValue) != oldValue);
- (void)order;
- return oldValue;
- }
- #endif
- #if defined(MA_ATOMIC_HAS_32)
- static MA_INLINE ma_uint32 __stdcall ma_atomic_fetch_sub_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
- {
- ma_uint32 oldValue;
- ma_uint32 newValue;
- do {
- oldValue = *dst;
- newValue = oldValue - src;
- } while (ma_atomic_compare_and_swap_32(dst, oldValue, newValue) != oldValue);
- (void)order;
- return oldValue;
- }
- #endif
- #if defined(MA_ATOMIC_HAS_64)
- static MA_INLINE ma_uint64 __stdcall ma_atomic_fetch_sub_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
- {
- ma_uint64 oldValue;
- ma_uint64 newValue;
- do {
- oldValue = *dst;
- newValue = oldValue - src;
- } while (ma_atomic_compare_and_swap_64(dst, oldValue, newValue) != oldValue);
- (void)order;
- return oldValue;
- }
- #endif
- #if defined(MA_ATOMIC_HAS_8)
- static MA_INLINE ma_uint8 __stdcall ma_atomic_fetch_and_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
- {
- #if defined(MA_ARM)
- MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedAnd8, ma_uint8, char);
#else
- ma_uint8 oldValue;
- ma_uint8 newValue;
- do {
- oldValue = *dst;
- newValue = (ma_uint8)(oldValue & src);
- } while (ma_atomic_compare_and_swap_8(dst, oldValue, newValue) != oldValue);
- (void)order;
- return oldValue;
- #endif
- }
- #endif
- #if defined(MA_ATOMIC_HAS_16)
- static MA_INLINE ma_uint16 __stdcall ma_atomic_fetch_and_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
{
- #if defined(MA_ARM)
- MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedAnd16, ma_uint16, short);
- #else
- ma_uint16 oldValue;
- ma_uint16 newValue;
- do {
- oldValue = *dst;
- newValue = (ma_uint16)(oldValue & src);
- } while (ma_atomic_compare_and_swap_16(dst, oldValue, newValue) != oldValue);
- (void)order;
- return oldValue;
- #endif
+ MA_ATOMIC_FETCH_ADD_LOCK(16, dst, src, order);
}
- #endif
- #if defined(MA_ATOMIC_HAS_32)
- static MA_INLINE ma_uint32 __stdcall ma_atomic_fetch_and_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
+ #endif
+ }
+ static MA_INLINE ma_uint32 __stdcall ma_atomic_fetch_add_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_32)
{
- #if defined(MA_ARM)
- MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedAnd, ma_uint32, long);
- #else
- ma_uint32 oldValue;
- ma_uint32 newValue;
- do {
- oldValue = *dst;
- newValue = oldValue & src;
- } while (ma_atomic_compare_and_swap_32(dst, oldValue, newValue) != oldValue);
+ ma_uint32 result = 0;
(void)order;
- return oldValue;
- #endif
+ __asm {
+ mov ecx, dst
+ mov eax, src
+ lock xadd [ecx], eax
+ mov result, eax
+ }
+ return result;
}
- #endif
- #if defined(MA_ATOMIC_HAS_64)
- static MA_INLINE ma_uint64 __stdcall ma_atomic_fetch_and_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
+ #else
{
- #if defined(MA_ARM)
- MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedAnd64, ma_uint64, long long);
- #else
- ma_uint64 oldValue;
- ma_uint64 newValue;
- do {
- oldValue = *dst;
- newValue = oldValue & src;
- } while (ma_atomic_compare_and_swap_64(dst, oldValue, newValue) != oldValue);
- (void)order;
- return oldValue;
- #endif
+ MA_ATOMIC_FETCH_ADD_LOCK(32, dst, src, order);
}
- #endif
- #if defined(MA_ATOMIC_HAS_8)
- static MA_INLINE ma_uint8 __stdcall ma_atomic_fetch_xor_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
+ #endif
+ }
+ static MA_INLINE ma_uint64 __stdcall ma_atomic_fetch_add_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_64)
{
- #if defined(MA_ARM)
- MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedXor8, ma_uint8, char);
- #else
- ma_uint8 oldValue;
- ma_uint8 newValue;
- do {
- oldValue = *dst;
- newValue = (ma_uint8)(oldValue ^ src);
- } while (ma_atomic_compare_and_swap_8(dst, oldValue, newValue) != oldValue);
- (void)order;
- return oldValue;
- #endif
+ MA_ATOMIC_FETCH_ADD_CAS(64, dst, src, order);
}
- #endif
- #if defined(MA_ATOMIC_HAS_16)
- static MA_INLINE ma_uint16 __stdcall ma_atomic_fetch_xor_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
+ #else
{
- #if defined(MA_ARM)
- MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedXor16, ma_uint16, short);
- #else
- ma_uint16 oldValue;
- ma_uint16 newValue;
- do {
- oldValue = *dst;
- newValue = (ma_uint16)(oldValue ^ src);
- } while (ma_atomic_compare_and_swap_16(dst, oldValue, newValue) != oldValue);
- (void)order;
- return oldValue;
- #endif
+ MA_ATOMIC_FETCH_ADD_LOCK(64, dst, src, order);
}
- #endif
- #if defined(MA_ATOMIC_HAS_32)
- static MA_INLINE ma_uint32 __stdcall ma_atomic_fetch_xor_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
+ #endif
+ }
+ static MA_INLINE ma_uint8 __stdcall ma_atomic_fetch_sub_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_8)
{
- #if defined(MA_ARM)
- MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedXor, ma_uint32, long);
- #else
- ma_uint32 oldValue;
- ma_uint32 newValue;
- do {
- oldValue = *dst;
- newValue = oldValue ^ src;
- } while (ma_atomic_compare_and_swap_32(dst, oldValue, newValue) != oldValue);
+ ma_uint8 result = 0;
(void)order;
- return oldValue;
- #endif
+ __asm {
+ mov ecx, dst
+ mov al, src
+ neg al
+ lock xadd [ecx], al
+ mov result, al
+ }
+ return result;
}
- #endif
- #if defined(MA_ATOMIC_HAS_64)
- static MA_INLINE ma_uint64 __stdcall ma_atomic_fetch_xor_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
+ #else
{
- #if defined(MA_ARM)
- MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedXor64, ma_uint64, long long);
- #else
- ma_uint64 oldValue;
- ma_uint64 newValue;
- do {
- oldValue = *dst;
- newValue = oldValue ^ src;
- } while (ma_atomic_compare_and_swap_64(dst, oldValue, newValue) != oldValue);
- (void)order;
- return oldValue;
- #endif
+ MA_ATOMIC_FETCH_ADD_LOCK(8, dst, (ma_uint8)(-(ma_int8)src), order);
}
- #endif
- #if defined(MA_ATOMIC_HAS_8)
- static MA_INLINE ma_uint8 __stdcall ma_atomic_fetch_or_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
+ #endif
+ }
+ static MA_INLINE ma_uint16 __stdcall ma_atomic_fetch_sub_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_16)
{
- #if defined(MA_ARM)
- MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedOr8, ma_uint8, char);
- #else
- ma_uint8 oldValue;
- ma_uint8 newValue;
- do {
- oldValue = *dst;
- newValue = (ma_uint8)(oldValue | src);
- } while (ma_atomic_compare_and_swap_8(dst, oldValue, newValue) != oldValue);
+ ma_uint16 result = 0;
(void)order;
- return oldValue;
- #endif
+ __asm {
+ mov ecx, dst
+ mov ax, src
+ neg ax
+ lock xadd [ecx], ax
+ mov result, ax
+ }
+ return result;
}
- #endif
- #if defined(MA_ATOMIC_HAS_16)
- static MA_INLINE ma_uint16 __stdcall ma_atomic_fetch_or_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
+ #else
{
- #if defined(MA_ARM)
- MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedOr16, ma_uint16, short);
- #else
- ma_uint16 oldValue;
- ma_uint16 newValue;
- do {
- oldValue = *dst;
- newValue = (ma_uint16)(oldValue | src);
- } while (ma_atomic_compare_and_swap_16(dst, oldValue, newValue) != oldValue);
- (void)order;
- return oldValue;
- #endif
+ MA_ATOMIC_FETCH_ADD_LOCK(16, dst, (ma_uint16)(-(ma_int16)src), order);
}
- #endif
- #if defined(MA_ATOMIC_HAS_32)
- static MA_INLINE ma_uint32 __stdcall ma_atomic_fetch_or_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
+ #endif
+ }
+ static MA_INLINE ma_uint32 __stdcall ma_atomic_fetch_sub_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_32)
{
- #if defined(MA_ARM)
- MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedOr, ma_uint32, long);
- #else
- ma_uint32 oldValue;
- ma_uint32 newValue;
- do {
- oldValue = *dst;
- newValue = oldValue | src;
- } while (ma_atomic_compare_and_swap_32(dst, oldValue, newValue) != oldValue);
+ ma_uint32 result = 0;
(void)order;
- return oldValue;
- #endif
+ __asm {
+ mov ecx, dst
+ mov eax, src
+ neg eax
+ lock xadd [ecx], eax
+ mov result, eax
+ }
+ return result;
}
- #endif
- #if defined(MA_ATOMIC_HAS_64)
- static MA_INLINE ma_uint64 __stdcall ma_atomic_fetch_or_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
+ #else
{
- #if defined(MA_ARM)
- MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, _InterlockedOr64, ma_uint64, long long);
- #else
- ma_uint64 oldValue;
- ma_uint64 newValue;
- do {
- oldValue = *dst;
- newValue = oldValue | src;
- } while (ma_atomic_compare_and_swap_64(dst, oldValue, newValue) != oldValue);
- (void)order;
- return oldValue;
- #endif
+ MA_ATOMIC_FETCH_ADD_LOCK(32, dst, (ma_uint32)(-(ma_int32)src), order);
}
- #endif
- #if defined(MA_ATOMIC_HAS_8)
- #define ma_atomic_test_and_set_explicit_8( dst, order) ma_atomic_exchange_explicit_8 (dst, 1, order)
- #endif
- #if defined(MA_ATOMIC_HAS_16)
- #define ma_atomic_test_and_set_explicit_16(dst, order) ma_atomic_exchange_explicit_16(dst, 1, order)
- #endif
- #if defined(MA_ATOMIC_HAS_32)
- #define ma_atomic_test_and_set_explicit_32(dst, order) ma_atomic_exchange_explicit_32(dst, 1, order)
- #endif
- #if defined(MA_ATOMIC_HAS_64)
- #define ma_atomic_test_and_set_explicit_64(dst, order) ma_atomic_exchange_explicit_64(dst, 1, order)
- #endif
- #if defined(MA_ATOMIC_HAS_8)
- #define ma_atomic_clear_explicit_8( dst, order) ma_atomic_store_explicit_8 (dst, 0, order)
- #endif
- #if defined(MA_ATOMIC_HAS_16)
- #define ma_atomic_clear_explicit_16(dst, order) ma_atomic_store_explicit_16(dst, 0, order)
- #endif
- #if defined(MA_ATOMIC_HAS_32)
- #define ma_atomic_clear_explicit_32(dst, order) ma_atomic_store_explicit_32(dst, 0, order)
- #endif
- #if defined(MA_ATOMIC_HAS_64)
- #define ma_atomic_clear_explicit_64(dst, order) ma_atomic_store_explicit_64(dst, 0, order)
- #endif
- #if defined(MA_ATOMIC_HAS_8)
- typedef ma_uint8 ma_atomic_flag;
- #define ma_atomic_flag_test_and_set_explicit(ptr, order) (ma_bool32)ma_atomic_test_and_set_explicit_8(ptr, order)
- #define ma_atomic_flag_clear_explicit(ptr, order) ma_atomic_clear_explicit_8(ptr, order)
- #define ma_atomic_flag_load_explicit(ptr, order) ma_atomic_load_explicit_8(ptr, order)
- #else
- typedef ma_uint32 ma_atomic_flag;
- #define ma_atomic_flag_test_and_set_explicit(ptr, order) (ma_bool32)ma_atomic_test_and_set_explicit_32(ptr, order)
- #define ma_atomic_flag_clear_explicit(ptr, order) ma_atomic_clear_explicit_32(ptr, order)
- #define ma_atomic_flag_load_explicit(ptr, order) ma_atomic_load_explicit_32(ptr, order)
- #endif
-#elif defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)))
+ #endif
+ }
+ static MA_INLINE ma_uint64 __stdcall ma_atomic_fetch_sub_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
+ {
+ MA_ATOMIC_FETCH_ADD_CAS(64, dst, (ma_uint64)(-(ma_int64)src), order);
+ }
+ static MA_INLINE ma_uint8 __stdcall ma_atomic_fetch_and_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
+ {
+ MA_ATOMIC_FETCH_AND_CAS(8, dst, src, order);
+ }
+ static MA_INLINE ma_uint16 __stdcall ma_atomic_fetch_and_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
+ {
+ MA_ATOMIC_FETCH_AND_CAS(16, dst, src, order);
+ }
+ static MA_INLINE ma_uint32 __stdcall ma_atomic_fetch_and_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
+ {
+ MA_ATOMIC_FETCH_AND_CAS(32, dst, src, order);
+ }
+ static MA_INLINE ma_uint64 __stdcall ma_atomic_fetch_and_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
+ {
+ MA_ATOMIC_FETCH_AND_CAS(64, dst, src, order);
+ }
+ static MA_INLINE ma_uint8 __stdcall ma_atomic_fetch_or_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
+ {
+ MA_ATOMIC_FETCH_OR_CAS(8, dst, src, order);
+ }
+ static MA_INLINE ma_uint16 __stdcall ma_atomic_fetch_or_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
+ {
+ MA_ATOMIC_FETCH_OR_CAS(16, dst, src, order);
+ }
+ static MA_INLINE ma_uint32 __stdcall ma_atomic_fetch_or_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
+ {
+ MA_ATOMIC_FETCH_OR_CAS(32, dst, src, order);
+ }
+ static MA_INLINE ma_uint64 __stdcall ma_atomic_fetch_or_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
+ {
+ MA_ATOMIC_FETCH_OR_CAS(64, dst, src, order);
+ }
+ static MA_INLINE ma_uint8 __stdcall ma_atomic_fetch_xor_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
+ {
+ MA_ATOMIC_FETCH_XOR_CAS(8, dst, src, order);
+ }
+ static MA_INLINE ma_uint16 __stdcall ma_atomic_fetch_xor_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
+ {
+ MA_ATOMIC_FETCH_XOR_CAS(16, dst, src, order);
+ }
+ static MA_INLINE ma_uint32 __stdcall ma_atomic_fetch_xor_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
+ {
+ MA_ATOMIC_FETCH_XOR_CAS(32, dst, src, order);
+ }
+ static MA_INLINE ma_uint64 __stdcall ma_atomic_fetch_xor_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
+ {
+ MA_ATOMIC_FETCH_XOR_CAS(64, dst, src, order);
+ }
+ static MA_INLINE void __stdcall ma_atomic_thread_fence(ma_atomic_memory_order order)
+ {
+ (void)order;
+ __asm {
+ lock add dword ptr [esp], 0
+ }
+ }
+ #define ma_atomic_signal_fence(order) __asm {}; (void)order
+#endif
+#if defined(MA_ATOMIC_MODERN_GCC)
#define MA_ATOMIC_HAS_NATIVE_COMPARE_EXCHANGE
- #define MA_ATOMIC_HAS_NATIVE_IS_LOCK_FREE
- #define ma_atomic_memory_order_relaxed __ATOMIC_RELAXED
- #define ma_atomic_memory_order_consume __ATOMIC_CONSUME
- #define ma_atomic_memory_order_acquire __ATOMIC_ACQUIRE
- #define ma_atomic_memory_order_release __ATOMIC_RELEASE
- #define ma_atomic_memory_order_acq_rel __ATOMIC_ACQ_REL
- #define ma_atomic_memory_order_seq_cst __ATOMIC_SEQ_CST
- #define ma_atomic_compiler_fence() __asm__ __volatile__("":::"memory")
#define ma_atomic_thread_fence(order) __atomic_thread_fence(order)
#define ma_atomic_signal_fence(order) __atomic_signal_fence(order)
#define ma_atomic_is_lock_free_8(ptr) __atomic_is_lock_free(1, ptr)
#define ma_atomic_is_lock_free_16(ptr) __atomic_is_lock_free(2, ptr)
#define ma_atomic_is_lock_free_32(ptr) __atomic_is_lock_free(4, ptr)
#define ma_atomic_is_lock_free_64(ptr) __atomic_is_lock_free(8, ptr)
- #define ma_atomic_test_and_set_explicit_8( dst, order) __atomic_exchange_n(dst, 1, order)
- #define ma_atomic_test_and_set_explicit_16(dst, order) __atomic_exchange_n(dst, 1, order)
- #define ma_atomic_test_and_set_explicit_32(dst, order) __atomic_exchange_n(dst, 1, order)
- #define ma_atomic_test_and_set_explicit_64(dst, order) __atomic_exchange_n(dst, 1, order)
- #define ma_atomic_clear_explicit_8( dst, order) __atomic_store_n(dst, 0, order)
- #define ma_atomic_clear_explicit_16(dst, order) __atomic_store_n(dst, 0, order)
- #define ma_atomic_clear_explicit_32(dst, order) __atomic_store_n(dst, 0, order)
- #define ma_atomic_clear_explicit_64(dst, order) __atomic_store_n(dst, 0, order)
#define ma_atomic_store_explicit_8( dst, src, order) __atomic_store_n(dst, src, order)
#define ma_atomic_store_explicit_16(dst, src, order) __atomic_store_n(dst, src, order)
#define ma_atomic_store_explicit_32(dst, src, order) __atomic_store_n(dst, src, order)
@@ -14864,14 +15773,14 @@ typedef int ma_atomic_memory_order;
#define ma_atomic_exchange_explicit_16(dst, src, order) __atomic_exchange_n(dst, src, order)
#define ma_atomic_exchange_explicit_32(dst, src, order) __atomic_exchange_n(dst, src, order)
#define ma_atomic_exchange_explicit_64(dst, src, order) __atomic_exchange_n(dst, src, order)
- #define ma_atomic_compare_exchange_strong_explicit_8( dst, expected, desired, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, desired, 0, successOrder, failureOrder)
- #define ma_atomic_compare_exchange_strong_explicit_16(dst, expected, desired, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, desired, 0, successOrder, failureOrder)
- #define ma_atomic_compare_exchange_strong_explicit_32(dst, expected, desired, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, desired, 0, successOrder, failureOrder)
- #define ma_atomic_compare_exchange_strong_explicit_64(dst, expected, desired, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, desired, 0, successOrder, failureOrder)
- #define ma_atomic_compare_exchange_weak_explicit_8( dst, expected, desired, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, desired, 1, successOrder, failureOrder)
- #define ma_atomic_compare_exchange_weak_explicit_16(dst, expected, desired, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, desired, 1, successOrder, failureOrder)
- #define ma_atomic_compare_exchange_weak_explicit_32(dst, expected, desired, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, desired, 1, successOrder, failureOrder)
- #define ma_atomic_compare_exchange_weak_explicit_64(dst, expected, desired, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, desired, 1, successOrder, failureOrder)
+ #define ma_atomic_compare_exchange_strong_explicit_8( dst, expected, replacement, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, replacement, 0, successOrder, failureOrder)
+ #define ma_atomic_compare_exchange_strong_explicit_16(dst, expected, replacement, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, replacement, 0, successOrder, failureOrder)
+ #define ma_atomic_compare_exchange_strong_explicit_32(dst, expected, replacement, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, replacement, 0, successOrder, failureOrder)
+ #define ma_atomic_compare_exchange_strong_explicit_64(dst, expected, replacement, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, replacement, 0, successOrder, failureOrder)
+ #define ma_atomic_compare_exchange_weak_explicit_8( dst, expected, replacement, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, replacement, 1, successOrder, failureOrder)
+ #define ma_atomic_compare_exchange_weak_explicit_16(dst, expected, replacement, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, replacement, 1, successOrder, failureOrder)
+ #define ma_atomic_compare_exchange_weak_explicit_32(dst, expected, replacement, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, replacement, 1, successOrder, failureOrder)
+ #define ma_atomic_compare_exchange_weak_explicit_64(dst, expected, replacement, successOrder, failureOrder) __atomic_compare_exchange_n(dst, expected, replacement, 1, successOrder, failureOrder)
#define ma_atomic_fetch_add_explicit_8( dst, src, order) __atomic_fetch_add(dst, src, order)
#define ma_atomic_fetch_add_explicit_16(dst, src, order) __atomic_fetch_add(dst, src, order)
#define ma_atomic_fetch_add_explicit_32(dst, src, order) __atomic_fetch_add(dst, src, order)
@@ -14892,19 +15801,19 @@ typedef int ma_atomic_memory_order;
#define ma_atomic_fetch_and_explicit_16(dst, src, order) __atomic_fetch_and(dst, src, order)
#define ma_atomic_fetch_and_explicit_32(dst, src, order) __atomic_fetch_and(dst, src, order)
#define ma_atomic_fetch_and_explicit_64(dst, src, order) __atomic_fetch_and(dst, src, order)
- static MA_INLINE ma_uint8 ma_atomic_compare_and_swap_8(volatile ma_uint8* dst, ma_uint8 expected, ma_uint8 desired)
+ static MA_INLINE ma_uint8 ma_atomic_compare_and_swap_8(volatile ma_uint8* dst, ma_uint8 expected, ma_uint8 replacement)
{
- __atomic_compare_exchange_n(dst, &expected, desired, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+ __atomic_compare_exchange_n(dst, &expected, replacement, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
return expected;
}
- static MA_INLINE ma_uint16 ma_atomic_compare_and_swap_16(volatile ma_uint16* dst, ma_uint16 expected, ma_uint16 desired)
+ static MA_INLINE ma_uint16 ma_atomic_compare_and_swap_16(volatile ma_uint16* dst, ma_uint16 expected, ma_uint16 replacement)
{
- __atomic_compare_exchange_n(dst, &expected, desired, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+ __atomic_compare_exchange_n(dst, &expected, replacement, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
return expected;
}
- static MA_INLINE ma_uint32 ma_atomic_compare_and_swap_32(volatile ma_uint32* dst, ma_uint32 expected, ma_uint32 desired)
+ static MA_INLINE ma_uint32 ma_atomic_compare_and_swap_32(volatile ma_uint32* dst, ma_uint32 expected, ma_uint32 replacement)
{
- __atomic_compare_exchange_n(dst, &expected, desired, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+ __atomic_compare_exchange_n(dst, &expected, replacement, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
return expected;
}
#if defined(__clang__)
@@ -14913,636 +15822,1134 @@ typedef int ma_atomic_memory_order;
#pragma clang diagnostic ignored "-Watomic-alignment"
#endif
#endif
- static MA_INLINE ma_uint64 ma_atomic_compare_and_swap_64(volatile ma_uint64* dst, ma_uint64 expected, ma_uint64 desired)
+ static MA_INLINE ma_uint64 ma_atomic_compare_and_swap_64(volatile ma_uint64* dst, ma_uint64 expected, ma_uint64 replacement)
{
- __atomic_compare_exchange_n(dst, &expected, desired, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+ __atomic_compare_exchange_n(dst, &expected, replacement, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
return expected;
}
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
- typedef ma_uint8 ma_atomic_flag;
- #define ma_atomic_flag_test_and_set_explicit(dst, order) (ma_bool32)__atomic_test_and_set(dst, order)
- #define ma_atomic_flag_clear_explicit(dst, order) __atomic_clear(dst, order)
- #define ma_atomic_flag_load_explicit(ptr, order) ma_atomic_load_explicit_8(ptr, order)
-#else
- #define ma_atomic_memory_order_relaxed 1
- #define ma_atomic_memory_order_consume 2
- #define ma_atomic_memory_order_acquire 3
- #define ma_atomic_memory_order_release 4
- #define ma_atomic_memory_order_acq_rel 5
- #define ma_atomic_memory_order_seq_cst 6
- #define ma_atomic_compiler_fence() __asm__ __volatile__("":::"memory")
- #if defined(__GNUC__)
+#endif
+#if defined(MA_ATOMIC_LEGACY_GCC) || defined(MA_ATOMIC_LEGACY_GCC_ASM)
+ #define ma_atomic_signal_fence(order) __asm__ __volatile__("":::"memory")
+ #if defined(MA_ATOMIC_LEGACY_GCC)
#define ma_atomic_thread_fence(order) __sync_synchronize(), (void)order
- static MA_INLINE ma_uint8 ma_atomic_exchange_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
+ static MA_INLINE ma_uint8 ma_atomic_compare_and_swap_8(volatile ma_uint8* dst, ma_uint8 expected, ma_uint8 replacement)
{
- if (order > ma_atomic_memory_order_acquire) {
- __sync_synchronize();
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_8)
+ {
+ return __sync_val_compare_and_swap(dst, expected, replacement);
}
- return __sync_lock_test_and_set(dst, src);
+ #else
+ {
+ MA_ATOMIC_COMPARE_AND_SWAP_LOCK(8, dst, expected, replacement);
+ }
+ #endif
}
- static MA_INLINE ma_uint16 ma_atomic_exchange_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
+ static MA_INLINE ma_uint16 ma_atomic_compare_and_swap_16(volatile ma_uint16* dst, ma_uint16 expected, ma_uint16 replacement)
{
- ma_uint16 oldValue;
- do {
- oldValue = *dst;
- } while (__sync_val_compare_and_swap(dst, oldValue, src) != oldValue);
- (void)order;
- return oldValue;
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_16)
+ {
+ return __sync_val_compare_and_swap(dst, expected, replacement);
+ }
+ #else
+ {
+ MA_ATOMIC_COMPARE_AND_SWAP_LOCK(16, dst, expected, replacement);
+ }
+ #endif
}
- static MA_INLINE ma_uint32 ma_atomic_exchange_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
+ static MA_INLINE ma_uint32 ma_atomic_compare_and_swap_32(volatile ma_uint32* dst, ma_uint32 expected, ma_uint32 replacement)
{
- ma_uint32 oldValue;
- do {
- oldValue = *dst;
- } while (__sync_val_compare_and_swap(dst, oldValue, src) != oldValue);
- (void)order;
- return oldValue;
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_32)
+ {
+ return __sync_val_compare_and_swap(dst, expected, replacement);
+ }
+ #else
+ {
+ MA_ATOMIC_COMPARE_AND_SWAP_LOCK(32, dst, expected, replacement);
+ }
+ #endif
}
- static MA_INLINE ma_uint64 ma_atomic_exchange_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
+ static MA_INLINE ma_uint64 ma_atomic_compare_and_swap_64(volatile ma_uint64* dst, ma_uint64 expected, ma_uint64 replacement)
{
- ma_uint64 oldValue;
- do {
- oldValue = *dst;
- } while (__sync_val_compare_and_swap(dst, oldValue, src) != oldValue);
- (void)order;
- return oldValue;
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_64)
+ {
+ return __sync_val_compare_and_swap(dst, expected, replacement);
+ }
+ #else
+ {
+ MA_ATOMIC_COMPARE_AND_SWAP_LOCK(64, dst, expected, replacement);
+ }
+ #endif
}
- static MA_INLINE ma_uint8 ma_atomic_fetch_add_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
+ static MA_INLINE ma_uint8 ma_atomic_load_explicit_8(volatile const ma_uint8* ptr, ma_atomic_memory_order order)
{
- (void)order;
- return __sync_fetch_and_add(dst, src);
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_8)
+ {
+ (void)order;
+ return ma_atomic_compare_and_swap_8((ma_uint8*)ptr, 0, 0);
+ }
+ #else
+ {
+ MA_ATOMIC_LOAD_EXPLICIT_LOCK(8, ptr, order);
+ }
+ #endif
}
- static MA_INLINE ma_uint16 ma_atomic_fetch_add_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
+ static MA_INLINE ma_uint16 ma_atomic_load_explicit_16(volatile const ma_uint16* ptr, ma_atomic_memory_order order)
{
- (void)order;
- return __sync_fetch_and_add(dst, src);
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_16)
+ {
+ (void)order;
+ return ma_atomic_compare_and_swap_16((ma_uint16*)ptr, 0, 0);
+ }
+ #else
+ {
+ MA_ATOMIC_LOAD_EXPLICIT_LOCK(16, ptr, order);
+ }
+ #endif
}
- static MA_INLINE ma_uint32 ma_atomic_fetch_add_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
+ static MA_INLINE ma_uint32 ma_atomic_load_explicit_32(volatile const ma_uint32* ptr, ma_atomic_memory_order order)
{
- (void)order;
- return __sync_fetch_and_add(dst, src);
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_32)
+ {
+ (void)order;
+ return ma_atomic_compare_and_swap_32((ma_uint32*)ptr, 0, 0);
+ }
+ #else
+ {
+ MA_ATOMIC_LOAD_EXPLICIT_LOCK(32, ptr, order);
+ }
+ #endif
}
- static MA_INLINE ma_uint64 ma_atomic_fetch_add_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
+ static MA_INLINE ma_uint64 ma_atomic_load_explicit_64(volatile const ma_uint64* ptr, ma_atomic_memory_order order)
{
- (void)order;
- return __sync_fetch_and_add(dst, src);
- }
- static MA_INLINE ma_uint8 ma_atomic_fetch_sub_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
- {
- (void)order;
- return __sync_fetch_and_sub(dst, src);
- }
- static MA_INLINE ma_uint16 ma_atomic_fetch_sub_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
- {
- (void)order;
- return __sync_fetch_and_sub(dst, src);
- }
- static MA_INLINE ma_uint32 ma_atomic_fetch_sub_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
- {
- (void)order;
- return __sync_fetch_and_sub(dst, src);
- }
- static MA_INLINE ma_uint64 ma_atomic_fetch_sub_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
- {
- (void)order;
- return __sync_fetch_and_sub(dst, src);
- }
- static MA_INLINE ma_uint8 ma_atomic_fetch_or_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
- {
- (void)order;
- return __sync_fetch_and_or(dst, src);
- }
- static MA_INLINE ma_uint16 ma_atomic_fetch_or_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
- {
- (void)order;
- return __sync_fetch_and_or(dst, src);
- }
- static MA_INLINE ma_uint32 ma_atomic_fetch_or_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
- {
- (void)order;
- return __sync_fetch_and_or(dst, src);
- }
- static MA_INLINE ma_uint64 ma_atomic_fetch_or_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
- {
- (void)order;
- return __sync_fetch_and_or(dst, src);
- }
- static MA_INLINE ma_uint8 ma_atomic_fetch_xor_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
- {
- (void)order;
- return __sync_fetch_and_xor(dst, src);
- }
- static MA_INLINE ma_uint16 ma_atomic_fetch_xor_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
- {
- (void)order;
- return __sync_fetch_and_xor(dst, src);
- }
- static MA_INLINE ma_uint32 ma_atomic_fetch_xor_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
- {
- (void)order;
- return __sync_fetch_and_xor(dst, src);
- }
- static MA_INLINE ma_uint64 ma_atomic_fetch_xor_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
- {
- (void)order;
- return __sync_fetch_and_xor(dst, src);
- }
- static MA_INLINE ma_uint8 ma_atomic_fetch_and_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
- {
- (void)order;
- return __sync_fetch_and_and(dst, src);
- }
- static MA_INLINE ma_uint16 ma_atomic_fetch_and_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
- {
- (void)order;
- return __sync_fetch_and_and(dst, src);
- }
- static MA_INLINE ma_uint32 ma_atomic_fetch_and_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
- {
- (void)order;
- return __sync_fetch_and_and(dst, src);
- }
- static MA_INLINE ma_uint64 ma_atomic_fetch_and_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
- {
- (void)order;
- return __sync_fetch_and_and(dst, src);
- }
- #define ma_atomic_compare_and_swap_8( dst, expected, desired) __sync_val_compare_and_swap(dst, expected, desired)
- #define ma_atomic_compare_and_swap_16(dst, expected, desired) __sync_val_compare_and_swap(dst, expected, desired)
- #define ma_atomic_compare_and_swap_32(dst, expected, desired) __sync_val_compare_and_swap(dst, expected, desired)
- #define ma_atomic_compare_and_swap_64(dst, expected, desired) __sync_val_compare_and_swap(dst, expected, desired)
- #else
- #if defined(MA_X86)
- #define ma_atomic_thread_fence(order) __asm__ __volatile__("lock; addl $0, (%%esp)" ::: "memory", "cc")
- #elif defined(MA_X64)
- #define ma_atomic_thread_fence(order) __asm__ __volatile__("lock; addq $0, (%%rsp)" ::: "memory", "cc")
- #else
- #error Unsupported architecture. Please submit a feature request.
- #endif
- static MA_INLINE ma_uint8 ma_atomic_compare_and_swap_8(volatile ma_uint8* dst, ma_uint8 expected, ma_uint8 desired)
- {
- ma_uint8 result;
- #if defined(MA_X86) || defined(MA_X64)
- __asm__ __volatile__("lock; cmpxchg %3, %0" : "+m"(*dst), "=a"(result) : "a"(expected), "d"(desired) : "cc");
- #else
- #error Unsupported architecture. Please submit a feature request.
- #endif
- return result;
- }
- static MA_INLINE ma_uint16 ma_atomic_compare_and_swap_16(volatile ma_uint16* dst, ma_uint16 expected, ma_uint16 desired)
- {
- ma_uint16 result;
- #if defined(MA_X86) || defined(MA_X64)
- __asm__ __volatile__("lock; cmpxchg %3, %0" : "+m"(*dst), "=a"(result) : "a"(expected), "d"(desired) : "cc");
- #else
- #error Unsupported architecture. Please submit a feature request.
- #endif
- return result;
- }
- static MA_INLINE ma_uint32 ma_atomic_compare_and_swap_32(volatile ma_uint32* dst, ma_uint32 expected, ma_uint32 desired)
- {
- ma_uint32 result;
- #if defined(MA_X86) || defined(MA_X64)
- __asm__ __volatile__("lock; cmpxchg %3, %0" : "+m"(*dst), "=a"(result) : "a"(expected), "d"(desired) : "cc");
- #else
- #error Unsupported architecture. Please submit a feature request.
- #endif
- return result;
- }
- static MA_INLINE ma_uint64 ma_atomic_compare_and_swap_64(volatile ma_uint64* dst, ma_uint64 expected, ma_uint64 desired)
- {
- volatile ma_uint64 result;
- #if defined(MA_X86)
- ma_uint32 resultEAX;
- ma_uint32 resultEDX;
- __asm__ __volatile__("push %%ebx; xchg %5, %%ebx; lock; cmpxchg8b %0; pop %%ebx" : "+m"(*dst), "=a"(resultEAX), "=d"(resultEDX) : "a"(expected & 0xFFFFFFFF), "d"(expected >> 32), "r"(desired & 0xFFFFFFFF), "c"(desired >> 32) : "cc");
- result = ((ma_uint64)resultEDX << 32) | resultEAX;
- #elif defined(MA_X64)
- __asm__ __volatile__("lock; cmpxchg %3, %0" : "+m"(*dst), "=a"(result) : "a"(expected), "d"(desired) : "cc");
- #else
- #error Unsupported architecture. Please submit a feature request.
- #endif
- return result;
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_64)
+ {
+ (void)order;
+ return ma_atomic_compare_and_swap_64((ma_uint64*)ptr, 0, 0);
+ }
+ #else
+ {
+ MA_ATOMIC_LOAD_EXPLICIT_LOCK(64, ptr, order);
+ }
+ #endif
}
static MA_INLINE ma_uint8 ma_atomic_exchange_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
{
- ma_uint8 result = 0;
- (void)order;
- #if defined(MA_X86) || defined(MA_X64)
- __asm__ __volatile__("lock; xchg %1, %0" : "+m"(*dst), "=a"(result) : "a"(src));
- #else
- #error Unsupported architecture. Please submit a feature request.
- #endif
- return result;
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_8)
+ {
+ if (order > ma_atomic_memory_order_acquire) {
+ __sync_synchronize();
+ }
+ return __sync_lock_test_and_set(dst, src);
+ }
+ #else
+ {
+ MA_ATOMIC_EXCHANGE_EXPLICIT_LOCK(8, dst, src, order);
+ }
+ #endif
}
static MA_INLINE ma_uint16 ma_atomic_exchange_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
{
- ma_uint16 result = 0;
- (void)order;
- #if defined(MA_X86) || defined(MA_X64)
- __asm__ __volatile__("lock; xchg %1, %0" : "+m"(*dst), "=a"(result) : "a"(src));
- #else
- #error Unsupported architecture. Please submit a feature request.
- #endif
- return result;
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_16)
+ {
+ if (order > ma_atomic_memory_order_acquire) {
+ __sync_synchronize();
+ }
+ return __sync_lock_test_and_set(dst, src);
+ }
+ #else
+ {
+ MA_ATOMIC_EXCHANGE_EXPLICIT_LOCK(16, dst, src, order);
+ }
+ #endif
}
static MA_INLINE ma_uint32 ma_atomic_exchange_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
{
- ma_uint32 result;
- (void)order;
- #if defined(MA_X86) || defined(MA_X64)
- __asm__ __volatile__("lock; xchg %1, %0" : "+m"(*dst), "=a"(result) : "a"(src));
- #else
- #error Unsupported architecture. Please submit a feature request.
- #endif
- return result;
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_32)
+ {
+ if (order > ma_atomic_memory_order_acquire) {
+ __sync_synchronize();
+ }
+ return __sync_lock_test_and_set(dst, src);
+ }
+ #else
+ {
+ MA_ATOMIC_EXCHANGE_EXPLICIT_LOCK(32, dst, src, order);
+ }
+ #endif
}
static MA_INLINE ma_uint64 ma_atomic_exchange_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
{
- ma_uint64 result;
- (void)order;
- #if defined(MA_X86)
- do {
- result = *dst;
- } while (ma_atomic_compare_and_swap_64(dst, result, src) != result);
- #elif defined(MA_X64)
- __asm__ __volatile__("lock; xchg %1, %0" : "+m"(*dst), "=a"(result) : "a"(src));
- #else
- #error Unsupported architecture. Please submit a feature request.
- #endif
- return result;
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_64)
+ {
+ if (order > ma_atomic_memory_order_acquire) {
+ __sync_synchronize();
+ }
+ return __sync_lock_test_and_set(dst, src);
+ }
+ #else
+ {
+ MA_ATOMIC_EXCHANGE_EXPLICIT_LOCK(64, dst, src, order);
+ }
+ #endif
}
+ #define ma_atomic_store_explicit_8( dst, src, order) (void)ma_atomic_exchange_explicit_8 (dst, src, order)
+ #define ma_atomic_store_explicit_16(dst, src, order) (void)ma_atomic_exchange_explicit_16(dst, src, order)
+ #define ma_atomic_store_explicit_32(dst, src, order) (void)ma_atomic_exchange_explicit_32(dst, src, order)
+ #define ma_atomic_store_explicit_64(dst, src, order) (void)ma_atomic_exchange_explicit_64(dst, src, order)
static MA_INLINE ma_uint8 ma_atomic_fetch_add_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
{
- ma_uint8 result;
- (void)order;
- #if defined(MA_X86) || defined(MA_X64)
- __asm__ __volatile__("lock; xadd %1, %0" : "+m"(*dst), "=a"(result) : "a"(src) : "cc");
- #else
- #error Unsupported architecture. Please submit a feature request.
- #endif
- return result;
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_8)
+ {
+ (void)order;
+ return __sync_fetch_and_add(dst, src);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_ADD_LOCK(8, dst, src, order);
+ }
+ #endif
}
static MA_INLINE ma_uint16 ma_atomic_fetch_add_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
{
- ma_uint16 result;
- (void)order;
- #if defined(MA_X86) || defined(MA_X64)
- __asm__ __volatile__("lock; xadd %1, %0" : "+m"(*dst), "=a"(result) : "a"(src) : "cc");
- #else
- #error Unsupported architecture. Please submit a feature request.
- #endif
- return result;
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_16)
+ {
+ (void)order;
+ return __sync_fetch_and_add(dst, src);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_ADD_LOCK(16, dst, src, order);
+ }
+ #endif
}
static MA_INLINE ma_uint32 ma_atomic_fetch_add_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
{
- ma_uint32 result;
- (void)order;
- #if defined(MA_X86) || defined(MA_X64)
- __asm__ __volatile__("lock; xadd %1, %0" : "+m"(*dst), "=a"(result) : "a"(src) : "cc");
- #else
- #error Unsupported architecture. Please submit a feature request.
- #endif
- return result;
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_32)
+ {
+ (void)order;
+ return __sync_fetch_and_add(dst, src);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_ADD_LOCK(32, dst, src, order);
+ }
+ #endif
}
static MA_INLINE ma_uint64 ma_atomic_fetch_add_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
{
- #if defined(MA_X86)
- ma_uint64 oldValue;
- ma_uint64 newValue;
- (void)order;
- do {
- oldValue = *dst;
- newValue = oldValue + src;
- } while (ma_atomic_compare_and_swap_64(dst, oldValue, newValue) != oldValue);
- return oldValue;
- #elif defined(MA_X64)
- ma_uint64 result;
- (void)order;
- __asm__ __volatile__("lock; xadd %1, %0" : "+m"(*dst), "=a"(result) : "a"(src) : "cc");
- return result;
- #endif
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_64)
+ {
+ (void)order;
+ return __sync_fetch_and_add(dst, src);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_ADD_LOCK(64, dst, src, order);
+ }
+ #endif
}
static MA_INLINE ma_uint8 ma_atomic_fetch_sub_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
{
- ma_uint8 oldValue;
- ma_uint8 newValue;
- do {
- oldValue = *dst;
- newValue = (ma_uint8)(oldValue - src);
- } while (ma_atomic_compare_and_swap_8(dst, oldValue, newValue) != oldValue);
- (void)order;
- return oldValue;
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_8)
+ {
+ (void)order;
+ return __sync_fetch_and_sub(dst, src);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_ADD_LOCK(8, dst, (ma_uint8)(-(ma_int8)src), order);
+ }
+ #endif
}
static MA_INLINE ma_uint16 ma_atomic_fetch_sub_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
{
- ma_uint16 oldValue;
- ma_uint16 newValue;
- do {
- oldValue = *dst;
- newValue = (ma_uint16)(oldValue - src);
- } while (ma_atomic_compare_and_swap_16(dst, oldValue, newValue) != oldValue);
- (void)order;
- return oldValue;
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_16)
+ {
+ (void)order;
+ return __sync_fetch_and_sub(dst, src);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_ADD_LOCK(16, dst, (ma_uint16)(-(ma_int16)src), order);
+ }
+ #endif
}
static MA_INLINE ma_uint32 ma_atomic_fetch_sub_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
{
- ma_uint32 oldValue;
- ma_uint32 newValue;
- do {
- oldValue = *dst;
- newValue = oldValue - src;
- } while (ma_atomic_compare_and_swap_32(dst, oldValue, newValue) != oldValue);
- (void)order;
- return oldValue;
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_32)
+ {
+ (void)order;
+ return __sync_fetch_and_sub(dst, src);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_ADD_LOCK(32, dst, (ma_uint32)(-(ma_int32)src), order);
+ }
+ #endif
}
static MA_INLINE ma_uint64 ma_atomic_fetch_sub_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
{
- ma_uint64 oldValue;
- ma_uint64 newValue;
- do {
- oldValue = *dst;
- newValue = oldValue - src;
- } while (ma_atomic_compare_and_swap_64(dst, oldValue, newValue) != oldValue);
- (void)order;
- return oldValue;
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_64)
+ {
+ (void)order;
+ return __sync_fetch_and_sub(dst, src);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_ADD_LOCK(64, dst, (ma_uint64)(-(ma_int64)src), order);
+ }
+ #endif
}
static MA_INLINE ma_uint8 ma_atomic_fetch_and_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
{
- ma_uint8 oldValue;
- ma_uint8 newValue;
- do {
- oldValue = *dst;
- newValue = (ma_uint8)(oldValue & src);
- } while (ma_atomic_compare_and_swap_8(dst, oldValue, newValue) != oldValue);
- (void)order;
- return oldValue;
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_8)
+ {
+ (void)order;
+ return __sync_fetch_and_and(dst, src);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_AND_CAS(8, dst, src, order);
+ }
+ #endif
}
static MA_INLINE ma_uint16 ma_atomic_fetch_and_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
{
- ma_uint16 oldValue;
- ma_uint16 newValue;
- do {
- oldValue = *dst;
- newValue = (ma_uint16)(oldValue & src);
- } while (ma_atomic_compare_and_swap_16(dst, oldValue, newValue) != oldValue);
- (void)order;
- return oldValue;
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_16)
+ {
+ (void)order;
+ return __sync_fetch_and_and(dst, src);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_AND_CAS(16, dst, src, order);
+ }
+ #endif
}
static MA_INLINE ma_uint32 ma_atomic_fetch_and_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
{
- ma_uint32 oldValue;
- ma_uint32 newValue;
- do {
- oldValue = *dst;
- newValue = oldValue & src;
- } while (ma_atomic_compare_and_swap_32(dst, oldValue, newValue) != oldValue);
- (void)order;
- return oldValue;
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_32)
+ {
+ (void)order;
+ return __sync_fetch_and_and(dst, src);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_AND_CAS(32, dst, src, order);
+ }
+ #endif
}
static MA_INLINE ma_uint64 ma_atomic_fetch_and_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
{
- ma_uint64 oldValue;
- ma_uint64 newValue;
- do {
- oldValue = *dst;
- newValue = oldValue & src;
- } while (ma_atomic_compare_and_swap_64(dst, oldValue, newValue) != oldValue);
- (void)order;
- return oldValue;
- }
- static MA_INLINE ma_uint8 ma_atomic_fetch_xor_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
- {
- ma_uint8 oldValue;
- ma_uint8 newValue;
- do {
- oldValue = *dst;
- newValue = (ma_uint8)(oldValue ^ src);
- } while (ma_atomic_compare_and_swap_8(dst, oldValue, newValue) != oldValue);
- (void)order;
- return oldValue;
- }
- static MA_INLINE ma_uint16 ma_atomic_fetch_xor_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
- {
- ma_uint16 oldValue;
- ma_uint16 newValue;
- do {
- oldValue = *dst;
- newValue = (ma_uint16)(oldValue ^ src);
- } while (ma_atomic_compare_and_swap_16(dst, oldValue, newValue) != oldValue);
- (void)order;
- return oldValue;
- }
- static MA_INLINE ma_uint32 ma_atomic_fetch_xor_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
- {
- ma_uint32 oldValue;
- ma_uint32 newValue;
- do {
- oldValue = *dst;
- newValue = oldValue ^ src;
- } while (ma_atomic_compare_and_swap_32(dst, oldValue, newValue) != oldValue);
- (void)order;
- return oldValue;
- }
- static MA_INLINE ma_uint64 ma_atomic_fetch_xor_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
- {
- ma_uint64 oldValue;
- ma_uint64 newValue;
- do {
- oldValue = *dst;
- newValue = oldValue ^ src;
- } while (ma_atomic_compare_and_swap_64(dst, oldValue, newValue) != oldValue);
- (void)order;
- return oldValue;
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_64)
+ {
+ (void)order;
+ return __sync_fetch_and_and(dst, src);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_AND_CAS(64, dst, src, order);
+ }
+ #endif
}
static MA_INLINE ma_uint8 ma_atomic_fetch_or_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
{
- ma_uint8 oldValue;
- ma_uint8 newValue;
- do {
- oldValue = *dst;
- newValue = (ma_uint8)(oldValue | src);
- } while (ma_atomic_compare_and_swap_8(dst, oldValue, newValue) != oldValue);
- (void)order;
- return oldValue;
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_8)
+ {
+ (void)order;
+ return __sync_fetch_and_or(dst, src);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_OR_CAS(8, dst, src, order);
+ }
+ #endif
}
static MA_INLINE ma_uint16 ma_atomic_fetch_or_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
{
- ma_uint16 oldValue;
- ma_uint16 newValue;
- do {
- oldValue = *dst;
- newValue = (ma_uint16)(oldValue | src);
- } while (ma_atomic_compare_and_swap_16(dst, oldValue, newValue) != oldValue);
- (void)order;
- return oldValue;
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_16)
+ {
+ (void)order;
+ return __sync_fetch_and_or(dst, src);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_OR_CAS(16, dst, src, order);
+ }
+ #endif
}
static MA_INLINE ma_uint32 ma_atomic_fetch_or_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
{
- ma_uint32 oldValue;
- ma_uint32 newValue;
- do {
- oldValue = *dst;
- newValue = oldValue | src;
- } while (ma_atomic_compare_and_swap_32(dst, oldValue, newValue) != oldValue);
- (void)order;
- return oldValue;
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_32)
+ {
+ (void)order;
+ return __sync_fetch_and_or(dst, src);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_OR_CAS(32, dst, src, order);
+ }
+ #endif
}
static MA_INLINE ma_uint64 ma_atomic_fetch_or_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
{
- ma_uint64 oldValue;
- ma_uint64 newValue;
- do {
- oldValue = *dst;
- newValue = oldValue | src;
- } while (ma_atomic_compare_and_swap_64(dst, oldValue, newValue) != oldValue);
- (void)order;
- return oldValue;
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_64)
+ {
+ (void)order;
+ return __sync_fetch_and_or(dst, src);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_OR_CAS(64, dst, src, order);
+ }
+ #endif
}
+ static MA_INLINE ma_uint8 ma_atomic_fetch_xor_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_8)
+ {
+ (void)order;
+ return __sync_fetch_and_xor(dst, src);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_XOR_CAS(8, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint16 ma_atomic_fetch_xor_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_16)
+ {
+ (void)order;
+ return __sync_fetch_and_xor(dst, src);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_XOR_CAS(16, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint32 ma_atomic_fetch_xor_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_32)
+ {
+ (void)order;
+ return __sync_fetch_and_xor(dst, src);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_XOR_CAS(32, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint64 ma_atomic_fetch_xor_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_64)
+ {
+ (void)order;
+ return __sync_fetch_and_xor(dst, src);
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_XOR_CAS(64, dst, src, order);
+ }
+ #endif
+ }
+ #elif defined(MA_ATOMIC_LEGACY_GCC_ASM)
+ #define MA_ATOMIC_CMPXCHG_GCC_X86(instructionSizeSuffix, result, dst, expected, replacement) \
+ __asm__ __volatile__( \
+ "lock; cmpxchg"instructionSizeSuffix" %2, %1" \
+ : "=a"(result), \
+ "=m"(*dst) \
+ : "r"(replacement), \
+ "0"(expected), \
+ "m"(*dst) \
+ : "cc", "memory")
+ #define MA_ATOMIC_XADD_GCC_X86(instructionSizeSuffix, result, dst, src) \
+ __asm__ __volatile__( \
+ "lock; xadd"instructionSizeSuffix" %0, %1" \
+ : "=a"(result), \
+ "=m"(*dst) \
+ : "0"(src), \
+ "m"(*dst) \
+ : "cc", "memory")
+ static MA_INLINE ma_uint8 ma_atomic_compare_and_swap_8(volatile ma_uint8* dst, ma_uint8 expected, ma_uint8 replacement)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_8) && (defined(MA_X86) || defined(MA_X64))
+ {
+ ma_uint8 result;
+ #if defined(MA_X86) || defined(MA_X64)
+ {
+ MA_ATOMIC_CMPXCHG_GCC_X86("b", result, dst, expected, replacement);
+ }
+ #else
+ {
+ #error Unsupported architecture.
+ }
+ #endif
+ return result;
+ }
+ #else
+ {
+ MA_ATOMIC_COMPARE_AND_SWAP_LOCK(8, dst, expected, replacement);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint16 ma_atomic_compare_and_swap_16(volatile ma_uint16* dst, ma_uint16 expected, ma_uint16 replacement)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_16) && (defined(MA_X86) || defined(MA_X64))
+ {
+ ma_uint16 result;
+ #if defined(MA_X86) || defined(MA_X64)
+ {
+ MA_ATOMIC_CMPXCHG_GCC_X86("w", result, dst, expected, replacement);
+ }
+ #else
+ {
+ #error Unsupported architecture.
+ }
+ #endif
+ return result;
+ }
+ #else
+ {
+ MA_ATOMIC_COMPARE_AND_SWAP_LOCK(16, dst, expected, replacement);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint32 ma_atomic_compare_and_swap_32(volatile ma_uint32* dst, ma_uint32 expected, ma_uint32 replacement)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_32) && (defined(MA_X86) || defined(MA_X64))
+ {
+ ma_uint32 result;
+ #if defined(MA_X86) || defined(MA_X64)
+ {
+ MA_ATOMIC_CMPXCHG_GCC_X86("l", result, dst, expected, replacement);
+ }
+ #else
+ {
+ #error Unsupported architecture.
+ }
+ #endif
+ return result;
+ }
+ #else
+ {
+ MA_ATOMIC_COMPARE_AND_SWAP_LOCK(32, dst, expected, replacement);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint64 ma_atomic_compare_and_swap_64(volatile ma_uint64* dst, ma_uint64 expected, ma_uint64 replacement)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_64) && (defined(MA_X86) || defined(MA_X64))
+ {
+ ma_uint64 result;
+ #if defined(MA_X86)
+ {
+ ma_uint32 resultEAX;
+ ma_uint32 resultEDX;
+ __asm__ __volatile__(
+ "pushl %%ebx\n"
+ "movl %4, %%ebx\n"
+ "lock cmpxchg8b (%%edi)\n"
+ "popl %%ebx\n"
+ : "=a"(resultEAX),
+ "=d"(resultEDX)
+ : "a"((ma_uint32)(expected & 0xFFFFFFFF)),
+ "d"((ma_uint32)(expected >> 32)),
+ "r"((ma_uint32)(replacement & 0xFFFFFFFF)),
+ "c"((ma_uint32)(replacement >> 32)),
+ "D"(dst)
+ : "memory", "cc");
+ result = ((ma_uint64)resultEDX << 32) | resultEAX;
+ }
+ #elif defined(MA_X64)
+ {
+ MA_ATOMIC_CMPXCHG_GCC_X86("q", result, dst, expected, replacement);
+ }
+ #else
+ {
+ #error Unsupported architecture.
+ }
+ #endif
+ return result;
+ }
+ #else
+ {
+ MA_ATOMIC_COMPARE_AND_SWAP_LOCK(64, dst, expected, replacement);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint8 ma_atomic_load_explicit_8(volatile const ma_uint8* dst, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_8) && (defined(MA_X86) || defined(MA_X64))
+ {
+ ma_uint8 result;
+ #if defined(MA_X86) || defined(MA_X64)
+ {
+ if (order == ma_atomic_memory_order_relaxed) {
+ MA_ATOMIC_LOAD_RELAXED_GCC_X86("b", result, dst);
+ } else if (order <= ma_atomic_memory_order_release) {
+ MA_ATOMIC_LOAD_RELEASE_GCC_X86("b", result, dst);
+ } else {
+ MA_ATOMIC_LOAD_SEQ_CST_GCC_X86("b", result, dst);
+ }
+ }
+ #else
+ {
+ #error Unsupported architecture.
+ }
+ #endif
+ return result;
+ }
+ #else
+ {
+ MA_ATOMIC_LOAD_EXPLICIT_LOCK(8, dst, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint16 ma_atomic_load_explicit_16(volatile const ma_uint16* dst, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_16) && (defined(MA_X86) || defined(MA_X64))
+ {
+ ma_uint16 result;
+ #if defined(MA_X86) || defined(MA_X64)
+ {
+ if (order == ma_atomic_memory_order_relaxed) {
+ MA_ATOMIC_LOAD_RELAXED_GCC_X86("w", result, dst);
+ } else if (order <= ma_atomic_memory_order_release) {
+ MA_ATOMIC_LOAD_RELEASE_GCC_X86("w", result, dst);
+ } else {
+ MA_ATOMIC_LOAD_SEQ_CST_GCC_X86("w", result, dst);
+ }
+ }
+ #else
+ {
+ #error Unsupported architecture.
+ }
+ #endif
+ return result;
+ }
+ #else
+ {
+ MA_ATOMIC_LOAD_EXPLICIT_LOCK(16, dst, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint32 ma_atomic_load_explicit_32(volatile const ma_uint32* dst, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_32) && (defined(MA_X86) || defined(MA_X64))
+ {
+ ma_uint32 result;
+ #if defined(MA_X86) || defined(MA_X64)
+ {
+ if (order == ma_atomic_memory_order_relaxed) {
+ MA_ATOMIC_LOAD_RELAXED_GCC_X86("l", result, dst);
+ } else if (order <= ma_atomic_memory_order_release) {
+ MA_ATOMIC_LOAD_RELEASE_GCC_X86("l", result, dst);
+ } else {
+ MA_ATOMIC_LOAD_SEQ_CST_GCC_X86("l", result, dst);
+ }
+ }
+ #else
+ {
+ #error Unsupported architecture.
+ }
+ #endif
+ return result;
+ }
+ #else
+ {
+ MA_ATOMIC_LOAD_EXPLICIT_LOCK(32, dst, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint64 ma_atomic_load_explicit_64(volatile const ma_uint64* dst, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_64) && (defined(MA_X86) || defined(MA_X64))
+ {
+ ma_uint64 result;
+ #if defined(MA_X64)
+ {
+ if (order == ma_atomic_memory_order_relaxed) {
+ MA_ATOMIC_LOAD_RELAXED_GCC_X86("q", result, dst);
+ } else if (order <= ma_atomic_memory_order_release) {
+ MA_ATOMIC_LOAD_RELEASE_GCC_X86("q", result, dst);
+ } else {
+ MA_ATOMIC_LOAD_SEQ_CST_GCC_X86("q", result, dst);
+ }
+ }
+ #elif defined(MA_X86)
+ {
+ (void)order;
+ return ma_atomic_compare_and_swap_64((volatile ma_uint64*)dst, 0, 0);
+ }
+ #else
+ {
+ #error Unsupported architecture.
+ }
+ #endif
+ return result;
+ }
+ #else
+ {
+ MA_ATOMIC_LOAD_EXPLICIT_LOCK(64, dst, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint8 ma_atomic_exchange_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_8) && (defined(MA_X86) || defined(MA_X64))
+ {
+ ma_uint8 result;
+ (void)order;
+ #if defined(MA_X86) || defined(MA_X64)
+ {
+ MA_ATOMIC_XCHG_GCC_X86("b", result, dst, src);
+ }
+ #else
+ {
+ #error Unsupported architecture.
+ }
+ #endif
+ return result;
+ }
+ #else
+ {
+ MA_ATOMIC_EXCHANGE_EXPLICIT_LOCK(8, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint16 ma_atomic_exchange_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_16) && (defined(MA_X86) || defined(MA_X64))
+ {
+ ma_uint16 result;
+ (void)order;
+ #if defined(MA_X86) || defined(MA_X64)
+ {
+ MA_ATOMIC_XCHG_GCC_X86("w", result, dst, src);
+ }
+ #else
+ {
+ #error Unsupported architecture.
+ }
+ #endif
+ return result;
+ }
+ #else
+ {
+ MA_ATOMIC_EXCHANGE_EXPLICIT_LOCK(16, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint32 ma_atomic_exchange_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_32) && (defined(MA_X86) || defined(MA_X64))
+ {
+ ma_uint32 result;
+ (void)order;
+ #if defined(MA_X86) || defined(MA_X64)
+ {
+ MA_ATOMIC_XCHG_GCC_X86("l", result, dst, src);
+ }
+ #else
+ {
+ #error Unsupported architecture.
+ }
+ #endif
+ return result;
+ }
+ #else
+ {
+ MA_ATOMIC_EXCHANGE_EXPLICIT_LOCK(32, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint64 ma_atomic_exchange_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_64) && (defined(MA_X86) || defined(MA_X64))
+ {
+ ma_uint64 result;
+ (void)order;
+ #if defined(MA_X86)
+ {
+ MA_ATOMIC_EXCHANGE_EXPLICIT_CAS(64, dst, src, order);
+ }
+ #elif defined(MA_X64)
+ {
+ MA_ATOMIC_XCHG_GCC_X86("q", result, dst, src);
+ }
+ #else
+ {
+ #error Unsupported architecture.
+ }
+ #endif
+ return result;
+ }
+ #else
+ {
+ MA_ATOMIC_EXCHANGE_EXPLICIT_LOCK(64, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE void ma_atomic_store_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_8) && (defined(MA_X86) || defined(MA_X64))
+ {
+ #if defined(MA_X86) || defined(MA_X64)
+ {
+ if (order == ma_atomic_memory_order_relaxed) {
+ __asm__ __volatile__ (
+ "movb %1, %0"
+ : "=m"(*dst)
+ : "r"(src)
+ );
+ } else {
+ __asm__ __volatile__ (
+ "xchgb %1, %0"
+ : "=m"(*dst)
+ : "r"(src)
+ : "memory"
+ );
+ }
+ }
+ #else
+ {
+ #error Unsupported architecture.
+ }
+ #endif
+ }
+ #else
+ {
+ MA_ATOMIC_STORE_EXPLICIT_LOCK(8, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE void ma_atomic_store_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_16) && (defined(MA_X86) || defined(MA_X64))
+ {
+ #if defined(MA_X86) || defined(MA_X64)
+ {
+ if (order == ma_atomic_memory_order_relaxed) {
+ __asm__ __volatile__ (
+ "movw %1, %0"
+ : "=m"(*dst)
+ : "r"(src)
+ );
+ } else {
+ __asm__ __volatile__ (
+ "xchgw %1, %0"
+ : "=m"(*dst)
+ : "r"(src)
+ : "memory"
+ );
+ }
+ }
+ #else
+ {
+ #error Unsupported architecture.
+ }
+ #endif
+ }
+ #else
+ {
+ MA_ATOMIC_STORE_EXPLICIT_LOCK(16, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE void ma_atomic_store_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_32) && (defined(MA_X86) || defined(MA_X64))
+ {
+ #if defined(MA_X86) || defined(MA_X64)
+ {
+ if (order == ma_atomic_memory_order_relaxed) {
+ __asm__ __volatile__ (
+ "movl %1, %0"
+ : "=m"(*dst)
+ : "r"(src)
+ );
+ } else {
+ __asm__ __volatile__ (
+ "xchgl %1, %0"
+ : "=m"(*dst)
+ : "r"(src)
+ : "memory"
+ );
+ }
+ }
+ #else
+ {
+ #error Unsupported architecture.
+ }
+ #endif
+ }
+ #else
+ {
+ MA_ATOMIC_STORE_EXPLICIT_LOCK(32, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE void ma_atomic_store_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_64) && (defined(MA_X86) || defined(MA_X64))
+ {
+ #if defined(MA_X64)
+ {
+ if (order == ma_atomic_memory_order_relaxed) {
+ __asm__ __volatile__ (
+ "movq %1, %0"
+ : "=m"(*dst)
+ : "r"(src)
+ );
+ } else {
+ __asm__ __volatile__ (
+ "xchgq %1, %0"
+ : "=m"(*dst)
+ : "r"(src)
+ : "memory"
+ );
+ }
+ }
+ #else
+ {
+ MA_ATOMIC_STORE_EXPLICIT_CAS(64, dst, src, order);
+ }
+ #endif
+ }
+ #else
+ {
+ MA_ATOMIC_STORE_EXPLICIT_LOCK(64, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint8 ma_atomic_fetch_add_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_8) && (defined(MA_X86) || defined(MA_X64))
+ {
+ #if defined(MA_X86) || defined(MA_X64)
+ {
+ ma_uint8 result;
+ (void)order;
+ MA_ATOMIC_XADD_GCC_X86("b", result, dst, src);
+ return result;
+ }
+ #else
+ {
+ #error Unsupported architecture.
+ }
+ #endif
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_ADD_LOCK(8, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint16 ma_atomic_fetch_add_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_16) && (defined(MA_X86) || defined(MA_X64))
+ {
+ #if defined(MA_X86) || defined(MA_X64)
+ {
+ ma_uint16 result;
+ (void)order;
+ MA_ATOMIC_XADD_GCC_X86("w", result, dst, src);
+ return result;
+ }
+ #else
+ {
+ #error Unsupported architecture.
+ }
+ #endif
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_ADD_LOCK(16, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint32 ma_atomic_fetch_add_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_32) && (defined(MA_X86) || defined(MA_X64))
+ {
+ #if defined(MA_X86) || defined(MA_X64)
+ {
+ ma_uint32 result;
+ (void)order;
+ MA_ATOMIC_XADD_GCC_X86("l", result, dst, src);
+ return result;
+ }
+ #else
+ {
+ #error Unsupported architecture.
+ }
+ #endif
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_ADD_LOCK(32, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint64 ma_atomic_fetch_add_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
+ {
+ #if defined(MA_ATOMIC_IS_LOCK_FREE_64) && (defined(MA_X86) || defined(MA_X64))
+ {
+ #if defined(MA_X86)
+ {
+ MA_ATOMIC_FETCH_ADD_CAS(64, dst, src, order);
+ }
+ #elif defined(MA_X64)
+ {
+ ma_uint64 result;
+ MA_ATOMIC_XADD_GCC_X86("q", result, dst, src);
+ (void)order;
+ return result;
+ }
+ #else
+ {
+ #error Unsupported architecture.
+ }
+ #endif
+ }
+ #else
+ {
+ MA_ATOMIC_FETCH_ADD_LOCK(64, dst, src, order);
+ }
+ #endif
+ }
+ static MA_INLINE ma_uint8 ma_atomic_fetch_sub_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
+ {
+ return ma_atomic_fetch_add_explicit_8(dst, (ma_uint8)(-(ma_int8)src), order);
+ }
+ static MA_INLINE ma_uint16 ma_atomic_fetch_sub_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
+ {
+ return ma_atomic_fetch_add_explicit_16(dst, (ma_uint16)(-(ma_int16)src), order);
+ }
+ static MA_INLINE ma_uint32 ma_atomic_fetch_sub_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
+ {
+ return ma_atomic_fetch_add_explicit_32(dst, (ma_uint32)(-(ma_int32)src), order);
+ }
+ static MA_INLINE ma_uint64 ma_atomic_fetch_sub_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
+ {
+ return ma_atomic_fetch_add_explicit_64(dst, (ma_uint64)(-(ma_int64)src), order);
+ }
+ static MA_INLINE ma_uint8 ma_atomic_fetch_and_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
+ {
+ MA_ATOMIC_FETCH_AND_CAS(8, dst, src, order);
+ }
+ static MA_INLINE ma_uint16 ma_atomic_fetch_and_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
+ {
+ MA_ATOMIC_FETCH_AND_CAS(16, dst, src, order);
+ }
+ static MA_INLINE ma_uint32 ma_atomic_fetch_and_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
+ {
+ MA_ATOMIC_FETCH_AND_CAS(32, dst, src, order);
+ }
+ static MA_INLINE ma_uint64 ma_atomic_fetch_and_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
+ {
+ MA_ATOMIC_FETCH_AND_CAS(64, dst, src, order);
+ }
+ static MA_INLINE ma_uint8 ma_atomic_fetch_or_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
+ {
+ MA_ATOMIC_FETCH_OR_CAS(8, dst, src, order);
+ }
+ static MA_INLINE ma_uint16 ma_atomic_fetch_or_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
+ {
+ MA_ATOMIC_FETCH_OR_CAS(16, dst, src, order);
+ }
+ static MA_INLINE ma_uint32 ma_atomic_fetch_or_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
+ {
+ MA_ATOMIC_FETCH_OR_CAS(32, dst, src, order);
+ }
+ static MA_INLINE ma_uint64 ma_atomic_fetch_or_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
+ {
+ MA_ATOMIC_FETCH_OR_CAS(64, dst, src, order);
+ }
+ static MA_INLINE ma_uint8 ma_atomic_fetch_xor_explicit_8(volatile ma_uint8* dst, ma_uint8 src, ma_atomic_memory_order order)
+ {
+ MA_ATOMIC_FETCH_XOR_CAS(8, dst, src, order);
+ }
+ static MA_INLINE ma_uint16 ma_atomic_fetch_xor_explicit_16(volatile ma_uint16* dst, ma_uint16 src, ma_atomic_memory_order order)
+ {
+ MA_ATOMIC_FETCH_XOR_CAS(16, dst, src, order);
+ }
+ static MA_INLINE ma_uint32 ma_atomic_fetch_xor_explicit_32(volatile ma_uint32* dst, ma_uint32 src, ma_atomic_memory_order order)
+ {
+ MA_ATOMIC_FETCH_XOR_CAS(32, dst, src, order);
+ }
+ static MA_INLINE ma_uint64 ma_atomic_fetch_xor_explicit_64(volatile ma_uint64* dst, ma_uint64 src, ma_atomic_memory_order order)
+ {
+ MA_ATOMIC_FETCH_XOR_CAS(64, dst, src, order);
+ }
+ #else
+ #error Unsupported compiler.
#endif
- #define ma_atomic_signal_fence(order) ma_atomic_thread_fence(order)
- static MA_INLINE ma_uint8 ma_atomic_load_explicit_8(volatile const ma_uint8* ptr, ma_atomic_memory_order order)
- {
- (void)order;
- return ma_atomic_compare_and_swap_8((ma_uint8*)ptr, 0, 0);
- }
- static MA_INLINE ma_uint16 ma_atomic_load_explicit_16(volatile const ma_uint16* ptr, ma_atomic_memory_order order)
- {
- (void)order;
- return ma_atomic_compare_and_swap_16((ma_uint16*)ptr, 0, 0);
- }
- static MA_INLINE ma_uint32 ma_atomic_load_explicit_32(volatile const ma_uint32* ptr, ma_atomic_memory_order order)
- {
- (void)order;
- return ma_atomic_compare_and_swap_32((ma_uint32*)ptr, 0, 0);
- }
- static MA_INLINE ma_uint64 ma_atomic_load_explicit_64(volatile const ma_uint64* ptr, ma_atomic_memory_order order)
- {
- (void)order;
- return ma_atomic_compare_and_swap_64((ma_uint64*)ptr, 0, 0);
- }
- #define ma_atomic_store_explicit_8( dst, src, order) (void)ma_atomic_exchange_explicit_8 (dst, src, order)
- #define ma_atomic_store_explicit_16(dst, src, order) (void)ma_atomic_exchange_explicit_16(dst, src, order)
- #define ma_atomic_store_explicit_32(dst, src, order) (void)ma_atomic_exchange_explicit_32(dst, src, order)
- #define ma_atomic_store_explicit_64(dst, src, order) (void)ma_atomic_exchange_explicit_64(dst, src, order)
- #define ma_atomic_test_and_set_explicit_8( dst, order) ma_atomic_exchange_explicit_8 (dst, 1, order)
- #define ma_atomic_test_and_set_explicit_16(dst, order) ma_atomic_exchange_explicit_16(dst, 1, order)
- #define ma_atomic_test_and_set_explicit_32(dst, order) ma_atomic_exchange_explicit_32(dst, 1, order)
- #define ma_atomic_test_and_set_explicit_64(dst, order) ma_atomic_exchange_explicit_64(dst, 1, order)
- #define ma_atomic_clear_explicit_8( dst, order) ma_atomic_store_explicit_8 (dst, 0, order)
- #define ma_atomic_clear_explicit_16(dst, order) ma_atomic_store_explicit_16(dst, 0, order)
- #define ma_atomic_clear_explicit_32(dst, order) ma_atomic_store_explicit_32(dst, 0, order)
- #define ma_atomic_clear_explicit_64(dst, order) ma_atomic_store_explicit_64(dst, 0, order)
- typedef ma_uint8 ma_atomic_flag;
- #define ma_atomic_flag_test_and_set_explicit(ptr, order) (ma_bool32)ma_atomic_test_and_set_explicit_8(ptr, order)
- #define ma_atomic_flag_clear_explicit(ptr, order) ma_atomic_clear_explicit_8(ptr, order)
- #define ma_atomic_flag_load_explicit(ptr, order) ma_atomic_load_explicit_8(ptr, order)
#endif
#if !defined(MA_ATOMIC_HAS_NATIVE_COMPARE_EXCHANGE)
- #if defined(MA_ATOMIC_HAS_8)
- static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_8(volatile ma_uint8* dst, ma_uint8* expected, ma_uint8 desired, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
- {
- ma_uint8 expectedValue;
- ma_uint8 result;
- (void)successOrder;
- (void)failureOrder;
- expectedValue = ma_atomic_load_explicit_8(expected, ma_atomic_memory_order_seq_cst);
- result = ma_atomic_compare_and_swap_8(dst, expectedValue, desired);
- if (result == expectedValue) {
- return 1;
- } else {
- ma_atomic_store_explicit_8(expected, result, failureOrder);
- return 0;
- }
- }
- #endif
- #if defined(MA_ATOMIC_HAS_16)
- static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_16(volatile ma_uint16* dst, ma_uint16* expected, ma_uint16 desired, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
- {
- ma_uint16 expectedValue;
- ma_uint16 result;
- (void)successOrder;
- (void)failureOrder;
- expectedValue = ma_atomic_load_explicit_16(expected, ma_atomic_memory_order_seq_cst);
- result = ma_atomic_compare_and_swap_16(dst, expectedValue, desired);
- if (result == expectedValue) {
- return 1;
- } else {
- ma_atomic_store_explicit_16(expected, result, failureOrder);
- return 0;
- }
- }
- #endif
- #if defined(MA_ATOMIC_HAS_32)
- static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_32(volatile ma_uint32* dst, ma_uint32* expected, ma_uint32 desired, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
- {
- ma_uint32 expectedValue;
- ma_uint32 result;
- (void)successOrder;
- (void)failureOrder;
- expectedValue = ma_atomic_load_explicit_32(expected, ma_atomic_memory_order_seq_cst);
- result = ma_atomic_compare_and_swap_32(dst, expectedValue, desired);
- if (result == expectedValue) {
- return 1;
- } else {
- ma_atomic_store_explicit_32(expected, result, failureOrder);
- return 0;
- }
- }
- #endif
- #if defined(MA_ATOMIC_HAS_64)
- static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_64(volatile ma_uint64* dst, volatile ma_uint64* expected, ma_uint64 desired, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
- {
- ma_uint64 expectedValue;
- ma_uint64 result;
- (void)successOrder;
- (void)failureOrder;
- expectedValue = ma_atomic_load_explicit_64(expected, ma_atomic_memory_order_seq_cst);
- result = ma_atomic_compare_and_swap_64(dst, expectedValue, desired);
- if (result == expectedValue) {
- return 1;
- } else {
- ma_atomic_store_explicit_64(expected, result, failureOrder);
- return 0;
- }
- }
- #endif
- #define ma_atomic_compare_exchange_weak_explicit_8( dst, expected, desired, successOrder, failureOrder) ma_atomic_compare_exchange_strong_explicit_8 (dst, expected, desired, successOrder, failureOrder)
- #define ma_atomic_compare_exchange_weak_explicit_16(dst, expected, desired, successOrder, failureOrder) ma_atomic_compare_exchange_strong_explicit_16(dst, expected, desired, successOrder, failureOrder)
- #define ma_atomic_compare_exchange_weak_explicit_32(dst, expected, desired, successOrder, failureOrder) ma_atomic_compare_exchange_strong_explicit_32(dst, expected, desired, successOrder, failureOrder)
- #define ma_atomic_compare_exchange_weak_explicit_64(dst, expected, desired, successOrder, failureOrder) ma_atomic_compare_exchange_strong_explicit_64(dst, expected, desired, successOrder, failureOrder)
-#endif
-#if !defined(MA_ATOMIC_HAS_NATIVE_IS_LOCK_FREE)
- static MA_INLINE ma_bool32 ma_atomic_is_lock_free_8(volatile void* ptr)
+ static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_8(volatile ma_uint8* dst, ma_uint8* expected, ma_uint8 replacement, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
{
- (void)ptr;
- return 1;
- }
- static MA_INLINE ma_bool32 ma_atomic_is_lock_free_16(volatile void* ptr)
- {
- (void)ptr;
- return 1;
- }
- static MA_INLINE ma_bool32 ma_atomic_is_lock_free_32(volatile void* ptr)
- {
- (void)ptr;
- return 1;
- }
- static MA_INLINE ma_bool32 ma_atomic_is_lock_free_64(volatile void* ptr)
- {
- (void)ptr;
- #if defined(MA_64BIT)
- return 1;
- #else
- #if defined(MA_X86) || defined(MA_X64)
+ ma_uint8 result;
+ (void)successOrder;
+ (void)failureOrder;
+ result = ma_atomic_compare_and_swap_8(dst, *expected, replacement);
+ if (result == *expected) {
return 1;
- #else
+ } else {
+ *expected = result;
return 0;
- #endif
- #endif
+ }
}
+ static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_16(volatile ma_uint16* dst, ma_uint16* expected, ma_uint16 replacement, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
+ {
+ ma_uint16 result;
+ (void)successOrder;
+ (void)failureOrder;
+ result = ma_atomic_compare_and_swap_16(dst, *expected, replacement);
+ if (result == *expected) {
+ return 1;
+ } else {
+ *expected = result;
+ return 0;
+ }
+ }
+ static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_32(volatile ma_uint32* dst, ma_uint32* expected, ma_uint32 replacement, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
+ {
+ ma_uint32 result;
+ (void)successOrder;
+ (void)failureOrder;
+ result = ma_atomic_compare_and_swap_32(dst, *expected, replacement);
+ if (result == *expected) {
+ return 1;
+ } else {
+ *expected = result;
+ return 0;
+ }
+ }
+ static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_64(volatile ma_uint64* dst, volatile ma_uint64* expected, ma_uint64 replacement, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
+ {
+ ma_uint64 result;
+ (void)successOrder;
+ (void)failureOrder;
+ result = ma_atomic_compare_and_swap_64(dst, *expected, replacement);
+ if (result == *expected) {
+ return 1;
+ } else {
+ *expected = result;
+ return 0;
+ }
+ }
+ #define ma_atomic_compare_exchange_weak_explicit_8( dst, expected, replacement, successOrder, failureOrder) ma_atomic_compare_exchange_strong_explicit_8 (dst, expected, replacement, successOrder, failureOrder)
+ #define ma_atomic_compare_exchange_weak_explicit_16(dst, expected, replacement, successOrder, failureOrder) ma_atomic_compare_exchange_strong_explicit_16(dst, expected, replacement, successOrder, failureOrder)
+ #define ma_atomic_compare_exchange_weak_explicit_32(dst, expected, replacement, successOrder, failureOrder) ma_atomic_compare_exchange_strong_explicit_32(dst, expected, replacement, successOrder, failureOrder)
+ #define ma_atomic_compare_exchange_weak_explicit_64(dst, expected, replacement, successOrder, failureOrder) ma_atomic_compare_exchange_strong_explicit_64(dst, expected, replacement, successOrder, failureOrder)
#endif
#if defined(MA_64BIT)
static MA_INLINE ma_bool32 ma_atomic_is_lock_free_ptr(volatile void** ptr)
@@ -15561,17 +16968,17 @@ typedef int ma_atomic_memory_order;
{
return (void*)ma_atomic_exchange_explicit_64((volatile ma_uint64*)dst, (ma_uint64)src, order);
}
- static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_ptr(volatile void** dst, void** expected, void* desired, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
+ static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_ptr(volatile void** dst, void** expected, void* replacement, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
{
- return ma_atomic_compare_exchange_strong_explicit_64((volatile ma_uint64*)dst, (ma_uint64*)expected, (ma_uint64)desired, successOrder, failureOrder);
+ return ma_atomic_compare_exchange_strong_explicit_64((volatile ma_uint64*)dst, (ma_uint64*)expected, (ma_uint64)replacement, successOrder, failureOrder);
}
- static MA_INLINE ma_bool32 ma_atomic_compare_exchange_weak_explicit_ptr(volatile void** dst, void** expected, void* desired, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
+ static MA_INLINE ma_bool32 ma_atomic_compare_exchange_weak_explicit_ptr(volatile void** dst, void** expected, void* replacement, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
{
- return ma_atomic_compare_exchange_weak_explicit_64((volatile ma_uint64*)dst, (ma_uint64*)expected, (ma_uint64)desired, successOrder, failureOrder);
+ return ma_atomic_compare_exchange_weak_explicit_64((volatile ma_uint64*)dst, (ma_uint64*)expected, (ma_uint64)replacement, successOrder, failureOrder);
}
- static MA_INLINE void* ma_atomic_compare_and_swap_ptr(volatile void** dst, void* expected, void* desired)
+ static MA_INLINE void* ma_atomic_compare_and_swap_ptr(volatile void** dst, void* expected, void* replacement)
{
- return (void*)ma_atomic_compare_and_swap_64((volatile ma_uint64*)dst, (ma_uint64)expected, (ma_uint64)desired);
+ return (void*)ma_atomic_compare_and_swap_64((volatile ma_uint64*)dst, (ma_uint64)expected, (ma_uint64)replacement);
}
#elif defined(MA_32BIT)
static MA_INLINE ma_bool32 ma_atomic_is_lock_free_ptr(volatile void** ptr)
@@ -15590,36 +16997,26 @@ typedef int ma_atomic_memory_order;
{
return (void*)ma_atomic_exchange_explicit_32((volatile ma_uint32*)dst, (ma_uint32)src, order);
}
- static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_ptr(volatile void** dst, void** expected, void* desired, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
+ static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_ptr(volatile void** dst, void** expected, void* replacement, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
{
- return ma_atomic_compare_exchange_strong_explicit_32((volatile ma_uint32*)dst, (ma_uint32*)expected, (ma_uint32)desired, successOrder, failureOrder);
+ return ma_atomic_compare_exchange_strong_explicit_32((volatile ma_uint32*)dst, (ma_uint32*)expected, (ma_uint32)replacement, successOrder, failureOrder);
}
- static MA_INLINE ma_bool32 ma_atomic_compare_exchange_weak_explicit_ptr(volatile void** dst, void** expected, void* desired, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
+ static MA_INLINE ma_bool32 ma_atomic_compare_exchange_weak_explicit_ptr(volatile void** dst, void** expected, void* replacement, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
{
- return ma_atomic_compare_exchange_weak_explicit_32((volatile ma_uint32*)dst, (ma_uint32*)expected, (ma_uint32)desired, successOrder, failureOrder);
+ return ma_atomic_compare_exchange_weak_explicit_32((volatile ma_uint32*)dst, (ma_uint32*)expected, (ma_uint32)replacement, successOrder, failureOrder);
}
- static MA_INLINE void* ma_atomic_compare_and_swap_ptr(volatile void** dst, void* expected, void* desired)
+ static MA_INLINE void* ma_atomic_compare_and_swap_ptr(volatile void** dst, void* expected, void* replacement)
{
- return (void*)ma_atomic_compare_and_swap_32((volatile ma_uint32*)dst, (ma_uint32)expected, (ma_uint32)desired);
+ return (void*)ma_atomic_compare_and_swap_32((volatile ma_uint32*)dst, (ma_uint32)expected, (ma_uint32)replacement);
}
#else
#error Unsupported architecture.
#endif
-#define ma_atomic_flag_test_and_set(ptr) ma_atomic_flag_test_and_set_explicit(ptr, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_flag_clear(ptr) ma_atomic_flag_clear_explicit(ptr, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_store_ptr(dst, src) ma_atomic_store_explicit_ptr((volatile void**)dst, (void*)src, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_load_ptr(ptr) ma_atomic_load_explicit_ptr((volatile void**)ptr, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_exchange_ptr(dst, src) ma_atomic_exchange_explicit_ptr((volatile void**)dst, (void*)src, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_compare_exchange_strong_ptr(dst, expected, desired) ma_atomic_compare_exchange_strong_explicit_ptr((volatile void**)dst, (void**)expected, (void*)desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_compare_exchange_weak_ptr(dst, expected, desired) ma_atomic_compare_exchange_weak_explicit_ptr((volatile void**)dst, (void**)expected, (void*)desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_test_and_set_8( ptr) ma_atomic_test_and_set_explicit_8( ptr, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_test_and_set_16(ptr) ma_atomic_test_and_set_explicit_16(ptr, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_test_and_set_32(ptr) ma_atomic_test_and_set_explicit_32(ptr, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_test_and_set_64(ptr) ma_atomic_test_and_set_explicit_64(ptr, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_clear_8( ptr) ma_atomic_clear_explicit_8( ptr, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_clear_16(ptr) ma_atomic_clear_explicit_16(ptr, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_clear_32(ptr) ma_atomic_clear_explicit_32(ptr, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_clear_64(ptr) ma_atomic_clear_explicit_64(ptr, ma_atomic_memory_order_seq_cst)
+#define ma_atomic_store_ptr(dst, src) ma_atomic_store_explicit_ptr((volatile void**)dst, (void*)src, ma_atomic_memory_order_seq_cst)
+#define ma_atomic_load_ptr(ptr) ma_atomic_load_explicit_ptr((volatile void**)ptr, ma_atomic_memory_order_seq_cst)
+#define ma_atomic_exchange_ptr(dst, src) ma_atomic_exchange_explicit_ptr((volatile void**)dst, (void*)src, ma_atomic_memory_order_seq_cst)
+#define ma_atomic_compare_exchange_strong_ptr(dst, expected, replacement) ma_atomic_compare_exchange_strong_explicit_ptr((volatile void**)dst, (void**)expected, (void*)replacement, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
+#define ma_atomic_compare_exchange_weak_ptr(dst, expected, replacement) ma_atomic_compare_exchange_weak_explicit_ptr((volatile void**)dst, (void**)expected, (void*)replacement, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
#define ma_atomic_store_8( dst, src) ma_atomic_store_explicit_8( dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_store_16(dst, src) ma_atomic_store_explicit_16(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_store_32(dst, src) ma_atomic_store_explicit_32(dst, src, ma_atomic_memory_order_seq_cst)
@@ -15632,14 +17029,14 @@ typedef int ma_atomic_memory_order;
#define ma_atomic_exchange_16(dst, src) ma_atomic_exchange_explicit_16(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_exchange_32(dst, src) ma_atomic_exchange_explicit_32(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_exchange_64(dst, src) ma_atomic_exchange_explicit_64(dst, src, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_compare_exchange_strong_8( dst, expected, desired) ma_atomic_compare_exchange_strong_explicit_8( dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_compare_exchange_strong_16(dst, expected, desired) ma_atomic_compare_exchange_strong_explicit_16(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_compare_exchange_strong_32(dst, expected, desired) ma_atomic_compare_exchange_strong_explicit_32(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_compare_exchange_strong_64(dst, expected, desired) ma_atomic_compare_exchange_strong_explicit_64(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_compare_exchange_weak_8( dst, expected, desired) ma_atomic_compare_exchange_weak_explicit_8( dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_compare_exchange_weak_16( dst, expected, desired) ma_atomic_compare_exchange_weak_explicit_16(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_compare_exchange_weak_32( dst, expected, desired) ma_atomic_compare_exchange_weak_explicit_32(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_compare_exchange_weak_64( dst, expected, desired) ma_atomic_compare_exchange_weak_explicit_64(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
+#define ma_atomic_compare_exchange_strong_8( dst, expected, replacement) ma_atomic_compare_exchange_strong_explicit_8( dst, expected, replacement, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
+#define ma_atomic_compare_exchange_strong_16(dst, expected, replacement) ma_atomic_compare_exchange_strong_explicit_16(dst, expected, replacement, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
+#define ma_atomic_compare_exchange_strong_32(dst, expected, replacement) ma_atomic_compare_exchange_strong_explicit_32(dst, expected, replacement, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
+#define ma_atomic_compare_exchange_strong_64(dst, expected, replacement) ma_atomic_compare_exchange_strong_explicit_64(dst, expected, replacement, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
+#define ma_atomic_compare_exchange_weak_8( dst, expected, replacement) ma_atomic_compare_exchange_weak_explicit_8( dst, expected, replacement, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
+#define ma_atomic_compare_exchange_weak_16( dst, expected, replacement) ma_atomic_compare_exchange_weak_explicit_16(dst, expected, replacement, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
+#define ma_atomic_compare_exchange_weak_32( dst, expected, replacement) ma_atomic_compare_exchange_weak_explicit_32(dst, expected, replacement, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
+#define ma_atomic_compare_exchange_weak_64( dst, expected, replacement) ma_atomic_compare_exchange_weak_explicit_64(dst, expected, replacement, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_add_8( dst, src) ma_atomic_fetch_add_explicit_8( dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_add_16(dst, src) ma_atomic_fetch_add_explicit_16(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_add_32(dst, src) ma_atomic_fetch_add_explicit_32(dst, src, ma_atomic_memory_order_seq_cst)
@@ -15660,14 +17057,6 @@ typedef int ma_atomic_memory_order;
#define ma_atomic_fetch_and_16(dst, src) ma_atomic_fetch_and_explicit_16(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_and_32(dst, src) ma_atomic_fetch_and_explicit_32(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_and_64(dst, src) ma_atomic_fetch_and_explicit_64(dst, src, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_test_and_set_explicit_i8( ptr, order) (ma_int8 )ma_atomic_test_and_set_explicit_8( (ma_uint8* )ptr, order)
-#define ma_atomic_test_and_set_explicit_i16(ptr, order) (ma_int16)ma_atomic_test_and_set_explicit_16((ma_uint16*)ptr, order)
-#define ma_atomic_test_and_set_explicit_i32(ptr, order) (ma_int32)ma_atomic_test_and_set_explicit_32((ma_uint32*)ptr, order)
-#define ma_atomic_test_and_set_explicit_i64(ptr, order) (ma_int64)ma_atomic_test_and_set_explicit_64((ma_uint64*)ptr, order)
-#define ma_atomic_clear_explicit_i8( ptr, order) ma_atomic_clear_explicit_8( (ma_uint8* )ptr, order)
-#define ma_atomic_clear_explicit_i16(ptr, order) ma_atomic_clear_explicit_16((ma_uint16*)ptr, order)
-#define ma_atomic_clear_explicit_i32(ptr, order) ma_atomic_clear_explicit_32((ma_uint32*)ptr, order)
-#define ma_atomic_clear_explicit_i64(ptr, order) ma_atomic_clear_explicit_64((ma_uint64*)ptr, order)
#define ma_atomic_store_explicit_i8( dst, src, order) ma_atomic_store_explicit_8( (ma_uint8* )dst, (ma_uint8 )src, order)
#define ma_atomic_store_explicit_i16(dst, src, order) ma_atomic_store_explicit_16((ma_uint16*)dst, (ma_uint16)src, order)
#define ma_atomic_store_explicit_i32(dst, src, order) ma_atomic_store_explicit_32((ma_uint32*)dst, (ma_uint32)src, order)
@@ -15680,14 +17069,14 @@ typedef int ma_atomic_memory_order;
#define ma_atomic_exchange_explicit_i16(dst, src, order) (ma_int16)ma_atomic_exchange_explicit_16((ma_uint16*)dst, (ma_uint16)src, order)
#define ma_atomic_exchange_explicit_i32(dst, src, order) (ma_int32)ma_atomic_exchange_explicit_32((ma_uint32*)dst, (ma_uint32)src, order)
#define ma_atomic_exchange_explicit_i64(dst, src, order) (ma_int64)ma_atomic_exchange_explicit_64((ma_uint64*)dst, (ma_uint64)src, order)
-#define ma_atomic_compare_exchange_strong_explicit_i8( dst, expected, desired, successOrder, failureOrder) ma_atomic_compare_exchange_strong_explicit_8( (ma_uint8* )dst, (ma_uint8* )expected, (ma_uint8 )desired, successOrder, failureOrder)
-#define ma_atomic_compare_exchange_strong_explicit_i16(dst, expected, desired, successOrder, failureOrder) ma_atomic_compare_exchange_strong_explicit_16((ma_uint16*)dst, (ma_uint16*)expected, (ma_uint16)desired, successOrder, failureOrder)
-#define ma_atomic_compare_exchange_strong_explicit_i32(dst, expected, desired, successOrder, failureOrder) ma_atomic_compare_exchange_strong_explicit_32((ma_uint32*)dst, (ma_uint32*)expected, (ma_uint32)desired, successOrder, failureOrder)
-#define ma_atomic_compare_exchange_strong_explicit_i64(dst, expected, desired, successOrder, failureOrder) ma_atomic_compare_exchange_strong_explicit_64((ma_uint64*)dst, (ma_uint64*)expected, (ma_uint64)desired, successOrder, failureOrder)
-#define ma_atomic_compare_exchange_weak_explicit_i8( dst, expected, desired, successOrder, failureOrder) ma_atomic_compare_exchange_weak_explicit_8( (ma_uint8* )dst, (ma_uint8* )expected, (ma_uint8 )desired, successOrder, failureOrder)
-#define ma_atomic_compare_exchange_weak_explicit_i16(dst, expected, desired, successOrder, failureOrder) ma_atomic_compare_exchange_weak_explicit_16((ma_uint16*)dst, (ma_uint16*)expected, (ma_uint16)desired, successOrder, failureOrder)
-#define ma_atomic_compare_exchange_weak_explicit_i32(dst, expected, desired, successOrder, failureOrder) ma_atomic_compare_exchange_weak_explicit_32((ma_uint32*)dst, (ma_uint32*)expected, (ma_uint32)desired, successOrder, failureOrder)
-#define ma_atomic_compare_exchange_weak_explicit_i64(dst, expected, desired, successOrder, failureOrder) ma_atomic_compare_exchange_weak_explicit_64((ma_uint64*)dst, (ma_uint64*)expected, (ma_uint64)desired, successOrder, failureOrder)
+#define ma_atomic_compare_exchange_strong_explicit_i8( dst, expected, replacement, successOrder, failureOrder) ma_atomic_compare_exchange_strong_explicit_8( (ma_uint8* )dst, (ma_uint8* )expected, (ma_uint8 )replacement, successOrder, failureOrder)
+#define ma_atomic_compare_exchange_strong_explicit_i16(dst, expected, replacement, successOrder, failureOrder) ma_atomic_compare_exchange_strong_explicit_16((ma_uint16*)dst, (ma_uint16*)expected, (ma_uint16)replacement, successOrder, failureOrder)
+#define ma_atomic_compare_exchange_strong_explicit_i32(dst, expected, replacement, successOrder, failureOrder) ma_atomic_compare_exchange_strong_explicit_32((ma_uint32*)dst, (ma_uint32*)expected, (ma_uint32)replacement, successOrder, failureOrder)
+#define ma_atomic_compare_exchange_strong_explicit_i64(dst, expected, replacement, successOrder, failureOrder) ma_atomic_compare_exchange_strong_explicit_64((ma_uint64*)dst, (ma_uint64*)expected, (ma_uint64)replacement, successOrder, failureOrder)
+#define ma_atomic_compare_exchange_weak_explicit_i8( dst, expected, replacement, successOrder, failureOrder) ma_atomic_compare_exchange_weak_explicit_8( (ma_uint8* )dst, (ma_uint8* )expected, (ma_uint8 )replacement, successOrder, failureOrder)
+#define ma_atomic_compare_exchange_weak_explicit_i16(dst, expected, replacement, successOrder, failureOrder) ma_atomic_compare_exchange_weak_explicit_16((ma_uint16*)dst, (ma_uint16*)expected, (ma_uint16)replacement, successOrder, failureOrder)
+#define ma_atomic_compare_exchange_weak_explicit_i32(dst, expected, replacement, successOrder, failureOrder) ma_atomic_compare_exchange_weak_explicit_32((ma_uint32*)dst, (ma_uint32*)expected, (ma_uint32)replacement, successOrder, failureOrder)
+#define ma_atomic_compare_exchange_weak_explicit_i64(dst, expected, replacement, successOrder, failureOrder) ma_atomic_compare_exchange_weak_explicit_64((ma_uint64*)dst, (ma_uint64*)expected, (ma_uint64)replacement, successOrder, failureOrder)
#define ma_atomic_fetch_add_explicit_i8( dst, src, order) (ma_int8 )ma_atomic_fetch_add_explicit_8( (ma_uint8* )dst, (ma_uint8 )src, order)
#define ma_atomic_fetch_add_explicit_i16(dst, src, order) (ma_int16)ma_atomic_fetch_add_explicit_16((ma_uint16*)dst, (ma_uint16)src, order)
#define ma_atomic_fetch_add_explicit_i32(dst, src, order) (ma_int32)ma_atomic_fetch_add_explicit_32((ma_uint32*)dst, (ma_uint32)src, order)
@@ -15708,14 +17097,6 @@ typedef int ma_atomic_memory_order;
#define ma_atomic_fetch_and_explicit_i16(dst, src, order) (ma_int16)ma_atomic_fetch_and_explicit_16((ma_uint16*)dst, (ma_uint16)src, order)
#define ma_atomic_fetch_and_explicit_i32(dst, src, order) (ma_int32)ma_atomic_fetch_and_explicit_32((ma_uint32*)dst, (ma_uint32)src, order)
#define ma_atomic_fetch_and_explicit_i64(dst, src, order) (ma_int64)ma_atomic_fetch_and_explicit_64((ma_uint64*)dst, (ma_uint64)src, order)
-#define ma_atomic_test_and_set_i8( ptr) ma_atomic_test_and_set_explicit_i8( ptr, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_test_and_set_i16(ptr) ma_atomic_test_and_set_explicit_i16(ptr, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_test_and_set_i32(ptr) ma_atomic_test_and_set_explicit_i32(ptr, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_test_and_set_i64(ptr) ma_atomic_test_and_set_explicit_i64(ptr, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_clear_i8( ptr) ma_atomic_clear_explicit_i8( ptr, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_clear_i16(ptr) ma_atomic_clear_explicit_i16(ptr, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_clear_i32(ptr) ma_atomic_clear_explicit_i32(ptr, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_clear_i64(ptr) ma_atomic_clear_explicit_i64(ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_store_i8( dst, src) ma_atomic_store_explicit_i8( dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_store_i16(dst, src) ma_atomic_store_explicit_i16(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_store_i32(dst, src) ma_atomic_store_explicit_i32(dst, src, ma_atomic_memory_order_seq_cst)
@@ -15728,14 +17109,14 @@ typedef int ma_atomic_memory_order;
#define ma_atomic_exchange_i16(dst, src) ma_atomic_exchange_explicit_i16(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_exchange_i32(dst, src) ma_atomic_exchange_explicit_i32(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_exchange_i64(dst, src) ma_atomic_exchange_explicit_i64(dst, src, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_compare_exchange_strong_i8( dst, expected, desired) ma_atomic_compare_exchange_strong_explicit_i8( dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_compare_exchange_strong_i16(dst, expected, desired) ma_atomic_compare_exchange_strong_explicit_i16(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_compare_exchange_strong_i32(dst, expected, desired) ma_atomic_compare_exchange_strong_explicit_i32(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_compare_exchange_strong_i64(dst, expected, desired) ma_atomic_compare_exchange_strong_explicit_i64(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_compare_exchange_weak_i8( dst, expected, desired) ma_atomic_compare_exchange_weak_explicit_i8( dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_compare_exchange_weak_i16(dst, expected, desired) ma_atomic_compare_exchange_weak_explicit_i16(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_compare_exchange_weak_i32(dst, expected, desired) ma_atomic_compare_exchange_weak_explicit_i32(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_compare_exchange_weak_i64(dst, expected, desired) ma_atomic_compare_exchange_weak_explicit_i64(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
+#define ma_atomic_compare_exchange_strong_i8( dst, expected, replacement) ma_atomic_compare_exchange_strong_explicit_i8( dst, expected, replacement, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
+#define ma_atomic_compare_exchange_strong_i16(dst, expected, replacement) ma_atomic_compare_exchange_strong_explicit_i16(dst, expected, replacement, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
+#define ma_atomic_compare_exchange_strong_i32(dst, expected, replacement) ma_atomic_compare_exchange_strong_explicit_i32(dst, expected, replacement, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
+#define ma_atomic_compare_exchange_strong_i64(dst, expected, replacement) ma_atomic_compare_exchange_strong_explicit_i64(dst, expected, replacement, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
+#define ma_atomic_compare_exchange_weak_i8( dst, expected, replacement) ma_atomic_compare_exchange_weak_explicit_i8( dst, expected, replacement, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
+#define ma_atomic_compare_exchange_weak_i16(dst, expected, replacement) ma_atomic_compare_exchange_weak_explicit_i16(dst, expected, replacement, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
+#define ma_atomic_compare_exchange_weak_i32(dst, expected, replacement) ma_atomic_compare_exchange_weak_explicit_i32(dst, expected, replacement, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
+#define ma_atomic_compare_exchange_weak_i64(dst, expected, replacement) ma_atomic_compare_exchange_weak_explicit_i64(dst, expected, replacement, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_add_i8( dst, src) ma_atomic_fetch_add_explicit_i8( dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_add_i16(dst, src) ma_atomic_fetch_add_explicit_i16(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_add_i32(dst, src) ma_atomic_fetch_add_explicit_i32(dst, src, ma_atomic_memory_order_seq_cst)
@@ -15812,28 +17193,28 @@ static MA_INLINE double ma_atomic_exchange_explicit_f64(volatile double* dst, do
r.i = ma_atomic_exchange_explicit_64((volatile ma_uint64*)dst, x.i, order);
return r.f;
}
-static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_f32(volatile float* dst, float* expected, float desired, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
+static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_f32(volatile float* dst, float* expected, float replacement, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
{
ma_atomic_if32 d;
- d.f = desired;
+ d.f = replacement;
return ma_atomic_compare_exchange_strong_explicit_32((volatile ma_uint32*)dst, (ma_uint32*)expected, d.i, successOrder, failureOrder);
}
-static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_f64(volatile double* dst, double* expected, double desired, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
+static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_f64(volatile double* dst, double* expected, double replacement, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
{
ma_atomic_if64 d;
- d.f = desired;
+ d.f = replacement;
return ma_atomic_compare_exchange_strong_explicit_64((volatile ma_uint64*)dst, (ma_uint64*)expected, d.i, successOrder, failureOrder);
}
-static MA_INLINE ma_bool32 ma_atomic_compare_exchange_weak_explicit_f32(volatile float* dst, float* expected, float desired, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
+static MA_INLINE ma_bool32 ma_atomic_compare_exchange_weak_explicit_f32(volatile float* dst, float* expected, float replacement, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
{
ma_atomic_if32 d;
- d.f = desired;
+ d.f = replacement;
return ma_atomic_compare_exchange_weak_explicit_32((volatile ma_uint32*)dst, (ma_uint32*)expected, d.i, successOrder, failureOrder);
}
-static MA_INLINE ma_bool32 ma_atomic_compare_exchange_weak_explicit_f64(volatile double* dst, double* expected, double desired, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
+static MA_INLINE ma_bool32 ma_atomic_compare_exchange_weak_explicit_f64(volatile double* dst, double* expected, double replacement, ma_atomic_memory_order successOrder, ma_atomic_memory_order failureOrder)
{
ma_atomic_if64 d;
- d.f = desired;
+ d.f = replacement;
return ma_atomic_compare_exchange_weak_explicit_64((volatile ma_uint64*)dst, (ma_uint64*)expected, d.i, successOrder, failureOrder);
}
static MA_INLINE float ma_atomic_fetch_add_explicit_f32(volatile float* dst, float src, ma_atomic_memory_order order)
@@ -15924,10 +17305,10 @@ static MA_INLINE double ma_atomic_fetch_and_explicit_f64(volatile double* dst, d
#define ma_atomic_load_f64(ptr) (double)ma_atomic_load_explicit_f64(ptr, ma_atomic_memory_order_seq_cst)
#define ma_atomic_exchange_f32(dst, src) (float )ma_atomic_exchange_explicit_f32(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_exchange_f64(dst, src) (double)ma_atomic_exchange_explicit_f64(dst, src, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_compare_exchange_strong_f32(dst, expected, desired) ma_atomic_compare_exchange_strong_explicit_f32(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_compare_exchange_strong_f64(dst, expected, desired) ma_atomic_compare_exchange_strong_explicit_f64(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_compare_exchange_weak_f32(dst, expected, desired) ma_atomic_compare_exchange_weak_explicit_f32(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
-#define ma_atomic_compare_exchange_weak_f64(dst, expected, desired) ma_atomic_compare_exchange_weak_explicit_f64(dst, expected, desired, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
+#define ma_atomic_compare_exchange_strong_f32(dst, expected, replacement) ma_atomic_compare_exchange_strong_explicit_f32(dst, expected, replacement, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
+#define ma_atomic_compare_exchange_strong_f64(dst, expected, replacement) ma_atomic_compare_exchange_strong_explicit_f64(dst, expected, replacement, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
+#define ma_atomic_compare_exchange_weak_f32(dst, expected, replacement) ma_atomic_compare_exchange_weak_explicit_f32(dst, expected, replacement, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
+#define ma_atomic_compare_exchange_weak_f64(dst, expected, replacement) ma_atomic_compare_exchange_weak_explicit_f64(dst, expected, replacement, ma_atomic_memory_order_seq_cst, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_add_f32(dst, src) ma_atomic_fetch_add_explicit_f32(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_add_f64(dst, src) ma_atomic_fetch_add_explicit_f64(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_sub_f32(dst, src) ma_atomic_fetch_sub_explicit_f32(dst, src, ma_atomic_memory_order_seq_cst)
@@ -15938,39 +17319,24 @@ static MA_INLINE double ma_atomic_fetch_and_explicit_f64(volatile double* dst, d
#define ma_atomic_fetch_xor_f64(dst, src) ma_atomic_fetch_xor_explicit_f64(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_and_f32(dst, src) ma_atomic_fetch_and_explicit_f32(dst, src, ma_atomic_memory_order_seq_cst)
#define ma_atomic_fetch_and_f64(dst, src) ma_atomic_fetch_and_explicit_f64(dst, src, ma_atomic_memory_order_seq_cst)
-static MA_INLINE float ma_atomic_compare_and_swap_f32(volatile float* dst, float expected, float desired)
+static MA_INLINE float ma_atomic_compare_and_swap_f32(volatile float* dst, float expected, float replacement)
{
ma_atomic_if32 r;
ma_atomic_if32 e, d;
e.f = expected;
- d.f = desired;
+ d.f = replacement;
r.i = ma_atomic_compare_and_swap_32((volatile ma_uint32*)dst, e.i, d.i);
return r.f;
}
-static MA_INLINE double ma_atomic_compare_and_swap_f64(volatile double* dst, double expected, double desired)
+static MA_INLINE double ma_atomic_compare_and_swap_f64(volatile double* dst, double expected, double replacement)
{
ma_atomic_if64 r;
ma_atomic_if64 e, d;
e.f = expected;
- d.f = desired;
+ d.f = replacement;
r.i = ma_atomic_compare_and_swap_64((volatile ma_uint64*)dst, e.i, d.i);
return r.f;
}
-typedef ma_atomic_flag ma_atomic_spinlock;
-static MA_INLINE void ma_atomic_spinlock_lock(volatile ma_atomic_spinlock* pSpinlock)
-{
- for (;;) {
- if (ma_atomic_flag_test_and_set_explicit(pSpinlock, ma_atomic_memory_order_acquire) == 0) {
- break;
- }
- while (ma_atomic_flag_load_explicit(pSpinlock, ma_atomic_memory_order_relaxed) == 1) {
- }
- }
-}
-static MA_INLINE void ma_atomic_spinlock_unlock(volatile ma_atomic_spinlock* pSpinlock)
-{
- ma_atomic_flag_clear_explicit(pSpinlock, ma_atomic_memory_order_release);
-}
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
#pragma GCC diagnostic pop
#endif
@@ -16176,7 +17542,7 @@ static ma_result ma_thread_create__posix(ma_thread* pThread, ma_thread_priority
int result;
pthread_attr_t* pAttr = NULL;
-#if !defined(__EMSCRIPTEN__) && !defined(__3DS__)
+#if !defined(MA_EMSCRIPTEN) && !defined(MA_3DS) && !defined(MA_SWITCH)
/* Try setting the thread priority. It's not critical if anything fails here. */
pthread_attr_t attr;
if (pthread_attr_init(&attr) == 0) {
@@ -16208,9 +17574,18 @@ static ma_result ma_thread_create__posix(ma_thread* pThread, ma_thread_priority
}
#endif
- if (stackSize > 0) {
- pthread_attr_setstacksize(&attr, stackSize);
+ #if defined(_POSIX_THREAD_ATTR_STACKSIZE) && _POSIX_THREAD_ATTR_STACKSIZE >= 0
+ {
+ if (stackSize > 0) {
+ pthread_attr_setstacksize(&attr, stackSize);
+ }
}
+ #else
+ {
+ (void)stackSize; /* Suppress unused parameter warning. */
+ }
+ #endif
+
if (scheduler != -1) {
int priorityMin = sched_get_priority_min(scheduler);
@@ -16267,6 +17642,21 @@ static ma_result ma_thread_create__posix(ma_thread* pThread, ma_thread_priority
}
if (result != 0) {
+ /*
+ There have been reports that attempting to create a realtime thread can sometimes fail. In this case,
+ fall back to a normal priority thread.
+
+ I'm including a compile-time option here to disable this functionality for those who have a hard
+ requirement on realtime threads and would rather an explicit failure.
+ */
+ #ifndef MA_NO_PTHREAD_REALTIME_PRIORITY_FALLBACK
+ {
+ if(result == EPERM && priority == ma_thread_priority_realtime) {
+ return ma_thread_create__posix(pThread, ma_thread_priority_normal, stackSize, entryProc, pData);
+ }
+ }
+ #endif
+
return ma_result_from_errno(result);
}
@@ -16538,7 +17928,7 @@ static ma_result ma_event_signal__win32(ma_event* pEvent)
static ma_result ma_semaphore_init__win32(int initialValue, ma_semaphore* pSemaphore)
{
- *pSemaphore = CreateSemaphoreW(NULL, (LONG)initialValue, LONG_MAX, NULL);
+ *pSemaphore = CreateSemaphore(NULL, (LONG)initialValue, LONG_MAX, NULL);
if (*pSemaphore == NULL) {
return ma_result_from_GetLastError(GetLastError());
}
@@ -17432,10 +18822,12 @@ static MA_INLINE ma_uint16 ma_job_extract_slot(ma_uint64 toc)
return (ma_uint16)(toc & 0x0000FFFF);
}
+#if 0 /* Currently unused, but might make use of this later. */
static MA_INLINE ma_uint16 ma_job_extract_code(ma_uint64 toc)
{
return (ma_uint16)((toc & 0xFFFF0000) >> 16);
}
+#endif
static MA_INLINE ma_uint64 ma_job_toc_to_allocation(ma_uint64 toc)
{
@@ -17900,6 +19292,13 @@ MA_API ma_result ma_job_queue_next(ma_job_queue* pQueue, ma_job* pJob)
Dynamic Linking
*******************************************************************************/
+/* Disable run-time linking on certain backends and platforms. */
+#ifndef MA_NO_RUNTIME_LINKING
+ #if defined(MA_EMSCRIPTEN) || defined(MA_ORBIS) || defined(MA_PROSPERO) || defined(MA_SWITCH) || defined(MA_DOS)
+ #define MA_NO_RUNTIME_LINKING
+ #endif
+#endif
+
#ifdef MA_POSIX
/* No need for dlfcn.h if we're not using runtime linking. */
#ifndef MA_NO_RUNTIME_LINKING
@@ -17909,104 +19308,124 @@ Dynamic Linking
MA_API ma_handle ma_dlopen(ma_log* pLog, const char* filename)
{
-#ifndef MA_NO_RUNTIME_LINKING
- ma_handle handle;
+ #ifndef MA_NO_RUNTIME_LINKING
+ {
+ ma_handle handle;
- ma_log_postf(pLog, MA_LOG_LEVEL_DEBUG, "Loading library: %s\n", filename);
+ ma_log_postf(pLog, MA_LOG_LEVEL_DEBUG, "Loading library: %s\n", filename);
- #ifdef MA_WIN32
- /* From MSDN: Desktop applications cannot use LoadPackagedLibrary; if a desktop application calls this function it fails with APPMODEL_ERROR_NO_PACKAGE.*/
- #if !defined(MA_WIN32_UWP) || !(defined(WINAPI_FAMILY) && ((defined(WINAPI_FAMILY_PHONE_APP) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)))
- handle = (ma_handle)LoadLibraryA(filename);
+ #ifdef MA_WIN32
+ /* From MSDN: Desktop applications cannot use LoadPackagedLibrary; if a desktop application calls this function it fails with APPMODEL_ERROR_NO_PACKAGE.*/
+ #if !defined(MA_WIN32_UWP) || !(defined(WINAPI_FAMILY) && ((defined(WINAPI_FAMILY_PHONE_APP) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)))
+ handle = (ma_handle)LoadLibraryA(filename);
+ #else
+ /* *sigh* It appears there is no ANSI version of LoadPackagedLibrary()... */
+ WCHAR filenameW[4096];
+ if (MultiByteToWideChar(CP_UTF8, 0, filename, -1, filenameW, sizeof(filenameW)) == 0) {
+ handle = NULL;
+ } else {
+ handle = (ma_handle)LoadPackagedLibrary(filenameW, 0);
+ }
+ #endif
#else
- /* *sigh* It appears there is no ANSI version of LoadPackagedLibrary()... */
- WCHAR filenameW[4096];
- if (MultiByteToWideChar(CP_UTF8, 0, filename, -1, filenameW, sizeof(filenameW)) == 0) {
- handle = NULL;
- } else {
- handle = (ma_handle)LoadPackagedLibrary(filenameW, 0);
- }
+ handle = (ma_handle)dlopen(filename, RTLD_NOW);
#endif
- #else
- handle = (ma_handle)dlopen(filename, RTLD_NOW);
- #endif
- /*
- I'm not considering failure to load a library an error nor a warning because seamlessly falling through to a lower-priority
- backend is a deliberate design choice. Instead I'm logging it as an informational message.
- */
- if (handle == NULL) {
- ma_log_postf(pLog, MA_LOG_LEVEL_INFO, "Failed to load library: %s\n", filename);
+ /*
+ I'm not considering failure to load a library an error nor a warning because seamlessly falling through to a lower-priority
+ backend is a deliberate design choice. Instead I'm logging it as an informational message.
+ */
+ if (handle == NULL) {
+ ma_log_postf(pLog, MA_LOG_LEVEL_INFO, "Failed to load library: %s\n", filename);
+ }
+
+ return handle;
}
-
- return handle;
-#else
- /* Runtime linking is disabled. */
- (void)pLog;
- (void)filename;
- return NULL;
-#endif
+ #else
+ {
+ /* Runtime linking is disabled. */
+ (void)pLog;
+ (void)filename;
+ return NULL;
+ }
+ #endif
}
MA_API void ma_dlclose(ma_log* pLog, ma_handle handle)
{
-#ifndef MA_NO_RUNTIME_LINKING
- #ifdef MA_WIN32
- FreeLibrary((HMODULE)handle);
- #else
- /* Hack for Android bug (see https://github.com/android/ndk/issues/360). Calling dlclose() pre-API 28 may segfault. */
- #if !defined(MA_ANDROID) || (defined(__ANDROID_API__) && __ANDROID_API__ >= 28)
+ #ifndef MA_NO_RUNTIME_LINKING
+ {
+ #ifdef MA_WIN32
{
- dlclose((void*)handle);
+ FreeLibrary((HMODULE)handle);
}
#else
{
- (void)handle;
+ /* Hack for Android bug (see https://github.com/android/ndk/issues/360). Calling dlclose() pre-API 28 may segfault. */
+ #if !defined(MA_ANDROID) || (defined(__ANDROID_API__) && __ANDROID_API__ >= 28)
+ {
+ dlclose((void*)handle);
+ }
+ #else
+ {
+ (void)handle;
+ }
+ #endif
}
#endif
- #endif
- (void)pLog;
-#else
- /* Runtime linking is disabled. */
- (void)pLog;
- (void)handle;
-#endif
+ (void)pLog;
+ }
+ #else
+ {
+ /* Runtime linking is disabled. */
+ (void)pLog;
+ (void)handle;
+ }
+ #endif
}
MA_API ma_proc ma_dlsym(ma_log* pLog, ma_handle handle, const char* symbol)
{
-#ifndef MA_NO_RUNTIME_LINKING
- ma_proc proc;
+ #ifndef MA_NO_RUNTIME_LINKING
+ {
+ ma_proc proc;
- ma_log_postf(pLog, MA_LOG_LEVEL_DEBUG, "Loading symbol: %s\n", symbol);
+ ma_log_postf(pLog, MA_LOG_LEVEL_DEBUG, "Loading symbol: %s\n", symbol);
-#ifdef _WIN32
- proc = (ma_proc)GetProcAddress((HMODULE)handle, symbol);
-#else
-#if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) || defined(__clang__)
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wpedantic"
-#endif
- proc = (ma_proc)dlsym((void*)handle, symbol);
-#if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) || defined(__clang__)
- #pragma GCC diagnostic pop
-#endif
-#endif
+ #ifdef _WIN32
+ {
+ proc = (ma_proc)GetProcAddress((HMODULE)handle, symbol);
+ }
+ #else
+ {
+ #if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) || defined(__clang__)
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wpedantic"
+ #endif
+ proc = (ma_proc)dlsym((void*)handle, symbol);
+ #if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) || defined(__clang__)
+ #pragma GCC diagnostic pop
+ #endif
+ }
+ #endif
- if (proc == NULL) {
- ma_log_postf(pLog, MA_LOG_LEVEL_WARNING, "Failed to load symbol: %s\n", symbol);
+ if (proc == NULL) {
+ ma_log_postf(pLog, MA_LOG_LEVEL_WARNING, "Failed to load symbol: %s\n", symbol);
+ }
+
+ (void)pLog; /* It's possible for pContext to be unused. */
+ return proc;
}
-
- (void)pLog; /* It's possible for pContext to be unused. */
- return proc;
-#else
- /* Runtime linking is disabled. */
- (void)pLog;
- (void)handle;
- (void)symbol;
- return NULL;
-#endif
+ #else
+ {
+ /* Runtime linking is disabled. */
+ (void)pLog;
+ (void)handle;
+ (void)symbol;
+ return NULL;
+ }
+ #endif
}
@@ -18020,13 +19439,6 @@ DEVICE I/O
*************************************************************************************************************************************************************
************************************************************************************************************************************************************/
-/* Disable run-time linking on certain backends and platforms. */
-#ifndef MA_NO_RUNTIME_LINKING
- #if defined(MA_EMSCRIPTEN) || defined(MA_ORBIS) || defined(MA_PROSPERO)
- #define MA_NO_RUNTIME_LINKING
- #endif
-#endif
-
#ifdef MA_APPLE
#include
#endif
@@ -18039,12 +19451,6 @@ DEVICE I/O
#ifdef MA_POSIX
#include
- #include
-
- /* No need for dlfcn.h if we're not using runtime linking. */
- #ifndef MA_NO_RUNTIME_LINKING
- #include
- #endif
#endif
/* This must be set to at least 26. */
@@ -18299,7 +19705,7 @@ MA_API ma_bool32 ma_is_loopback_supported(ma_backend backend)
-#if defined(MA_WIN32)
+#if defined(MA_WIN32) && !defined(MA_XBOX)
/* WASAPI error codes. */
#define MA_AUDCLNT_E_NOT_INITIALIZED ((HRESULT)0x88890001)
#define MA_AUDCLNT_E_ALREADY_INITIALIZED ((HRESULT)0x88890002)
@@ -18514,6 +19920,11 @@ typedef LONG (WINAPI * MA_PFN_RegCloseKey)(HKEY hKey);
typedef LONG (WINAPI * MA_PFN_RegQueryValueExA)(HKEY hKey, const char* lpValueName, DWORD* lpReserved, DWORD* lpType, BYTE* lpData, DWORD* lpcbData);
#endif /* MA_WIN32_DESKTOP */
+static GUID MA_GUID_KSDATAFORMAT_SUBTYPE_PCM = {0x00000001, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+static GUID MA_GUID_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = {0x00000003, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+/*static GUID MA_GUID_KSDATAFORMAT_SUBTYPE_ALAW = {0x00000006, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};*/
+/*static GUID MA_GUID_KSDATAFORMAT_SUBTYPE_MULAW = {0x00000007, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};*/
+
MA_API size_t ma_strlen_WCHAR(const WCHAR* str)
{
size_t len = 0;
@@ -18577,7 +19988,7 @@ Timing
*******************************************************************************/
#if defined(MA_WIN32) && !defined(MA_POSIX)
static LARGE_INTEGER g_ma_TimerFrequency; /* <-- Initialized to zero since it's static. */
- static void ma_timer_init(ma_timer* pTimer)
+ static MA_INLINE void ma_timer_init(ma_timer* pTimer)
{
LARGE_INTEGER counter;
@@ -18589,7 +20000,7 @@ Timing
pTimer->counter = counter.QuadPart;
}
- static double ma_timer_get_time_in_seconds(ma_timer* pTimer)
+ static MA_INLINE double ma_timer_get_time_in_seconds(ma_timer* pTimer)
{
LARGE_INTEGER counter;
if (!QueryPerformanceCounter(&counter)) {
@@ -18600,7 +20011,7 @@ Timing
}
#elif defined(MA_APPLE) && (MAC_OS_X_VERSION_MIN_REQUIRED < 101200)
static ma_uint64 g_ma_TimerFrequency = 0;
- static void ma_timer_init(ma_timer* pTimer)
+ static MA_INLINE void ma_timer_init(ma_timer* pTimer)
{
mach_timebase_info_data_t baseTime;
mach_timebase_info(&baseTime);
@@ -18609,7 +20020,7 @@ Timing
pTimer->counter = mach_absolute_time();
}
- static double ma_timer_get_time_in_seconds(ma_timer* pTimer)
+ static MA_INLINE double ma_timer_get_time_in_seconds(ma_timer* pTimer)
{
ma_uint64 newTimeCounter = mach_absolute_time();
ma_uint64 oldTimeCounter = pTimer->counter;
@@ -18634,7 +20045,7 @@ Timing
#define MA_CLOCK_ID CLOCK_REALTIME
#endif
- static void ma_timer_init(ma_timer* pTimer)
+ static MA_INLINE void ma_timer_init(ma_timer* pTimer)
{
struct timespec newTime;
clock_gettime(MA_CLOCK_ID, &newTime);
@@ -18642,7 +20053,7 @@ Timing
pTimer->counter = (newTime.tv_sec * 1000000000) + newTime.tv_nsec;
}
- static double ma_timer_get_time_in_seconds(ma_timer* pTimer)
+ static MA_INLINE double ma_timer_get_time_in_seconds(ma_timer* pTimer)
{
ma_uint64 newTimeCounter;
ma_uint64 oldTimeCounter;
@@ -18656,7 +20067,7 @@ Timing
return (newTimeCounter - oldTimeCounter) / 1000000000.0;
}
#else
- static void ma_timer_init(ma_timer* pTimer)
+ static MA_INLINE void ma_timer_init(ma_timer* pTimer)
{
struct timeval newTime;
gettimeofday(&newTime, NULL);
@@ -18664,7 +20075,7 @@ Timing
pTimer->counter = (newTime.tv_sec * 1000000) + newTime.tv_usec;
}
- static double ma_timer_get_time_in_seconds(ma_timer* pTimer)
+ static MA_INLINE double ma_timer_get_time_in_seconds(ma_timer* pTimer)
{
ma_uint64 newTimeCounter;
ma_uint64 oldTimeCounter;
@@ -19248,14 +20659,6 @@ static MA_INLINE void ma_device__set_state(ma_device* pDevice, ma_device_state n
}
-#if defined(MA_WIN32)
- static GUID MA_GUID_KSDATAFORMAT_SUBTYPE_PCM = {0x00000001, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
- static GUID MA_GUID_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = {0x00000003, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
- /*static GUID MA_GUID_KSDATAFORMAT_SUBTYPE_ALAW = {0x00000006, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};*/
- /*static GUID MA_GUID_KSDATAFORMAT_SUBTYPE_MULAW = {0x00000007, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};*/
-#endif
-
-
MA_API ma_uint32 ma_get_format_priority_index(ma_format format) /* Lower = better. */
{
@@ -19967,7 +21370,7 @@ static ma_result ma_context_init__null(ma_context* pContext, const ma_context_co
WIN32 COMMON
*******************************************************************************/
-#if defined(MA_WIN32)
+#if defined(MA_WIN32) && !defined(MA_XBOX)
#if defined(MA_WIN32_DESKTOP) || defined(MA_WIN32_GDK)
#define ma_CoInitializeEx(pContext, pvReserved, dwCoInit) ((pContext->win32.CoInitializeEx) ? ((MA_PFN_CoInitializeEx)pContext->win32.CoInitializeEx)(pvReserved, dwCoInit) : ((MA_PFN_CoInitialize)pContext->win32.CoInitialize)(pvReserved))
#define ma_CoUninitialize(pContext) ((MA_PFN_CoUninitialize)pContext->win32.CoUninitialize)()
@@ -19982,7 +21385,7 @@ WIN32 COMMON
#define ma_PropVariantClear(pContext, pvar) PropVariantClear(pvar)
#endif
-#if !defined(MAXULONG_PTR) && !defined(__WATCOMC__)
+#if !defined(MAXULONG_PTR) && !defined(__WATCOMC__) && !defined(MA_XBOX_NXDK)
typedef size_t DWORD_PTR;
#endif
@@ -20409,11 +21812,21 @@ typedef enum
MA_AudioCategory_Other = 0 /* <-- miniaudio is only caring about Other. */
} MA_AUDIO_STREAM_CATEGORY;
+typedef enum
+{
+ MA_AUDCLNT_STREAMOPTIONS_NONE,
+ MA_AUDCLNT_STREAMOPTIONS_RAW,
+ MA_AUDCLNT_STREAMOPTIONS_MATCH_FORMAT,
+ MA_AUDCLNT_STREAMOPTIONS_AMBISONICS,
+ MA_AUDCLNT_STREAMOPTIONS_POST_VOLUME_LOOPBACK
+} MA_AUDCLNT_STREAMOPTIONS;
+
typedef struct
{
ma_uint32 cbSize;
BOOL bIsOffload;
MA_AUDIO_STREAM_CATEGORY eCategory;
+ MA_AUDCLNT_STREAMOPTIONS Options;
} ma_AudioClientProperties;
/* IUnknown */
@@ -21588,6 +23001,7 @@ static ma_result ma_context_get_MMDevice__wasapi(ma_context* pContext, ma_device
{
ma_IMMDeviceEnumerator* pDeviceEnumerator;
HRESULT hr;
+ HRESULT CoInitializeResult;
MA_ASSERT(pContext != NULL);
MA_ASSERT(ppMMDevice != NULL);
@@ -21601,12 +23015,17 @@ static ma_result ma_context_get_MMDevice__wasapi(ma_context* pContext, ma_device
The community has reported that this seems to fix the crash. There are future plans to move all WASAPI operation
over to a single thread to make everything safer, but in the meantime while we wait for that to come online I'm
happy enough to use this hack instead.
+
+ CoUninitialize should only be called if we successfully initialized. S_OK and S_FALSE both mean that we need to
+ call CoUninitialize since the internal ref count was increased. RPC_E_CHANGED_MODE means that CoInitializeEx was
+ called with a different COINIT value, and we don't call CoUninitialize in that case. Other errors are possible,
+ so we check for S_OK and S_FALSE specifically.
*/
- ma_CoInitializeEx(pContext, NULL, MA_COINIT_VALUE);
+ CoInitializeResult = ma_CoInitializeEx(pContext, NULL, MA_COINIT_VALUE);
{
hr = ma_CoCreateInstance(pContext, &MA_CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, &MA_IID_IMMDeviceEnumerator, (void**)&pDeviceEnumerator);
- }
- ma_CoUninitialize(pContext);
+ }
+ if (CoInitializeResult == S_OK || CoInitializeResult == S_FALSE) { ma_CoUninitialize(pContext); }
if (FAILED(hr)) { /* <-- This is checking the call above to ma_CoCreateInstance(). */
ma_log_postf(ma_context_get_log(pContext), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to create IMMDeviceEnumerator.\n");
@@ -21950,7 +23369,7 @@ static ma_result ma_context_get_IAudioClient__wasapi(ma_context* pContext, ma_de
pActivationParams = &activationParams;
/* When requesting a specific device ID we need to use a special device ID. */
- MA_COPY_MEMORY(virtualDeviceID.wasapi, MA_VIRTUAL_AUDIO_DEVICE_PROCESS_LOOPBACK, (wcslen(MA_VIRTUAL_AUDIO_DEVICE_PROCESS_LOOPBACK) + 1) * sizeof(wchar_t)); /* +1 for the null terminator. */
+ MA_COPY_MEMORY(virtualDeviceID.wasapi, MA_VIRTUAL_AUDIO_DEVICE_PROCESS_LOOPBACK, (ma_wcslen(MA_VIRTUAL_AUDIO_DEVICE_PROCESS_LOOPBACK) + 1) * sizeof(wchar_t)); /* +1 for the null terminator. */
pDeviceID = &virtualDeviceID;
} else {
pActivationParams = NULL; /* No activation parameters required. */
@@ -26679,6 +28098,9 @@ typedef snd_pcm_channel_area_t ma_snd_pcm_channel_area_t;
typedef snd_pcm_chmap_t ma_snd_pcm_chmap_t;
typedef snd_pcm_state_t ma_snd_pcm_state_t;
+/* snd_pcm_state_t */
+#define MA_SND_PCM_STATE_XRUN SND_PCM_STATE_XRUN
+
/* snd_pcm_stream_t */
#define MA_SND_PCM_STREAM_PLAYBACK SND_PCM_STREAM_PLAYBACK
#define MA_SND_PCM_STREAM_CAPTURE SND_PCM_STREAM_CAPTURE
@@ -26874,6 +28296,7 @@ typedef int (* ma_snd_pcm_hw_params_set_channels_minmax_proc) (
typedef int (* ma_snd_pcm_hw_params_set_rate_resample_proc) (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, unsigned int val);
typedef int (* ma_snd_pcm_hw_params_set_rate_proc) (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, unsigned int val, int dir);
typedef int (* ma_snd_pcm_hw_params_set_rate_near_proc) (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
+typedef int (* ma_snd_pcm_hw_params_set_rate_minmax_proc) (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir);
typedef int (* ma_snd_pcm_hw_params_set_buffer_size_near_proc)(ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, ma_snd_pcm_uframes_t *val);
typedef int (* ma_snd_pcm_hw_params_set_periods_near_proc) (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
typedef int (* ma_snd_pcm_hw_params_set_access_proc) (ma_snd_pcm_t *pcm, ma_snd_pcm_hw_params_t *params, ma_snd_pcm_access_t _access);
@@ -28640,8 +30063,9 @@ static ma_result ma_context_init__alsa(ma_context* pContext, const ma_context_co
ma_snd_pcm_hw_params_get_format_mask_proc _snd_pcm_hw_params_get_format_mask = snd_pcm_hw_params_get_format_mask;
ma_snd_pcm_hw_params_set_channels_proc _snd_pcm_hw_params_set_channels = snd_pcm_hw_params_set_channels;
ma_snd_pcm_hw_params_set_channels_near_proc _snd_pcm_hw_params_set_channels_near = snd_pcm_hw_params_set_channels_near;
+ ma_snd_pcm_hw_params_set_channels_minmax_proc _snd_pcm_hw_params_set_channels_minmax = snd_pcm_hw_params_set_channels_minmax;
ma_snd_pcm_hw_params_set_rate_resample_proc _snd_pcm_hw_params_set_rate_resample = snd_pcm_hw_params_set_rate_resample;
- ma_snd_pcm_hw_params_set_rate_near _snd_pcm_hw_params_set_rate = snd_pcm_hw_params_set_rate;
+ ma_snd_pcm_hw_params_set_rate_proc _snd_pcm_hw_params_set_rate = snd_pcm_hw_params_set_rate;
ma_snd_pcm_hw_params_set_rate_near_proc _snd_pcm_hw_params_set_rate_near = snd_pcm_hw_params_set_rate_near;
ma_snd_pcm_hw_params_set_rate_minmax_proc _snd_pcm_hw_params_set_rate_minmax = snd_pcm_hw_params_set_rate_minmax;
ma_snd_pcm_hw_params_set_buffer_size_near_proc _snd_pcm_hw_params_set_buffer_size_near = snd_pcm_hw_params_set_buffer_size_near;
@@ -28693,9 +30117,9 @@ static ma_result ma_context_init__alsa(ma_context* pContext, const ma_context_co
ma_snd_pcm_info_proc _snd_pcm_info = snd_pcm_info;
ma_snd_pcm_info_sizeof_proc _snd_pcm_info_sizeof = snd_pcm_info_sizeof;
ma_snd_pcm_info_get_name_proc _snd_pcm_info_get_name = snd_pcm_info_get_name;
- ma_snd_pcm_poll_descriptors _snd_pcm_poll_descriptors = snd_pcm_poll_descriptors;
- ma_snd_pcm_poll_descriptors_count _snd_pcm_poll_descriptors_count = snd_pcm_poll_descriptors_count;
- ma_snd_pcm_poll_descriptors_revents _snd_pcm_poll_descriptors_revents = snd_pcm_poll_descriptors_revents;
+ ma_snd_pcm_poll_descriptors_proc _snd_pcm_poll_descriptors = snd_pcm_poll_descriptors;
+ ma_snd_pcm_poll_descriptors_count_proc _snd_pcm_poll_descriptors_count = snd_pcm_poll_descriptors_count;
+ ma_snd_pcm_poll_descriptors_revents_proc _snd_pcm_poll_descriptors_revents = snd_pcm_poll_descriptors_revents;
ma_snd_config_update_free_global_proc _snd_config_update_free_global = snd_config_update_free_global;
pContext->alsa.snd_pcm_open = (ma_proc)_snd_pcm_open;
@@ -28711,6 +30135,7 @@ static ma_result ma_context_init__alsa(ma_context* pContext, const ma_context_co
pContext->alsa.snd_pcm_hw_params_set_rate_resample = (ma_proc)_snd_pcm_hw_params_set_rate_resample;
pContext->alsa.snd_pcm_hw_params_set_rate = (ma_proc)_snd_pcm_hw_params_set_rate;
pContext->alsa.snd_pcm_hw_params_set_rate_near = (ma_proc)_snd_pcm_hw_params_set_rate_near;
+ pContext->alsa.snd_pcm_hw_params_set_rate_minmax = (ma_proc)_snd_pcm_hw_params_set_rate_minmax;
pContext->alsa.snd_pcm_hw_params_set_buffer_size_near = (ma_proc)_snd_pcm_hw_params_set_buffer_size_near;
pContext->alsa.snd_pcm_hw_params_set_periods_near = (ma_proc)_snd_pcm_hw_params_set_periods_near;
pContext->alsa.snd_pcm_hw_params_set_access = (ma_proc)_snd_pcm_hw_params_set_access;
@@ -29436,7 +30861,7 @@ typedef void (* ma_pa_threaded_mainloop_unlock_proc) (
typedef void (* ma_pa_threaded_mainloop_wait_proc) (ma_pa_threaded_mainloop* m);
typedef void (* ma_pa_threaded_mainloop_signal_proc) (ma_pa_threaded_mainloop* m, int wait_for_accept);
typedef void (* ma_pa_threaded_mainloop_accept_proc) (ma_pa_threaded_mainloop* m);
-typedef int (* ma_pa_threaded_mainloop_get_retval_proc) (ma_pa_threaded_mainloop* m);
+typedef int (* ma_pa_threaded_mainloop_get_retval_proc) (const ma_pa_threaded_mainloop* m);
typedef ma_pa_mainloop_api* (* ma_pa_threaded_mainloop_get_api_proc) (ma_pa_threaded_mainloop* m);
typedef int (* ma_pa_threaded_mainloop_in_thread_proc) (ma_pa_threaded_mainloop* m);
typedef void (* ma_pa_threaded_mainloop_set_name_proc) (ma_pa_threaded_mainloop* m, const char* name);
@@ -29445,13 +30870,13 @@ typedef void (* ma_pa_context_unref_proc) (
typedef int (* ma_pa_context_connect_proc) (ma_pa_context* c, const char* server, ma_pa_context_flags_t flags, const ma_pa_spawn_api* api);
typedef void (* ma_pa_context_disconnect_proc) (ma_pa_context* c);
typedef void (* ma_pa_context_set_state_callback_proc) (ma_pa_context* c, ma_pa_context_notify_cb_t cb, void* userdata);
-typedef ma_pa_context_state_t (* ma_pa_context_get_state_proc) (ma_pa_context* c);
+typedef ma_pa_context_state_t (* ma_pa_context_get_state_proc) (const ma_pa_context* c);
typedef ma_pa_operation* (* ma_pa_context_get_sink_info_list_proc) (ma_pa_context* c, ma_pa_sink_info_cb_t cb, void* userdata);
typedef ma_pa_operation* (* ma_pa_context_get_source_info_list_proc) (ma_pa_context* c, ma_pa_source_info_cb_t cb, void* userdata);
typedef ma_pa_operation* (* ma_pa_context_get_sink_info_by_name_proc) (ma_pa_context* c, const char* name, ma_pa_sink_info_cb_t cb, void* userdata);
typedef ma_pa_operation* (* ma_pa_context_get_source_info_by_name_proc)(ma_pa_context* c, const char* name, ma_pa_source_info_cb_t cb, void* userdata);
typedef void (* ma_pa_operation_unref_proc) (ma_pa_operation* o);
-typedef ma_pa_operation_state_t (* ma_pa_operation_get_state_proc) (ma_pa_operation* o);
+typedef ma_pa_operation_state_t (* ma_pa_operation_get_state_proc) (const ma_pa_operation* o);
typedef ma_pa_channel_map* (* ma_pa_channel_map_init_extend_proc) (ma_pa_channel_map* m, unsigned channels, ma_pa_channel_map_def_t def);
typedef int (* ma_pa_channel_map_valid_proc) (const ma_pa_channel_map* m);
typedef int (* ma_pa_channel_map_compatible_proc) (const ma_pa_channel_map* m, const ma_pa_sample_spec* ss);
@@ -29460,12 +30885,12 @@ typedef void (* ma_pa_stream_unref_proc) (
typedef int (* ma_pa_stream_connect_playback_proc) (ma_pa_stream* s, const char* dev, const ma_pa_buffer_attr* attr, ma_pa_stream_flags_t flags, const ma_pa_cvolume* volume, ma_pa_stream* sync_stream);
typedef int (* ma_pa_stream_connect_record_proc) (ma_pa_stream* s, const char* dev, const ma_pa_buffer_attr* attr, ma_pa_stream_flags_t flags);
typedef int (* ma_pa_stream_disconnect_proc) (ma_pa_stream* s);
-typedef ma_pa_stream_state_t (* ma_pa_stream_get_state_proc) (ma_pa_stream* s);
+typedef ma_pa_stream_state_t (* ma_pa_stream_get_state_proc) (const ma_pa_stream* s);
typedef const ma_pa_sample_spec* (* ma_pa_stream_get_sample_spec_proc) (ma_pa_stream* s);
typedef const ma_pa_channel_map* (* ma_pa_stream_get_channel_map_proc) (ma_pa_stream* s);
typedef const ma_pa_buffer_attr* (* ma_pa_stream_get_buffer_attr_proc) (ma_pa_stream* s);
typedef ma_pa_operation* (* ma_pa_stream_set_buffer_attr_proc) (ma_pa_stream* s, const ma_pa_buffer_attr* attr, ma_pa_stream_success_cb_t cb, void* userdata);
-typedef const char* (* ma_pa_stream_get_device_name_proc) (ma_pa_stream* s);
+typedef const char* (* ma_pa_stream_get_device_name_proc) (const ma_pa_stream* s);
typedef void (* ma_pa_stream_set_write_callback_proc) (ma_pa_stream* s, ma_pa_stream_request_cb_t cb, void* userdata);
typedef void (* ma_pa_stream_set_read_callback_proc) (ma_pa_stream* s, ma_pa_stream_request_cb_t cb, void* userdata);
typedef void (* ma_pa_stream_set_suspended_callback_proc) (ma_pa_stream* s, ma_pa_stream_notify_cb_t cb, void* userdata);
@@ -29473,15 +30898,15 @@ typedef void (* ma_pa_stream_set_moved_callback_proc) (
typedef int (* ma_pa_stream_is_suspended_proc) (const ma_pa_stream* s);
typedef ma_pa_operation* (* ma_pa_stream_flush_proc) (ma_pa_stream* s, ma_pa_stream_success_cb_t cb, void* userdata);
typedef ma_pa_operation* (* ma_pa_stream_drain_proc) (ma_pa_stream* s, ma_pa_stream_success_cb_t cb, void* userdata);
-typedef int (* ma_pa_stream_is_corked_proc) (ma_pa_stream* s);
+typedef int (* ma_pa_stream_is_corked_proc) (const ma_pa_stream* s);
typedef ma_pa_operation* (* ma_pa_stream_cork_proc) (ma_pa_stream* s, int b, ma_pa_stream_success_cb_t cb, void* userdata);
typedef ma_pa_operation* (* ma_pa_stream_trigger_proc) (ma_pa_stream* s, ma_pa_stream_success_cb_t cb, void* userdata);
typedef int (* ma_pa_stream_begin_write_proc) (ma_pa_stream* s, void** data, size_t* nbytes);
typedef int (* ma_pa_stream_write_proc) (ma_pa_stream* s, const void* data, size_t nbytes, ma_pa_free_cb_t free_cb, int64_t offset, ma_pa_seek_mode_t seek);
typedef int (* ma_pa_stream_peek_proc) (ma_pa_stream* s, const void** data, size_t* nbytes);
typedef int (* ma_pa_stream_drop_proc) (ma_pa_stream* s);
-typedef size_t (* ma_pa_stream_writable_size_proc) (ma_pa_stream* s);
-typedef size_t (* ma_pa_stream_readable_size_proc) (ma_pa_stream* s);
+typedef size_t (* ma_pa_stream_writable_size_proc) (const ma_pa_stream* s);
+typedef size_t (* ma_pa_stream_readable_size_proc) (const ma_pa_stream* s);
typedef struct
{
@@ -29777,7 +31202,7 @@ static ma_result ma_init_pa_mainloop_and_pa_context__pulse(ma_context* pContext,
}
/* Now we need to connect to the context. Everything is asynchronous so we need to wait for it to connect before returning. */
- result = ma_result_from_pulse(((ma_pa_context_connect_proc)pContext->pulse.pa_context_connect)((ma_pa_context*)pPulseContext, pServerName, (tryAutoSpawn) ? 0 : MA_PA_CONTEXT_NOAUTOSPAWN, NULL));
+ result = ma_result_from_pulse(((ma_pa_context_connect_proc)pContext->pulse.pa_context_connect)((ma_pa_context*)pPulseContext, pServerName, (tryAutoSpawn) ? MA_PA_CONTEXT_NOFLAGS : MA_PA_CONTEXT_NOAUTOSPAWN, NULL));
if (result != MA_SUCCESS) {
ma_log_postf(ma_context_get_log(pContext), MA_LOG_LEVEL_ERROR, "[PulseAudio] Failed to connect PulseAudio context.");
((ma_pa_mainloop_free_proc)pContext->pulse.pa_mainloop_free)((ma_pa_mainloop*)(pMainLoop));
@@ -30510,7 +31935,7 @@ static ma_result ma_device_init__pulse(ma_device* pDevice, const ma_device_confi
const ma_pa_buffer_attr* pActualAttr = NULL;
const ma_pa_channel_map* pActualChannelMap = NULL;
ma_uint32 iChannel;
- ma_pa_stream_flags_t streamFlags;
+ int streamFlags;
MA_ASSERT(pDevice != NULL);
MA_ZERO_OBJECT(&pDevice->pulse);
@@ -30568,8 +31993,13 @@ static ma_result ma_device_init__pulse(ma_device* pDevice, const ma_device_confi
ss.channels = pDescriptorCapture->channels;
}
+ /* PulseAudio has a maximum channel count of 32. We'll get a crash if this is exceeded. */
+ if (ss.channels > 32) {
+ ss.channels = 32;
+ }
+
/* Use a default channel map. */
- ((ma_pa_channel_map_init_extend_proc)pDevice->pContext->pulse.pa_channel_map_init_extend)(&cmap, ss.channels, pConfig->pulse.channelMap);
+ ((ma_pa_channel_map_init_extend_proc)pDevice->pContext->pulse.pa_channel_map_init_extend)(&cmap, ss.channels, (ma_pa_channel_map_def_t)pConfig->pulse.channelMap);
/* Use the requested sample rate if one was specified. */
if (pDescriptorCapture->sampleRate != 0) {
@@ -30626,7 +32056,7 @@ static ma_result ma_device_init__pulse(ma_device* pDevice, const ma_device_confi
streamFlags |= MA_PA_STREAM_DONT_MOVE;
}
- error = ((ma_pa_stream_connect_record_proc)pDevice->pContext->pulse.pa_stream_connect_record)((ma_pa_stream*)pDevice->pulse.pStreamCapture, devCapture, &attr, streamFlags);
+ error = ((ma_pa_stream_connect_record_proc)pDevice->pContext->pulse.pa_stream_connect_record)((ma_pa_stream*)pDevice->pulse.pStreamCapture, devCapture, &attr, (ma_pa_stream_flags_t)streamFlags);
if (error != MA_PA_OK) {
ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[PulseAudio] Failed to connect PulseAudio capture stream.");
result = ma_result_from_pulse(error);
@@ -30720,8 +32150,13 @@ static ma_result ma_device_init__pulse(ma_device* pDevice, const ma_device_confi
ss.channels = pDescriptorPlayback->channels;
}
+ /* PulseAudio has a maximum channel count of 32. We'll get a crash if this is exceeded. */
+ if (ss.channels > 32) {
+ ss.channels = 32;
+ }
+
/* Use a default channel map. */
- ((ma_pa_channel_map_init_extend_proc)pDevice->pContext->pulse.pa_channel_map_init_extend)(&cmap, ss.channels, pConfig->pulse.channelMap);
+ ((ma_pa_channel_map_init_extend_proc)pDevice->pContext->pulse.pa_channel_map_init_extend)(&cmap, ss.channels, (ma_pa_channel_map_def_t)pConfig->pulse.channelMap);
/* Use the requested sample rate if one was specified. */
@@ -30783,7 +32218,7 @@ static ma_result ma_device_init__pulse(ma_device* pDevice, const ma_device_confi
streamFlags |= MA_PA_STREAM_DONT_MOVE;
}
- error = ((ma_pa_stream_connect_playback_proc)pDevice->pContext->pulse.pa_stream_connect_playback)((ma_pa_stream*)pDevice->pulse.pStreamPlayback, devPlayback, &attr, streamFlags, NULL, NULL);
+ error = ((ma_pa_stream_connect_playback_proc)pDevice->pContext->pulse.pa_stream_connect_playback)((ma_pa_stream*)pDevice->pulse.pStreamPlayback, devPlayback, &attr, (ma_pa_stream_flags_t)streamFlags, NULL, NULL);
if (error != MA_PA_OK) {
ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[PulseAudio] Failed to connect PulseAudio playback stream.");
result = ma_result_from_pulse(error);
@@ -31338,6 +32773,7 @@ typedef JackProcessCallback ma_JackProcessCallback;
typedef JackBufferSizeCallback ma_JackBufferSizeCallback;
typedef JackShutdownCallback ma_JackShutdownCallback;
#define MA_JACK_DEFAULT_AUDIO_TYPE JACK_DEFAULT_AUDIO_TYPE
+#define ma_JackNullOption JackNullOption
#define ma_JackNoStartServer JackNoStartServer
#define ma_JackPortIsInput JackPortIsInput
#define ma_JackPortIsOutput JackPortIsOutput
@@ -31352,6 +32788,7 @@ typedef int (* ma_JackProcessCallback) (ma_jack_nframes_t nframes, void* arg)
typedef int (* ma_JackBufferSizeCallback)(ma_jack_nframes_t nframes, void* arg);
typedef void (* ma_JackShutdownCallback) (void* arg);
#define MA_JACK_DEFAULT_AUDIO_TYPE "32 bit float mono audio"
+#define ma_JackNullOption 0
#define ma_JackNoStartServer 1
#define ma_JackPortIsInput 1
#define ma_JackPortIsOutput 2
@@ -31392,7 +32829,7 @@ static ma_result ma_context_open_client__jack(ma_context* pContext, ma_jack_clie
maxClientNameSize = ((ma_jack_client_name_size_proc)pContext->jack.jack_client_name_size)(); /* Includes null terminator. */
ma_strncpy_s(clientName, ma_min(sizeof(clientName), maxClientNameSize), (pContext->jack.pClientName != NULL) ? pContext->jack.pClientName : "miniaudio", (size_t)-1);
- pClient = ((ma_jack_client_open_proc)pContext->jack.jack_client_open)(clientName, (pContext->jack.tryStartServer) ? 0 : ma_JackNoStartServer, &status, NULL);
+ pClient = ((ma_jack_client_open_proc)pContext->jack.jack_client_open)(clientName, (pContext->jack.tryStartServer) ? ma_JackNullOption : ma_JackNoStartServer, &status, NULL);
if (pClient == NULL) {
return MA_FAILED_TO_OPEN_BACKEND_DEVICE;
}
@@ -36994,7 +38431,7 @@ OSS Backend
#define MA_OSS_DEFAULT_DEVICE_NAME "/dev/dsp"
-static int ma_open_temp_device__oss()
+static int ma_open_temp_device__oss(void)
{
/* The OSS sample code uses "/dev/mixer" as the device for getting system properties so I'm going to do the same. */
int fd = open("/dev/mixer", O_RDONLY, 0);
@@ -37834,25 +39271,30 @@ static void ma_stream_error_callback__aaudio(ma_AAudioStream* pStream, void* pUs
(void)error;
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_INFO, "[AAudio] ERROR CALLBACK: error=%d, AAudioStream_getState()=%d\n", error, ((MA_PFN_AAudioStream_getState)pDevice->pContext->aaudio.AAudioStream_getState)(pStream));
+
/*
When we get an error, we'll assume that the stream is in an erroneous state and needs to be restarted. From the documentation,
we cannot do this from the error callback. Therefore we are going to use an event thread for the AAudio backend to do this
cleanly and safely.
*/
- job = ma_job_init(MA_JOB_TYPE_DEVICE_AAUDIO_REROUTE);
- job.data.device.aaudio.reroute.pDevice = pDevice;
-
- if (pStream == pDevice->aaudio.pStreamCapture) {
- job.data.device.aaudio.reroute.deviceType = ma_device_type_capture;
+ if (ma_atomic_bool32_get(&pDevice->aaudio.isTearingDown)) {
+ ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_INFO, "[AAudio] Device Disconnected. Tearing down device.\n");
}
else {
- job.data.device.aaudio.reroute.deviceType = ma_device_type_playback;
- }
-
- result = ma_device_job_thread_post(&pDevice->pContext->aaudio.jobThread, &job);
- if (result != MA_SUCCESS) {
- ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_INFO, "[AAudio] Device Disconnected. Failed to post job for rerouting.\n");
- return;
+ job = ma_job_init(MA_JOB_TYPE_DEVICE_AAUDIO_REROUTE);
+ job.data.device.aaudio.reroute.pDevice = pDevice;
+
+ if (pStream == pDevice->aaudio.pStreamCapture) {
+ job.data.device.aaudio.reroute.deviceType = ma_device_type_capture;
+ } else {
+ job.data.device.aaudio.reroute.deviceType = ma_device_type_playback;
+ }
+
+ result = ma_device_job_thread_post(&pDevice->pContext->aaudio.jobThread, &job);
+ if (result != MA_SUCCESS) {
+ ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_INFO, "[AAudio] Device Disconnected. Failed to post job for rerouting.\n");
+ return;
+ }
}
}
@@ -38169,7 +39611,7 @@ static ma_result ma_close_streams__aaudio(ma_device* pDevice)
{
MA_ASSERT(pDevice != NULL);
- /* When re-routing, streams may have been closed and never re-opened. Hence the extra checks below. */
+ /* When rerouting, streams may have been closed and never re-opened. Hence the extra checks below. */
if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) {
ma_close_stream__aaudio(pDevice->pContext, (ma_AAudioStream*)pDevice->aaudio.pStreamCapture);
pDevice->aaudio.pStreamCapture = NULL;
@@ -38186,6 +39628,12 @@ static ma_result ma_device_uninit__aaudio(ma_device* pDevice)
{
MA_ASSERT(pDevice != NULL);
+ /*
+ Note: Closing the streams may cause a timeout error, which would then trigger rerouting in our error callback.
+ We must not schedule a reroute when device is getting destroyed.
+ */
+ ma_atomic_bool32_set(&pDevice->aaudio.isTearingDown, MA_TRUE);
+
/* Wait for any rerouting to finish before attempting to close the streams. */
ma_mutex_lock(&pDevice->aaudio.rerouteLock);
{
@@ -38193,7 +39641,7 @@ static ma_result ma_device_uninit__aaudio(ma_device* pDevice)
}
ma_mutex_unlock(&pDevice->aaudio.rerouteLock);
- /* Destroy re-routing lock. */
+ /* Destroy rerouting lock. */
ma_mutex_uninit(&pDevice->aaudio.rerouteLock);
return MA_SUCCESS;
@@ -38429,17 +39877,22 @@ static ma_result ma_device_stop__aaudio(ma_device* pDevice)
static ma_result ma_device_reinit__aaudio(ma_device* pDevice, ma_device_type deviceType)
{
+ const ma_int32 maxAttempts = 4; /* Reasonable retry limit. */
+
ma_result result;
- int32_t retries = 0;
+ ma_int32 iAttempt;
MA_ASSERT(pDevice != NULL);
- /*
- TODO: Stop retrying if main thread is about to uninit device.
- */
- ma_mutex_lock(&pDevice->aaudio.rerouteLock);
- {
-error_disconnected:
+ /* We got disconnected! Retry a few times, until we find a connected device! */
+ iAttempt = 0;
+ while (iAttempt++ < maxAttempts) {
+ /* Device tearing down? No need to reroute! */
+ if (ma_atomic_bool32_get(&pDevice->aaudio.isTearingDown)) {
+ result = MA_SUCCESS; /* Caller should continue as normal. */
+ break;
+ }
+
/* The first thing to do is close the streams. */
ma_close_streams__aaudio(pDevice);
@@ -38495,14 +39948,16 @@ error_disconnected:
result = ma_device_init_streams__aaudio(pDevice, &deviceConfig, &descriptorPlayback, &descriptorCapture);
if (result != MA_SUCCESS) {
ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_WARNING, "[AAudio] Failed to create stream after route change.");
- goto done;
+ /* Reroute failed! */
+ break;
}
result = ma_device_post_init(pDevice, deviceType, &descriptorPlayback, &descriptorCapture);
if (result != MA_SUCCESS) {
ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_WARNING, "[AAudio] Failed to initialize device after route change.");
ma_close_streams__aaudio(pDevice);
- goto done;
+ /* Reroute failed! */
+ break;
}
/* We'll only ever do this in response to a reroute. */
@@ -38513,26 +39968,23 @@ error_disconnected:
if (pDevice->aaudio.noAutoStartAfterReroute == MA_FALSE) {
result = ma_device_start__aaudio(pDevice);
if (result != MA_SUCCESS) {
- /* We got disconnected! Retry a few times, until we find a connected device! */
- retries += 1;
- if (retries <= 3) {
- ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_INFO, "[AAudio] Failed to start stream after route change, retrying(%d)", retries);
- goto error_disconnected;
+ if (iAttempt < maxAttempts) {
+ ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_INFO, "[AAudio] Failed to start stream after route change, retrying(%d)", iAttempt);
+ } else {
+ ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_INFO, "[AAudio] Failed to start stream after route change, giving up.");
}
- ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_INFO, "[AAudio] Failed to start stream after route change.");
- goto done;
}
} else {
- ma_device_stop(pDevice); /* Do a full device stop so we set internal state correctly. */
+ ma_device_stop(pDevice); /* Do a full device stop so we set internal state correctly. */
}
}
-
- result = MA_SUCCESS;
- }
-done:
- /* Re-routing done */
- ma_mutex_unlock(&pDevice->aaudio.rerouteLock);
+ if (result == MA_SUCCESS) {
+ /* Reroute successful! */
+ break;
+ }
+ }
+
return result;
}
@@ -38698,7 +40150,7 @@ static ma_result ma_context_init__aaudio(ma_context* pContext, const ma_context_
static ma_result ma_job_process__device__aaudio_reroute(ma_job* pJob)
{
- ma_result result;
+ ma_result result = MA_SUCCESS;
ma_device* pDevice;
MA_ASSERT(pJob != NULL);
@@ -38706,19 +40158,22 @@ static ma_result ma_job_process__device__aaudio_reroute(ma_job* pJob)
pDevice = (ma_device*)pJob->data.device.aaudio.reroute.pDevice;
MA_ASSERT(pDevice != NULL);
- /* Here is where we need to reroute the device. To do this we need to uninitialize the stream and reinitialize it. */
- result = ma_device_reinit__aaudio(pDevice, (ma_device_type)pJob->data.device.aaudio.reroute.deviceType);
- if (result != MA_SUCCESS) {
- /*
- Getting here means we failed to reroute the device. The best thing I can think of here is to
- just stop the device.
- */
- ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[AAudio] Stopping device due to reroute failure.");
- ma_device_stop(pDevice);
- return result;
+ ma_mutex_lock(&pDevice->aaudio.rerouteLock);
+ {
+ /* Here is where we need to reroute the device. To do this we need to uninitialize the stream and reinitialize it. */
+ result = ma_device_reinit__aaudio(pDevice, (ma_device_type)pJob->data.device.aaudio.reroute.deviceType);
+ if (result != MA_SUCCESS) {
+ /*
+ Getting here means we failed to reroute the device. The best thing I can think of here is to
+ just stop the device.
+ */
+ ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[AAudio] Stopping device due to reroute failure.");
+ ma_device_stop(pDevice);
+ }
}
+ ma_mutex_unlock(&pDevice->aaudio.rerouteLock);
- return MA_SUCCESS;
+ return result;
}
#else
/* Getting here means there is no AAudio backend so we need a no-op job implementation. */
@@ -41236,13 +42691,13 @@ MA_API ma_result ma_device_post_init(ma_device* pDevice, ma_device_type deviceTy
static ma_thread_result MA_THREADCALL ma_worker_thread(void* pData)
{
ma_device* pDevice = (ma_device*)pData;
-#ifdef MA_WIN32
+#if defined(MA_WIN32) && !defined(MA_XBOX)
HRESULT CoInitializeResult;
#endif
MA_ASSERT(pDevice != NULL);
-#ifdef MA_WIN32
+#if defined(MA_WIN32) && !defined(MA_XBOX)
CoInitializeResult = ma_CoInitializeEx(pDevice->pContext, NULL, MA_COINIT_VALUE);
#endif
@@ -41333,8 +42788,8 @@ static ma_thread_result MA_THREADCALL ma_worker_thread(void* pData)
ma_event_signal(&pDevice->stopEvent);
}
-#ifdef MA_WIN32
- if (CoInitializeResult == S_OK) {
+#if defined(MA_WIN32) && !defined(MA_XBOX)
+ if (CoInitializeResult == S_OK || CoInitializeResult == S_FALSE) {
ma_CoUninitialize(pDevice->pContext);
}
#endif
@@ -41358,67 +42813,92 @@ static ma_bool32 ma_device__is_initialized(ma_device* pDevice)
static ma_result ma_context_uninit_backend_apis__win32(ma_context* pContext)
{
/* For some reason UWP complains when CoUninitialize() is called. I'm just not going to call it on UWP. */
-#if defined(MA_WIN32_DESKTOP) || defined(MA_WIN32_GDK)
- if (pContext->win32.CoInitializeResult == S_OK) {
- ma_CoUninitialize(pContext);
+ #if defined(MA_WIN32_DESKTOP) || defined(MA_WIN32_GDK)
+ {
+ /* TODO: Remove this once the new single threaded backend system is in place in 0.12. */
+ #if !defined(MA_XBOX)
+ {
+ if (pContext->win32.CoInitializeResult == S_OK || pContext->win32.CoInitializeResult == S_FALSE) {
+ ma_CoUninitialize(pContext); /* TODO: Remove this once the new single threaded backend system is in place in 0.12. */
+ }
+ }
+ #endif
+
+ #if defined(MA_WIN32_DESKTOP)
+ ma_dlclose(ma_context_get_log(pContext), pContext->win32.hUser32DLL);
+ ma_dlclose(ma_context_get_log(pContext), pContext->win32.hAdvapi32DLL);
+ #endif
+
+ ma_dlclose(ma_context_get_log(pContext), pContext->win32.hOle32DLL);
+ }
+ #else
+ {
+ (void)pContext;
}
-
- #if defined(MA_WIN32_DESKTOP)
- ma_dlclose(ma_context_get_log(pContext), pContext->win32.hUser32DLL);
- ma_dlclose(ma_context_get_log(pContext), pContext->win32.hAdvapi32DLL);
#endif
- ma_dlclose(ma_context_get_log(pContext), pContext->win32.hOle32DLL);
-#else
- (void)pContext;
-#endif
-
return MA_SUCCESS;
}
static ma_result ma_context_init_backend_apis__win32(ma_context* pContext)
{
-#if defined(MA_WIN32_DESKTOP) || defined(MA_WIN32_GDK)
- #if defined(MA_WIN32_DESKTOP)
- /* User32.dll */
- pContext->win32.hUser32DLL = ma_dlopen(ma_context_get_log(pContext), "user32.dll");
- if (pContext->win32.hUser32DLL == NULL) {
+ /*
+ TODO: Reassess all of this stuff and move everything to the relevant backends. For example, I think
+ GetForegroundWindow() and GetDesktopWindow() are only used by the DirectSound backend.
+ */
+ #if (defined(MA_WIN32_DESKTOP) || defined(MA_WIN32_GDK)) && !defined(MA_XBOX)
+ {
+ #if defined(MA_WIN32_DESKTOP)
+ {
+ /* User32.dll */
+ pContext->win32.hUser32DLL = ma_dlopen(ma_context_get_log(pContext), "user32.dll");
+ if (pContext->win32.hUser32DLL == NULL) {
+ return MA_FAILED_TO_INIT_BACKEND;
+ }
+
+ pContext->win32.GetForegroundWindow = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hUser32DLL, "GetForegroundWindow");
+ pContext->win32.GetDesktopWindow = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hUser32DLL, "GetDesktopWindow");
+
+
+ /* Advapi32.dll */
+ pContext->win32.hAdvapi32DLL = ma_dlopen(ma_context_get_log(pContext), "advapi32.dll");
+ if (pContext->win32.hAdvapi32DLL == NULL) {
+ return MA_FAILED_TO_INIT_BACKEND;
+ }
+
+ pContext->win32.RegOpenKeyExA = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hAdvapi32DLL, "RegOpenKeyExA");
+ pContext->win32.RegCloseKey = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hAdvapi32DLL, "RegCloseKey");
+ pContext->win32.RegQueryValueExA = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hAdvapi32DLL, "RegQueryValueExA");
+ }
+ #endif
+
+ /* Ole32.dll */
+ pContext->win32.hOle32DLL = ma_dlopen(ma_context_get_log(pContext), "ole32.dll");
+ if (pContext->win32.hOle32DLL == NULL) {
return MA_FAILED_TO_INIT_BACKEND;
}
- pContext->win32.GetForegroundWindow = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hUser32DLL, "GetForegroundWindow");
- pContext->win32.GetDesktopWindow = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hUser32DLL, "GetDesktopWindow");
-
-
- /* Advapi32.dll */
- pContext->win32.hAdvapi32DLL = ma_dlopen(ma_context_get_log(pContext), "advapi32.dll");
- if (pContext->win32.hAdvapi32DLL == NULL) {
- return MA_FAILED_TO_INIT_BACKEND;
- }
-
- pContext->win32.RegOpenKeyExA = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hAdvapi32DLL, "RegOpenKeyExA");
- pContext->win32.RegCloseKey = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hAdvapi32DLL, "RegCloseKey");
- pContext->win32.RegQueryValueExA = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hAdvapi32DLL, "RegQueryValueExA");
+ pContext->win32.CoInitialize = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hOle32DLL, "CoInitialize");
+ pContext->win32.CoInitializeEx = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hOle32DLL, "CoInitializeEx");
+ pContext->win32.CoUninitialize = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hOle32DLL, "CoUninitialize");
+ pContext->win32.CoCreateInstance = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hOle32DLL, "CoCreateInstance");
+ pContext->win32.CoTaskMemFree = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hOle32DLL, "CoTaskMemFree");
+ pContext->win32.PropVariantClear = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hOle32DLL, "PropVariantClear");
+ pContext->win32.StringFromGUID2 = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hOle32DLL, "StringFromGUID2");
+ }
+ #else
+ {
+ (void)pContext; /* Unused. */
+ }
#endif
- /* Ole32.dll */
- pContext->win32.hOle32DLL = ma_dlopen(ma_context_get_log(pContext), "ole32.dll");
- if (pContext->win32.hOle32DLL == NULL) {
- return MA_FAILED_TO_INIT_BACKEND;
+ /* TODO: Remove this once the new single threaded backend system is in place in 0.12. */
+ #if !defined(MA_XBOX)
+ {
+ pContext->win32.CoInitializeResult = ma_CoInitializeEx(pContext, NULL, MA_COINIT_VALUE);
}
+ #endif
- pContext->win32.CoInitialize = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hOle32DLL, "CoInitialize");
- pContext->win32.CoInitializeEx = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hOle32DLL, "CoInitializeEx");
- pContext->win32.CoUninitialize = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hOle32DLL, "CoUninitialize");
- pContext->win32.CoCreateInstance = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hOle32DLL, "CoCreateInstance");
- pContext->win32.CoTaskMemFree = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hOle32DLL, "CoTaskMemFree");
- pContext->win32.PropVariantClear = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hOle32DLL, "PropVariantClear");
- pContext->win32.StringFromGUID2 = (ma_proc)ma_dlsym(ma_context_get_log(pContext), pContext->win32.hOle32DLL, "StringFromGUID2");
-#else
- (void)pContext; /* Unused. */
-#endif
-
- pContext->win32.CoInitializeResult = ma_CoInitializeEx(pContext, NULL, MA_COINIT_VALUE);
return MA_SUCCESS;
}
#else
@@ -44016,7 +45496,7 @@ static MA_INLINE void ma_pcm_s16_to_s32__reference(void* dst, const void* src, m
ma_uint64 i;
for (i = 0; i < count; i += 1) {
- dst_s32[i] = src_s16[i] << 16;
+ dst_s32[i] = (ma_int32)src_s16[i] << 16;
}
(void)ditherMode;
@@ -56408,8 +57888,12 @@ MA_API size_t ma_channel_map_to_string(const ma_channel* pChannelMap, ma_uint32
}
/* Null terminate. Don't increment the length here. */
- if (pBufferOut != NULL && bufferCap > len + 1) {
- pBufferOut[len] = '\0';
+ if (pBufferOut != NULL) {
+ if (bufferCap > len) {
+ pBufferOut[len] = '\0';
+ } else if (bufferCap > 0) {
+ pBufferOut[bufferCap - 1] = '\0';
+ }
}
return len;
@@ -56620,7 +58104,7 @@ MA_API ma_result ma_rb_init_ex(size_t subbufferSizeInBytes, size_t subbufferCoun
Here is where we allocate our own buffer. We always want to align this to MA_SIMD_ALIGNMENT for future SIMD optimization opportunity. To do this
we need to make sure the stride is a multiple of MA_SIMD_ALIGNMENT.
*/
- pRB->subbufferStrideInBytes = (pRB->subbufferSizeInBytes + (MA_SIMD_ALIGNMENT-1)) & ~MA_SIMD_ALIGNMENT;
+ pRB->subbufferStrideInBytes = ma_align(pRB->subbufferSizeInBytes, MA_SIMD_ALIGNMENT);
bufferSizeInBytes = (size_t)pRB->subbufferCount*pRB->subbufferStrideInBytes;
pRB->pBuffer = ma_aligned_malloc(bufferSizeInBytes, MA_SIMD_ALIGNMENT, &pRB->allocationCallbacks);
@@ -59515,7 +60999,7 @@ MA_API ma_result ma_vfs_info(ma_vfs* pVFS, ma_vfs_file file, ma_file_info* pInfo
}
-#if !defined(MA_USE_WIN32_FILEIO) && (defined(MA_WIN32) && defined(MA_WIN32_DESKTOP) && !defined(MA_NO_WIN32_FILEIO) && !defined(MA_POSIX))
+#if !defined(MA_USE_WIN32_FILEIO) && (defined(MA_WIN32) && (defined(MA_WIN32_DESKTOP) || defined(MA_WIN32_NXDK)) && !defined(MA_NO_WIN32_FILEIO) && !defined(MA_POSIX))
#define MA_USE_WIN32_FILEIO
#endif
@@ -59592,25 +61076,34 @@ static ma_result ma_default_vfs_open__win32(ma_vfs* pVFS, const char* pFilePath,
static ma_result ma_default_vfs_open_w__win32(ma_vfs* pVFS, const wchar_t* pFilePath, ma_uint32 openMode, ma_vfs_file* pFile)
{
- HANDLE hFile;
- DWORD dwDesiredAccess;
- DWORD dwShareMode;
- DWORD dwCreationDisposition;
+ #if !defined(MA_XBOX_NXDK)
+ {
+ HANDLE hFile;
+ DWORD dwDesiredAccess;
+ DWORD dwShareMode;
+ DWORD dwCreationDisposition;
- (void)pVFS;
+ (void)pVFS;
- /* Load some Win32 symbols dynamically so we can dynamically check for the existence of SetFilePointerEx. */
- ma_win32_fileio_init();
+ /* Load some Win32 symbols dynamically so we can dynamically check for the existence of SetFilePointerEx. */
+ ma_win32_fileio_init();
- ma_default_vfs__get_open_settings_win32(openMode, &dwDesiredAccess, &dwShareMode, &dwCreationDisposition);
+ ma_default_vfs__get_open_settings_win32(openMode, &dwDesiredAccess, &dwShareMode, &dwCreationDisposition);
- hFile = CreateFileW(pFilePath, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, FILE_ATTRIBUTE_NORMAL, NULL);
- if (hFile == INVALID_HANDLE_VALUE) {
- return ma_result_from_GetLastError(GetLastError());
+ hFile = CreateFileW(pFilePath, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hFile == INVALID_HANDLE_VALUE) {
+ return ma_result_from_GetLastError(GetLastError());
+ }
+
+ *pFile = hFile;
+ return MA_SUCCESS;
}
-
- *pFile = hFile;
- return MA_SUCCESS;
+ #else
+ {
+ /* No CreateFileW() available. */
+ return MA_NOT_IMPLEMENTED;
+ }
+ #endif
}
static ma_result ma_default_vfs_close__win32(ma_vfs* pVFS, ma_vfs_file file)
@@ -59781,19 +61274,28 @@ static ma_result ma_default_vfs_tell__win32(ma_vfs* pVFS, ma_vfs_file file, ma_i
static ma_result ma_default_vfs_info__win32(ma_vfs* pVFS, ma_vfs_file file, ma_file_info* pInfo)
{
- BY_HANDLE_FILE_INFORMATION fi;
- BOOL result;
-
(void)pVFS;
- result = GetFileInformationByHandle((HANDLE)file, &fi);
- if (result == 0) {
- return ma_result_from_GetLastError(GetLastError());
+ #if !defined(MA_XBOX_NXDK)
+ {
+ BY_HANDLE_FILE_INFORMATION fi;
+ BOOL result;
+
+ result = GetFileInformationByHandle((HANDLE)file, &fi);
+ if (result == 0) {
+ return ma_result_from_GetLastError(GetLastError());
+ }
+
+ pInfo->sizeInBytes = ((ma_uint64)fi.nFileSizeHigh << 32) | ((ma_uint64)fi.nFileSizeLow);
+
+ return MA_SUCCESS;
}
-
- pInfo->sizeInBytes = ((ma_uint64)fi.nFileSizeHigh << 32) | ((ma_uint64)fi.nFileSizeLow);
-
- return MA_SUCCESS;
+ #else
+ {
+ /* GetFileInformationByHandle() is unavailable. */
+ return MA_NOT_IMPLEMENTED;
+ }
+ #endif
}
#else
static ma_result ma_default_vfs_open__stdio(ma_vfs* pVFS, const char* pFilePath, ma_uint32 openMode, ma_vfs_file* pFile)
@@ -60131,6 +61633,8 @@ static ma_result ma_default_vfs_tell(ma_vfs* pVFS, ma_vfs_file file, ma_int64* p
static ma_result ma_default_vfs_info(ma_vfs* pVFS, ma_vfs_file file, ma_file_info* pInfo)
{
+ ma_result result;
+
if (pInfo == NULL) {
return MA_INVALID_ARGS;
}
@@ -60142,10 +61646,43 @@ static ma_result ma_default_vfs_info(ma_vfs* pVFS, ma_vfs_file file, ma_file_inf
}
#if defined(MA_USE_WIN32_FILEIO)
- return ma_default_vfs_info__win32(pVFS, file, pInfo);
+ result = ma_default_vfs_info__win32(pVFS, file, pInfo);
#else
- return ma_default_vfs_info__stdio(pVFS, file, pInfo);
+ result = ma_default_vfs_info__stdio(pVFS, file, pInfo);
#endif
+
+ if (result == MA_NOT_IMPLEMENTED) {
+ /* Not implemented. Fall back to seek/tell/seek. */
+ ma_result result;
+ ma_int64 cursor;
+ ma_int64 sizeInBytes;
+
+ result = ma_default_vfs_tell(pVFS, file, &cursor);
+ if (result != MA_SUCCESS) {
+ return result;
+ }
+
+ result = ma_default_vfs_seek(pVFS, file, 0, ma_seek_origin_end);
+ if (result != MA_SUCCESS) {
+ return result;
+ }
+
+ result = ma_default_vfs_tell(pVFS, file, &sizeInBytes);
+ if (result != MA_SUCCESS) {
+ return result;
+ }
+
+ pInfo->sizeInBytes = sizeInBytes;
+
+ result = ma_default_vfs_seek(pVFS, file, cursor, ma_seek_origin_start);
+ if (result != MA_SUCCESS) {
+ return result;
+ }
+
+ MA_ASSERT(result == MA_SUCCESS);
+ }
+
+ return result;
}
@@ -60333,8 +61870,8 @@ extern "C" {
#define MA_DR_WAV_STRINGIFY(x) #x
#define MA_DR_WAV_XSTRINGIFY(x) MA_DR_WAV_STRINGIFY(x)
#define MA_DR_WAV_VERSION_MAJOR 0
-#define MA_DR_WAV_VERSION_MINOR 13
-#define MA_DR_WAV_VERSION_REVISION 18
+#define MA_DR_WAV_VERSION_MINOR 14
+#define MA_DR_WAV_VERSION_REVISION 1
#define MA_DR_WAV_VERSION_STRING MA_DR_WAV_XSTRINGIFY(MA_DR_WAV_VERSION_MAJOR) "." MA_DR_WAV_XSTRINGIFY(MA_DR_WAV_VERSION_MINOR) "." MA_DR_WAV_XSTRINGIFY(MA_DR_WAV_VERSION_REVISION)
#include
#define MA_DR_WAVE_FORMAT_PCM 0x1
@@ -60350,8 +61887,9 @@ MA_API void ma_dr_wav_version(ma_uint32* pMajor, ma_uint32* pMinor, ma_uint32* p
MA_API const char* ma_dr_wav_version_string(void);
typedef enum
{
- ma_dr_wav_seek_origin_start,
- ma_dr_wav_seek_origin_current
+ MA_DR_WAV_SEEK_SET,
+ MA_DR_WAV_SEEK_CUR,
+ MA_DR_WAV_SEEK_END
} ma_dr_wav_seek_origin;
typedef enum
{
@@ -60388,6 +61926,7 @@ MA_API ma_uint16 ma_dr_wav_fmt_get_format(const ma_dr_wav_fmt* pFMT);
typedef size_t (* ma_dr_wav_read_proc)(void* pUserData, void* pBufferOut, size_t bytesToRead);
typedef size_t (* ma_dr_wav_write_proc)(void* pUserData, const void* pData, size_t bytesToWrite);
typedef ma_bool32 (* ma_dr_wav_seek_proc)(void* pUserData, int offset, ma_dr_wav_seek_origin origin);
+typedef ma_bool32 (* ma_dr_wav_tell_proc)(void* pUserData, ma_int64* pCursor);
typedef ma_uint64 (* ma_dr_wav_chunk_proc)(void* pChunkUserData, ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, void* pReadSeekUserData, const ma_dr_wav_chunk_header* pChunkHeader, ma_dr_wav_container container, const ma_dr_wav_fmt* pFMT);
typedef struct
{
@@ -60432,6 +61971,11 @@ typedef enum
ma_dr_wav_metadata_type_list_info_genre = 1 << 15,
ma_dr_wav_metadata_type_list_info_album = 1 << 16,
ma_dr_wav_metadata_type_list_info_tracknumber = 1 << 17,
+ ma_dr_wav_metadata_type_list_info_location = 1 << 18,
+ ma_dr_wav_metadata_type_list_info_organization = 1 << 19,
+ ma_dr_wav_metadata_type_list_info_keywords = 1 << 20,
+ ma_dr_wav_metadata_type_list_info_medium = 1 << 21,
+ ma_dr_wav_metadata_type_list_info_description = 1 << 22,
ma_dr_wav_metadata_type_list_all_info_strings = ma_dr_wav_metadata_type_list_info_software
| ma_dr_wav_metadata_type_list_info_copyright
| ma_dr_wav_metadata_type_list_info_title
@@ -60440,7 +61984,12 @@ typedef enum
| ma_dr_wav_metadata_type_list_info_date
| ma_dr_wav_metadata_type_list_info_genre
| ma_dr_wav_metadata_type_list_info_album
- | ma_dr_wav_metadata_type_list_info_tracknumber,
+ | ma_dr_wav_metadata_type_list_info_tracknumber
+ | ma_dr_wav_metadata_type_list_info_location
+ | ma_dr_wav_metadata_type_list_info_organization
+ | ma_dr_wav_metadata_type_list_info_keywords
+ | ma_dr_wav_metadata_type_list_info_medium
+ | ma_dr_wav_metadata_type_list_info_description,
ma_dr_wav_metadata_type_list_all_adtl = ma_dr_wav_metadata_type_list_label
| ma_dr_wav_metadata_type_list_note
| ma_dr_wav_metadata_type_list_labelled_cue_region,
@@ -60457,8 +62006,8 @@ typedef struct
{
ma_uint32 cuePointId;
ma_uint32 type;
- ma_uint32 firstSampleByteOffset;
- ma_uint32 lastSampleByteOffset;
+ ma_uint32 firstSampleOffset;
+ ma_uint32 lastSampleOffset;
ma_uint32 sampleFraction;
ma_uint32 playCount;
} ma_dr_wav_smpl_loop;
@@ -60493,7 +62042,7 @@ typedef struct
ma_uint8 dataChunkId[4];
ma_uint32 chunkStart;
ma_uint32 blockStart;
- ma_uint32 sampleByteOffset;
+ ma_uint32 sampleOffset;
} ma_dr_wav_cue_point;
typedef struct
{
@@ -60595,6 +62144,7 @@ typedef struct
ma_dr_wav_read_proc onRead;
ma_dr_wav_write_proc onWrite;
ma_dr_wav_seek_proc onSeek;
+ ma_dr_wav_tell_proc onTell;
void* pUserData;
ma_allocation_callbacks allocationCallbacks;
ma_dr_wav_container container;
@@ -60637,9 +62187,9 @@ typedef struct
ma_bool8 isUnsigned;
} aiff;
} ma_dr_wav;
-MA_API ma_bool32 ma_dr_wav_init(ma_dr_wav* pWav, ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks);
-MA_API ma_bool32 ma_dr_wav_init_ex(ma_dr_wav* pWav, ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, ma_dr_wav_chunk_proc onChunk, void* pReadSeekUserData, void* pChunkUserData, ma_uint32 flags, const ma_allocation_callbacks* pAllocationCallbacks);
-MA_API ma_bool32 ma_dr_wav_init_with_metadata(ma_dr_wav* pWav, ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, void* pUserData, ma_uint32 flags, const ma_allocation_callbacks* pAllocationCallbacks);
+MA_API ma_bool32 ma_dr_wav_init(ma_dr_wav* pWav, ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, ma_dr_wav_tell_proc onTell, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks);
+MA_API ma_bool32 ma_dr_wav_init_ex(ma_dr_wav* pWav, ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, ma_dr_wav_tell_proc onTell, ma_dr_wav_chunk_proc onChunk, void* pReadSeekTellUserData, void* pChunkUserData, ma_uint32 flags, const ma_allocation_callbacks* pAllocationCallbacks);
+MA_API ma_bool32 ma_dr_wav_init_with_metadata(ma_dr_wav* pWav, ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, ma_dr_wav_tell_proc onTell, void* pUserData, ma_uint32 flags, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_wav_init_write(ma_dr_wav* pWav, const ma_dr_wav_data_format* pFormat, ma_dr_wav_write_proc onWrite, ma_dr_wav_seek_proc onSeek, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_wav_init_write_sequential(ma_dr_wav* pWav, const ma_dr_wav_data_format* pFormat, ma_uint64 totalSampleCount, ma_dr_wav_write_proc onWrite, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_wav_init_write_sequential_pcm_frames(ma_dr_wav* pWav, const ma_dr_wav_data_format* pFormat, ma_uint64 totalPCMFrameCount, ma_dr_wav_write_proc onWrite, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks);
@@ -60711,9 +62261,9 @@ MA_API ma_bool32 ma_dr_wav_init_memory_write(ma_dr_wav* pWav, void** ppData, siz
MA_API ma_bool32 ma_dr_wav_init_memory_write_sequential(ma_dr_wav* pWav, void** ppData, size_t* pDataSize, const ma_dr_wav_data_format* pFormat, ma_uint64 totalSampleCount, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_wav_init_memory_write_sequential_pcm_frames(ma_dr_wav* pWav, void** ppData, size_t* pDataSize, const ma_dr_wav_data_format* pFormat, ma_uint64 totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
#ifndef MA_DR_WAV_NO_CONVERSION_API
-MA_API ma_int16* ma_dr_wav_open_and_read_pcm_frames_s16(ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks);
-MA_API float* ma_dr_wav_open_and_read_pcm_frames_f32(ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks);
-MA_API ma_int32* ma_dr_wav_open_and_read_pcm_frames_s32(ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks);
+MA_API ma_int16* ma_dr_wav_open_and_read_pcm_frames_s16(ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, ma_dr_wav_tell_proc onTell, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks);
+MA_API float* ma_dr_wav_open_and_read_pcm_frames_f32(ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, ma_dr_wav_tell_proc onTell, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks);
+MA_API ma_int32* ma_dr_wav_open_and_read_pcm_frames_s32(ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, ma_dr_wav_tell_proc onTell, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks);
#ifndef MA_DR_WAV_NO_STDIO
MA_API ma_int16* ma_dr_wav_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API float* ma_dr_wav_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks);
@@ -60753,8 +62303,8 @@ extern "C" {
#define MA_DR_FLAC_STRINGIFY(x) #x
#define MA_DR_FLAC_XSTRINGIFY(x) MA_DR_FLAC_STRINGIFY(x)
#define MA_DR_FLAC_VERSION_MAJOR 0
-#define MA_DR_FLAC_VERSION_MINOR 12
-#define MA_DR_FLAC_VERSION_REVISION 43
+#define MA_DR_FLAC_VERSION_MINOR 13
+#define MA_DR_FLAC_VERSION_REVISION 1
#define MA_DR_FLAC_VERSION_STRING MA_DR_FLAC_XSTRINGIFY(MA_DR_FLAC_VERSION_MAJOR) "." MA_DR_FLAC_XSTRINGIFY(MA_DR_FLAC_VERSION_MINOR) "." MA_DR_FLAC_XSTRINGIFY(MA_DR_FLAC_VERSION_REVISION)
#include
#if defined(_MSC_VER) && _MSC_VER >= 1700
@@ -60817,8 +62367,9 @@ typedef enum
} ma_dr_flac_container;
typedef enum
{
- ma_dr_flac_seek_origin_start,
- ma_dr_flac_seek_origin_current
+ MA_DR_FLAC_SEEK_SET,
+ MA_DR_FLAC_SEEK_CUR,
+ MA_DR_FLAC_SEEK_END
} ma_dr_flac_seek_origin;
typedef struct
{
@@ -60894,6 +62445,7 @@ typedef struct
} ma_dr_flac_metadata;
typedef size_t (* ma_dr_flac_read_proc)(void* pUserData, void* pBufferOut, size_t bytesToRead);
typedef ma_bool32 (* ma_dr_flac_seek_proc)(void* pUserData, int offset, ma_dr_flac_seek_origin origin);
+typedef ma_bool32 (* ma_dr_flac_tell_proc)(void* pUserData, ma_int64* pCursor);
typedef void (* ma_dr_flac_meta_proc)(void* pUserData, ma_dr_flac_metadata* pMetadata);
typedef struct
{
@@ -60905,6 +62457,7 @@ typedef struct
{
ma_dr_flac_read_proc onRead;
ma_dr_flac_seek_proc onSeek;
+ ma_dr_flac_tell_proc onTell;
void* pUserData;
size_t unalignedByteCount;
ma_dr_flac_cache_t unalignedCache;
@@ -60964,10 +62517,10 @@ typedef struct
ma_dr_flac_bs bs;
ma_uint8 pExtraData[1];
} ma_dr_flac;
-MA_API ma_dr_flac* ma_dr_flac_open(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks);
-MA_API ma_dr_flac* ma_dr_flac_open_relaxed(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_container container, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks);
-MA_API ma_dr_flac* ma_dr_flac_open_with_metadata(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_meta_proc onMeta, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks);
-MA_API ma_dr_flac* ma_dr_flac_open_with_metadata_relaxed(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_meta_proc onMeta, ma_dr_flac_container container, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks);
+MA_API ma_dr_flac* ma_dr_flac_open(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_tell_proc onTell, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks);
+MA_API ma_dr_flac* ma_dr_flac_open_relaxed(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_tell_proc onTell, ma_dr_flac_container container, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks);
+MA_API ma_dr_flac* ma_dr_flac_open_with_metadata(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_tell_proc onTell, ma_dr_flac_meta_proc onMeta, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks);
+MA_API ma_dr_flac* ma_dr_flac_open_with_metadata_relaxed(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_tell_proc onTell, ma_dr_flac_meta_proc onMeta, ma_dr_flac_container container, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API void ma_dr_flac_close(ma_dr_flac* pFlac);
MA_API ma_uint64 ma_dr_flac_read_pcm_frames_s32(ma_dr_flac* pFlac, ma_uint64 framesToRead, ma_int32* pBufferOut);
MA_API ma_uint64 ma_dr_flac_read_pcm_frames_s16(ma_dr_flac* pFlac, ma_uint64 framesToRead, ma_int16* pBufferOut);
@@ -60981,9 +62534,9 @@ MA_API ma_dr_flac* ma_dr_flac_open_file_with_metadata_w(const wchar_t* pFileName
#endif
MA_API ma_dr_flac* ma_dr_flac_open_memory(const void* pData, size_t dataSize, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_dr_flac* ma_dr_flac_open_memory_with_metadata(const void* pData, size_t dataSize, ma_dr_flac_meta_proc onMeta, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks);
-MA_API ma_int32* ma_dr_flac_open_and_read_pcm_frames_s32(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, ma_uint64* totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
-MA_API ma_int16* ma_dr_flac_open_and_read_pcm_frames_s16(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, ma_uint64* totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
-MA_API float* ma_dr_flac_open_and_read_pcm_frames_f32(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, ma_uint64* totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
+MA_API ma_int32* ma_dr_flac_open_and_read_pcm_frames_s32(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_tell_proc onTell, void* pUserData, unsigned int* channels, unsigned int* sampleRate, ma_uint64* totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
+MA_API ma_int16* ma_dr_flac_open_and_read_pcm_frames_s16(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_tell_proc onTell, void* pUserData, unsigned int* channels, unsigned int* sampleRate, ma_uint64* totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
+MA_API float* ma_dr_flac_open_and_read_pcm_frames_f32(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_tell_proc onTell, void* pUserData, unsigned int* channels, unsigned int* sampleRate, ma_uint64* totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
#ifndef MA_DR_FLAC_NO_STDIO
MA_API ma_int32* ma_dr_flac_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, ma_uint64* totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_int16* ma_dr_flac_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, ma_uint64* totalPCMFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
@@ -61031,6 +62584,12 @@ MA_API ma_bool32 ma_dr_flac_next_cuesheet_track(ma_dr_flac_cuesheet_track_iterat
#endif /* MA_NO_FLAC */
#if !defined(MA_NO_MP3) && !defined(MA_NO_DECODING)
+#ifndef MA_DR_MP3_NO_SIMD
+ #if (defined(MA_NO_NEON) && defined(MA_ARM)) || (defined(MA_NO_SSE2) && (defined(MA_X86) || defined(MA_X64)))
+ #define MA_DR_MP3_NO_SIMD
+ #endif
+#endif
+
/* dr_mp3_h begin */
#ifndef ma_dr_mp3_h
#define ma_dr_mp3_h
@@ -61040,8 +62599,8 @@ extern "C" {
#define MA_DR_MP3_STRINGIFY(x) #x
#define MA_DR_MP3_XSTRINGIFY(x) MA_DR_MP3_STRINGIFY(x)
#define MA_DR_MP3_VERSION_MAJOR 0
-#define MA_DR_MP3_VERSION_MINOR 6
-#define MA_DR_MP3_VERSION_REVISION 40
+#define MA_DR_MP3_VERSION_MINOR 7
+#define MA_DR_MP3_VERSION_REVISION 1
#define MA_DR_MP3_VERSION_STRING MA_DR_MP3_XSTRINGIFY(MA_DR_MP3_VERSION_MAJOR) "." MA_DR_MP3_XSTRINGIFY(MA_DR_MP3_VERSION_MINOR) "." MA_DR_MP3_XSTRINGIFY(MA_DR_MP3_VERSION_REVISION)
#include
#define MA_DR_MP3_MAX_PCM_FRAMES_PER_MP3_FRAME 1152
@@ -61050,7 +62609,7 @@ MA_API void ma_dr_mp3_version(ma_uint32* pMajor, ma_uint32* pMinor, ma_uint32* p
MA_API const char* ma_dr_mp3_version_string(void);
typedef struct
{
- int frame_bytes, channels, hz, layer, bitrate_kbps;
+ int frame_bytes, channels, sample_rate, layer, bitrate_kbps;
} ma_dr_mp3dec_frame_info;
typedef struct
{
@@ -61063,8 +62622,9 @@ MA_API int ma_dr_mp3dec_decode_frame(ma_dr_mp3dec *dec, const ma_uint8 *mp3, int
MA_API void ma_dr_mp3dec_f32_to_s16(const float *in, ma_int16 *out, size_t num_samples);
typedef enum
{
- ma_dr_mp3_seek_origin_start,
- ma_dr_mp3_seek_origin_current
+ MA_DR_MP3_SEEK_SET,
+ MA_DR_MP3_SEEK_CUR,
+ MA_DR_MP3_SEEK_END
} ma_dr_mp3_seek_origin;
typedef struct
{
@@ -61073,8 +62633,24 @@ typedef struct
ma_uint16 mp3FramesToDiscard;
ma_uint16 pcmFramesToDiscard;
} ma_dr_mp3_seek_point;
+typedef enum
+{
+ MA_DR_MP3_METADATA_TYPE_ID3V1,
+ MA_DR_MP3_METADATA_TYPE_ID3V2,
+ MA_DR_MP3_METADATA_TYPE_APE,
+ MA_DR_MP3_METADATA_TYPE_XING,
+ MA_DR_MP3_METADATA_TYPE_VBRI
+} ma_dr_mp3_metadata_type;
+typedef struct
+{
+ ma_dr_mp3_metadata_type type;
+ const void* pRawData;
+ size_t rawDataSize;
+} ma_dr_mp3_metadata;
typedef size_t (* ma_dr_mp3_read_proc)(void* pUserData, void* pBufferOut, size_t bytesToRead);
typedef ma_bool32 (* ma_dr_mp3_seek_proc)(void* pUserData, int offset, ma_dr_mp3_seek_origin origin);
+typedef ma_bool32 (* ma_dr_mp3_tell_proc)(void* pUserData, ma_int64* pCursor);
+typedef void (* ma_dr_mp3_meta_proc)(void* pUserData, const ma_dr_mp3_metadata* pMetadata);
typedef struct
{
ma_uint32 channels;
@@ -61087,7 +62663,9 @@ typedef struct
ma_uint32 sampleRate;
ma_dr_mp3_read_proc onRead;
ma_dr_mp3_seek_proc onSeek;
+ ma_dr_mp3_meta_proc onMeta;
void* pUserData;
+ void* pUserDataMeta;
ma_allocation_callbacks allocationCallbacks;
ma_uint32 mp3FrameChannels;
ma_uint32 mp3FrameSampleRate;
@@ -61096,13 +62674,20 @@ typedef struct
ma_uint8 pcmFrames[sizeof(float)*MA_DR_MP3_MAX_SAMPLES_PER_FRAME];
ma_uint64 currentPCMFrame;
ma_uint64 streamCursor;
+ ma_uint64 streamLength;
+ ma_uint64 streamStartOffset;
ma_dr_mp3_seek_point* pSeekPoints;
ma_uint32 seekPointCount;
+ ma_uint32 delayInPCMFrames;
+ ma_uint32 paddingInPCMFrames;
+ ma_uint64 totalPCMFrameCount;
+ ma_bool32 isVBR;
+ ma_bool32 isCBR;
size_t dataSize;
size_t dataCapacity;
size_t dataConsumed;
ma_uint8* pData;
- ma_bool32 atEnd : 1;
+ ma_bool32 atEnd;
struct
{
const ma_uint8* pData;
@@ -61110,9 +62695,12 @@ typedef struct
size_t currentReadPos;
} memory;
} ma_dr_mp3;
-MA_API ma_bool32 ma_dr_mp3_init(ma_dr_mp3* pMP3, ma_dr_mp3_read_proc onRead, ma_dr_mp3_seek_proc onSeek, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks);
+MA_API ma_bool32 ma_dr_mp3_init(ma_dr_mp3* pMP3, ma_dr_mp3_read_proc onRead, ma_dr_mp3_seek_proc onSeek, ma_dr_mp3_tell_proc onTell, ma_dr_mp3_meta_proc onMeta, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks);
+MA_API ma_bool32 ma_dr_mp3_init_memory_with_metadata(ma_dr_mp3* pMP3, const void* pData, size_t dataSize, ma_dr_mp3_meta_proc onMeta, void* pUserDataMeta, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_mp3_init_memory(ma_dr_mp3* pMP3, const void* pData, size_t dataSize, const ma_allocation_callbacks* pAllocationCallbacks);
#ifndef MA_DR_MP3_NO_STDIO
+MA_API ma_bool32 ma_dr_mp3_init_file_with_metadata(ma_dr_mp3* pMP3, const char* pFilePath, ma_dr_mp3_meta_proc onMeta, void* pUserDataMeta, const ma_allocation_callbacks* pAllocationCallbacks);
+MA_API ma_bool32 ma_dr_mp3_init_file_with_metadata_w(ma_dr_mp3* pMP3, const wchar_t* pFilePath, ma_dr_mp3_meta_proc onMeta, void* pUserDataMeta, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_mp3_init_file(ma_dr_mp3* pMP3, const char* pFilePath, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_bool32 ma_dr_mp3_init_file_w(ma_dr_mp3* pMP3, const wchar_t* pFilePath, const ma_allocation_callbacks* pAllocationCallbacks);
#endif
@@ -61125,8 +62713,8 @@ MA_API ma_uint64 ma_dr_mp3_get_mp3_frame_count(ma_dr_mp3* pMP3);
MA_API ma_bool32 ma_dr_mp3_get_mp3_and_pcm_frame_count(ma_dr_mp3* pMP3, ma_uint64* pMP3FrameCount, ma_uint64* pPCMFrameCount);
MA_API ma_bool32 ma_dr_mp3_calculate_seek_points(ma_dr_mp3* pMP3, ma_uint32* pSeekPointCount, ma_dr_mp3_seek_point* pSeekPoints);
MA_API ma_bool32 ma_dr_mp3_bind_seek_table(ma_dr_mp3* pMP3, ma_uint32 seekPointCount, ma_dr_mp3_seek_point* pSeekPoints);
-MA_API float* ma_dr_mp3_open_and_read_pcm_frames_f32(ma_dr_mp3_read_proc onRead, ma_dr_mp3_seek_proc onSeek, void* pUserData, ma_dr_mp3_config* pConfig, ma_uint64* pTotalFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
-MA_API ma_int16* ma_dr_mp3_open_and_read_pcm_frames_s16(ma_dr_mp3_read_proc onRead, ma_dr_mp3_seek_proc onSeek, void* pUserData, ma_dr_mp3_config* pConfig, ma_uint64* pTotalFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
+MA_API float* ma_dr_mp3_open_and_read_pcm_frames_f32(ma_dr_mp3_read_proc onRead, ma_dr_mp3_seek_proc onSeek, ma_dr_mp3_tell_proc onTell, void* pUserData, ma_dr_mp3_config* pConfig, ma_uint64* pTotalFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
+MA_API ma_int16* ma_dr_mp3_open_and_read_pcm_frames_s16(ma_dr_mp3_read_proc onRead, ma_dr_mp3_seek_proc onSeek, ma_dr_mp3_tell_proc onTell, void* pUserData, ma_dr_mp3_config* pConfig, ma_uint64* pTotalFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API float* ma_dr_mp3_open_memory_and_read_pcm_frames_f32(const void* pData, size_t dataSize, ma_dr_mp3_config* pConfig, ma_uint64* pTotalFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
MA_API ma_int16* ma_dr_mp3_open_memory_and_read_pcm_frames_s16(const void* pData, size_t dataSize, ma_dr_mp3_config* pConfig, ma_uint64* pTotalFrameCount, const ma_allocation_callbacks* pAllocationCallbacks);
#ifndef MA_DR_MP3_NO_STDIO
@@ -61679,8 +63267,10 @@ static ma_bool32 ma_wav_dr_callback__seek(void* pUserData, int offset, ma_dr_wav
MA_ASSERT(pWav != NULL);
maSeekOrigin = ma_seek_origin_start;
- if (origin == ma_dr_wav_seek_origin_current) {
- maSeekOrigin = ma_seek_origin_current;
+ if (origin == MA_DR_WAV_SEEK_CUR) {
+ maSeekOrigin = ma_seek_origin_current;
+ } else if (origin == MA_DR_WAV_SEEK_END) {
+ maSeekOrigin = ma_seek_origin_end;
}
result = pWav->onSeek(pWav->pReadSeekTellUserData, offset, maSeekOrigin);
@@ -61690,6 +63280,26 @@ static ma_bool32 ma_wav_dr_callback__seek(void* pUserData, int offset, ma_dr_wav
return MA_TRUE;
}
+
+static ma_bool32 ma_wav_dr_callback__tell(void* pUserData, ma_int64* pCursor)
+{
+ ma_wav* pWav = (ma_wav*)pUserData;
+ ma_result result;
+
+ MA_ASSERT(pWav != NULL);
+ MA_ASSERT(pCursor != NULL);
+
+ if (pWav->onTell == NULL) {
+ return MA_FALSE; /* Not implemented. */
+ }
+
+ result = pWav->onTell(pWav->pReadSeekTellUserData, pCursor);
+ if (result != MA_SUCCESS) {
+ return MA_FALSE; /* Failed to tell. */
+ }
+
+ return MA_TRUE;
+}
#endif
static ma_result ma_wav_init_internal(const ma_decoding_backend_config* pConfig, ma_wav* pWav)
@@ -61784,7 +63394,7 @@ MA_API ma_result ma_wav_init(ma_read_proc onRead, ma_seek_proc onSeek, ma_tell_p
{
ma_bool32 wavResult;
- wavResult = ma_dr_wav_init(&pWav->dr, ma_wav_dr_callback__read, ma_wav_dr_callback__seek, pWav, pAllocationCallbacks);
+ wavResult = ma_dr_wav_init(&pWav->dr, ma_wav_dr_callback__read, ma_wav_dr_callback__seek, ma_wav_dr_callback__tell, pWav, pAllocationCallbacks);
if (wavResult != MA_TRUE) {
return MA_INVALID_FILE;
}
@@ -62363,8 +63973,10 @@ static ma_bool32 ma_flac_dr_callback__seek(void* pUserData, int offset, ma_dr_fl
MA_ASSERT(pFlac != NULL);
maSeekOrigin = ma_seek_origin_start;
- if (origin == ma_dr_flac_seek_origin_current) {
- maSeekOrigin = ma_seek_origin_current;
+ if (origin == MA_DR_FLAC_SEEK_CUR) {
+ maSeekOrigin = ma_seek_origin_current;
+ } else if (origin == MA_DR_FLAC_SEEK_END) {
+ maSeekOrigin = ma_seek_origin_end;
}
result = pFlac->onSeek(pFlac->pReadSeekTellUserData, offset, maSeekOrigin);
@@ -62374,6 +63986,26 @@ static ma_bool32 ma_flac_dr_callback__seek(void* pUserData, int offset, ma_dr_fl
return MA_TRUE;
}
+
+static ma_bool32 ma_flac_dr_callback__tell(void* pUserData, ma_int64* pCursor)
+{
+ ma_flac* pFlac = (ma_flac*)pUserData;
+ ma_result result;
+
+ MA_ASSERT(pFlac != NULL);
+ MA_ASSERT(pCursor != NULL);
+
+ if (pFlac->onTell == NULL) {
+ return MA_FALSE; /* Not implemented. */
+ }
+
+ result = pFlac->onTell(pFlac->pReadSeekTellUserData, pCursor);
+ if (result != MA_SUCCESS) {
+ return MA_FALSE; /* Failed to tell. */
+ }
+
+ return MA_TRUE;
+}
#endif
static ma_result ma_flac_init_internal(const ma_decoding_backend_config* pConfig, ma_flac* pFlac)
@@ -62425,7 +64057,7 @@ MA_API ma_result ma_flac_init(ma_read_proc onRead, ma_seek_proc onSeek, ma_tell_
#if !defined(MA_NO_FLAC)
{
- pFlac->dr = ma_dr_flac_open(ma_flac_dr_callback__read, ma_flac_dr_callback__seek, pFlac, pAllocationCallbacks);
+ pFlac->dr = ma_dr_flac_open(ma_flac_dr_callback__read, ma_flac_dr_callback__seek, ma_flac_dr_callback__tell, pFlac, pAllocationCallbacks);
if (pFlac->dr == NULL) {
return MA_INVALID_FILE;
}
@@ -62986,9 +64618,12 @@ static ma_bool32 ma_mp3_dr_callback__seek(void* pUserData, int offset, ma_dr_mp3
MA_ASSERT(pMP3 != NULL);
- maSeekOrigin = ma_seek_origin_start;
- if (origin == ma_dr_mp3_seek_origin_current) {
- maSeekOrigin = ma_seek_origin_current;
+ if (origin == MA_DR_MP3_SEEK_SET) {
+ maSeekOrigin = ma_seek_origin_start;
+ } else if (origin == MA_DR_MP3_SEEK_END) {
+ maSeekOrigin = ma_seek_origin_end;
+ } else {
+ maSeekOrigin = ma_seek_origin_current;
}
result = pMP3->onSeek(pMP3->pReadSeekTellUserData, offset, maSeekOrigin);
@@ -62998,6 +64633,21 @@ static ma_bool32 ma_mp3_dr_callback__seek(void* pUserData, int offset, ma_dr_mp3
return MA_TRUE;
}
+
+static ma_bool32 ma_mp3_dr_callback__tell(void* pUserData, ma_int64* pCursor)
+{
+ ma_mp3* pMP3 = (ma_mp3*)pUserData;
+ ma_result result;
+
+ MA_ASSERT(pMP3 != NULL);
+
+ result = pMP3->onTell(pMP3->pReadSeekTellUserData, pCursor);
+ if (result != MA_SUCCESS) {
+ return MA_FALSE;
+ }
+
+ return MA_TRUE;
+}
#endif
static ma_result ma_mp3_init_internal(const ma_decoding_backend_config* pConfig, ma_mp3* pMP3)
@@ -63098,7 +64748,7 @@ MA_API ma_result ma_mp3_init(ma_read_proc onRead, ma_seek_proc onSeek, ma_tell_p
{
ma_bool32 mp3Result;
- mp3Result = ma_dr_mp3_init(&pMP3->dr, ma_mp3_dr_callback__read, ma_mp3_dr_callback__seek, pMP3, pAllocationCallbacks);
+ mp3Result = ma_dr_mp3_init(&pMP3->dr, ma_mp3_dr_callback__read, ma_mp3_dr_callback__seek, ma_mp3_dr_callback__tell, NULL, pMP3, pAllocationCallbacks);
if (mp3Result != MA_TRUE) {
return MA_INVALID_FILE;
}
@@ -64997,14 +66647,16 @@ static ma_bool32 ma_path_extension_equal_w(const wchar_t* path, const wchar_t* e
ext1 = extension;
ext2 = ma_path_extension_w(path);
-#if defined(_MSC_VER) || defined(__WATCOMC__) || defined(__DMC__)
- return _wcsicmp(ext1, ext2) == 0;
-#else
- /*
- I'm not aware of a wide character version of strcasecmp(). I'm therefore converting the extensions to multibyte strings and comparing those. This
- isn't the most efficient way to do it, but it should work OK.
- */
+ #if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__DMC__)) && !defined(MA_XBOX_NXDK)
{
+ return _wcsicmp(ext1, ext2) == 0;
+ }
+ #elif !defined(MA_XBOX_NXDK) && !defined(MA_DOS)
+ {
+ /*
+ I'm not aware of a wide character version of strcasecmp(). I'm therefore converting the extensions to multibyte strings and comparing those. This
+ isn't the most efficient way to do it, but it should work OK.
+ */
char ext1MB[4096];
char ext2MB[4096];
const wchar_t* pext1 = ext1;
@@ -65024,7 +66676,13 @@ static ma_bool32 ma_path_extension_equal_w(const wchar_t* path, const wchar_t* e
return strcasecmp(ext1MB, ext2MB) == 0;
}
-#endif
+ #else
+ {
+ /* Getting here means we don't have a way to do a case-sensitive comparison for wide strings. Fall back to a simple case-sensitive comparison. */
+ /* TODO: Implement our own wchar_t-to-char conversion routine and then use the char* version for comparing. */
+ return ma_wcscmp(ext1, ext2) == 0;
+ }
+ #endif
}
#endif /* MA_HAS_PATH_API */
@@ -66119,10 +67777,18 @@ static ma_bool32 ma_encoder__internal_on_seek_wav(void* pUserData, int offset, m
{
ma_encoder* pEncoder = (ma_encoder*)pUserData;
ma_result result;
+ ma_seek_origin maSeekOrigin;
MA_ASSERT(pEncoder != NULL);
- result = pEncoder->onSeek(pEncoder, offset, (origin == ma_dr_wav_seek_origin_start) ? ma_seek_origin_start : ma_seek_origin_current);
+ maSeekOrigin = ma_seek_origin_start;
+ if (origin == MA_DR_WAV_SEEK_CUR) {
+ maSeekOrigin = ma_seek_origin_current;
+ } else if (origin == MA_DR_WAV_SEEK_END) {
+ maSeekOrigin = ma_seek_origin_end;
+ }
+
+ result = pEncoder->onSeek(pEncoder, offset, maSeekOrigin);
if (result != MA_SUCCESS) {
return MA_FALSE;
} else {
@@ -67644,7 +69310,7 @@ static MA_INLINE ma_uint32 ma_hash_getblock(const ma_uint32* blocks, int i)
ma_uint32 block;
/* Try silencing a sanitization warning about unaligned access by doing a memcpy() instead of assignment. */
- MA_COPY_MEMORY(&block, ma_offset_ptr(blocks, i * sizeof(block)), sizeof(block));
+ MA_COPY_MEMORY(&block, ma_offset_ptr(blocks, i * (int) sizeof(block)), sizeof(block));
if (ma_is_little_endian()) {
return block;
@@ -67720,7 +69386,7 @@ static ma_uint32 ma_hash_string_32(const char* str)
static ma_uint32 ma_hash_string_w_32(const wchar_t* str)
{
- return ma_hash_32(str, (int)wcslen(str) * sizeof(*str), MA_DEFAULT_HASH_SEED);
+ return ma_hash_32(str, (int)ma_wcslen(str) * sizeof(*str), MA_DEFAULT_HASH_SEED);
}
@@ -67880,6 +69546,7 @@ static MA_INLINE ma_resource_manager_data_buffer_node* ma_resource_manager_data_
return ma_resource_manager_data_buffer_node_find_min(pDataBufferNode->pChildHi);
}
+#if 0 /* Currently unused, but might make use of this later. */
static MA_INLINE ma_resource_manager_data_buffer_node* ma_resource_manager_data_buffer_node_find_inorder_predecessor(ma_resource_manager_data_buffer_node* pDataBufferNode)
{
MA_ASSERT(pDataBufferNode != NULL);
@@ -67887,6 +69554,7 @@ static MA_INLINE ma_resource_manager_data_buffer_node* ma_resource_manager_data_
return ma_resource_manager_data_buffer_node_find_max(pDataBufferNode->pChildLo);
}
+#endif
static ma_result ma_resource_manager_data_buffer_node_remove(ma_resource_manager* pResourceManager, ma_resource_manager_data_buffer_node* pDataBufferNode)
{
@@ -69009,16 +70677,19 @@ static ma_result ma_resource_manager_data_buffer_node_acquire_critical_section(m
/* Failed to post job. Probably ran out of memory. */
ma_log_postf(ma_resource_manager_get_log(pResourceManager), MA_LOG_LEVEL_ERROR, "Failed to post MA_JOB_TYPE_RESOURCE_MANAGER_LOAD_DATA_BUFFER_NODE job. %s.\n", ma_result_description(result));
- /*
- Fences were acquired before posting the job, but since the job was not able to
- be posted, we need to make sure we release them so nothing gets stuck waiting.
- */
- if (pInitFence != NULL) { ma_fence_release(pInitFence); }
- if (pDoneFence != NULL) { ma_fence_release(pDoneFence); }
-
if ((flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_WAIT_INIT) != 0) {
ma_resource_manager_inline_notification_uninit(pInitNotification);
} else {
+ /*
+ Fences were acquired before posting the job, but since the job was not able to
+ be posted, we need to make sure we release them so nothing gets stuck waiting.
+
+ In the WAIT_INIT case, these will have already been released in ma_job_process()
+ so we should only release fences in this branch.
+ */
+ if (pInitFence != NULL) { ma_fence_release(pInitFence); }
+ if (pDoneFence != NULL) { ma_fence_release(pDoneFence); }
+
/* These will have been freed by the job thread, but with WAIT_INIT they will already have happened since the job has already been handled. */
ma_free(pFilePathCopy, &pResourceManager->config.allocationCallbacks);
ma_free(pFilePathWCopy, &pResourceManager->config.allocationCallbacks);
@@ -76674,7 +78345,7 @@ static ma_result ma_sound_init_from_data_source_internal(ma_engine* pEngine, con
}
if (pConfig->loopPointBegInPCMFrames != 0 || pConfig->loopPointEndInPCMFrames != ~((ma_uint64)0)) {
- ma_data_source_set_range_in_pcm_frames(ma_sound_get_data_source(pSound), pConfig->loopPointBegInPCMFrames, pConfig->loopPointEndInPCMFrames);
+ ma_data_source_set_loop_point_in_pcm_frames(ma_sound_get_data_source(pSound), pConfig->loopPointBegInPCMFrames, pConfig->loopPointEndInPCMFrames);
}
ma_sound_set_looping(pSound, pConfig->isLooping || ((pConfig->flags & MA_SOUND_FLAG_LOOPING) != 0));
@@ -76736,6 +78407,7 @@ MA_API ma_result ma_sound_init_from_file_internal(ma_engine* pEngine, const ma_s
result = ma_resource_manager_data_source_init_ex(pEngine->pResourceManager, &resourceManagerDataSourceConfig, pSound->pResourceManagerDataSource);
if (result != MA_SUCCESS) {
+ ma_free(pSound->pResourceManagerDataSource, &pEngine->allocationCallbacks);
goto done;
}
@@ -77541,7 +79213,12 @@ MA_API ma_uint64 ma_sound_get_time_in_pcm_frames(const ma_sound* pSound)
MA_API ma_uint64 ma_sound_get_time_in_milliseconds(const ma_sound* pSound)
{
- return ma_sound_get_time_in_pcm_frames(pSound) * 1000 / ma_engine_get_sample_rate(ma_sound_get_engine(pSound));
+ ma_uint32 sampleRate = ma_engine_get_sample_rate(ma_sound_get_engine(pSound));
+ if (sampleRate == 0) {
+ return 0; /* Prevent a division by zero. */
+ }
+
+ return ma_sound_get_time_in_pcm_frames(pSound) * 1000 / sampleRate;
}
MA_API void ma_sound_set_looping(ma_sound* pSound, ma_bool32 isLooping)
@@ -77625,7 +79302,7 @@ MA_API ma_result ma_sound_seek_to_second(ma_sound* pSound, float seekPointInSeco
return ma_sound_seek_to_pcm_frame(pSound, frameIndex);
}
-MA_API ma_result ma_sound_get_data_format(ma_sound* pSound, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
+MA_API ma_result ma_sound_get_data_format(const ma_sound* pSound, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{
if (pSound == NULL) {
return MA_INVALID_ARGS;
@@ -77658,7 +79335,7 @@ MA_API ma_result ma_sound_get_data_format(ma_sound* pSound, ma_format* pFormat,
}
}
-MA_API ma_result ma_sound_get_cursor_in_pcm_frames(ma_sound* pSound, ma_uint64* pCursor)
+MA_API ma_result ma_sound_get_cursor_in_pcm_frames(const ma_sound* pSound, ma_uint64* pCursor)
{
ma_uint64 seekTarget;
@@ -77680,7 +79357,7 @@ MA_API ma_result ma_sound_get_cursor_in_pcm_frames(ma_sound* pSound, ma_uint64*
}
}
-MA_API ma_result ma_sound_get_length_in_pcm_frames(ma_sound* pSound, ma_uint64* pLength)
+MA_API ma_result ma_sound_get_length_in_pcm_frames(const ma_sound* pSound, ma_uint64* pLength)
{
if (pSound == NULL) {
return MA_INVALID_ARGS;
@@ -77694,7 +79371,7 @@ MA_API ma_result ma_sound_get_length_in_pcm_frames(ma_sound* pSound, ma_uint64*
return ma_data_source_get_length_in_pcm_frames(pSound->pDataSource, pLength);
}
-MA_API ma_result ma_sound_get_cursor_in_seconds(ma_sound* pSound, float* pCursor)
+MA_API ma_result ma_sound_get_cursor_in_seconds(const ma_sound* pSound, float* pCursor)
{
ma_result result;
ma_uint64 cursorInPCMFrames;
@@ -77720,7 +79397,7 @@ MA_API ma_result ma_sound_get_cursor_in_seconds(ma_sound* pSound, float* pCursor
return MA_SUCCESS;
}
-MA_API ma_result ma_sound_get_length_in_seconds(ma_sound* pSound, float* pLength)
+MA_API ma_result ma_sound_get_length_in_seconds(const ma_sound* pSound, float* pLength)
{
if (pSound == NULL) {
return MA_INVALID_ARGS;
@@ -78539,12 +80216,12 @@ MA_PRIVATE ma_bool32 ma_dr_wav__seek_forward(ma_dr_wav_seek_proc onSeek, ma_uint
ma_uint64 bytesRemainingToSeek = offset;
while (bytesRemainingToSeek > 0) {
if (bytesRemainingToSeek > 0x7FFFFFFF) {
- if (!onSeek(pUserData, 0x7FFFFFFF, ma_dr_wav_seek_origin_current)) {
+ if (!onSeek(pUserData, 0x7FFFFFFF, MA_DR_WAV_SEEK_CUR)) {
return MA_FALSE;
}
bytesRemainingToSeek -= 0x7FFFFFFF;
} else {
- if (!onSeek(pUserData, (int)bytesRemainingToSeek, ma_dr_wav_seek_origin_current)) {
+ if (!onSeek(pUserData, (int)bytesRemainingToSeek, MA_DR_WAV_SEEK_CUR)) {
return MA_FALSE;
}
bytesRemainingToSeek = 0;
@@ -78555,17 +80232,17 @@ MA_PRIVATE ma_bool32 ma_dr_wav__seek_forward(ma_dr_wav_seek_proc onSeek, ma_uint
MA_PRIVATE ma_bool32 ma_dr_wav__seek_from_start(ma_dr_wav_seek_proc onSeek, ma_uint64 offset, void* pUserData)
{
if (offset <= 0x7FFFFFFF) {
- return onSeek(pUserData, (int)offset, ma_dr_wav_seek_origin_start);
+ return onSeek(pUserData, (int)offset, MA_DR_WAV_SEEK_SET);
}
- if (!onSeek(pUserData, 0x7FFFFFFF, ma_dr_wav_seek_origin_start)) {
+ if (!onSeek(pUserData, 0x7FFFFFFF, MA_DR_WAV_SEEK_SET)) {
return MA_FALSE;
}
offset -= 0x7FFFFFFF;
for (;;) {
if (offset <= 0x7FFFFFFF) {
- return onSeek(pUserData, (int)offset, ma_dr_wav_seek_origin_current);
+ return onSeek(pUserData, (int)offset, MA_DR_WAV_SEEK_CUR);
}
- if (!onSeek(pUserData, 0x7FFFFFFF, ma_dr_wav_seek_origin_current)) {
+ if (!onSeek(pUserData, 0x7FFFFFFF, MA_DR_WAV_SEEK_CUR)) {
return MA_FALSE;
}
offset -= 0x7FFFFFFF;
@@ -78588,7 +80265,7 @@ MA_PRIVATE ma_bool32 ma_dr_wav__on_seek(ma_dr_wav_seek_proc onSeek, void* pUserD
if (!onSeek(pUserData, offset, origin)) {
return MA_FALSE;
}
- if (origin == ma_dr_wav_seek_origin_start) {
+ if (origin == MA_DR_WAV_SEEK_SET) {
*pCursor = offset;
} else {
*pCursor += offset;
@@ -78707,12 +80384,12 @@ MA_PRIVATE ma_uint64 ma_dr_wav__read_smpl_to_metadata_obj(ma_dr_wav__metadata_pa
ma_uint8 smplLoopData[MA_DR_WAV_SMPL_LOOP_BYTES];
bytesJustRead = ma_dr_wav__metadata_parser_read(pParser, smplLoopData, sizeof(smplLoopData), &totalBytesRead);
if (bytesJustRead == sizeof(smplLoopData)) {
- pMetadata->data.smpl.pLoops[iSampleLoop].cuePointId = ma_dr_wav_bytes_to_u32(smplLoopData + 0);
- pMetadata->data.smpl.pLoops[iSampleLoop].type = ma_dr_wav_bytes_to_u32(smplLoopData + 4);
- pMetadata->data.smpl.pLoops[iSampleLoop].firstSampleByteOffset = ma_dr_wav_bytes_to_u32(smplLoopData + 8);
- pMetadata->data.smpl.pLoops[iSampleLoop].lastSampleByteOffset = ma_dr_wav_bytes_to_u32(smplLoopData + 12);
- pMetadata->data.smpl.pLoops[iSampleLoop].sampleFraction = ma_dr_wav_bytes_to_u32(smplLoopData + 16);
- pMetadata->data.smpl.pLoops[iSampleLoop].playCount = ma_dr_wav_bytes_to_u32(smplLoopData + 20);
+ pMetadata->data.smpl.pLoops[iSampleLoop].cuePointId = ma_dr_wav_bytes_to_u32(smplLoopData + 0);
+ pMetadata->data.smpl.pLoops[iSampleLoop].type = ma_dr_wav_bytes_to_u32(smplLoopData + 4);
+ pMetadata->data.smpl.pLoops[iSampleLoop].firstSampleOffset = ma_dr_wav_bytes_to_u32(smplLoopData + 8);
+ pMetadata->data.smpl.pLoops[iSampleLoop].lastSampleOffset = ma_dr_wav_bytes_to_u32(smplLoopData + 12);
+ pMetadata->data.smpl.pLoops[iSampleLoop].sampleFraction = ma_dr_wav_bytes_to_u32(smplLoopData + 16);
+ pMetadata->data.smpl.pLoops[iSampleLoop].playCount = ma_dr_wav_bytes_to_u32(smplLoopData + 20);
} else {
break;
}
@@ -78756,7 +80433,7 @@ MA_PRIVATE ma_uint64 ma_dr_wav__read_cue_to_metadata_obj(ma_dr_wav__metadata_par
pMetadata->data.cue.pCuePoints[iCuePoint].dataChunkId[3] = cuePointData[11];
pMetadata->data.cue.pCuePoints[iCuePoint].chunkStart = ma_dr_wav_bytes_to_u32(cuePointData + 12);
pMetadata->data.cue.pCuePoints[iCuePoint].blockStart = ma_dr_wav_bytes_to_u32(cuePointData + 16);
- pMetadata->data.cue.pCuePoints[iCuePoint].sampleByteOffset = ma_dr_wav_bytes_to_u32(cuePointData + 20);
+ pMetadata->data.cue.pCuePoints[iCuePoint].sampleOffset = ma_dr_wav_bytes_to_u32(cuePointData + 20);
} else {
break;
}
@@ -79096,7 +80773,7 @@ MA_PRIVATE ma_uint64 ma_dr_wav__metadata_process_chunk(ma_dr_wav__metadata_parse
if (pParser->stage == ma_dr_wav__metadata_parser_stage_count) {
ma_uint8 buffer[4];
size_t bytesJustRead;
- if (!pParser->onSeek(pParser->pReadSeekUserData, 28, ma_dr_wav_seek_origin_current)) {
+ if (!pParser->onSeek(pParser->pReadSeekUserData, 28, MA_DR_WAV_SEEK_CUR)) {
return bytesRead;
}
bytesRead += 28;
@@ -79191,7 +80868,7 @@ MA_PRIVATE ma_uint64 ma_dr_wav__metadata_process_chunk(ma_dr_wav__metadata_parse
return bytesRead;
}
allocSizeNeeded += ma_dr_wav__strlen(buffer) + 1;
- allocSizeNeeded += (size_t)pChunkHeader->sizeInBytes - MA_DR_WAV_BEXT_BYTES;
+ allocSizeNeeded += (size_t)pChunkHeader->sizeInBytes - MA_DR_WAV_BEXT_BYTES + 1;
ma_dr_wav__metadata_request_extra_memory_for_stage_2(pParser, allocSizeNeeded, 1);
pParser->metadataCount += 1;
} else {
@@ -79274,6 +80951,16 @@ MA_PRIVATE ma_uint64 ma_dr_wav__metadata_process_chunk(ma_dr_wav__metadata_parse
subchunkBytesRead = ma_dr_wav__metadata_process_info_text_chunk(pParser, subchunkDataSize, ma_dr_wav_metadata_type_list_info_album);
} else if (ma_dr_wav__chunk_matches(allowedMetadataTypes, subchunkId, ma_dr_wav_metadata_type_list_info_tracknumber, "ITRK")) {
subchunkBytesRead = ma_dr_wav__metadata_process_info_text_chunk(pParser, subchunkDataSize, ma_dr_wav_metadata_type_list_info_tracknumber);
+ } else if (ma_dr_wav__chunk_matches(allowedMetadataTypes, subchunkId, ma_dr_wav_metadata_type_list_info_location, "IARL")) {
+ subchunkBytesRead = ma_dr_wav__metadata_process_info_text_chunk(pParser, subchunkDataSize, ma_dr_wav_metadata_type_list_info_location);
+ } else if (ma_dr_wav__chunk_matches(allowedMetadataTypes, subchunkId, ma_dr_wav_metadata_type_list_info_organization, "ICMS")) {
+ subchunkBytesRead = ma_dr_wav__metadata_process_info_text_chunk(pParser, subchunkDataSize, ma_dr_wav_metadata_type_list_info_organization);
+ } else if (ma_dr_wav__chunk_matches(allowedMetadataTypes, subchunkId, ma_dr_wav_metadata_type_list_info_keywords, "IKEY")) {
+ subchunkBytesRead = ma_dr_wav__metadata_process_info_text_chunk(pParser, subchunkDataSize, ma_dr_wav_metadata_type_list_info_keywords);
+ } else if (ma_dr_wav__chunk_matches(allowedMetadataTypes, subchunkId, ma_dr_wav_metadata_type_list_info_medium, "IMED")) {
+ subchunkBytesRead = ma_dr_wav__metadata_process_info_text_chunk(pParser, subchunkDataSize, ma_dr_wav_metadata_type_list_info_medium);
+ } else if (ma_dr_wav__chunk_matches(allowedMetadataTypes, subchunkId, ma_dr_wav_metadata_type_list_info_description, "ISBJ")) {
+ subchunkBytesRead = ma_dr_wav__metadata_process_info_text_chunk(pParser, subchunkDataSize, ma_dr_wav_metadata_type_list_info_description);
} else if ((allowedMetadataTypes & ma_dr_wav_metadata_type_unknown) != 0) {
subchunkBytesRead = ma_dr_wav__metadata_process_unknown_chunk(pParser, subchunkId, subchunkDataSize, listType);
}
@@ -79281,13 +80968,13 @@ MA_PRIVATE ma_uint64 ma_dr_wav__metadata_process_chunk(ma_dr_wav__metadata_parse
MA_DR_WAV_ASSERT(subchunkBytesRead <= subchunkDataSize);
if (subchunkBytesRead < subchunkDataSize) {
ma_uint64 bytesToSeek = subchunkDataSize - subchunkBytesRead;
- if (!pParser->onSeek(pParser->pReadSeekUserData, (int)bytesToSeek, ma_dr_wav_seek_origin_current)) {
+ if (!pParser->onSeek(pParser->pReadSeekUserData, (int)bytesToSeek, MA_DR_WAV_SEEK_CUR)) {
break;
}
bytesRead += bytesToSeek;
}
if ((subchunkDataSize % 2) == 1) {
- if (!pParser->onSeek(pParser->pReadSeekUserData, 1, ma_dr_wav_seek_origin_current)) {
+ if (!pParser->onSeek(pParser->pReadSeekUserData, 1, MA_DR_WAV_SEEK_CUR)) {
break;
}
bytesRead += 1;
@@ -79324,7 +81011,7 @@ MA_API ma_uint16 ma_dr_wav_fmt_get_format(const ma_dr_wav_fmt* pFMT)
return ma_dr_wav_bytes_to_u16(pFMT->subFormat);
}
}
-MA_PRIVATE ma_bool32 ma_dr_wav_preinit(ma_dr_wav* pWav, ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, void* pReadSeekUserData, const ma_allocation_callbacks* pAllocationCallbacks)
+MA_PRIVATE ma_bool32 ma_dr_wav_preinit(ma_dr_wav* pWav, ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, ma_dr_wav_tell_proc onTell, void* pReadSeekTellUserData, const ma_allocation_callbacks* pAllocationCallbacks)
{
if (pWav == NULL || onRead == NULL || onSeek == NULL) {
return MA_FALSE;
@@ -79332,7 +81019,8 @@ MA_PRIVATE ma_bool32 ma_dr_wav_preinit(ma_dr_wav* pWav, ma_dr_wav_read_proc onRe
MA_DR_WAV_ZERO_MEMORY(pWav, sizeof(*pWav));
pWav->onRead = onRead;
pWav->onSeek = onSeek;
- pWav->pUserData = pReadSeekUserData;
+ pWav->onTell = onTell;
+ pWav->pUserData = pReadSeekTellUserData;
pWav->allocationCallbacks = ma_dr_wav_copy_allocation_callbacks_or_defaults(pAllocationCallbacks);
if (pWav->allocationCallbacks.onFree == NULL || (pWav->allocationCallbacks.onMalloc == NULL && pWav->allocationCallbacks.onRealloc == NULL)) {
return MA_FALSE;
@@ -79546,14 +81234,14 @@ MA_PRIVATE ma_bool32 ma_dr_wav_init__internal(ma_dr_wav* pWav, ma_dr_wav_chunk_p
fmt.channelMask = ma_dr_wav_bytes_to_u32_ex(fmtext + 2, pWav->container);
ma_dr_wav_bytes_to_guid(fmtext + 6, fmt.subFormat);
} else {
- if (pWav->onSeek(pWav->pUserData, fmt.extendedSize, ma_dr_wav_seek_origin_current) == MA_FALSE) {
+ if (pWav->onSeek(pWav->pUserData, fmt.extendedSize, MA_DR_WAV_SEEK_CUR) == MA_FALSE) {
return MA_FALSE;
}
}
cursor += fmt.extendedSize;
bytesReadSoFar += fmt.extendedSize;
}
- if (pWav->onSeek(pWav->pUserData, (int)(header.sizeInBytes - bytesReadSoFar), ma_dr_wav_seek_origin_current) == MA_FALSE) {
+ if (pWav->onSeek(pWav->pUserData, (int)(header.sizeInBytes - bytesReadSoFar), MA_DR_WAV_SEEK_CUR) == MA_FALSE) {
return MA_FALSE;
}
cursor += (header.sizeInBytes - bytesReadSoFar);
@@ -79704,15 +81392,26 @@ MA_PRIVATE ma_bool32 ma_dr_wav_init__internal(ma_dr_wav* pWav, ma_dr_wav_chunk_p
return MA_FALSE;
}
offset = ma_dr_wav_bytes_to_u32_ex(offsetAndBlockSizeData + 0, pWav->container);
- if (ma_dr_wav__seek_forward(pWav->onSeek, offset, pWav->pUserData) == MA_FALSE) {
- return MA_FALSE;
- }
- cursor += offset;
- pWav->dataChunkDataPos = cursor;
+ pWav->dataChunkDataPos = cursor + offset;
dataChunkSize = chunkSize;
- if (sequential || !isProcessingMetadata) {
- break;
+ if (dataChunkSize > offset) {
+ dataChunkSize -= offset;
} else {
+ dataChunkSize = 0;
+ }
+ if (sequential) {
+ if (foundChunk_fmt) {
+ if (ma_dr_wav__seek_forward(pWav->onSeek, offset, pWav->pUserData) == MA_FALSE) {
+ return MA_FALSE;
+ }
+ cursor += offset;
+ break;
+ } else {
+ return MA_FALSE;
+ }
+ } else {
+ chunkSize += header.paddingSize;
+ chunkSize -= sizeof(offsetAndBlockSizeData);
if (ma_dr_wav__seek_forward(pWav->onSeek, chunkSize, pWav->pUserData) == MA_FALSE) {
break;
}
@@ -79776,6 +81475,17 @@ MA_PRIVATE ma_bool32 ma_dr_wav_init__internal(ma_dr_wav* pWav, ma_dr_wav_chunk_p
pWav->pMetadata = metadataParser.pMetadata;
pWav->metadataCount = metadataParser.metadataCount;
}
+ if (pWav->onTell != NULL && pWav->onSeek != NULL) {
+ if (pWav->onSeek(pWav->pUserData, 0, MA_DR_WAV_SEEK_END) == MA_TRUE) {
+ ma_int64 fileSize;
+ if (pWav->onTell(pWav->pUserData, &fileSize)) {
+ if (dataChunkSize + pWav->dataChunkDataPos > (ma_uint64)fileSize) {
+ dataChunkSize = (ma_uint64)fileSize - pWav->dataChunkDataPos;
+ }
+ }
+ } else {
+ }
+ }
if (dataChunkSize == 0xFFFFFFFF && (pWav->container == ma_dr_wav_container_riff || pWav->container == ma_dr_wav_container_rifx) && pWav->isSequentialWrite == MA_FALSE) {
dataChunkSize = 0;
for (;;) {
@@ -79795,8 +81505,14 @@ MA_PRIVATE ma_bool32 ma_dr_wav_init__internal(ma_dr_wav* pWav, ma_dr_wav_chunk_p
pWav->sampleRate = fmt.sampleRate;
pWav->channels = fmt.channels;
pWav->bitsPerSample = fmt.bitsPerSample;
- pWav->bytesRemaining = dataChunkSize;
pWav->translatedFormatTag = translatedFormatTag;
+ if (!ma_dr_wav__is_compressed_format_tag(translatedFormatTag)) {
+ ma_uint32 bytesPerFrame = ma_dr_wav_get_bytes_per_pcm_frame(pWav);
+ if (bytesPerFrame > 0) {
+ dataChunkSize -= (dataChunkSize % bytesPerFrame);
+ }
+ }
+ pWav->bytesRemaining = dataChunkSize;
pWav->dataChunkDataSize = dataChunkSize;
if (sampleCountFromFactChunk != 0) {
pWav->totalPCMFrameCount = sampleCountFromFactChunk;
@@ -79851,20 +81567,20 @@ MA_PRIVATE ma_bool32 ma_dr_wav_init__internal(ma_dr_wav* pWav, ma_dr_wav_chunk_p
#endif
return MA_TRUE;
}
-MA_API ma_bool32 ma_dr_wav_init(ma_dr_wav* pWav, ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks)
+MA_API ma_bool32 ma_dr_wav_init(ma_dr_wav* pWav, ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, ma_dr_wav_tell_proc onTell, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks)
{
- return ma_dr_wav_init_ex(pWav, onRead, onSeek, NULL, pUserData, NULL, 0, pAllocationCallbacks);
+ return ma_dr_wav_init_ex(pWav, onRead, onSeek, onTell, NULL, pUserData, NULL, 0, pAllocationCallbacks);
}
-MA_API ma_bool32 ma_dr_wav_init_ex(ma_dr_wav* pWav, ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, ma_dr_wav_chunk_proc onChunk, void* pReadSeekUserData, void* pChunkUserData, ma_uint32 flags, const ma_allocation_callbacks* pAllocationCallbacks)
+MA_API ma_bool32 ma_dr_wav_init_ex(ma_dr_wav* pWav, ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, ma_dr_wav_tell_proc onTell, ma_dr_wav_chunk_proc onChunk, void* pReadSeekTellUserData, void* pChunkUserData, ma_uint32 flags, const ma_allocation_callbacks* pAllocationCallbacks)
{
- if (!ma_dr_wav_preinit(pWav, onRead, onSeek, pReadSeekUserData, pAllocationCallbacks)) {
+ if (!ma_dr_wav_preinit(pWav, onRead, onSeek, onTell, pReadSeekTellUserData, pAllocationCallbacks)) {
return MA_FALSE;
}
return ma_dr_wav_init__internal(pWav, onChunk, pChunkUserData, flags);
}
-MA_API ma_bool32 ma_dr_wav_init_with_metadata(ma_dr_wav* pWav, ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, void* pUserData, ma_uint32 flags, const ma_allocation_callbacks* pAllocationCallbacks)
+MA_API ma_bool32 ma_dr_wav_init_with_metadata(ma_dr_wav* pWav, ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, ma_dr_wav_tell_proc onTell, void* pUserData, ma_uint32 flags, const ma_allocation_callbacks* pAllocationCallbacks)
{
- if (!ma_dr_wav_preinit(pWav, onRead, onSeek, pUserData, pAllocationCallbacks)) {
+ if (!ma_dr_wav_preinit(pWav, onRead, onSeek, onTell, pUserData, pAllocationCallbacks)) {
return MA_FALSE;
}
return ma_dr_wav_init__internal(pWav, NULL, NULL, flags | MA_DR_WAV_WITH_METADATA);
@@ -80026,8 +81742,8 @@ MA_PRIVATE size_t ma_dr_wav__write_or_count_metadata(ma_dr_wav* pWav, ma_dr_wav_
for (iLoop = 0; iLoop < pMetadata->data.smpl.sampleLoopCount; ++iLoop) {
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].cuePointId);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].type);
- bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].firstSampleByteOffset);
- bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].lastSampleByteOffset);
+ bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].firstSampleOffset);
+ bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].lastSampleOffset);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].sampleFraction);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].playCount);
}
@@ -80061,7 +81777,7 @@ MA_PRIVATE size_t ma_dr_wav__write_or_count_metadata(ma_dr_wav* pWav, ma_dr_wav_
bytesWritten += ma_dr_wav__write_or_count(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].dataChunkId, 4);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].chunkStart);
bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].blockStart);
- bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].sampleByteOffset);
+ bytesWritten += ma_dr_wav__write_or_count_u32ne_to_le(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].sampleOffset);
}
} break;
case ma_dr_wav_metadata_type_acid:
@@ -80147,15 +81863,20 @@ MA_PRIVATE size_t ma_dr_wav__write_or_count_metadata(ma_dr_wav* pWav, ma_dr_wav_
if (pMetadata->type & ma_dr_wav_metadata_type_list_all_info_strings) {
const char* pID = NULL;
switch (pMetadata->type) {
- case ma_dr_wav_metadata_type_list_info_software: pID = "ISFT"; break;
- case ma_dr_wav_metadata_type_list_info_copyright: pID = "ICOP"; break;
- case ma_dr_wav_metadata_type_list_info_title: pID = "INAM"; break;
- case ma_dr_wav_metadata_type_list_info_artist: pID = "IART"; break;
- case ma_dr_wav_metadata_type_list_info_comment: pID = "ICMT"; break;
- case ma_dr_wav_metadata_type_list_info_date: pID = "ICRD"; break;
- case ma_dr_wav_metadata_type_list_info_genre: pID = "IGNR"; break;
- case ma_dr_wav_metadata_type_list_info_album: pID = "IPRD"; break;
- case ma_dr_wav_metadata_type_list_info_tracknumber: pID = "ITRK"; break;
+ case ma_dr_wav_metadata_type_list_info_software: pID = "ISFT"; break;
+ case ma_dr_wav_metadata_type_list_info_copyright: pID = "ICOP"; break;
+ case ma_dr_wav_metadata_type_list_info_title: pID = "INAM"; break;
+ case ma_dr_wav_metadata_type_list_info_artist: pID = "IART"; break;
+ case ma_dr_wav_metadata_type_list_info_comment: pID = "ICMT"; break;
+ case ma_dr_wav_metadata_type_list_info_date: pID = "ICRD"; break;
+ case ma_dr_wav_metadata_type_list_info_genre: pID = "IGNR"; break;
+ case ma_dr_wav_metadata_type_list_info_album: pID = "IPRD"; break;
+ case ma_dr_wav_metadata_type_list_info_tracknumber: pID = "ITRK"; break;
+ case ma_dr_wav_metadata_type_list_info_location: pID = "IARL"; break;
+ case ma_dr_wav_metadata_type_list_info_organization: pID = "ICMS"; break;
+ case ma_dr_wav_metadata_type_list_info_keywords: pID = "IKEY"; break;
+ case ma_dr_wav_metadata_type_list_info_medium: pID = "IMED"; break;
+ case ma_dr_wav_metadata_type_list_info_description: pID = "ISBJ"; break;
default: break;
}
MA_DR_WAV_ASSERT(pID != NULL);
@@ -80370,7 +82091,7 @@ MA_PRIVATE ma_bool32 ma_dr_wav_init_write__internal(ma_dr_wav* pWav, const ma_dr
}
pWav->dataChunkDataSizeTargetWrite = initialDataChunkSize;
if (pFormat->container == ma_dr_wav_container_riff) {
- ma_uint32 chunkSizeRIFF = 28 + (ma_uint32)initialDataChunkSize;
+ ma_uint32 chunkSizeRIFF = 36 + (ma_uint32)initialDataChunkSize;
runningPos += ma_dr_wav__write(pWav, "RIFF", 4);
runningPos += ma_dr_wav__write_u32ne_to_le(pWav, chunkSizeRIFF);
runningPos += ma_dr_wav__write(pWav, "WAVE", 4);
@@ -80493,7 +82214,31 @@ MA_PRIVATE size_t ma_dr_wav__on_write_stdio(void* pUserData, const void* pData,
}
MA_PRIVATE ma_bool32 ma_dr_wav__on_seek_stdio(void* pUserData, int offset, ma_dr_wav_seek_origin origin)
{
- return fseek((FILE*)pUserData, offset, (origin == ma_dr_wav_seek_origin_current) ? SEEK_CUR : SEEK_SET) == 0;
+ int whence = SEEK_SET;
+ if (origin == MA_DR_WAV_SEEK_CUR) {
+ whence = SEEK_CUR;
+ } else if (origin == MA_DR_WAV_SEEK_END) {
+ whence = SEEK_END;
+ }
+ return fseek((FILE*)pUserData, offset, whence) == 0;
+}
+MA_PRIVATE ma_bool32 ma_dr_wav__on_tell_stdio(void* pUserData, ma_int64* pCursor)
+{
+ FILE* pFileStdio = (FILE*)pUserData;
+ ma_int64 result;
+ MA_DR_WAV_ASSERT(pFileStdio != NULL);
+ MA_DR_WAV_ASSERT(pCursor != NULL);
+#if defined(_WIN32) && !defined(NXDK)
+ #if defined(_MSC_VER) && _MSC_VER > 1200
+ result = _ftelli64(pFileStdio);
+ #else
+ result = ftell(pFileStdio);
+ #endif
+#else
+ result = ftell(pFileStdio);
+#endif
+ *pCursor = result;
+ return MA_TRUE;
}
MA_API ma_bool32 ma_dr_wav_init_file(ma_dr_wav* pWav, const char* filename, const ma_allocation_callbacks* pAllocationCallbacks)
{
@@ -80502,7 +82247,7 @@ MA_API ma_bool32 ma_dr_wav_init_file(ma_dr_wav* pWav, const char* filename, cons
MA_PRIVATE ma_bool32 ma_dr_wav_init_file__internal_FILE(ma_dr_wav* pWav, FILE* pFile, ma_dr_wav_chunk_proc onChunk, void* pChunkUserData, ma_uint32 flags, const ma_allocation_callbacks* pAllocationCallbacks)
{
ma_bool32 result;
- result = ma_dr_wav_preinit(pWav, ma_dr_wav__on_read_stdio, ma_dr_wav__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
+ result = ma_dr_wav_preinit(pWav, ma_dr_wav__on_read_stdio, ma_dr_wav__on_seek_stdio, ma_dr_wav__on_tell_stdio, (void*)pFile, pAllocationCallbacks);
if (result != MA_TRUE) {
fclose(pFile);
return result;
@@ -80639,25 +82384,27 @@ MA_PRIVATE size_t ma_dr_wav__on_read_memory(void* pUserData, void* pBufferOut, s
MA_PRIVATE ma_bool32 ma_dr_wav__on_seek_memory(void* pUserData, int offset, ma_dr_wav_seek_origin origin)
{
ma_dr_wav* pWav = (ma_dr_wav*)pUserData;
+ ma_int64 newCursor;
MA_DR_WAV_ASSERT(pWav != NULL);
- if (origin == ma_dr_wav_seek_origin_current) {
- if (offset > 0) {
- if (pWav->memoryStream.currentReadPos + offset > pWav->memoryStream.dataSize) {
- return MA_FALSE;
- }
- } else {
- if (pWav->memoryStream.currentReadPos < (size_t)-offset) {
- return MA_FALSE;
- }
- }
- pWav->memoryStream.currentReadPos += offset;
+ newCursor = pWav->memoryStream.currentReadPos;
+ if (origin == MA_DR_WAV_SEEK_SET) {
+ newCursor = 0;
+ } else if (origin == MA_DR_WAV_SEEK_CUR) {
+ newCursor = (ma_int64)pWav->memoryStream.currentReadPos;
+ } else if (origin == MA_DR_WAV_SEEK_END) {
+ newCursor = (ma_int64)pWav->memoryStream.dataSize;
} else {
- if ((ma_uint32)offset <= pWav->memoryStream.dataSize) {
- pWav->memoryStream.currentReadPos = offset;
- } else {
- return MA_FALSE;
- }
+ MA_DR_WAV_ASSERT(!"Invalid seek origin");
+ return MA_FALSE;
}
+ newCursor += offset;
+ if (newCursor < 0) {
+ return MA_FALSE;
+ }
+ if ((size_t)newCursor > pWav->memoryStream.dataSize) {
+ return MA_FALSE;
+ }
+ pWav->memoryStream.currentReadPos = (size_t)newCursor;
return MA_TRUE;
}
MA_PRIVATE size_t ma_dr_wav__on_write_memory(void* pUserData, const void* pDataIn, size_t bytesToWrite)
@@ -80691,25 +82438,35 @@ MA_PRIVATE size_t ma_dr_wav__on_write_memory(void* pUserData, const void* pDataI
MA_PRIVATE ma_bool32 ma_dr_wav__on_seek_memory_write(void* pUserData, int offset, ma_dr_wav_seek_origin origin)
{
ma_dr_wav* pWav = (ma_dr_wav*)pUserData;
+ ma_int64 newCursor;
MA_DR_WAV_ASSERT(pWav != NULL);
- if (origin == ma_dr_wav_seek_origin_current) {
- if (offset > 0) {
- if (pWav->memoryStreamWrite.currentWritePos + offset > pWav->memoryStreamWrite.dataSize) {
- offset = (int)(pWav->memoryStreamWrite.dataSize - pWav->memoryStreamWrite.currentWritePos);
- }
- } else {
- if (pWav->memoryStreamWrite.currentWritePos < (size_t)-offset) {
- offset = -(int)pWav->memoryStreamWrite.currentWritePos;
- }
- }
- pWav->memoryStreamWrite.currentWritePos += offset;
+ newCursor = pWav->memoryStreamWrite.currentWritePos;
+ if (origin == MA_DR_WAV_SEEK_SET) {
+ newCursor = 0;
+ } else if (origin == MA_DR_WAV_SEEK_CUR) {
+ newCursor = (ma_int64)pWav->memoryStreamWrite.currentWritePos;
+ } else if (origin == MA_DR_WAV_SEEK_END) {
+ newCursor = (ma_int64)pWav->memoryStreamWrite.dataSize;
} else {
- if ((ma_uint32)offset <= pWav->memoryStreamWrite.dataSize) {
- pWav->memoryStreamWrite.currentWritePos = offset;
- } else {
- pWav->memoryStreamWrite.currentWritePos = pWav->memoryStreamWrite.dataSize;
- }
+ MA_DR_WAV_ASSERT(!"Invalid seek origin");
+ return MA_INVALID_ARGS;
}
+ newCursor += offset;
+ if (newCursor < 0) {
+ return MA_FALSE;
+ }
+ if ((size_t)newCursor > pWav->memoryStreamWrite.dataSize) {
+ return MA_FALSE;
+ }
+ pWav->memoryStreamWrite.currentWritePos = (size_t)newCursor;
+ return MA_TRUE;
+}
+MA_PRIVATE ma_bool32 ma_dr_wav__on_tell_memory(void* pUserData, ma_int64* pCursor)
+{
+ ma_dr_wav* pWav = (ma_dr_wav*)pUserData;
+ MA_DR_WAV_ASSERT(pWav != NULL);
+ MA_DR_WAV_ASSERT(pCursor != NULL);
+ *pCursor = (ma_int64)pWav->memoryStream.currentReadPos;
return MA_TRUE;
}
MA_API ma_bool32 ma_dr_wav_init_memory(ma_dr_wav* pWav, const void* data, size_t dataSize, const ma_allocation_callbacks* pAllocationCallbacks)
@@ -80721,7 +82478,7 @@ MA_API ma_bool32 ma_dr_wav_init_memory_ex(ma_dr_wav* pWav, const void* data, siz
if (data == NULL || dataSize == 0) {
return MA_FALSE;
}
- if (!ma_dr_wav_preinit(pWav, ma_dr_wav__on_read_memory, ma_dr_wav__on_seek_memory, pWav, pAllocationCallbacks)) {
+ if (!ma_dr_wav_preinit(pWav, ma_dr_wav__on_read_memory, ma_dr_wav__on_seek_memory, ma_dr_wav__on_tell_memory, pWav, pAllocationCallbacks)) {
return MA_FALSE;
}
pWav->memoryStream.data = (const ma_uint8*)data;
@@ -80734,7 +82491,7 @@ MA_API ma_bool32 ma_dr_wav_init_memory_with_metadata(ma_dr_wav* pWav, const void
if (data == NULL || dataSize == 0) {
return MA_FALSE;
}
- if (!ma_dr_wav_preinit(pWav, ma_dr_wav__on_read_memory, ma_dr_wav__on_seek_memory, pWav, pAllocationCallbacks)) {
+ if (!ma_dr_wav_preinit(pWav, ma_dr_wav__on_read_memory, ma_dr_wav__on_seek_memory, ma_dr_wav__on_tell_memory, pWav, pAllocationCallbacks)) {
return MA_FALSE;
}
pWav->memoryStream.data = (const ma_uint8*)data;
@@ -80793,30 +82550,30 @@ MA_API ma_result ma_dr_wav_uninit(ma_dr_wav* pWav)
}
if (pWav->onSeek && !pWav->isSequentialWrite) {
if (pWav->container == ma_dr_wav_container_riff) {
- if (pWav->onSeek(pWav->pUserData, 4, ma_dr_wav_seek_origin_start)) {
+ if (pWav->onSeek(pWav->pUserData, 4, MA_DR_WAV_SEEK_SET)) {
ma_uint32 riffChunkSize = ma_dr_wav__riff_chunk_size_riff(pWav->dataChunkDataSize, pWav->pMetadata, pWav->metadataCount);
ma_dr_wav__write_u32ne_to_le(pWav, riffChunkSize);
}
- if (pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos - 4, ma_dr_wav_seek_origin_start)) {
+ if (pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos - 4, MA_DR_WAV_SEEK_SET)) {
ma_uint32 dataChunkSize = ma_dr_wav__data_chunk_size_riff(pWav->dataChunkDataSize);
ma_dr_wav__write_u32ne_to_le(pWav, dataChunkSize);
}
} else if (pWav->container == ma_dr_wav_container_w64) {
- if (pWav->onSeek(pWav->pUserData, 16, ma_dr_wav_seek_origin_start)) {
+ if (pWav->onSeek(pWav->pUserData, 16, MA_DR_WAV_SEEK_SET)) {
ma_uint64 riffChunkSize = ma_dr_wav__riff_chunk_size_w64(pWav->dataChunkDataSize);
ma_dr_wav__write_u64ne_to_le(pWav, riffChunkSize);
}
- if (pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos - 8, ma_dr_wav_seek_origin_start)) {
+ if (pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos - 8, MA_DR_WAV_SEEK_SET)) {
ma_uint64 dataChunkSize = ma_dr_wav__data_chunk_size_w64(pWav->dataChunkDataSize);
ma_dr_wav__write_u64ne_to_le(pWav, dataChunkSize);
}
} else if (pWav->container == ma_dr_wav_container_rf64) {
int ds64BodyPos = 12 + 8;
- if (pWav->onSeek(pWav->pUserData, ds64BodyPos + 0, ma_dr_wav_seek_origin_start)) {
+ if (pWav->onSeek(pWav->pUserData, ds64BodyPos + 0, MA_DR_WAV_SEEK_SET)) {
ma_uint64 riffChunkSize = ma_dr_wav__riff_chunk_size_rf64(pWav->dataChunkDataSize, pWav->pMetadata, pWav->metadataCount);
ma_dr_wav__write_u64ne_to_le(pWav, riffChunkSize);
}
- if (pWav->onSeek(pWav->pUserData, ds64BodyPos + 8, ma_dr_wav_seek_origin_start)) {
+ if (pWav->onSeek(pWav->pUserData, ds64BodyPos + 8, MA_DR_WAV_SEEK_SET)) {
ma_uint64 dataChunkSize = ma_dr_wav__data_chunk_size_rf64(pWav->dataChunkDataSize);
ma_dr_wav__write_u64ne_to_le(pWav, dataChunkSize);
}
@@ -80863,7 +82620,7 @@ MA_API size_t ma_dr_wav_read_raw(ma_dr_wav* pWav, size_t bytesToRead, void* pBuf
if (bytesToSeek > 0x7FFFFFFF) {
bytesToSeek = 0x7FFFFFFF;
}
- if (pWav->onSeek(pWav->pUserData, (int)bytesToSeek, ma_dr_wav_seek_origin_current) == MA_FALSE) {
+ if (pWav->onSeek(pWav->pUserData, (int)bytesToSeek, MA_DR_WAV_SEEK_CUR) == MA_FALSE) {
break;
}
bytesRead += bytesToSeek;
@@ -80962,7 +82719,7 @@ MA_PRIVATE ma_bool32 ma_dr_wav_seek_to_first_pcm_frame(ma_dr_wav* pWav)
if (pWav->onWrite != NULL) {
return MA_FALSE;
}
- if (!pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos, ma_dr_wav_seek_origin_start)) {
+ if (!pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos, MA_DR_WAV_SEEK_SET)) {
return MA_FALSE;
}
if (ma_dr_wav__is_compressed_format_tag(pWav->translatedFormatTag)) {
@@ -81043,7 +82800,7 @@ MA_API ma_bool32 ma_dr_wav_seek_to_pcm_frame(ma_dr_wav* pWav, ma_uint64 targetFr
}
while (offset > 0) {
int offset32 = ((offset > INT_MAX) ? INT_MAX : (int)offset);
- if (!pWav->onSeek(pWav->pUserData, offset32, ma_dr_wav_seek_origin_current)) {
+ if (!pWav->onSeek(pWav->pUserData, offset32, MA_DR_WAV_SEEK_CUR)) {
return MA_FALSE;
}
pWav->readCursorInPCMFrames += offset32 / bytesPerFrame;
@@ -81169,12 +82926,12 @@ MA_API ma_uint64 ma_dr_wav_write_pcm_frames(ma_dr_wav* pWav, ma_uint64 framesToW
MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s16__msadpcm(ma_dr_wav* pWav, ma_uint64 framesToRead, ma_int16* pBufferOut)
{
ma_uint64 totalFramesRead = 0;
- static ma_int32 adaptationTable[] = {
+ static const ma_int32 adaptationTable[] = {
230, 230, 230, 230, 307, 409, 512, 614,
768, 614, 512, 409, 307, 230, 230, 230
};
- static ma_int32 coeff1Table[] = { 256, 512, 0, 192, 240, 460, 392 };
- static ma_int32 coeff2Table[] = { 0, -256, 0, 64, 0, -208, -232 };
+ static const ma_int32 coeff1Table[] = { 256, 512, 0, 192, 240, 460, 392 };
+ static const ma_int32 coeff2Table[] = { 0, -256, 0, 64, 0, -208, -232 };
MA_DR_WAV_ASSERT(pWav != NULL);
MA_DR_WAV_ASSERT(framesToRead > 0);
while (pWav->readCursorInPCMFrames < pWav->totalPCMFrameCount) {
@@ -81307,11 +83064,11 @@ MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s16__ima(ma_dr_wav* pWav, ma_uint
{
ma_uint64 totalFramesRead = 0;
ma_uint32 iChannel;
- static ma_int32 indexTable[16] = {
+ static const ma_int32 indexTable[16] = {
-1, -1, -1, -1, 2, 4, 6, 8,
-1, -1, -1, -1, 2, 4, 6, 8
};
- static ma_int32 stepTable[89] = {
+ static const ma_int32 stepTable[89] = {
7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
@@ -81334,7 +83091,7 @@ MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s16__ima(ma_dr_wav* pWav, ma_uint
}
pWav->ima.bytesRemainingInBlock = pWav->fmt.blockAlign - sizeof(header);
if (header[2] >= ma_dr_wav_countof(stepTable)) {
- pWav->onSeek(pWav->pUserData, pWav->ima.bytesRemainingInBlock, ma_dr_wav_seek_origin_current);
+ pWav->onSeek(pWav->pUserData, pWav->ima.bytesRemainingInBlock, MA_DR_WAV_SEEK_CUR);
pWav->ima.bytesRemainingInBlock = 0;
return totalFramesRead;
}
@@ -81349,7 +83106,7 @@ MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s16__ima(ma_dr_wav* pWav, ma_uint
}
pWav->ima.bytesRemainingInBlock = pWav->fmt.blockAlign - sizeof(header);
if (header[2] >= ma_dr_wav_countof(stepTable) || header[6] >= ma_dr_wav_countof(stepTable)) {
- pWav->onSeek(pWav->pUserData, pWav->ima.bytesRemainingInBlock, ma_dr_wav_seek_origin_current);
+ pWav->onSeek(pWav->pUserData, pWav->ima.bytesRemainingInBlock, MA_DR_WAV_SEEK_CUR);
pWav->ima.bytesRemainingInBlock = 0;
return totalFramesRead;
}
@@ -81424,7 +83181,7 @@ MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s16__ima(ma_dr_wav* pWav, ma_uint
return totalFramesRead;
}
#ifndef MA_DR_WAV_NO_CONVERSION_API
-static unsigned short g_ma_dr_wavAlawTable[256] = {
+static const unsigned short ma_dr_wav_gAlawTable[256] = {
0xEA80, 0xEB80, 0xE880, 0xE980, 0xEE80, 0xEF80, 0xEC80, 0xED80, 0xE280, 0xE380, 0xE080, 0xE180, 0xE680, 0xE780, 0xE480, 0xE580,
0xF540, 0xF5C0, 0xF440, 0xF4C0, 0xF740, 0xF7C0, 0xF640, 0xF6C0, 0xF140, 0xF1C0, 0xF040, 0xF0C0, 0xF340, 0xF3C0, 0xF240, 0xF2C0,
0xAA00, 0xAE00, 0xA200, 0xA600, 0xBA00, 0xBE00, 0xB200, 0xB600, 0x8A00, 0x8E00, 0x8200, 0x8600, 0x9A00, 0x9E00, 0x9200, 0x9600,
@@ -81442,7 +83199,7 @@ static unsigned short g_ma_dr_wavAlawTable[256] = {
0x0560, 0x0520, 0x05E0, 0x05A0, 0x0460, 0x0420, 0x04E0, 0x04A0, 0x0760, 0x0720, 0x07E0, 0x07A0, 0x0660, 0x0620, 0x06E0, 0x06A0,
0x02B0, 0x0290, 0x02F0, 0x02D0, 0x0230, 0x0210, 0x0270, 0x0250, 0x03B0, 0x0390, 0x03F0, 0x03D0, 0x0330, 0x0310, 0x0370, 0x0350
};
-static unsigned short g_ma_dr_wavMulawTable[256] = {
+static const unsigned short ma_dr_wav_gMulawTable[256] = {
0x8284, 0x8684, 0x8A84, 0x8E84, 0x9284, 0x9684, 0x9A84, 0x9E84, 0xA284, 0xA684, 0xAA84, 0xAE84, 0xB284, 0xB684, 0xBA84, 0xBE84,
0xC184, 0xC384, 0xC584, 0xC784, 0xC984, 0xCB84, 0xCD84, 0xCF84, 0xD184, 0xD384, 0xD584, 0xD784, 0xD984, 0xDB84, 0xDD84, 0xDF84,
0xE104, 0xE204, 0xE304, 0xE404, 0xE504, 0xE604, 0xE704, 0xE804, 0xE904, 0xEA04, 0xEB04, 0xEC04, 0xED04, 0xEE04, 0xEF04, 0xF004,
@@ -81462,11 +83219,11 @@ static unsigned short g_ma_dr_wavMulawTable[256] = {
};
static MA_INLINE ma_int16 ma_dr_wav__alaw_to_s16(ma_uint8 sampleIn)
{
- return (short)g_ma_dr_wavAlawTable[sampleIn];
+ return (short)ma_dr_wav_gAlawTable[sampleIn];
}
static MA_INLINE ma_int16 ma_dr_wav__mulaw_to_s16(ma_uint8 sampleIn)
{
- return (short)g_ma_dr_wavMulawTable[sampleIn];
+ return (short)ma_dr_wav_gMulawTable[sampleIn];
}
MA_PRIVATE void ma_dr_wav__pcm_to_s16(ma_int16* pOut, const ma_uint8* pIn, size_t totalSampleCount, unsigned int bytesPerSample)
{
@@ -82625,7 +84382,7 @@ MA_PRIVATE ma_int32* ma_dr_wav__read_pcm_frames_and_close_s32(ma_dr_wav* pWav, u
}
return pSampleData;
}
-MA_API ma_int16* ma_dr_wav_open_and_read_pcm_frames_s16(ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks)
+MA_API ma_int16* ma_dr_wav_open_and_read_pcm_frames_s16(ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, ma_dr_wav_tell_proc onTell, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks)
{
ma_dr_wav wav;
if (channelsOut) {
@@ -82637,12 +84394,12 @@ MA_API ma_int16* ma_dr_wav_open_and_read_pcm_frames_s16(ma_dr_wav_read_proc onRe
if (totalFrameCountOut) {
*totalFrameCountOut = 0;
}
- if (!ma_dr_wav_init(&wav, onRead, onSeek, pUserData, pAllocationCallbacks)) {
+ if (!ma_dr_wav_init(&wav, onRead, onSeek, onTell, pUserData, pAllocationCallbacks)) {
return NULL;
}
return ma_dr_wav__read_pcm_frames_and_close_s16(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
}
-MA_API float* ma_dr_wav_open_and_read_pcm_frames_f32(ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks)
+MA_API float* ma_dr_wav_open_and_read_pcm_frames_f32(ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, ma_dr_wav_tell_proc onTell, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks)
{
ma_dr_wav wav;
if (channelsOut) {
@@ -82654,12 +84411,12 @@ MA_API float* ma_dr_wav_open_and_read_pcm_frames_f32(ma_dr_wav_read_proc onRead,
if (totalFrameCountOut) {
*totalFrameCountOut = 0;
}
- if (!ma_dr_wav_init(&wav, onRead, onSeek, pUserData, pAllocationCallbacks)) {
+ if (!ma_dr_wav_init(&wav, onRead, onSeek, onTell, pUserData, pAllocationCallbacks)) {
return NULL;
}
return ma_dr_wav__read_pcm_frames_and_close_f32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
}
-MA_API ma_int32* ma_dr_wav_open_and_read_pcm_frames_s32(ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks)
+MA_API ma_int32* ma_dr_wav_open_and_read_pcm_frames_s32(ma_dr_wav_read_proc onRead, ma_dr_wav_seek_proc onSeek, ma_dr_wav_tell_proc onTell, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks)
{
ma_dr_wav wav;
if (channelsOut) {
@@ -82671,7 +84428,7 @@ MA_API ma_int32* ma_dr_wav_open_and_read_pcm_frames_s32(ma_dr_wav_read_proc onRe
if (totalFrameCountOut) {
*totalFrameCountOut = 0;
}
- if (!ma_dr_wav_init(&wav, onRead, onSeek, pUserData, pAllocationCallbacks)) {
+ if (!ma_dr_wav_init(&wav, onRead, onSeek, onTell, pUserData, pAllocationCallbacks)) {
return NULL;
}
return ma_dr_wav__read_pcm_frames_and_close_s32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
@@ -84106,23 +85863,23 @@ static ma_bool32 ma_dr_flac__seek_to_byte(ma_dr_flac_bs* bs, ma_uint64 offsetFro
MA_DR_FLAC_ASSERT(offsetFromStart > 0);
if (offsetFromStart > 0x7FFFFFFF) {
ma_uint64 bytesRemaining = offsetFromStart;
- if (!bs->onSeek(bs->pUserData, 0x7FFFFFFF, ma_dr_flac_seek_origin_start)) {
+ if (!bs->onSeek(bs->pUserData, 0x7FFFFFFF, MA_DR_FLAC_SEEK_SET)) {
return MA_FALSE;
}
bytesRemaining -= 0x7FFFFFFF;
while (bytesRemaining > 0x7FFFFFFF) {
- if (!bs->onSeek(bs->pUserData, 0x7FFFFFFF, ma_dr_flac_seek_origin_current)) {
+ if (!bs->onSeek(bs->pUserData, 0x7FFFFFFF, MA_DR_FLAC_SEEK_CUR)) {
return MA_FALSE;
}
bytesRemaining -= 0x7FFFFFFF;
}
if (bytesRemaining > 0) {
- if (!bs->onSeek(bs->pUserData, (int)bytesRemaining, ma_dr_flac_seek_origin_current)) {
+ if (!bs->onSeek(bs->pUserData, (int)bytesRemaining, MA_DR_FLAC_SEEK_CUR)) {
return MA_FALSE;
}
}
} else {
- if (!bs->onSeek(bs->pUserData, (int)offsetFromStart, ma_dr_flac_seek_origin_start)) {
+ if (!bs->onSeek(bs->pUserData, (int)offsetFromStart, MA_DR_FLAC_SEEK_SET)) {
return MA_FALSE;
}
}
@@ -86600,6 +88357,7 @@ typedef struct
{
ma_dr_flac_read_proc onRead;
ma_dr_flac_seek_proc onSeek;
+ ma_dr_flac_tell_proc onTell;
ma_dr_flac_meta_proc onMeta;
ma_dr_flac_container container;
void* pUserData;
@@ -86728,11 +88486,12 @@ static void ma_dr_flac__free_from_callbacks(void* p, const ma_allocation_callbac
pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData);
}
}
-static ma_bool32 ma_dr_flac__read_and_decode_metadata(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_meta_proc onMeta, void* pUserData, void* pUserDataMD, ma_uint64* pFirstFramePos, ma_uint64* pSeektablePos, ma_uint32* pSeekpointCount, ma_allocation_callbacks* pAllocationCallbacks)
+static ma_bool32 ma_dr_flac__read_and_decode_metadata(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_tell_proc onTell, ma_dr_flac_meta_proc onMeta, void* pUserData, void* pUserDataMD, ma_uint64* pFirstFramePos, ma_uint64* pSeektablePos, ma_uint32* pSeekpointCount, ma_allocation_callbacks* pAllocationCallbacks)
{
ma_uint64 runningFilePos = 42;
ma_uint64 seektablePos = 0;
ma_uint32 seektableSize = 0;
+ (void)onTell;
for (;;) {
ma_dr_flac_metadata metadata;
ma_uint8 isLastBlock = 0;
@@ -86990,7 +88749,7 @@ static ma_bool32 ma_dr_flac__read_and_decode_metadata(ma_dr_flac_read_proc onRea
{
if (onMeta) {
metadata.data.padding.unused = 0;
- if (!onSeek(pUserData, blockSize, ma_dr_flac_seek_origin_current)) {
+ if (!onSeek(pUserData, blockSize, MA_DR_FLAC_SEEK_CUR)) {
isLastBlock = MA_TRUE;
} else {
onMeta(pUserDataMD, &metadata);
@@ -87000,7 +88759,7 @@ static ma_bool32 ma_dr_flac__read_and_decode_metadata(ma_dr_flac_read_proc onRea
case MA_DR_FLAC_METADATA_BLOCK_TYPE_INVALID:
{
if (onMeta) {
- if (!onSeek(pUserData, blockSize, ma_dr_flac_seek_origin_current)) {
+ if (!onSeek(pUserData, blockSize, MA_DR_FLAC_SEEK_CUR)) {
isLastBlock = MA_TRUE;
}
}
@@ -87024,7 +88783,7 @@ static ma_bool32 ma_dr_flac__read_and_decode_metadata(ma_dr_flac_read_proc onRea
} break;
}
if (onMeta == NULL && blockSize > 0) {
- if (!onSeek(pUserData, blockSize, ma_dr_flac_seek_origin_current)) {
+ if (!onSeek(pUserData, blockSize, MA_DR_FLAC_SEEK_CUR)) {
isLastBlock = MA_TRUE;
}
}
@@ -87288,6 +89047,7 @@ typedef struct
{
ma_dr_flac_read_proc onRead;
ma_dr_flac_seek_proc onSeek;
+ ma_dr_flac_tell_proc onTell;
void* pUserData;
ma_uint64 currentBytePos;
ma_uint64 firstBytePos;
@@ -87306,29 +89066,29 @@ static size_t ma_dr_flac_oggbs__read_physical(ma_dr_flac_oggbs* oggbs, void* buf
}
static ma_bool32 ma_dr_flac_oggbs__seek_physical(ma_dr_flac_oggbs* oggbs, ma_uint64 offset, ma_dr_flac_seek_origin origin)
{
- if (origin == ma_dr_flac_seek_origin_start) {
+ if (origin == MA_DR_FLAC_SEEK_SET) {
if (offset <= 0x7FFFFFFF) {
- if (!oggbs->onSeek(oggbs->pUserData, (int)offset, ma_dr_flac_seek_origin_start)) {
+ if (!oggbs->onSeek(oggbs->pUserData, (int)offset, MA_DR_FLAC_SEEK_SET)) {
return MA_FALSE;
}
oggbs->currentBytePos = offset;
return MA_TRUE;
} else {
- if (!oggbs->onSeek(oggbs->pUserData, 0x7FFFFFFF, ma_dr_flac_seek_origin_start)) {
+ if (!oggbs->onSeek(oggbs->pUserData, 0x7FFFFFFF, MA_DR_FLAC_SEEK_SET)) {
return MA_FALSE;
}
oggbs->currentBytePos = offset;
- return ma_dr_flac_oggbs__seek_physical(oggbs, offset - 0x7FFFFFFF, ma_dr_flac_seek_origin_current);
+ return ma_dr_flac_oggbs__seek_physical(oggbs, offset - 0x7FFFFFFF, MA_DR_FLAC_SEEK_CUR);
}
} else {
while (offset > 0x7FFFFFFF) {
- if (!oggbs->onSeek(oggbs->pUserData, 0x7FFFFFFF, ma_dr_flac_seek_origin_current)) {
+ if (!oggbs->onSeek(oggbs->pUserData, 0x7FFFFFFF, MA_DR_FLAC_SEEK_CUR)) {
return MA_FALSE;
}
oggbs->currentBytePos += 0x7FFFFFFF;
offset -= 0x7FFFFFFF;
}
- if (!oggbs->onSeek(oggbs->pUserData, (int)offset, ma_dr_flac_seek_origin_current)) {
+ if (!oggbs->onSeek(oggbs->pUserData, (int)offset, MA_DR_FLAC_SEEK_CUR)) {
return MA_FALSE;
}
oggbs->currentBytePos += offset;
@@ -87354,7 +89114,7 @@ static ma_bool32 ma_dr_flac_oggbs__goto_next_page(ma_dr_flac_oggbs* oggbs, ma_dr
continue;
}
if (header.serialNumber != oggbs->serialNumber) {
- if (pageBodySize > 0 && !ma_dr_flac_oggbs__seek_physical(oggbs, pageBodySize, ma_dr_flac_seek_origin_current)) {
+ if (pageBodySize > 0 && !ma_dr_flac_oggbs__seek_physical(oggbs, pageBodySize, MA_DR_FLAC_SEEK_CUR)) {
return MA_FALSE;
}
continue;
@@ -87416,7 +89176,7 @@ static ma_bool32 ma_dr_flac_oggbs__seek_to_next_packet(ma_dr_flac_oggbs* oggbs)
}
bytesToEndOfPacketOrPage += segmentSize;
}
- ma_dr_flac_oggbs__seek_physical(oggbs, bytesToEndOfPacketOrPage, ma_dr_flac_seek_origin_current);
+ ma_dr_flac_oggbs__seek_physical(oggbs, bytesToEndOfPacketOrPage, MA_DR_FLAC_SEEK_CUR);
oggbs->bytesRemainingInPage -= bytesToEndOfPacketOrPage;
if (atEndOfPage) {
if (!ma_dr_flac_oggbs__goto_next_page(oggbs)) {
@@ -87469,36 +89229,44 @@ static ma_bool32 ma_dr_flac__on_seek_ogg(void* pUserData, int offset, ma_dr_flac
int bytesSeeked = 0;
MA_DR_FLAC_ASSERT(oggbs != NULL);
MA_DR_FLAC_ASSERT(offset >= 0);
- if (origin == ma_dr_flac_seek_origin_start) {
- if (!ma_dr_flac_oggbs__seek_physical(oggbs, (int)oggbs->firstBytePos, ma_dr_flac_seek_origin_start)) {
+ if (origin == MA_DR_FLAC_SEEK_SET) {
+ if (!ma_dr_flac_oggbs__seek_physical(oggbs, (int)oggbs->firstBytePos, MA_DR_FLAC_SEEK_SET)) {
return MA_FALSE;
}
if (!ma_dr_flac_oggbs__goto_next_page(oggbs, ma_dr_flac_ogg_fail_on_crc_mismatch)) {
return MA_FALSE;
}
- return ma_dr_flac__on_seek_ogg(pUserData, offset, ma_dr_flac_seek_origin_current);
- }
- MA_DR_FLAC_ASSERT(origin == ma_dr_flac_seek_origin_current);
- while (bytesSeeked < offset) {
- int bytesRemainingToSeek = offset - bytesSeeked;
- MA_DR_FLAC_ASSERT(bytesRemainingToSeek >= 0);
- if (oggbs->bytesRemainingInPage >= (size_t)bytesRemainingToSeek) {
- bytesSeeked += bytesRemainingToSeek;
- (void)bytesSeeked;
- oggbs->bytesRemainingInPage -= bytesRemainingToSeek;
- break;
- }
- if (oggbs->bytesRemainingInPage > 0) {
- bytesSeeked += (int)oggbs->bytesRemainingInPage;
- oggbs->bytesRemainingInPage = 0;
- }
- MA_DR_FLAC_ASSERT(bytesRemainingToSeek > 0);
- if (!ma_dr_flac_oggbs__goto_next_page(oggbs, ma_dr_flac_ogg_fail_on_crc_mismatch)) {
- return MA_FALSE;
+ return ma_dr_flac__on_seek_ogg(pUserData, offset, MA_DR_FLAC_SEEK_CUR);
+ } else if (origin == MA_DR_FLAC_SEEK_CUR) {
+ while (bytesSeeked < offset) {
+ int bytesRemainingToSeek = offset - bytesSeeked;
+ MA_DR_FLAC_ASSERT(bytesRemainingToSeek >= 0);
+ if (oggbs->bytesRemainingInPage >= (size_t)bytesRemainingToSeek) {
+ bytesSeeked += bytesRemainingToSeek;
+ (void)bytesSeeked;
+ oggbs->bytesRemainingInPage -= bytesRemainingToSeek;
+ break;
+ }
+ if (oggbs->bytesRemainingInPage > 0) {
+ bytesSeeked += (int)oggbs->bytesRemainingInPage;
+ oggbs->bytesRemainingInPage = 0;
+ }
+ MA_DR_FLAC_ASSERT(bytesRemainingToSeek > 0);
+ if (!ma_dr_flac_oggbs__goto_next_page(oggbs, ma_dr_flac_ogg_fail_on_crc_mismatch)) {
+ return MA_FALSE;
+ }
}
+ } else if (origin == MA_DR_FLAC_SEEK_END) {
+ return MA_FALSE;
}
return MA_TRUE;
}
+static ma_bool32 ma_dr_flac__on_tell_ogg(void* pUserData, ma_int64* pCursor)
+{
+ (void)pUserData;
+ (void)pCursor;
+ return MA_FALSE;
+}
static ma_bool32 ma_dr_flac_ogg__seek_to_pcm_frame(ma_dr_flac* pFlac, ma_uint64 pcmFrameIndex)
{
ma_dr_flac_oggbs* oggbs = (ma_dr_flac_oggbs*)pFlac->_oggbs;
@@ -87515,7 +89283,7 @@ static ma_bool32 ma_dr_flac_ogg__seek_to_pcm_frame(ma_dr_flac* pFlac, ma_uint64
runningGranulePosition = 0;
for (;;) {
if (!ma_dr_flac_oggbs__goto_next_page(oggbs, ma_dr_flac_ogg_recover_on_crc_mismatch)) {
- ma_dr_flac_oggbs__seek_physical(oggbs, originalBytePos, ma_dr_flac_seek_origin_start);
+ ma_dr_flac_oggbs__seek_physical(oggbs, originalBytePos, MA_DR_FLAC_SEEK_SET);
return MA_FALSE;
}
runningFrameBytePos = oggbs->currentBytePos - ma_dr_flac_ogg__get_page_header_size(&oggbs->currentPageHeader) - oggbs->pageDataSize;
@@ -87534,7 +89302,7 @@ static ma_bool32 ma_dr_flac_ogg__seek_to_pcm_frame(ma_dr_flac* pFlac, ma_uint64
}
}
}
- if (!ma_dr_flac_oggbs__seek_physical(oggbs, runningFrameBytePos, ma_dr_flac_seek_origin_start)) {
+ if (!ma_dr_flac_oggbs__seek_physical(oggbs, runningFrameBytePos, MA_DR_FLAC_SEEK_SET)) {
return MA_FALSE;
}
if (!ma_dr_flac_oggbs__goto_next_page(oggbs, ma_dr_flac_ogg_recover_on_crc_mismatch)) {
@@ -87629,7 +89397,7 @@ static ma_bool32 ma_dr_flac__init_private__ogg(ma_dr_flac_init_info* pInit, ma_d
if (mappingVersion[0] != 1) {
return MA_FALSE;
}
- if (!onSeek(pUserData, 2, ma_dr_flac_seek_origin_current)) {
+ if (!onSeek(pUserData, 2, MA_DR_FLAC_SEEK_CUR)) {
return MA_FALSE;
}
if (onRead(pUserData, sig, 4) != 4) {
@@ -87674,17 +89442,17 @@ static ma_bool32 ma_dr_flac__init_private__ogg(ma_dr_flac_init_info* pInit, ma_d
return MA_FALSE;
}
} else {
- if (!onSeek(pUserData, bytesRemainingInPage, ma_dr_flac_seek_origin_current)) {
+ if (!onSeek(pUserData, bytesRemainingInPage, MA_DR_FLAC_SEEK_CUR)) {
return MA_FALSE;
}
}
} else {
- if (!onSeek(pUserData, bytesRemainingInPage, ma_dr_flac_seek_origin_current)) {
+ if (!onSeek(pUserData, bytesRemainingInPage, MA_DR_FLAC_SEEK_CUR)) {
return MA_FALSE;
}
}
} else {
- if (!onSeek(pUserData, pageBodySize, ma_dr_flac_seek_origin_current)) {
+ if (!onSeek(pUserData, pageBodySize, MA_DR_FLAC_SEEK_CUR)) {
return MA_FALSE;
}
}
@@ -87698,7 +89466,7 @@ static ma_bool32 ma_dr_flac__init_private__ogg(ma_dr_flac_init_info* pInit, ma_d
return MA_TRUE;
}
#endif
-static ma_bool32 ma_dr_flac__init_private(ma_dr_flac_init_info* pInit, ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_meta_proc onMeta, ma_dr_flac_container container, void* pUserData, void* pUserDataMD)
+static ma_bool32 ma_dr_flac__init_private(ma_dr_flac_init_info* pInit, ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_tell_proc onTell, ma_dr_flac_meta_proc onMeta, ma_dr_flac_container container, void* pUserData, void* pUserDataMD)
{
ma_bool32 relaxed;
ma_uint8 id[4];
@@ -87708,12 +89476,14 @@ static ma_bool32 ma_dr_flac__init_private(ma_dr_flac_init_info* pInit, ma_dr_fla
MA_DR_FLAC_ZERO_MEMORY(pInit, sizeof(*pInit));
pInit->onRead = onRead;
pInit->onSeek = onSeek;
+ pInit->onTell = onTell;
pInit->onMeta = onMeta;
pInit->container = container;
pInit->pUserData = pUserData;
pInit->pUserDataMD = pUserDataMD;
pInit->bs.onRead = onRead;
pInit->bs.onSeek = onSeek;
+ pInit->bs.onTell = onTell;
pInit->bs.pUserData = pUserData;
ma_dr_flac__reset_cache(&pInit->bs);
relaxed = container != ma_dr_flac_container_unknown;
@@ -87736,7 +89506,7 @@ static ma_bool32 ma_dr_flac__init_private(ma_dr_flac_init_info* pInit, ma_dr_fla
if (flags & 0x10) {
headerSize += 10;
}
- if (!onSeek(pUserData, headerSize, ma_dr_flac_seek_origin_current)) {
+ if (!onSeek(pUserData, headerSize, MA_DR_FLAC_SEEK_CUR)) {
return MA_FALSE;
}
pInit->runningFilePos += headerSize;
@@ -87779,7 +89549,7 @@ static void ma_dr_flac__init_from_info(ma_dr_flac* pFlac, const ma_dr_flac_init_
pFlac->totalPCMFrameCount = pInit->totalPCMFrameCount;
pFlac->container = pInit->container;
}
-static ma_dr_flac* ma_dr_flac_open_with_metadata_private(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_meta_proc onMeta, ma_dr_flac_container container, void* pUserData, void* pUserDataMD, const ma_allocation_callbacks* pAllocationCallbacks)
+static ma_dr_flac* ma_dr_flac_open_with_metadata_private(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_tell_proc onTell, ma_dr_flac_meta_proc onMeta, ma_dr_flac_container container, void* pUserData, void* pUserDataMD, const ma_allocation_callbacks* pAllocationCallbacks)
{
ma_dr_flac_init_info init;
ma_uint32 allocationSize;
@@ -87794,7 +89564,7 @@ static ma_dr_flac* ma_dr_flac_open_with_metadata_private(ma_dr_flac_read_proc on
ma_allocation_callbacks allocationCallbacks;
ma_dr_flac* pFlac;
ma_dr_flac__init_cpu_caps();
- if (!ma_dr_flac__init_private(&init, onRead, onSeek, onMeta, container, pUserData, pUserDataMD)) {
+ if (!ma_dr_flac__init_private(&init, onRead, onSeek, onTell, onMeta, container, pUserData, pUserDataMD)) {
return NULL;
}
if (pAllocationCallbacks != NULL) {
@@ -87827,6 +89597,7 @@ static ma_dr_flac* ma_dr_flac_open_with_metadata_private(ma_dr_flac_read_proc on
MA_DR_FLAC_ZERO_MEMORY(pOggbs, sizeof(*pOggbs));
pOggbs->onRead = onRead;
pOggbs->onSeek = onSeek;
+ pOggbs->onTell = onTell;
pOggbs->pUserData = pUserData;
pOggbs->currentBytePos = init.oggFirstBytePos;
pOggbs->firstBytePos = init.oggFirstBytePos;
@@ -87841,15 +89612,17 @@ static ma_dr_flac* ma_dr_flac_open_with_metadata_private(ma_dr_flac_read_proc on
if (init.hasMetadataBlocks) {
ma_dr_flac_read_proc onReadOverride = onRead;
ma_dr_flac_seek_proc onSeekOverride = onSeek;
+ ma_dr_flac_tell_proc onTellOverride = onTell;
void* pUserDataOverride = pUserData;
#ifndef MA_DR_FLAC_NO_OGG
if (init.container == ma_dr_flac_container_ogg) {
onReadOverride = ma_dr_flac__on_read_ogg;
onSeekOverride = ma_dr_flac__on_seek_ogg;
+ onTellOverride = ma_dr_flac__on_tell_ogg;
pUserDataOverride = (void*)pOggbs;
}
#endif
- if (!ma_dr_flac__read_and_decode_metadata(onReadOverride, onSeekOverride, onMeta, pUserDataOverride, pUserDataMD, &firstFramePos, &seektablePos, &seekpointCount, &allocationCallbacks)) {
+ if (!ma_dr_flac__read_and_decode_metadata(onReadOverride, onSeekOverride, onTellOverride, onMeta, pUserDataOverride, pUserDataMD, &firstFramePos, &seektablePos, &seekpointCount, &allocationCallbacks)) {
#ifndef MA_DR_FLAC_NO_OGG
ma_dr_flac__free_from_callbacks(pOggbs, &allocationCallbacks);
#endif
@@ -87875,6 +89648,7 @@ static ma_dr_flac* ma_dr_flac_open_with_metadata_private(ma_dr_flac_read_proc on
pOggbs = NULL;
pFlac->bs.onRead = ma_dr_flac__on_read_ogg;
pFlac->bs.onSeek = ma_dr_flac__on_seek_ogg;
+ pFlac->bs.onTell = ma_dr_flac__on_tell_ogg;
pFlac->bs.pUserData = (void*)pInternalOggbs;
pFlac->_oggbs = (void*)pInternalOggbs;
}
@@ -87894,7 +89668,7 @@ static ma_dr_flac* ma_dr_flac_open_with_metadata_private(ma_dr_flac_read_proc on
pFlac->pSeekpoints = (ma_dr_flac_seekpoint*)((ma_uint8*)pFlac->pDecodedSamples + decodedSamplesAllocationSize);
MA_DR_FLAC_ASSERT(pFlac->bs.onSeek != NULL);
MA_DR_FLAC_ASSERT(pFlac->bs.onRead != NULL);
- if (pFlac->bs.onSeek(pFlac->bs.pUserData, (int)seektablePos, ma_dr_flac_seek_origin_start)) {
+ if (pFlac->bs.onSeek(pFlac->bs.pUserData, (int)seektablePos, MA_DR_FLAC_SEEK_SET)) {
ma_uint32 iSeekpoint;
for (iSeekpoint = 0; iSeekpoint < seekpointCount; iSeekpoint += 1) {
if (pFlac->bs.onRead(pFlac->bs.pUserData, pFlac->pSeekpoints + iSeekpoint, MA_DR_FLAC_SEEKPOINT_SIZE_IN_BYTES) == MA_DR_FLAC_SEEKPOINT_SIZE_IN_BYTES) {
@@ -87907,7 +89681,7 @@ static ma_dr_flac* ma_dr_flac_open_with_metadata_private(ma_dr_flac_read_proc on
break;
}
}
- if (!pFlac->bs.onSeek(pFlac->bs.pUserData, (int)pFlac->firstFLACFramePosInBytes, ma_dr_flac_seek_origin_start)) {
+ if (!pFlac->bs.onSeek(pFlac->bs.pUserData, (int)pFlac->firstFLACFramePosInBytes, MA_DR_FLAC_SEEK_SET)) {
ma_dr_flac__free_from_callbacks(pFlac, &allocationCallbacks);
return NULL;
}
@@ -87950,8 +89724,31 @@ static size_t ma_dr_flac__on_read_stdio(void* pUserData, void* bufferOut, size_t
}
static ma_bool32 ma_dr_flac__on_seek_stdio(void* pUserData, int offset, ma_dr_flac_seek_origin origin)
{
- MA_DR_FLAC_ASSERT(offset >= 0);
- return fseek((FILE*)pUserData, offset, (origin == ma_dr_flac_seek_origin_current) ? SEEK_CUR : SEEK_SET) == 0;
+ int whence = SEEK_SET;
+ if (origin == MA_DR_FLAC_SEEK_CUR) {
+ whence = SEEK_CUR;
+ } else if (origin == MA_DR_FLAC_SEEK_END) {
+ whence = SEEK_END;
+ }
+ return fseek((FILE*)pUserData, offset, whence) == 0;
+}
+static ma_bool32 ma_dr_flac__on_tell_stdio(void* pUserData, ma_int64* pCursor)
+{
+ FILE* pFileStdio = (FILE*)pUserData;
+ ma_int64 result;
+ MA_DR_FLAC_ASSERT(pFileStdio != NULL);
+ MA_DR_FLAC_ASSERT(pCursor != NULL);
+#if defined(_WIN32) && !defined(NXDK)
+ #if defined(_MSC_VER) && _MSC_VER > 1200
+ result = _ftelli64(pFileStdio);
+ #else
+ result = ftell(pFileStdio);
+ #endif
+#else
+ result = ftell(pFileStdio);
+#endif
+ *pCursor = result;
+ return MA_TRUE;
}
MA_API ma_dr_flac* ma_dr_flac_open_file(const char* pFileName, const ma_allocation_callbacks* pAllocationCallbacks)
{
@@ -87960,7 +89757,7 @@ MA_API ma_dr_flac* ma_dr_flac_open_file(const char* pFileName, const ma_allocati
if (ma_fopen(&pFile, pFileName, "rb") != MA_SUCCESS) {
return NULL;
}
- pFlac = ma_dr_flac_open(ma_dr_flac__on_read_stdio, ma_dr_flac__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
+ pFlac = ma_dr_flac_open(ma_dr_flac__on_read_stdio, ma_dr_flac__on_seek_stdio, ma_dr_flac__on_tell_stdio, (void*)pFile, pAllocationCallbacks);
if (pFlac == NULL) {
fclose(pFile);
return NULL;
@@ -87975,7 +89772,7 @@ MA_API ma_dr_flac* ma_dr_flac_open_file_w(const wchar_t* pFileName, const ma_all
if (ma_wfopen(&pFile, pFileName, L"rb", pAllocationCallbacks) != MA_SUCCESS) {
return NULL;
}
- pFlac = ma_dr_flac_open(ma_dr_flac__on_read_stdio, ma_dr_flac__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
+ pFlac = ma_dr_flac_open(ma_dr_flac__on_read_stdio, ma_dr_flac__on_seek_stdio, ma_dr_flac__on_tell_stdio, (void*)pFile, pAllocationCallbacks);
if (pFlac == NULL) {
fclose(pFile);
return NULL;
@@ -87990,7 +89787,7 @@ MA_API ma_dr_flac* ma_dr_flac_open_file_with_metadata(const char* pFileName, ma_
if (ma_fopen(&pFile, pFileName, "rb") != MA_SUCCESS) {
return NULL;
}
- pFlac = ma_dr_flac_open_with_metadata_private(ma_dr_flac__on_read_stdio, ma_dr_flac__on_seek_stdio, onMeta, ma_dr_flac_container_unknown, (void*)pFile, pUserData, pAllocationCallbacks);
+ pFlac = ma_dr_flac_open_with_metadata_private(ma_dr_flac__on_read_stdio, ma_dr_flac__on_seek_stdio, ma_dr_flac__on_tell_stdio, onMeta, ma_dr_flac_container_unknown, (void*)pFile, pUserData, pAllocationCallbacks);
if (pFlac == NULL) {
fclose(pFile);
return pFlac;
@@ -88005,7 +89802,7 @@ MA_API ma_dr_flac* ma_dr_flac_open_file_with_metadata_w(const wchar_t* pFileName
if (ma_wfopen(&pFile, pFileName, L"rb", pAllocationCallbacks) != MA_SUCCESS) {
return NULL;
}
- pFlac = ma_dr_flac_open_with_metadata_private(ma_dr_flac__on_read_stdio, ma_dr_flac__on_seek_stdio, onMeta, ma_dr_flac_container_unknown, (void*)pFile, pUserData, pAllocationCallbacks);
+ pFlac = ma_dr_flac_open_with_metadata_private(ma_dr_flac__on_read_stdio, ma_dr_flac__on_seek_stdio, ma_dr_flac__on_tell_stdio, onMeta, ma_dr_flac_container_unknown, (void*)pFile, pUserData, pAllocationCallbacks);
if (pFlac == NULL) {
fclose(pFile);
return pFlac;
@@ -88033,24 +89830,35 @@ static size_t ma_dr_flac__on_read_memory(void* pUserData, void* bufferOut, size_
static ma_bool32 ma_dr_flac__on_seek_memory(void* pUserData, int offset, ma_dr_flac_seek_origin origin)
{
ma_dr_flac__memory_stream* memoryStream = (ma_dr_flac__memory_stream*)pUserData;
+ ma_int64 newCursor;
MA_DR_FLAC_ASSERT(memoryStream != NULL);
- MA_DR_FLAC_ASSERT(offset >= 0);
- if (offset > (ma_int64)memoryStream->dataSize) {
+ newCursor = memoryStream->currentReadPos;
+ if (origin == MA_DR_FLAC_SEEK_SET) {
+ newCursor = 0;
+ } else if (origin == MA_DR_FLAC_SEEK_CUR) {
+ newCursor = (ma_int64)memoryStream->currentReadPos;
+ } else if (origin == MA_DR_FLAC_SEEK_END) {
+ newCursor = (ma_int64)memoryStream->dataSize;
+ } else {
+ MA_DR_FLAC_ASSERT(!"Invalid seek origin");
return MA_FALSE;
}
- if (origin == ma_dr_flac_seek_origin_current) {
- if (memoryStream->currentReadPos + offset <= memoryStream->dataSize) {
- memoryStream->currentReadPos += offset;
- } else {
- return MA_FALSE;
- }
- } else {
- if ((ma_uint32)offset <= memoryStream->dataSize) {
- memoryStream->currentReadPos = offset;
- } else {
- return MA_FALSE;
- }
+ newCursor += offset;
+ if (newCursor < 0) {
+ return MA_FALSE;
}
+ if ((size_t)newCursor > memoryStream->dataSize) {
+ return MA_FALSE;
+ }
+ memoryStream->currentReadPos = (size_t)newCursor;
+ return MA_TRUE;
+}
+static ma_bool32 ma_dr_flac__on_tell_memory(void* pUserData, ma_int64* pCursor)
+{
+ ma_dr_flac__memory_stream* memoryStream = (ma_dr_flac__memory_stream*)pUserData;
+ MA_DR_FLAC_ASSERT(memoryStream != NULL);
+ MA_DR_FLAC_ASSERT(pCursor != NULL);
+ *pCursor = (ma_int64)memoryStream->currentReadPos;
return MA_TRUE;
}
MA_API ma_dr_flac* ma_dr_flac_open_memory(const void* pData, size_t dataSize, const ma_allocation_callbacks* pAllocationCallbacks)
@@ -88060,7 +89868,7 @@ MA_API ma_dr_flac* ma_dr_flac_open_memory(const void* pData, size_t dataSize, co
memoryStream.data = (const ma_uint8*)pData;
memoryStream.dataSize = dataSize;
memoryStream.currentReadPos = 0;
- pFlac = ma_dr_flac_open(ma_dr_flac__on_read_memory, ma_dr_flac__on_seek_memory, &memoryStream, pAllocationCallbacks);
+ pFlac = ma_dr_flac_open(ma_dr_flac__on_read_memory, ma_dr_flac__on_seek_memory, ma_dr_flac__on_tell_memory, &memoryStream, pAllocationCallbacks);
if (pFlac == NULL) {
return NULL;
}
@@ -88085,7 +89893,7 @@ MA_API ma_dr_flac* ma_dr_flac_open_memory_with_metadata(const void* pData, size_
memoryStream.data = (const ma_uint8*)pData;
memoryStream.dataSize = dataSize;
memoryStream.currentReadPos = 0;
- pFlac = ma_dr_flac_open_with_metadata_private(ma_dr_flac__on_read_memory, ma_dr_flac__on_seek_memory, onMeta, ma_dr_flac_container_unknown, &memoryStream, pUserData, pAllocationCallbacks);
+ pFlac = ma_dr_flac_open_with_metadata_private(ma_dr_flac__on_read_memory, ma_dr_flac__on_seek_memory, ma_dr_flac__on_tell_memory, onMeta, ma_dr_flac_container_unknown, &memoryStream, pUserData, pAllocationCallbacks);
if (pFlac == NULL) {
return NULL;
}
@@ -88103,21 +89911,21 @@ MA_API ma_dr_flac* ma_dr_flac_open_memory_with_metadata(const void* pData, size_
}
return pFlac;
}
-MA_API ma_dr_flac* ma_dr_flac_open(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks)
+MA_API ma_dr_flac* ma_dr_flac_open(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_tell_proc onTell, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks)
{
- return ma_dr_flac_open_with_metadata_private(onRead, onSeek, NULL, ma_dr_flac_container_unknown, pUserData, pUserData, pAllocationCallbacks);
+ return ma_dr_flac_open_with_metadata_private(onRead, onSeek, onTell, NULL, ma_dr_flac_container_unknown, pUserData, pUserData, pAllocationCallbacks);
}
-MA_API ma_dr_flac* ma_dr_flac_open_relaxed(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_container container, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks)
+MA_API ma_dr_flac* ma_dr_flac_open_relaxed(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_tell_proc onTell, ma_dr_flac_container container, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks)
{
- return ma_dr_flac_open_with_metadata_private(onRead, onSeek, NULL, container, pUserData, pUserData, pAllocationCallbacks);
+ return ma_dr_flac_open_with_metadata_private(onRead, onSeek, onTell, NULL, container, pUserData, pUserData, pAllocationCallbacks);
}
-MA_API ma_dr_flac* ma_dr_flac_open_with_metadata(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_meta_proc onMeta, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks)
+MA_API ma_dr_flac* ma_dr_flac_open_with_metadata(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_tell_proc onTell, ma_dr_flac_meta_proc onMeta, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks)
{
- return ma_dr_flac_open_with_metadata_private(onRead, onSeek, onMeta, ma_dr_flac_container_unknown, pUserData, pUserData, pAllocationCallbacks);
+ return ma_dr_flac_open_with_metadata_private(onRead, onSeek, onTell, onMeta, ma_dr_flac_container_unknown, pUserData, pUserData, pAllocationCallbacks);
}
-MA_API ma_dr_flac* ma_dr_flac_open_with_metadata_relaxed(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_meta_proc onMeta, ma_dr_flac_container container, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks)
+MA_API ma_dr_flac* ma_dr_flac_open_with_metadata_relaxed(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_tell_proc onTell, ma_dr_flac_meta_proc onMeta, ma_dr_flac_container container, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks)
{
- return ma_dr_flac_open_with_metadata_private(onRead, onSeek, onMeta, container, pUserData, pUserData, pAllocationCallbacks);
+ return ma_dr_flac_open_with_metadata_private(onRead, onSeek, onTell, onMeta, container, pUserData, pUserData, pAllocationCallbacks);
}
MA_API void ma_dr_flac_close(ma_dr_flac* pFlac)
{
@@ -90410,7 +92218,7 @@ on_error:
MA_DR_FLAC_DEFINE_FULL_READ_AND_CLOSE(s32, ma_int32)
MA_DR_FLAC_DEFINE_FULL_READ_AND_CLOSE(s16, ma_int16)
MA_DR_FLAC_DEFINE_FULL_READ_AND_CLOSE(f32, float)
-MA_API ma_int32* ma_dr_flac_open_and_read_pcm_frames_s32(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalPCMFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks)
+MA_API ma_int32* ma_dr_flac_open_and_read_pcm_frames_s32(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_tell_proc onTell, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalPCMFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks)
{
ma_dr_flac* pFlac;
if (channelsOut) {
@@ -90422,13 +92230,13 @@ MA_API ma_int32* ma_dr_flac_open_and_read_pcm_frames_s32(ma_dr_flac_read_proc on
if (totalPCMFrameCountOut) {
*totalPCMFrameCountOut = 0;
}
- pFlac = ma_dr_flac_open(onRead, onSeek, pUserData, pAllocationCallbacks);
+ pFlac = ma_dr_flac_open(onRead, onSeek, onTell, pUserData, pAllocationCallbacks);
if (pFlac == NULL) {
return NULL;
}
return ma_dr_flac__full_read_and_close_s32(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut);
}
-MA_API ma_int16* ma_dr_flac_open_and_read_pcm_frames_s16(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalPCMFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks)
+MA_API ma_int16* ma_dr_flac_open_and_read_pcm_frames_s16(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_tell_proc onTell, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalPCMFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks)
{
ma_dr_flac* pFlac;
if (channelsOut) {
@@ -90440,13 +92248,13 @@ MA_API ma_int16* ma_dr_flac_open_and_read_pcm_frames_s16(ma_dr_flac_read_proc on
if (totalPCMFrameCountOut) {
*totalPCMFrameCountOut = 0;
}
- pFlac = ma_dr_flac_open(onRead, onSeek, pUserData, pAllocationCallbacks);
+ pFlac = ma_dr_flac_open(onRead, onSeek, onTell, pUserData, pAllocationCallbacks);
if (pFlac == NULL) {
return NULL;
}
return ma_dr_flac__full_read_and_close_s16(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut);
}
-MA_API float* ma_dr_flac_open_and_read_pcm_frames_f32(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalPCMFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks)
+MA_API float* ma_dr_flac_open_and_read_pcm_frames_f32(ma_dr_flac_read_proc onRead, ma_dr_flac_seek_proc onSeek, ma_dr_flac_tell_proc onTell, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, ma_uint64* totalPCMFrameCountOut, const ma_allocation_callbacks* pAllocationCallbacks)
{
ma_dr_flac* pFlac;
if (channelsOut) {
@@ -90458,7 +92266,7 @@ MA_API float* ma_dr_flac_open_and_read_pcm_frames_f32(ma_dr_flac_read_proc onRea
if (totalPCMFrameCountOut) {
*totalPCMFrameCountOut = 0;
}
- pFlac = ma_dr_flac_open(onRead, onSeek, pUserData, pAllocationCallbacks);
+ pFlac = ma_dr_flac_open(onRead, onSeek, onTell, pUserData, pAllocationCallbacks);
if (pFlac == NULL) {
return NULL;
}
@@ -91262,6 +93070,10 @@ static float ma_dr_mp3_L3_ldexp_q2(float y, int exp_q2)
} while ((exp_q2 -= e) > 0);
return y;
}
+#if (defined(__GNUC__) && (__GNUC__ >= 14)) && !defined(__clang__)
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wstringop-overflow"
+#endif
static void ma_dr_mp3_L3_decode_scalefactors(const ma_uint8 *hdr, ma_uint8 *ist_pos, ma_dr_mp3_bs *bs, const ma_dr_mp3_L3_gr_info *gr, float *scf, int ch)
{
static const ma_uint8 g_scf_partitions[3][28] = {
@@ -91320,7 +93132,10 @@ static void ma_dr_mp3_L3_decode_scalefactors(const ma_uint8 *hdr, ma_uint8 *ist_
scf[i] = ma_dr_mp3_L3_ldexp_q2(gain, iscf[i] << scf_shift);
}
}
-static const float g_ma_dr_mp3_pow43[129 + 16] = {
+#if (defined(__GNUC__) && (__GNUC__ >= 14)) && !defined(__clang__)
+ #pragma GCC diagnostic pop
+#endif
+static const float ma_dr_mp3_g_pow43[129 + 16] = {
0,-1,-2.519842f,-4.326749f,-6.349604f,-8.549880f,-10.902724f,-13.390518f,-16.000000f,-18.720754f,-21.544347f,-24.463781f,-27.473142f,-30.567351f,-33.741992f,-36.993181f,
0,1,2.519842f,4.326749f,6.349604f,8.549880f,10.902724f,13.390518f,16.000000f,18.720754f,21.544347f,24.463781f,27.473142f,30.567351f,33.741992f,36.993181f,40.317474f,43.711787f,47.173345f,50.699631f,54.288352f,57.937408f,61.644865f,65.408941f,69.227979f,73.100443f,77.024898f,81.000000f,85.024491f,89.097188f,93.216975f,97.382800f,101.593667f,105.848633f,110.146801f,114.487321f,118.869381f,123.292209f,127.755065f,132.257246f,136.798076f,141.376907f,145.993119f,150.646117f,155.335327f,160.060199f,164.820202f,169.614826f,174.443577f,179.305980f,184.201575f,189.129918f,194.090580f,199.083145f,204.107210f,209.162385f,214.248292f,219.364564f,224.510845f,229.686789f,234.892058f,240.126328f,245.389280f,250.680604f,256.000000f,261.347174f,266.721841f,272.123723f,277.552547f,283.008049f,288.489971f,293.998060f,299.532071f,305.091761f,310.676898f,316.287249f,321.922592f,327.582707f,333.267377f,338.976394f,344.709550f,350.466646f,356.247482f,362.051866f,367.879608f,373.730522f,379.604427f,385.501143f,391.420496f,397.362314f,403.326427f,409.312672f,415.320884f,421.350905f,427.402579f,433.475750f,439.570269f,445.685987f,451.822757f,457.980436f,464.158883f,470.357960f,476.577530f,482.817459f,489.077615f,495.357868f,501.658090f,507.978156f,514.317941f,520.677324f,527.056184f,533.454404f,539.871867f,546.308458f,552.764065f,559.238575f,565.731879f,572.243870f,578.774440f,585.323483f,591.890898f,598.476581f,605.080431f,611.702349f,618.342238f,625.000000f,631.675540f,638.368763f,645.079578f
};
@@ -91330,7 +93145,7 @@ static float ma_dr_mp3_L3_pow_43(int x)
int sign, mult = 256;
if (x < 129)
{
- return g_ma_dr_mp3_pow43[16 + x];
+ return ma_dr_mp3_g_pow43[16 + x];
}
if (x < 1024)
{
@@ -91339,7 +93154,7 @@ static float ma_dr_mp3_L3_pow_43(int x)
}
sign = 2*x & 64;
frac = (float)((x & 63) - sign) / ((x & ~63) + sign);
- return g_ma_dr_mp3_pow43[16 + ((x + sign) >> 6)]*(1.f + frac*((4.f/3) + frac*(2.f/9)))*mult;
+ return ma_dr_mp3_g_pow43[16 + ((x + sign) >> 6)]*(1.f + frac*((4.f/3) + frac*(2.f/9)))*mult;
}
static void ma_dr_mp3_L3_huffman(float *dst, ma_dr_mp3_bs *bs, const ma_dr_mp3_L3_gr_info *gr_info, const float *scf, int layer3gr_limit)
{
@@ -91409,7 +93224,7 @@ static void ma_dr_mp3_L3_huffman(float *dst, ma_dr_mp3_bs *bs, const ma_dr_mp3_L
*dst = one*ma_dr_mp3_L3_pow_43(lsb)*((ma_int32)bs_cache < 0 ? -1: 1);
} else
{
- *dst = g_ma_dr_mp3_pow43[16 + lsb - 16*(bs_cache >> 31)]*one;
+ *dst = ma_dr_mp3_g_pow43[16 + lsb - 16*(bs_cache >> 31)]*one;
}
MA_DR_MP3_FLUSH_BITS(lsb ? 1 : 0);
}
@@ -91437,7 +93252,7 @@ static void ma_dr_mp3_L3_huffman(float *dst, ma_dr_mp3_bs *bs, const ma_dr_mp3_L
for (j = 0; j < 2; j++, dst++, leaf >>= 4)
{
int lsb = leaf & 0x0F;
- *dst = g_ma_dr_mp3_pow43[16 + lsb - 16*(bs_cache >> 31)]*one;
+ *dst = ma_dr_mp3_g_pow43[16 + lsb - 16*(bs_cache >> 31)]*one;
MA_DR_MP3_FLUSH_BITS(lsb ? 1 : 0);
}
MA_DR_MP3_CHECK_BITS;
@@ -92268,7 +94083,7 @@ MA_API int ma_dr_mp3dec_decode_frame(ma_dr_mp3dec *dec, const ma_uint8 *mp3, int
MA_DR_MP3_COPY_MEMORY(dec->header, hdr, MA_DR_MP3_HDR_SIZE);
info->frame_bytes = i + frame_size;
info->channels = MA_DR_MP3_HDR_IS_MONO(hdr) ? 1 : 2;
- info->hz = ma_dr_mp3_hdr_sample_rate_hz(hdr);
+ info->sample_rate = ma_dr_mp3_hdr_sample_rate_hz(hdr);
info->layer = 4 - MA_DR_MP3_HDR_GET_LAYER(hdr);
info->bitrate_kbps = ma_dr_mp3_hdr_bitrate_kbps(hdr);
ma_dr_mp3_bs_init(bs_frame, hdr + MA_DR_MP3_HDR_SIZE, frame_size - MA_DR_MP3_HDR_SIZE);
@@ -92491,19 +94306,41 @@ static ma_allocation_callbacks ma_dr_mp3_copy_allocation_callbacks_or_defaults(c
}
static size_t ma_dr_mp3__on_read(ma_dr_mp3* pMP3, void* pBufferOut, size_t bytesToRead)
{
- size_t bytesRead = pMP3->onRead(pMP3->pUserData, pBufferOut, bytesToRead);
+ size_t bytesRead;
+ MA_DR_MP3_ASSERT(pMP3 != NULL);
+ MA_DR_MP3_ASSERT(pMP3->onRead != NULL);
+ if (bytesToRead == 0) {
+ return 0;
+ }
+ bytesRead = pMP3->onRead(pMP3->pUserData, pBufferOut, bytesToRead);
pMP3->streamCursor += bytesRead;
return bytesRead;
}
+static size_t ma_dr_mp3__on_read_clamped(ma_dr_mp3* pMP3, void* pBufferOut, size_t bytesToRead)
+{
+ MA_DR_MP3_ASSERT(pMP3 != NULL);
+ MA_DR_MP3_ASSERT(pMP3->onRead != NULL);
+ if (pMP3->streamLength == MA_UINT64_MAX) {
+ return ma_dr_mp3__on_read(pMP3, pBufferOut, bytesToRead);
+ } else {
+ ma_uint64 bytesRemaining;
+ bytesRemaining = (pMP3->streamLength - pMP3->streamCursor);
+ if (bytesToRead > bytesRemaining) {
+ bytesToRead = (size_t)bytesRemaining;
+ }
+ return ma_dr_mp3__on_read(pMP3, pBufferOut, bytesToRead);
+ }
+}
static ma_bool32 ma_dr_mp3__on_seek(ma_dr_mp3* pMP3, int offset, ma_dr_mp3_seek_origin origin)
{
MA_DR_MP3_ASSERT(offset >= 0);
+ MA_DR_MP3_ASSERT(origin == MA_DR_MP3_SEEK_SET || origin == MA_DR_MP3_SEEK_CUR);
if (!pMP3->onSeek(pMP3->pUserData, offset, origin)) {
return MA_FALSE;
}
- if (origin == ma_dr_mp3_seek_origin_start) {
+ if (origin == MA_DR_MP3_SEEK_SET) {
pMP3->streamCursor = (ma_uint64)offset;
- } else {
+ } else{
pMP3->streamCursor += offset;
}
return MA_TRUE;
@@ -92513,18 +94350,18 @@ static ma_bool32 ma_dr_mp3__on_seek_64(ma_dr_mp3* pMP3, ma_uint64 offset, ma_dr_
if (offset <= 0x7FFFFFFF) {
return ma_dr_mp3__on_seek(pMP3, (int)offset, origin);
}
- if (!ma_dr_mp3__on_seek(pMP3, 0x7FFFFFFF, ma_dr_mp3_seek_origin_start)) {
+ if (!ma_dr_mp3__on_seek(pMP3, 0x7FFFFFFF, MA_DR_MP3_SEEK_SET)) {
return MA_FALSE;
}
offset -= 0x7FFFFFFF;
while (offset > 0) {
if (offset <= 0x7FFFFFFF) {
- if (!ma_dr_mp3__on_seek(pMP3, (int)offset, ma_dr_mp3_seek_origin_current)) {
+ if (!ma_dr_mp3__on_seek(pMP3, (int)offset, MA_DR_MP3_SEEK_CUR)) {
return MA_FALSE;
}
offset = 0;
} else {
- if (!ma_dr_mp3__on_seek(pMP3, 0x7FFFFFFF, ma_dr_mp3_seek_origin_current)) {
+ if (!ma_dr_mp3__on_seek(pMP3, 0x7FFFFFFF, MA_DR_MP3_SEEK_CUR)) {
return MA_FALSE;
}
offset -= 0x7FFFFFFF;
@@ -92532,7 +94369,18 @@ static ma_bool32 ma_dr_mp3__on_seek_64(ma_dr_mp3* pMP3, ma_uint64 offset, ma_dr_
}
return MA_TRUE;
}
-static ma_uint32 ma_dr_mp3_decode_next_frame_ex__callbacks(ma_dr_mp3* pMP3, ma_dr_mp3d_sample_t* pPCMFrames)
+static void ma_dr_mp3__on_meta(ma_dr_mp3* pMP3, ma_dr_mp3_metadata_type type, const void* pRawData, size_t rawDataSize)
+{
+ if (pMP3->onMeta) {
+ ma_dr_mp3_metadata metadata;
+ MA_DR_MP3_ZERO_OBJECT(&metadata);
+ metadata.type = type;
+ metadata.pRawData = pRawData;
+ metadata.rawDataSize = rawDataSize;
+ pMP3->onMeta(pMP3->pUserDataMeta, &metadata);
+ }
+}
+static ma_uint32 ma_dr_mp3_decode_next_frame_ex__callbacks(ma_dr_mp3* pMP3, ma_dr_mp3d_sample_t* pPCMFrames, ma_dr_mp3dec_frame_info* pMP3FrameInfo, const ma_uint8** ppMP3FrameData)
{
ma_uint32 pcmFramesRead = 0;
MA_DR_MP3_ASSERT(pMP3 != NULL);
@@ -92559,7 +94407,7 @@ static ma_uint32 ma_dr_mp3_decode_next_frame_ex__callbacks(ma_dr_mp3* pMP3, ma_d
pMP3->pData = pNewData;
pMP3->dataCapacity = newDataCap;
}
- bytesRead = ma_dr_mp3__on_read(pMP3, pMP3->pData + pMP3->dataSize, (pMP3->dataCapacity - pMP3->dataSize));
+ bytesRead = ma_dr_mp3__on_read_clamped(pMP3, pMP3->pData + pMP3->dataSize, (pMP3->dataCapacity - pMP3->dataSize));
if (bytesRead == 0) {
if (pMP3->dataSize == 0) {
pMP3->atEnd = MA_TRUE;
@@ -92578,16 +94426,20 @@ static ma_uint32 ma_dr_mp3_decode_next_frame_ex__callbacks(ma_dr_mp3* pMP3, ma_d
return 0;
}
pcmFramesRead = ma_dr_mp3dec_decode_frame(&pMP3->decoder, pMP3->pData + pMP3->dataConsumed, (int)pMP3->dataSize, pPCMFrames, &info);
- if (info.frame_bytes > 0) {
- pMP3->dataConsumed += (size_t)info.frame_bytes;
- pMP3->dataSize -= (size_t)info.frame_bytes;
- }
+ pMP3->dataConsumed += (size_t)info.frame_bytes;
+ pMP3->dataSize -= (size_t)info.frame_bytes;
if (pcmFramesRead > 0) {
pcmFramesRead = ma_dr_mp3_hdr_frame_samples(pMP3->decoder.header);
pMP3->pcmFramesConsumedInMP3Frame = 0;
pMP3->pcmFramesRemainingInMP3Frame = pcmFramesRead;
pMP3->mp3FrameChannels = info.channels;
- pMP3->mp3FrameSampleRate = info.hz;
+ pMP3->mp3FrameSampleRate = info.sample_rate;
+ if (pMP3FrameInfo != NULL) {
+ *pMP3FrameInfo = info;
+ }
+ if (ppMP3FrameData != NULL) {
+ *ppMP3FrameData = pMP3->pData + pMP3->dataConsumed - (size_t)info.frame_bytes;
+ }
break;
} else if (info.frame_bytes == 0) {
size_t bytesRead;
@@ -92604,7 +94456,7 @@ static ma_uint32 ma_dr_mp3_decode_next_frame_ex__callbacks(ma_dr_mp3* pMP3, ma_d
pMP3->pData = pNewData;
pMP3->dataCapacity = newDataCap;
}
- bytesRead = ma_dr_mp3__on_read(pMP3, pMP3->pData + pMP3->dataSize, (pMP3->dataCapacity - pMP3->dataSize));
+ bytesRead = ma_dr_mp3__on_read_clamped(pMP3, pMP3->pData + pMP3->dataSize, (pMP3->dataCapacity - pMP3->dataSize));
if (bytesRead == 0) {
pMP3->atEnd = MA_TRUE;
return 0;
@@ -92614,7 +94466,7 @@ static ma_uint32 ma_dr_mp3_decode_next_frame_ex__callbacks(ma_dr_mp3* pMP3, ma_d
};
return pcmFramesRead;
}
-static ma_uint32 ma_dr_mp3_decode_next_frame_ex__memory(ma_dr_mp3* pMP3, ma_dr_mp3d_sample_t* pPCMFrames)
+static ma_uint32 ma_dr_mp3_decode_next_frame_ex__memory(ma_dr_mp3* pMP3, ma_dr_mp3d_sample_t* pPCMFrames, ma_dr_mp3dec_frame_info* pMP3FrameInfo, const ma_uint8** ppMP3FrameData)
{
ma_uint32 pcmFramesRead = 0;
ma_dr_mp3dec_frame_info info;
@@ -92630,36 +94482,44 @@ static ma_uint32 ma_dr_mp3_decode_next_frame_ex__memory(ma_dr_mp3* pMP3, ma_dr_m
pMP3->pcmFramesConsumedInMP3Frame = 0;
pMP3->pcmFramesRemainingInMP3Frame = pcmFramesRead;
pMP3->mp3FrameChannels = info.channels;
- pMP3->mp3FrameSampleRate = info.hz;
+ pMP3->mp3FrameSampleRate = info.sample_rate;
+ if (pMP3FrameInfo != NULL) {
+ *pMP3FrameInfo = info;
+ }
+ if (ppMP3FrameData != NULL) {
+ *ppMP3FrameData = pMP3->memory.pData + pMP3->memory.currentReadPos;
+ }
break;
} else if (info.frame_bytes > 0) {
pMP3->memory.currentReadPos += (size_t)info.frame_bytes;
+ pMP3->streamCursor += (size_t)info.frame_bytes;
} else {
break;
}
}
pMP3->memory.currentReadPos += (size_t)info.frame_bytes;
+ pMP3->streamCursor += (size_t)info.frame_bytes;
return pcmFramesRead;
}
-static ma_uint32 ma_dr_mp3_decode_next_frame_ex(ma_dr_mp3* pMP3, ma_dr_mp3d_sample_t* pPCMFrames)
+static ma_uint32 ma_dr_mp3_decode_next_frame_ex(ma_dr_mp3* pMP3, ma_dr_mp3d_sample_t* pPCMFrames, ma_dr_mp3dec_frame_info* pMP3FrameInfo, const ma_uint8** ppMP3FrameData)
{
if (pMP3->memory.pData != NULL && pMP3->memory.dataSize > 0) {
- return ma_dr_mp3_decode_next_frame_ex__memory(pMP3, pPCMFrames);
+ return ma_dr_mp3_decode_next_frame_ex__memory(pMP3, pPCMFrames, pMP3FrameInfo, ppMP3FrameData);
} else {
- return ma_dr_mp3_decode_next_frame_ex__callbacks(pMP3, pPCMFrames);
+ return ma_dr_mp3_decode_next_frame_ex__callbacks(pMP3, pPCMFrames, pMP3FrameInfo, ppMP3FrameData);
}
}
static ma_uint32 ma_dr_mp3_decode_next_frame(ma_dr_mp3* pMP3)
{
MA_DR_MP3_ASSERT(pMP3 != NULL);
- return ma_dr_mp3_decode_next_frame_ex(pMP3, (ma_dr_mp3d_sample_t*)pMP3->pcmFrames);
+ return ma_dr_mp3_decode_next_frame_ex(pMP3, (ma_dr_mp3d_sample_t*)pMP3->pcmFrames, NULL, NULL);
}
#if 0
static ma_uint32 ma_dr_mp3_seek_next_frame(ma_dr_mp3* pMP3)
{
ma_uint32 pcmFrameCount;
MA_DR_MP3_ASSERT(pMP3 != NULL);
- pcmFrameCount = ma_dr_mp3_decode_next_frame_ex(pMP3, NULL);
+ pcmFrameCount = ma_dr_mp3_decode_next_frame_ex(pMP3, NULL, NULL, NULL);
if (pcmFrameCount == 0) {
return 0;
}
@@ -92669,33 +94529,249 @@ static ma_uint32 ma_dr_mp3_seek_next_frame(ma_dr_mp3* pMP3)
return pcmFrameCount;
}
#endif
-static ma_bool32 ma_dr_mp3_init_internal(ma_dr_mp3* pMP3, ma_dr_mp3_read_proc onRead, ma_dr_mp3_seek_proc onSeek, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks)
+static ma_bool32 ma_dr_mp3_init_internal(ma_dr_mp3* pMP3, ma_dr_mp3_read_proc onRead, ma_dr_mp3_seek_proc onSeek, ma_dr_mp3_tell_proc onTell, ma_dr_mp3_meta_proc onMeta, void* pUserData, void* pUserDataMeta, const ma_allocation_callbacks* pAllocationCallbacks)
{
+ ma_dr_mp3dec_frame_info firstFrameInfo;
+ const ma_uint8* pFirstFrameData;
+ ma_uint32 firstFramePCMFrameCount;
+ ma_uint32 detectedMP3FrameCount = 0xFFFFFFFF;
MA_DR_MP3_ASSERT(pMP3 != NULL);
MA_DR_MP3_ASSERT(onRead != NULL);
ma_dr_mp3dec_init(&pMP3->decoder);
pMP3->onRead = onRead;
pMP3->onSeek = onSeek;
+ pMP3->onMeta = onMeta;
pMP3->pUserData = pUserData;
+ pMP3->pUserDataMeta = pUserDataMeta;
pMP3->allocationCallbacks = ma_dr_mp3_copy_allocation_callbacks_or_defaults(pAllocationCallbacks);
if (pMP3->allocationCallbacks.onFree == NULL || (pMP3->allocationCallbacks.onMalloc == NULL && pMP3->allocationCallbacks.onRealloc == NULL)) {
return MA_FALSE;
}
- if (ma_dr_mp3_decode_next_frame(pMP3) == 0) {
+ pMP3->streamCursor = 0;
+ pMP3->streamLength = MA_UINT64_MAX;
+ pMP3->streamStartOffset = 0;
+ pMP3->delayInPCMFrames = 0;
+ pMP3->paddingInPCMFrames = 0;
+ pMP3->totalPCMFrameCount = MA_UINT64_MAX;
+ #if 1
+ if (onSeek != NULL && onTell != NULL) {
+ if (onSeek(pUserData, 0, MA_DR_MP3_SEEK_END)) {
+ ma_int64 streamLen;
+ int streamEndOffset = 0;
+ if (onTell(pUserData, &streamLen)) {
+ if (streamLen > 128) {
+ char id3[3];
+ if (onSeek(pUserData, streamEndOffset - 128, MA_DR_MP3_SEEK_END)) {
+ if (onRead(pUserData, id3, 3) == 3 && id3[0] == 'T' && id3[1] == 'A' && id3[2] == 'G') {
+ streamEndOffset -= 128;
+ streamLen -= 128;
+ if (onMeta != NULL) {
+ ma_uint8 tag[128];
+ tag[0] = 'T'; tag[1] = 'A'; tag[2] = 'G';
+ if (onRead(pUserData, tag + 3, 125) == 125) {
+ ma_dr_mp3__on_meta(pMP3, MA_DR_MP3_METADATA_TYPE_ID3V1, tag, 128);
+ }
+ }
+ } else {
+ }
+ } else {
+ }
+ } else {
+ }
+ if (streamLen > 32) {
+ char ape[32];
+ if (onSeek(pUserData, streamEndOffset - 32, MA_DR_MP3_SEEK_END)) {
+ if (onRead(pUserData, ape, 32) == 32 && ape[0] == 'A' && ape[1] == 'P' && ape[2] == 'E' && ape[3] == 'T' && ape[4] == 'A' && ape[5] == 'G' && ape[6] == 'E' && ape[7] == 'X') {
+ ma_uint32 tagSize =
+ ((ma_uint32)ape[24] << 0) |
+ ((ma_uint32)ape[25] << 8) |
+ ((ma_uint32)ape[26] << 16) |
+ ((ma_uint32)ape[27] << 24);
+ streamEndOffset -= 32 + tagSize;
+ streamLen -= 32 + tagSize;
+ if (onMeta != NULL) {
+ if (onSeek(pUserData, streamEndOffset, MA_DR_MP3_SEEK_END)) {
+ size_t apeTagSize = (size_t)tagSize + 32;
+ ma_uint8* pTagData = (ma_uint8*)ma_dr_mp3_malloc(apeTagSize, pAllocationCallbacks);
+ if (pTagData != NULL) {
+ if (onRead(pUserData, pTagData, apeTagSize) == apeTagSize) {
+ ma_dr_mp3__on_meta(pMP3, MA_DR_MP3_METADATA_TYPE_APE, pTagData, apeTagSize);
+ }
+ ma_dr_mp3_free(pTagData, pAllocationCallbacks);
+ }
+ }
+ }
+ }
+ }
+ } else {
+ }
+ if (!onSeek(pUserData, 0, MA_DR_MP3_SEEK_SET)) {
+ return MA_FALSE;
+ }
+ pMP3->streamLength = (ma_uint64)streamLen;
+ if (pMP3->memory.pData != NULL) {
+ pMP3->memory.dataSize = (size_t)pMP3->streamLength;
+ }
+ } else {
+ if (!onSeek(pUserData, 0, MA_DR_MP3_SEEK_SET)) {
+ return MA_FALSE;
+ }
+ }
+ } else {
+ }
+ } else {
+ }
+ #endif
+ #if 1
+ {
+ char header[10];
+ if (onRead(pUserData, header, 10) == 10) {
+ if (header[0] == 'I' && header[1] == 'D' && header[2] == '3') {
+ ma_uint32 tagSize =
+ (((ma_uint32)header[6] & 0x7F) << 21) |
+ (((ma_uint32)header[7] & 0x7F) << 14) |
+ (((ma_uint32)header[8] & 0x7F) << 7) |
+ (((ma_uint32)header[9] & 0x7F) << 0);
+ if (header[5] & 0x10) {
+ tagSize += 10;
+ }
+ if (onMeta != NULL) {
+ size_t tagSizeWithHeader = 10 + tagSize;
+ ma_uint8* pTagData = (ma_uint8*)ma_dr_mp3_malloc(tagSizeWithHeader, pAllocationCallbacks);
+ if (pTagData != NULL) {
+ MA_DR_MP3_COPY_MEMORY(pTagData, header, 10);
+ if (onRead(pUserData, pTagData + 10, tagSize) == tagSize) {
+ ma_dr_mp3__on_meta(pMP3, MA_DR_MP3_METADATA_TYPE_ID3V2, pTagData, tagSizeWithHeader);
+ }
+ ma_dr_mp3_free(pTagData, pAllocationCallbacks);
+ }
+ } else {
+ if (onSeek != NULL) {
+ if (!onSeek(pUserData, tagSize, MA_DR_MP3_SEEK_CUR)) {
+ return MA_FALSE;
+ }
+ } else {
+ char discard[1024];
+ while (tagSize > 0) {
+ size_t bytesToRead = tagSize;
+ if (bytesToRead > sizeof(discard)) {
+ bytesToRead = sizeof(discard);
+ }
+ if (onRead(pUserData, discard, bytesToRead) != bytesToRead) {
+ return MA_FALSE;
+ }
+ tagSize -= (ma_uint32)bytesToRead;
+ }
+ }
+ }
+ pMP3->streamStartOffset += 10 + tagSize;
+ pMP3->streamCursor = pMP3->streamStartOffset;
+ } else {
+ if (onSeek != NULL) {
+ if (!onSeek(pUserData, 0, MA_DR_MP3_SEEK_SET)) {
+ return MA_FALSE;
+ }
+ } else {
+ }
+ }
+ } else {
+ return MA_FALSE;
+ }
+ }
+ #endif
+ firstFramePCMFrameCount = ma_dr_mp3_decode_next_frame_ex(pMP3, (ma_dr_mp3d_sample_t*)pMP3->pcmFrames, &firstFrameInfo, &pFirstFrameData);
+ if (firstFramePCMFrameCount > 0) {
+ MA_DR_MP3_ASSERT(pFirstFrameData != NULL);
+ #if 1
+ MA_DR_MP3_ASSERT(firstFrameInfo.frame_bytes > 0);
+ {
+ ma_dr_mp3_bs bs;
+ ma_dr_mp3_L3_gr_info grInfo[4];
+ const ma_uint8* pTagData = pFirstFrameData;
+ ma_dr_mp3_bs_init(&bs, pFirstFrameData + MA_DR_MP3_HDR_SIZE, firstFrameInfo.frame_bytes - MA_DR_MP3_HDR_SIZE);
+ if (MA_DR_MP3_HDR_IS_CRC(pFirstFrameData)) {
+ ma_dr_mp3_bs_get_bits(&bs, 16);
+ }
+ if (ma_dr_mp3_L3_read_side_info(&bs, grInfo, pFirstFrameData) >= 0) {
+ ma_bool32 isXing = MA_FALSE;
+ ma_bool32 isInfo = MA_FALSE;
+ const ma_uint8* pTagDataBeg;
+ pTagDataBeg = pFirstFrameData + MA_DR_MP3_HDR_SIZE + (bs.pos/8);
+ pTagData = pTagDataBeg;
+ isXing = (pTagData[0] == 'X' && pTagData[1] == 'i' && pTagData[2] == 'n' && pTagData[3] == 'g');
+ isInfo = (pTagData[0] == 'I' && pTagData[1] == 'n' && pTagData[2] == 'f' && pTagData[3] == 'o');
+ if (isXing || isInfo) {
+ ma_uint32 bytes = 0;
+ ma_uint32 flags = pTagData[7];
+ pTagData += 8;
+ if (flags & 0x01) {
+ detectedMP3FrameCount = (ma_uint32)pTagData[0] << 24 | (ma_uint32)pTagData[1] << 16 | (ma_uint32)pTagData[2] << 8 | (ma_uint32)pTagData[3];
+ pTagData += 4;
+ }
+ if (flags & 0x02) {
+ bytes = (ma_uint32)pTagData[0] << 24 | (ma_uint32)pTagData[1] << 16 | (ma_uint32)pTagData[2] << 8 | (ma_uint32)pTagData[3];
+ (void)bytes;
+ pTagData += 4;
+ }
+ if (flags & 0x04) {
+ pTagData += 100;
+ }
+ if (flags & 0x08) {
+ pTagData += 4;
+ }
+ if (pTagData[0]) {
+ pTagData += 21;
+ if (pTagData - pFirstFrameData + 14 < firstFrameInfo.frame_bytes) {
+ int delayInPCMFrames;
+ int paddingInPCMFrames;
+ delayInPCMFrames = (( (ma_uint32)pTagData[0] << 4) | ((ma_uint32)pTagData[1] >> 4)) + (528 + 1);
+ paddingInPCMFrames = ((((ma_uint32)pTagData[1] & 0xF) << 8) | ((ma_uint32)pTagData[2] )) - (528 + 1);
+ if (paddingInPCMFrames < 0) {
+ paddingInPCMFrames = 0;
+ }
+ pMP3->delayInPCMFrames = (ma_uint32)delayInPCMFrames;
+ pMP3->paddingInPCMFrames = (ma_uint32)paddingInPCMFrames;
+ }
+ }
+ if (isXing) {
+ pMP3->isVBR = MA_TRUE;
+ } else if (isInfo) {
+ pMP3->isCBR = MA_TRUE;
+ }
+ if (onMeta != NULL) {
+ ma_dr_mp3_metadata_type metadataType = isXing ? MA_DR_MP3_METADATA_TYPE_XING : MA_DR_MP3_METADATA_TYPE_VBRI;
+ size_t tagDataSize;
+ tagDataSize = (size_t)firstFrameInfo.frame_bytes;
+ tagDataSize -= (size_t)(pTagDataBeg - pFirstFrameData);
+ ma_dr_mp3__on_meta(pMP3, metadataType, pTagDataBeg, tagDataSize);
+ }
+ pMP3->pcmFramesRemainingInMP3Frame = 0;
+ pMP3->streamStartOffset += (ma_uint32)(firstFrameInfo.frame_bytes);
+ pMP3->streamCursor = pMP3->streamStartOffset;
+ ma_dr_mp3dec_init(&pMP3->decoder);
+ }
+ } else {
+ }
+ }
+ #endif
+ } else {
ma_dr_mp3__free_from_callbacks(pMP3->pData, &pMP3->allocationCallbacks);
return MA_FALSE;
}
+ if (detectedMP3FrameCount != 0xFFFFFFFF) {
+ pMP3->totalPCMFrameCount = detectedMP3FrameCount * firstFramePCMFrameCount;
+ }
pMP3->channels = pMP3->mp3FrameChannels;
pMP3->sampleRate = pMP3->mp3FrameSampleRate;
return MA_TRUE;
}
-MA_API ma_bool32 ma_dr_mp3_init(ma_dr_mp3* pMP3, ma_dr_mp3_read_proc onRead, ma_dr_mp3_seek_proc onSeek, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks)
+MA_API ma_bool32 ma_dr_mp3_init(ma_dr_mp3* pMP3, ma_dr_mp3_read_proc onRead, ma_dr_mp3_seek_proc onSeek, ma_dr_mp3_tell_proc onTell, ma_dr_mp3_meta_proc onMeta, void* pUserData, const ma_allocation_callbacks* pAllocationCallbacks)
{
if (pMP3 == NULL || onRead == NULL) {
return MA_FALSE;
}
MA_DR_MP3_ZERO_OBJECT(pMP3);
- return ma_dr_mp3_init_internal(pMP3, onRead, onSeek, pUserData, pAllocationCallbacks);
+ return ma_dr_mp3_init_internal(pMP3, onRead, onSeek, onTell, onMeta, pUserData, pUserData, pAllocationCallbacks);
}
static size_t ma_dr_mp3__on_read_memory(void* pUserData, void* pBufferOut, size_t bytesToRead)
{
@@ -92716,29 +94792,40 @@ static size_t ma_dr_mp3__on_read_memory(void* pUserData, void* pBufferOut, size_
static ma_bool32 ma_dr_mp3__on_seek_memory(void* pUserData, int byteOffset, ma_dr_mp3_seek_origin origin)
{
ma_dr_mp3* pMP3 = (ma_dr_mp3*)pUserData;
+ ma_int64 newCursor;
MA_DR_MP3_ASSERT(pMP3 != NULL);
- if (origin == ma_dr_mp3_seek_origin_current) {
- if (byteOffset > 0) {
- if (pMP3->memory.currentReadPos + byteOffset > pMP3->memory.dataSize) {
- byteOffset = (int)(pMP3->memory.dataSize - pMP3->memory.currentReadPos);
- }
- } else {
- if (pMP3->memory.currentReadPos < (size_t)-byteOffset) {
- byteOffset = -(int)pMP3->memory.currentReadPos;
- }
- }
- pMP3->memory.currentReadPos += byteOffset;
+ newCursor = pMP3->memory.currentReadPos;
+ if (origin == MA_DR_MP3_SEEK_SET) {
+ newCursor = 0;
+ } else if (origin == MA_DR_MP3_SEEK_CUR) {
+ newCursor = (ma_int64)pMP3->memory.currentReadPos;
+ } else if (origin == MA_DR_MP3_SEEK_END) {
+ newCursor = (ma_int64)pMP3->memory.dataSize;
} else {
- if ((ma_uint32)byteOffset <= pMP3->memory.dataSize) {
- pMP3->memory.currentReadPos = byteOffset;
- } else {
- pMP3->memory.currentReadPos = pMP3->memory.dataSize;
- }
+ MA_DR_MP3_ASSERT(!"Invalid seek origin");
+ return MA_FALSE;
}
+ newCursor += byteOffset;
+ if (newCursor < 0) {
+ return MA_FALSE;
+ }
+ if ((size_t)newCursor > pMP3->memory.dataSize) {
+ return MA_FALSE;
+ }
+ pMP3->memory.currentReadPos = (size_t)newCursor;
return MA_TRUE;
}
-MA_API ma_bool32 ma_dr_mp3_init_memory(ma_dr_mp3* pMP3, const void* pData, size_t dataSize, const ma_allocation_callbacks* pAllocationCallbacks)
+static ma_bool32 ma_dr_mp3__on_tell_memory(void* pUserData, ma_int64* pCursor)
{
+ ma_dr_mp3* pMP3 = (ma_dr_mp3*)pUserData;
+ MA_DR_MP3_ASSERT(pMP3 != NULL);
+ MA_DR_MP3_ASSERT(pCursor != NULL);
+ *pCursor = (ma_int64)pMP3->memory.currentReadPos;
+ return MA_TRUE;
+}
+MA_API ma_bool32 ma_dr_mp3_init_memory_with_metadata(ma_dr_mp3* pMP3, const void* pData, size_t dataSize, ma_dr_mp3_meta_proc onMeta, void* pUserDataMeta, const ma_allocation_callbacks* pAllocationCallbacks)
+{
+ ma_bool32 result;
if (pMP3 == NULL) {
return MA_FALSE;
}
@@ -92749,7 +94836,21 @@ MA_API ma_bool32 ma_dr_mp3_init_memory(ma_dr_mp3* pMP3, const void* pData, size_
pMP3->memory.pData = (const ma_uint8*)pData;
pMP3->memory.dataSize = dataSize;
pMP3->memory.currentReadPos = 0;
- return ma_dr_mp3_init_internal(pMP3, ma_dr_mp3__on_read_memory, ma_dr_mp3__on_seek_memory, pMP3, pAllocationCallbacks);
+ result = ma_dr_mp3_init_internal(pMP3, ma_dr_mp3__on_read_memory, ma_dr_mp3__on_seek_memory, ma_dr_mp3__on_tell_memory, onMeta, pMP3, pUserDataMeta, pAllocationCallbacks);
+ if (result == MA_FALSE) {
+ return MA_FALSE;
+ }
+ if (pMP3->streamLength <= (ma_uint64)MA_SIZE_MAX) {
+ pMP3->memory.dataSize = (size_t)pMP3->streamLength;
+ }
+ if (pMP3->streamStartOffset > (ma_uint64)MA_SIZE_MAX) {
+ return MA_FALSE;
+ }
+ return MA_TRUE;
+}
+MA_API ma_bool32 ma_dr_mp3_init_memory(ma_dr_mp3* pMP3, const void* pData, size_t dataSize, const ma_allocation_callbacks* pAllocationCallbacks)
+{
+ return ma_dr_mp3_init_memory_with_metadata(pMP3, pData, dataSize, NULL, NULL, pAllocationCallbacks);
}
#ifndef MA_DR_MP3_NO_STDIO
#include
@@ -92760,36 +94861,76 @@ static size_t ma_dr_mp3__on_read_stdio(void* pUserData, void* pBufferOut, size_t
}
static ma_bool32 ma_dr_mp3__on_seek_stdio(void* pUserData, int offset, ma_dr_mp3_seek_origin origin)
{
- return fseek((FILE*)pUserData, offset, (origin == ma_dr_mp3_seek_origin_current) ? SEEK_CUR : SEEK_SET) == 0;
+ int whence = SEEK_SET;
+ if (origin == MA_DR_MP3_SEEK_CUR) {
+ whence = SEEK_CUR;
+ } else if (origin == MA_DR_MP3_SEEK_END) {
+ whence = SEEK_END;
+ }
+ return fseek((FILE*)pUserData, offset, whence) == 0;
}
-MA_API ma_bool32 ma_dr_mp3_init_file(ma_dr_mp3* pMP3, const char* pFilePath, const ma_allocation_callbacks* pAllocationCallbacks)
+static ma_bool32 ma_dr_mp3__on_tell_stdio(void* pUserData, ma_int64* pCursor)
+{
+ FILE* pFileStdio = (FILE*)pUserData;
+ ma_int64 result;
+ MA_DR_MP3_ASSERT(pFileStdio != NULL);
+ MA_DR_MP3_ASSERT(pCursor != NULL);
+#if defined(_WIN32) && !defined(NXDK)
+ #if defined(_MSC_VER) && _MSC_VER > 1200
+ result = _ftelli64(pFileStdio);
+ #else
+ result = ftell(pFileStdio);
+ #endif
+#else
+ result = ftell(pFileStdio);
+#endif
+ *pCursor = result;
+ return MA_TRUE;
+}
+MA_API ma_bool32 ma_dr_mp3_init_file_with_metadata(ma_dr_mp3* pMP3, const char* pFilePath, ma_dr_mp3_meta_proc onMeta, void* pUserDataMeta, const ma_allocation_callbacks* pAllocationCallbacks)
{
ma_bool32 result;
FILE* pFile;
+ if (pMP3 == NULL) {
+ return MA_FALSE;
+ }
+ MA_DR_MP3_ZERO_OBJECT(pMP3);
if (ma_fopen(&pFile, pFilePath, "rb") != MA_SUCCESS) {
return MA_FALSE;
}
- result = ma_dr_mp3_init(pMP3, ma_dr_mp3__on_read_stdio, ma_dr_mp3__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
+ result = ma_dr_mp3_init_internal(pMP3, ma_dr_mp3__on_read_stdio, ma_dr_mp3__on_seek_stdio, ma_dr_mp3__on_tell_stdio, onMeta, (void*)pFile, pUserDataMeta, pAllocationCallbacks);
if (result != MA_TRUE) {
fclose(pFile);
return result;
}
return MA_TRUE;
}
-MA_API ma_bool32 ma_dr_mp3_init_file_w(ma_dr_mp3* pMP3, const wchar_t* pFilePath, const ma_allocation_callbacks* pAllocationCallbacks)
+MA_API ma_bool32 ma_dr_mp3_init_file_with_metadata_w(ma_dr_mp3* pMP3, const wchar_t* pFilePath, ma_dr_mp3_meta_proc onMeta, void* pUserDataMeta, const ma_allocation_callbacks* pAllocationCallbacks)
{
ma_bool32 result;
FILE* pFile;
+ if (pMP3 == NULL) {
+ return MA_FALSE;
+ }
+ MA_DR_MP3_ZERO_OBJECT(pMP3);
if (ma_wfopen(&pFile, pFilePath, L"rb", pAllocationCallbacks) != MA_SUCCESS) {
return MA_FALSE;
}
- result = ma_dr_mp3_init(pMP3, ma_dr_mp3__on_read_stdio, ma_dr_mp3__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
+ result = ma_dr_mp3_init_internal(pMP3, ma_dr_mp3__on_read_stdio, ma_dr_mp3__on_seek_stdio, ma_dr_mp3__on_tell_stdio, onMeta, (void*)pFile, pUserDataMeta, pAllocationCallbacks);
if (result != MA_TRUE) {
fclose(pFile);
return result;
}
return MA_TRUE;
}
+MA_API ma_bool32 ma_dr_mp3_init_file(ma_dr_mp3* pMP3, const char* pFilePath, const ma_allocation_callbacks* pAllocationCallbacks)
+{
+ return ma_dr_mp3_init_file_with_metadata(pMP3, pFilePath, NULL, NULL, pAllocationCallbacks);
+}
+MA_API ma_bool32 ma_dr_mp3_init_file_w(ma_dr_mp3* pMP3, const wchar_t* pFilePath, const ma_allocation_callbacks* pAllocationCallbacks)
+{
+ return ma_dr_mp3_init_file_with_metadata_w(pMP3, pFilePath, NULL, NULL, pAllocationCallbacks);
+}
#endif
MA_API void ma_dr_mp3_uninit(ma_dr_mp3* pMP3)
{
@@ -92859,17 +95000,38 @@ static ma_uint64 ma_dr_mp3_read_pcm_frames_raw(ma_dr_mp3* pMP3, ma_uint64 frames
MA_DR_MP3_ASSERT(pMP3 != NULL);
MA_DR_MP3_ASSERT(pMP3->onRead != NULL);
while (framesToRead > 0) {
- ma_uint32 framesToConsume = (ma_uint32)MA_DR_MP3_MIN(pMP3->pcmFramesRemainingInMP3Frame, framesToRead);
+ ma_uint32 framesToConsume;
+ if (pMP3->currentPCMFrame < pMP3->delayInPCMFrames) {
+ ma_uint32 framesToSkip = (ma_uint32)MA_DR_MP3_MIN(pMP3->pcmFramesRemainingInMP3Frame, pMP3->delayInPCMFrames - pMP3->currentPCMFrame);
+ pMP3->currentPCMFrame += framesToSkip;
+ pMP3->pcmFramesConsumedInMP3Frame += framesToSkip;
+ pMP3->pcmFramesRemainingInMP3Frame -= framesToSkip;
+ }
+ framesToConsume = (ma_uint32)MA_DR_MP3_MIN(pMP3->pcmFramesRemainingInMP3Frame, framesToRead);
+ if (pMP3->totalPCMFrameCount != MA_UINT64_MAX && pMP3->totalPCMFrameCount > pMP3->paddingInPCMFrames) {
+ if (pMP3->currentPCMFrame < (pMP3->totalPCMFrameCount - pMP3->paddingInPCMFrames)) {
+ ma_uint64 framesRemainigToPadding = (pMP3->totalPCMFrameCount - pMP3->paddingInPCMFrames) - pMP3->currentPCMFrame;
+ if (framesToConsume > framesRemainigToPadding) {
+ framesToConsume = (ma_uint32)framesRemainigToPadding;
+ }
+ } else {
+ break;
+ }
+ }
if (pBufferOut != NULL) {
- #if defined(MA_DR_MP3_FLOAT_OUTPUT)
- float* pFramesOutF32 = (float*)MA_DR_MP3_OFFSET_PTR(pBufferOut, sizeof(float) * totalFramesRead * pMP3->channels);
- float* pFramesInF32 = (float*)MA_DR_MP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(float) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels);
- MA_DR_MP3_COPY_MEMORY(pFramesOutF32, pFramesInF32, sizeof(float) * framesToConsume * pMP3->channels);
- #else
- ma_int16* pFramesOutS16 = (ma_int16*)MA_DR_MP3_OFFSET_PTR(pBufferOut, sizeof(ma_int16) * totalFramesRead * pMP3->channels);
- ma_int16* pFramesInS16 = (ma_int16*)MA_DR_MP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(ma_int16) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels);
- MA_DR_MP3_COPY_MEMORY(pFramesOutS16, pFramesInS16, sizeof(ma_int16) * framesToConsume * pMP3->channels);
- #endif
+ #if defined(MA_DR_MP3_FLOAT_OUTPUT)
+ {
+ float* pFramesOutF32 = (float*)MA_DR_MP3_OFFSET_PTR(pBufferOut, sizeof(float) * totalFramesRead * pMP3->channels);
+ float* pFramesInF32 = (float*)MA_DR_MP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(float) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels);
+ MA_DR_MP3_COPY_MEMORY(pFramesOutF32, pFramesInF32, sizeof(float) * framesToConsume * pMP3->channels);
+ }
+ #else
+ {
+ ma_int16* pFramesOutS16 = (ma_int16*)MA_DR_MP3_OFFSET_PTR(pBufferOut, sizeof(ma_int16) * totalFramesRead * pMP3->channels);
+ ma_int16* pFramesInS16 = (ma_int16*)MA_DR_MP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(ma_int16) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels);
+ MA_DR_MP3_COPY_MEMORY(pFramesOutS16, pFramesInS16, sizeof(ma_int16) * framesToConsume * pMP3->channels);
+ }
+ #endif
}
pMP3->currentPCMFrame += framesToConsume;
pMP3->pcmFramesConsumedInMP3Frame += framesToConsume;
@@ -92879,6 +95041,9 @@ static ma_uint64 ma_dr_mp3_read_pcm_frames_raw(ma_dr_mp3* pMP3, ma_uint64 frames
if (framesToRead == 0) {
break;
}
+ if (pMP3->totalPCMFrameCount != MA_UINT64_MAX && pMP3->totalPCMFrameCount > pMP3->paddingInPCMFrames && pMP3->currentPCMFrame >= (pMP3->totalPCMFrameCount - pMP3->paddingInPCMFrames)) {
+ break;
+ }
MA_DR_MP3_ASSERT(pMP3->pcmFramesRemainingInMP3Frame == 0);
if (ma_dr_mp3_decode_next_frame(pMP3) == 0) {
break;
@@ -92958,7 +95123,7 @@ static ma_bool32 ma_dr_mp3_seek_to_start_of_stream(ma_dr_mp3* pMP3)
{
MA_DR_MP3_ASSERT(pMP3 != NULL);
MA_DR_MP3_ASSERT(pMP3->onSeek != NULL);
- if (!ma_dr_mp3__on_seek(pMP3, 0, ma_dr_mp3_seek_origin_start)) {
+ if (!ma_dr_mp3__on_seek_64(pMP3, pMP3->streamStartOffset, MA_DR_MP3_SEEK_SET)) {
return MA_FALSE;
}
ma_dr_mp3_reset(pMP3);
@@ -93024,7 +95189,7 @@ static ma_bool32 ma_dr_mp3_seek_to_pcm_frame__seek_table(ma_dr_mp3* pMP3, ma_uin
seekPoint.mp3FramesToDiscard = 0;
seekPoint.pcmFramesToDiscard = 0;
}
- if (!ma_dr_mp3__on_seek_64(pMP3, seekPoint.seekPosInBytes, ma_dr_mp3_seek_origin_start)) {
+ if (!ma_dr_mp3__on_seek_64(pMP3, seekPoint.seekPosInBytes, MA_DR_MP3_SEEK_SET)) {
return MA_FALSE;
}
ma_dr_mp3_reset(pMP3);
@@ -93035,7 +95200,7 @@ static ma_bool32 ma_dr_mp3_seek_to_pcm_frame__seek_table(ma_dr_mp3* pMP3, ma_uin
if (iMP3Frame == seekPoint.mp3FramesToDiscard-1) {
pPCMFrames = (ma_dr_mp3d_sample_t*)pMP3->pcmFrames;
}
- pcmFramesRead = ma_dr_mp3_decode_next_frame_ex(pMP3, pPCMFrames);
+ pcmFramesRead = ma_dr_mp3_decode_next_frame_ex(pMP3, pPCMFrames, NULL, NULL);
if (pcmFramesRead == 0) {
return MA_FALSE;
}
@@ -93077,7 +95242,7 @@ MA_API ma_bool32 ma_dr_mp3_get_mp3_and_pcm_frame_count(ma_dr_mp3* pMP3, ma_uint6
totalMP3FrameCount = 0;
for (;;) {
ma_uint32 pcmFramesInCurrentMP3Frame;
- pcmFramesInCurrentMP3Frame = ma_dr_mp3_decode_next_frame_ex(pMP3, NULL);
+ pcmFramesInCurrentMP3Frame = ma_dr_mp3_decode_next_frame_ex(pMP3, NULL, NULL, NULL);
if (pcmFramesInCurrentMP3Frame == 0) {
break;
}
@@ -93101,10 +95266,26 @@ MA_API ma_bool32 ma_dr_mp3_get_mp3_and_pcm_frame_count(ma_dr_mp3* pMP3, ma_uint6
MA_API ma_uint64 ma_dr_mp3_get_pcm_frame_count(ma_dr_mp3* pMP3)
{
ma_uint64 totalPCMFrameCount;
- if (!ma_dr_mp3_get_mp3_and_pcm_frame_count(pMP3, NULL, &totalPCMFrameCount)) {
+ if (pMP3 == NULL) {
return 0;
}
- return totalPCMFrameCount;
+ if (pMP3->totalPCMFrameCount != MA_UINT64_MAX) {
+ totalPCMFrameCount = pMP3->totalPCMFrameCount;
+ if (totalPCMFrameCount >= pMP3->delayInPCMFrames) {
+ totalPCMFrameCount -= pMP3->delayInPCMFrames;
+ } else {
+ }
+ if (totalPCMFrameCount >= pMP3->paddingInPCMFrames) {
+ totalPCMFrameCount -= pMP3->paddingInPCMFrames;
+ } else {
+ }
+ return totalPCMFrameCount;
+ } else {
+ if (!ma_dr_mp3_get_mp3_and_pcm_frame_count(pMP3, NULL, &totalPCMFrameCount)) {
+ return 0;
+ }
+ return totalPCMFrameCount;
+ }
}
MA_API ma_uint64 ma_dr_mp3_get_mp3_frame_count(ma_dr_mp3* pMP3)
{
@@ -93174,7 +95355,7 @@ MA_API ma_bool32 ma_dr_mp3_calculate_seek_points(ma_dr_mp3* pMP3, ma_uint32* pSe
MA_DR_MP3_ASSERT(pMP3->streamCursor >= pMP3->dataSize);
mp3FrameInfo[iMP3Frame].bytePos = pMP3->streamCursor - pMP3->dataSize;
mp3FrameInfo[iMP3Frame].pcmFrameIndex = runningPCMFrameCount;
- pcmFramesInCurrentMP3FrameIn = ma_dr_mp3_decode_next_frame_ex(pMP3, NULL);
+ pcmFramesInCurrentMP3FrameIn = ma_dr_mp3_decode_next_frame_ex(pMP3, NULL, NULL, NULL);
if (pcmFramesInCurrentMP3FrameIn == 0) {
return MA_FALSE;
}
@@ -93198,7 +95379,7 @@ MA_API ma_bool32 ma_dr_mp3_calculate_seek_points(ma_dr_mp3* pMP3, ma_uint32* pSe
}
mp3FrameInfo[MA_DR_MP3_COUNTOF(mp3FrameInfo)-1].bytePos = pMP3->streamCursor - pMP3->dataSize;
mp3FrameInfo[MA_DR_MP3_COUNTOF(mp3FrameInfo)-1].pcmFrameIndex = runningPCMFrameCount;
- pcmFramesInCurrentMP3FrameIn = ma_dr_mp3_decode_next_frame_ex(pMP3, NULL);
+ pcmFramesInCurrentMP3FrameIn = ma_dr_mp3_decode_next_frame_ex(pMP3, NULL, NULL, NULL);
if (pcmFramesInCurrentMP3FrameIn == 0) {
pSeekPoints[iSeekPoint].seekPosInBytes = mp3FrameInfo[0].bytePos;
pSeekPoints[iSeekPoint].pcmFrameIndex = nextTargetPCMFrame;
@@ -93336,18 +95517,18 @@ static ma_int16* ma_dr_mp3__full_read_and_close_s16(ma_dr_mp3* pMP3, ma_dr_mp3_c
}
return pFrames;
}
-MA_API float* ma_dr_mp3_open_and_read_pcm_frames_f32(ma_dr_mp3_read_proc onRead, ma_dr_mp3_seek_proc onSeek, void* pUserData, ma_dr_mp3_config* pConfig, ma_uint64* pTotalFrameCount, const ma_allocation_callbacks* pAllocationCallbacks)
+MA_API float* ma_dr_mp3_open_and_read_pcm_frames_f32(ma_dr_mp3_read_proc onRead, ma_dr_mp3_seek_proc onSeek, ma_dr_mp3_tell_proc onTell, void* pUserData, ma_dr_mp3_config* pConfig, ma_uint64* pTotalFrameCount, const ma_allocation_callbacks* pAllocationCallbacks)
{
ma_dr_mp3 mp3;
- if (!ma_dr_mp3_init(&mp3, onRead, onSeek, pUserData, pAllocationCallbacks)) {
+ if (!ma_dr_mp3_init(&mp3, onRead, onSeek, onTell, NULL, pUserData, pAllocationCallbacks)) {
return NULL;
}
return ma_dr_mp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount);
}
-MA_API ma_int16* ma_dr_mp3_open_and_read_pcm_frames_s16(ma_dr_mp3_read_proc onRead, ma_dr_mp3_seek_proc onSeek, void* pUserData, ma_dr_mp3_config* pConfig, ma_uint64* pTotalFrameCount, const ma_allocation_callbacks* pAllocationCallbacks)
+MA_API ma_int16* ma_dr_mp3_open_and_read_pcm_frames_s16(ma_dr_mp3_read_proc onRead, ma_dr_mp3_seek_proc onSeek, ma_dr_mp3_tell_proc onTell, void* pUserData, ma_dr_mp3_config* pConfig, ma_uint64* pTotalFrameCount, const ma_allocation_callbacks* pAllocationCallbacks)
{
ma_dr_mp3 mp3;
- if (!ma_dr_mp3_init(&mp3, onRead, onSeek, pUserData, pAllocationCallbacks)) {
+ if (!ma_dr_mp3_init(&mp3, onRead, onSeek, onTell, NULL, pUserData, pAllocationCallbacks)) {
return NULL;
}
return ma_dr_mp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount);
@@ -93465,4 +95646,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-*/
+*/
\ No newline at end of file
diff --git a/src/external/qoa.h b/src/external/qoa.h
index f0f44214d..57b85d131 100644
--- a/src/external/qoa.h
+++ b/src/external/qoa.h
@@ -500,7 +500,7 @@ void *qoa_encode(const short *sample_data, qoa_desc *qoa, unsigned int *out_len)
num_frames * QOA_LMS_LEN * 4 * qoa->channels + /* 4 * 4 bytes lms state per channel */
num_slices * 8 * qoa->channels; /* 8 byte slices */
- unsigned char *bytes = QOA_MALLOC(encoded_size);
+ unsigned char *bytes = (unsigned char *)QOA_MALLOC(encoded_size);
for (unsigned int c = 0; c < qoa->channels; c++) {
/* Set the initial LMS weights to {0, 0, -1, 2}. This helps with the
@@ -657,7 +657,7 @@ short *qoa_decode(const unsigned char *bytes, int size, qoa_desc *qoa) {
/* Calculate the required size of the sample buffer and allocate */
int total_samples = qoa->samples * qoa->channels;
- short *sample_data = QOA_MALLOC(total_samples * sizeof(short));
+ short *sample_data = (short *)QOA_MALLOC(total_samples * sizeof(short));
unsigned int sample_index = 0;
unsigned int frame_len;
@@ -733,7 +733,7 @@ void *qoa_read(const char *filename, qoa_desc *qoa) {
bytes_read = fread(data, 1, size, f);
fclose(f);
- sample_data = qoa_decode(data, bytes_read, qoa);
+ sample_data = qoa_decode((const unsigned char *)data, bytes_read, qoa);
QOA_FREE(data);
return sample_data;
}
diff --git a/src/external/qoaplay.c b/src/external/qoaplay.c
index 4378e5ebd..0ac6f6c06 100644
--- a/src/external/qoaplay.c
+++ b/src/external/qoaplay.c
@@ -104,7 +104,7 @@ qoaplay_desc *qoaplay_open(const char *path)
// + a buffer to hold one frame of encoded data
unsigned int buffer_size = qoa_max_frame_size(&qoa);
unsigned int sample_data_size = qoa.channels*QOA_FRAME_LEN*sizeof(short)*2;
- qoaplay_desc *qoa_ctx = QOA_MALLOC(sizeof(qoaplay_desc) + buffer_size + sample_data_size);
+ qoaplay_desc *qoa_ctx = (qoaplay_desc *)QOA_MALLOC(sizeof(qoaplay_desc) + buffer_size + sample_data_size);
memset(qoa_ctx, 0, sizeof(qoaplay_desc));
qoa_ctx->file = file;
@@ -136,7 +136,7 @@ qoaplay_desc *qoaplay_open_memory(const unsigned char *data, int data_size)
// + the sample data for one frame
// + a buffer to hold one frame of encoded data
unsigned int sample_data_size = qoa.channels*QOA_FRAME_LEN*sizeof(short)*2;
- qoaplay_desc *qoa_ctx = QOA_MALLOC(sizeof(qoaplay_desc) + sample_data_size + data_size);
+ qoaplay_desc *qoa_ctx = (qoaplay_desc *)QOA_MALLOC(sizeof(qoaplay_desc) + sample_data_size + data_size);
memset(qoa_ctx, 0, sizeof(qoaplay_desc));
qoa_ctx->file = NULL;
diff --git a/src/external/tinyobj_loader_c.h b/src/external/tinyobj_loader_c.h
index 55d595a69..88b2acbdc 100644
--- a/src/external/tinyobj_loader_c.h
+++ b/src/external/tinyobj_loader_c.h
@@ -454,7 +454,7 @@ static void parseFloat3(float *x, float *y, float *z, const char **token) {
}
static unsigned int my_strnlen(const char *s, unsigned int n) {
- const char *p = memchr(s, 0, n);
+ const char *p = (const char *)memchr(s, 0, n);
return p ? (unsigned int)(p - s) : n;
}
diff --git a/src/external/vox_loader.h b/src/external/vox_loader.h
index 0d328c078..6d933907c 100644
--- a/src/external/vox_loader.h
+++ b/src/external/vox_loader.h
@@ -151,7 +151,7 @@ void Vox_FreeArrays(VoxArray3D* voxarray);
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
// Implementation
-/////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
#ifdef VOX_LOADER_IMPLEMENTATION
@@ -165,7 +165,7 @@ void Vox_FreeArrays(VoxArray3D* voxarray);
static void initArrayUShort(ArrayUShort* a, int initialSize)
{
- a->array = VOX_MALLOC(initialSize * sizeof(unsigned short));
+ a->array = (unsigned short *)VOX_MALLOC(initialSize * sizeof(unsigned short));
a->used = 0;
a->size = initialSize;
}
@@ -175,7 +175,7 @@ static void insertArrayUShort(ArrayUShort* a, unsigned short element)
if (a->used == a->size)
{
a->size *= 2;
- a->array = VOX_REALLOC(a->array, a->size * sizeof(unsigned short));
+ a->array = (unsigned short *)VOX_REALLOC(a->array, a->size * sizeof(unsigned short));
}
a->array[a->used++] = element;
}
@@ -194,7 +194,7 @@ static void freeArrayUShort(ArrayUShort* a)
static void initArrayVector3(ArrayVector3* a, int initialSize)
{
- a->array = VOX_MALLOC(initialSize * sizeof(VoxVector3));
+ a->array = (VoxVector3 *)VOX_MALLOC(initialSize * sizeof(VoxVector3));
a->used = 0;
a->size = initialSize;
}
@@ -204,7 +204,7 @@ static void insertArrayVector3(ArrayVector3* a, VoxVector3 element)
if (a->used == a->size)
{
a->size *= 2;
- a->array = VOX_REALLOC(a->array, a->size * sizeof(VoxVector3));
+ a->array = (VoxVector3 *)VOX_REALLOC(a->array, a->size * sizeof(VoxVector3));
}
a->array[a->used++] = element;
}
@@ -222,7 +222,7 @@ static void freeArrayVector3(ArrayVector3* a)
static void initArrayColor(ArrayColor* a, int initialSize)
{
- a->array = VOX_MALLOC(initialSize * sizeof(VoxColor));
+ a->array = (VoxColor *)VOX_MALLOC(initialSize * sizeof(VoxColor));
a->used = 0;
a->size = initialSize;
}
@@ -232,7 +232,7 @@ static void insertArrayColor(ArrayColor* a, VoxColor element)
if (a->used == a->size)
{
a->size *= 2;
- a->array = VOX_REALLOC(a->array, a->size * sizeof(VoxColor));
+ a->array = (VoxColor *)VOX_REALLOC(a->array, a->size * sizeof(VoxColor));
}
a->array[a->used++] = element;
}
@@ -327,7 +327,7 @@ static void Vox_AllocArray(VoxArray3D* pvoxarray, int _sx, int _sy, int _sz)
// Alloc chunks array
int size = sizeof(CubeChunk3D) * chx * chy * chz;
- pvoxarray->m_arrayChunks = VOX_MALLOC(size);
+ pvoxarray->m_arrayChunks = (CubeChunk3D *)VOX_MALLOC(size);
pvoxarray->arrayChunksSize = size;
// Init chunks array
@@ -366,7 +366,7 @@ static void Vox_SetVoxel(VoxArray3D* pvoxarray, int x, int y, int z, unsigned ch
if (chunk->m_array == 0)
{
int size = CHUNKSIZE * CHUNKSIZE * CHUNKSIZE;
- chunk->m_array = VOX_MALLOC(size);
+ chunk->m_array = (unsigned char *)VOX_MALLOC(size);
chunk->arraySize = size;
memset(chunk->m_array, 0, size);
diff --git a/src/external/win32_clipboard.h b/src/external/win32_clipboard.h
index 832856432..1f9a27521 100644
--- a/src/external/win32_clipboard.h
+++ b/src/external/win32_clipboard.h
@@ -13,7 +13,7 @@ unsigned char* Win32GetClipboardImageData(int* width, int* height, unsigned long
#include
#include
-// NOTE: These search for architecture is taken from "Windows.h", and it's necessary if we really don't wanna import windows.h
+// NOTE: These search for architecture is taken from "Windows.h", and it's necessary if we really don't wanna import windows.h
// and still make it compile on msvc, because import indirectly importing "winnt.h" (e.g. ) can cause problems is these are not defined.
#if !defined(_X86_) && !defined(_68K_) && !defined(_MPPC_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64_) && !defined(_ARM64EC_) && defined(_M_IX86)
#define _X86_
@@ -93,14 +93,6 @@ unsigned char* Win32GetClipboardImageData(int* width, int* height, unsigned long
typedef int WINBOOL;
-
-// typedef HANDLE HGLOBAL;
-
-#ifndef HWND
-#define HWND void*
-#endif
-
-
#if !defined(_WINUSER_) || !defined(WINUSER_ALREADY_INCLUDED)
WINUSERAPI WINBOOL WINAPI OpenClipboard(HWND hWndNewOwner);
WINUSERAPI WINBOOL WINAPI CloseClipboard(VOID);
@@ -284,7 +276,7 @@ unsigned char* Win32GetClipboardImageData(int* width, int* height, unsigned long
// This may be wrong since we might be allocating in a DLL and freeing from another module, the main application
// that may cause heap corruption. We could create a FreeImage function
//
- bmpData = malloc(sizeof(bmpFileHeader) + clipDataSize);
+ bmpData = (BYTE *)malloc(sizeof(bmpFileHeader) + clipDataSize);
// First we add the header for a bmp file
memcpy(bmpData, &bmpFileHeader, sizeof(bmpFileHeader));
// Then we add the header for the bmp itself + the pixel data
@@ -371,4 +363,3 @@ static int GetPixelDataOffset(BITMAPINFOHEADER bih)
}
#endif // WIN32_CLIPBOARD_IMPLEMENTATION
// EOF
-
diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c
index cab497266..729ca308c 100644
--- a/src/platforms/rcore_desktop_glfw.c
+++ b/src/platforms/rcore_desktop_glfw.c
@@ -56,10 +56,14 @@
// Support retrieving native window handlers
#if defined(_WIN32)
- typedef void *PVOID;
- typedef PVOID HANDLE;
- #include "../external/win32_clipboard.h"
- typedef HANDLE HWND;
+ #if !defined(HWND) && !defined(_MSVC_LANG)
+ #define HWND void*
+ #elif !defined(HWND) && defined(_MSVC_LANG)
+ typedef struct HWND__ *HWND;
+ #endif
+
+ #include "../external/win32_clipboard.h" // Clipboard image copy-paste
+
#define GLFW_EXPOSE_NATIVE_WIN32
#define GLFW_NATIVE_INCLUDE_NONE // To avoid some symbols re-definition in windows.h
#include "GLFW/glfw3native.h"
@@ -959,8 +963,11 @@ int GetMonitorRefreshRate(int monitor)
if ((monitor >= 0) && (monitor < monitorCount))
{
- const GLFWvidmode *vidmode = glfwGetVideoMode(monitors[monitor]);
- refresh = vidmode->refreshRate;
+ const GLFWvidmode *mode = glfwGetVideoMode(monitors[monitor]);
+
+ if (mode) refresh = mode->refreshRate;
+ else TRACELOG(LOG_WARNING, "GLFW: Failed to find video mode for selected monitor");
+
}
else TRACELOG(LOG_WARNING, "GLFW: Failed to find selected monitor");
@@ -1025,10 +1032,10 @@ Image GetClipboardImage(void)
int width = 0;
int height = 0;
- fileData = (void*)Win32GetClipboardImageData(&width, &height, &dataSize);
+ fileData = (void *)Win32GetClipboardImageData(&width, &height, &dataSize);
if (fileData == NULL) TRACELOG(LOG_WARNING, "Clipboard image: Couldn't get clipboard data.");
- else image = LoadImageFromMemory(".bmp", fileData, (int)dataSize);
+ else image = LoadImageFromMemory(".bmp", (const unsigned char *)fileData, (int)dataSize);
#else
TRACELOG(LOG_WARNING, "GetClipboardImage() not implemented on target platform");
#endif
@@ -1350,8 +1357,8 @@ int InitPlatform(void)
const GLFWallocator allocator = {
.allocate = AllocateWrapper,
- .deallocate = DeallocateWrapper,
.reallocate = ReallocateWrapper,
+ .deallocate = DeallocateWrapper,
.user = NULL, // RL_*ALLOC macros are not capable of handling user-provided data
};
diff --git a/src/platforms/rcore_desktop_rgfw.c b/src/platforms/rcore_desktop_rgfw.c
index f2e2a7407..52ec6ac94 100644
--- a/src/platforms/rcore_desktop_rgfw.c
+++ b/src/platforms/rcore_desktop_rgfw.c
@@ -83,7 +83,14 @@ void CloseWindow(void);
#undef MAX_PATH
+#if defined(__cplusplus)
+extern "C" {
+#endif
__declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int CodePage, unsigned long dwFlags, const char *lpMultiByteStr, int cbMultiByte, wchar_t *lpWideCharStr, int cchWideChar);
+#if defined(__cplusplus)
+}
+#endif
+
#endif
#if defined(__APPLE__)
@@ -135,7 +142,6 @@ static bool RGFW_disableCursor = false;
static const unsigned short keyMappingRGFW[] = {
[RGFW_keyNULL] = KEY_NULL,
[RGFW_return] = KEY_ENTER,
- [RGFW_return] = KEY_ENTER,
[RGFW_apostrophe] = KEY_APOSTROPHE,
[RGFW_comma] = KEY_COMMA,
[RGFW_minus] = KEY_MINUS,
@@ -565,7 +571,7 @@ int RGFW_formatToChannels(int format)
// Set icon for window
void SetWindowIcon(Image image)
{
- RGFW_window_setIcon(platform.window, image.data, RGFW_AREA(image.width, image.height), RGFW_formatToChannels(image.format));
+ RGFW_window_setIcon(platform.window, (u8 *)image.data, RGFW_AREA(image.width, image.height), RGFW_formatToChannels(image.format));
}
// Set icon for window
@@ -586,8 +592,8 @@ void SetWindowIcons(Image *images, int count)
if ((smallIcon == NULL) || ((images[i].width < smallIcon->width) && (images[i].height > smallIcon->height))) smallIcon = &images[i];
}
- if (smallIcon != NULL) RGFW_window_setIconEx(platform.window, smallIcon->data, RGFW_AREA(smallIcon->width, smallIcon->height), RGFW_formatToChannels(smallIcon->format), RGFW_iconWindow);
- if (bigIcon != NULL) RGFW_window_setIconEx(platform.window, bigIcon->data, RGFW_AREA(bigIcon->width, bigIcon->height), RGFW_formatToChannels(bigIcon->format), RGFW_iconTaskbar);
+ if (smallIcon != NULL) RGFW_window_setIconEx(platform.window, (u8 *)smallIcon->data, RGFW_AREA(smallIcon->width, smallIcon->height), RGFW_formatToChannels(smallIcon->format), RGFW_iconWindow);
+ if (bigIcon != NULL) RGFW_window_setIconEx(platform.window, (u8 *)bigIcon->data, RGFW_AREA(bigIcon->width, bigIcon->height), RGFW_formatToChannels(bigIcon->format), RGFW_iconTaskbar);
}
}
@@ -806,7 +812,7 @@ Image GetClipboardImage(void)
fileData = (void *)Win32GetClipboardImageData(&width, &height, &dataSize);
if (fileData == NULL) TRACELOG(LOG_WARNING, "Clipboard image: Couldn't get clipboard data");
- else image = LoadImageFromMemory(".bmp", fileData, dataSize);
+ else image = LoadImageFromMemory(".bmp", (const unsigned char *)fileData, dataSize);
#else
TRACELOG(LOG_WARNING, "Clipboard image: PLATFORM_DESKTOP_RGFW doesn't implement GetClipboardImage() for this OS");
#endif
@@ -1419,7 +1425,8 @@ void ClosePlatform(void)
// Keycode mapping
static KeyboardKey ConvertScancodeToKey(u32 keycode)
{
- if (keycode > sizeof(keyMappingRGFW)/sizeof(unsigned short)) return 0;
+ if (keycode > sizeof(keyMappingRGFW)/sizeof(unsigned short)) return KEY_NULL;
- return keyMappingRGFW[keycode];
+ return (KeyboardKey)keyMappingRGFW[keycode];
}
+
diff --git a/src/platforms/rcore_desktop_win32.c b/src/platforms/rcore_desktop_win32.c
index b9acde0e8..3ccd4d3bd 100644
--- a/src/platforms/rcore_desktop_win32.c
+++ b/src/platforms/rcore_desktop_win32.c
@@ -1486,7 +1486,7 @@ int InitPlatform(void)
platform.hbitmap = CreateDIBSection(
platform.hdcmem, &bmi, DIB_RGB_COLORS,
- (void**)&platform.pixels, NULL, 0);
+ (void **)&platform.pixels, NULL, 0);
SelectObject(platform.hdcmem, platform.hbitmap);
diff --git a/src/raudio.c b/src/raudio.c
index 798c062e9..de2bf81b2 100644
--- a/src/raudio.c
+++ b/src/raudio.c
@@ -575,7 +575,7 @@ AudioBuffer *LoadAudioBuffer(ma_format format, ma_uint32 channels, ma_uint32 sam
return NULL;
}
- if (sizeInFrames > 0) audioBuffer->data = RL_CALLOC(sizeInFrames*channels*ma_get_bytes_per_sample(format), 1);
+ if (sizeInFrames > 0) audioBuffer->data = (unsigned char *)RL_CALLOC(sizeInFrames*channels*ma_get_bytes_per_sample(format), 1);
// Audio data runs through a format converter
ma_data_converter_config converterConfig = ma_data_converter_config_init(format, AUDIO_DEVICE_FORMAT, channels, AUDIO_DEVICE_CHANNELS, sampleRate, AUDIO.System.device.sampleRate);
@@ -808,7 +808,7 @@ Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int
wave.data = (short *)RL_MALLOC((size_t)wave.frameCount*wave.channels*sizeof(short));
// NOTE: We are forcing conversion to 16bit sample size on reading
- drwav_read_pcm_frames_s16(&wav, wave.frameCount, wave.data);
+ drwav_read_pcm_frames_s16(&wav, wave.frameCount, (drwav_int16 *)wave.data);
}
else TRACELOG(LOG_WARNING, "WAVE: Failed to load WAV data");
@@ -1091,7 +1091,7 @@ bool ExportWave(Wave wave, const char *fileName)
qoa.samplerate = wave.sampleRate;
qoa.samples = wave.frameCount;
- int bytesWritten = qoa_write(fileName, wave.data, &qoa);
+ int bytesWritten = qoa_write(fileName, (const short *)wave.data, &qoa);
if (bytesWritten > 0) success = true;
}
else TRACELOG(LOG_WARNING, "AUDIO: Wave data must be 16 bit per sample for QOA format export");
@@ -1587,7 +1587,7 @@ Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data,
else if ((strcmp(fileType, ".mp3") == 0) || (strcmp(fileType, ".MP3") == 0))
{
drmp3 *ctxMp3 = (drmp3 *)RL_CALLOC(1, sizeof(drmp3));
- int success = drmp3_init_memory(ctxMp3, (const void*)data, dataSize, NULL);
+ int success = drmp3_init_memory(ctxMp3, (const void *)data, dataSize, NULL);
if (success)
{
@@ -1631,7 +1631,7 @@ Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data,
#if defined(SUPPORT_FILEFORMAT_FLAC)
else if ((strcmp(fileType, ".flac") == 0) || (strcmp(fileType, ".FLAC") == 0))
{
- drflac *ctxFlac = drflac_open_memory((const void*)data, dataSize, NULL);
+ drflac *ctxFlac = drflac_open_memory((const void *)data, dataSize, NULL);
if (ctxFlac != NULL)
{
@@ -2079,7 +2079,7 @@ float GetMusicTimePlayed(Music music)
{
uint64_t framesPlayed = 0;
- jar_xm_get_position(music.ctxData, NULL, NULL, NULL, &framesPlayed);
+ jar_xm_get_position((jar_xm_context_t *)music.ctxData, NULL, NULL, NULL, &framesPlayed);
secondsPlayed = (float)framesPlayed/music.stream.sampleRate;
}
else
diff --git a/src/raylib.h b/src/raylib.h
index c57efc2e1..e4be11084 100644
--- a/src/raylib.h
+++ b/src/raylib.h
@@ -1161,9 +1161,10 @@ RLAPI unsigned char *CompressData(const unsigned char *data, int dataSize, int *
RLAPI unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize); // Decompress data (DEFLATE algorithm), memory must be MemFree()
RLAPI char *EncodeDataBase64(const unsigned char *data, int dataSize, int *outputSize); // Encode data to Base64 string (includes NULL terminator), memory must be MemFree()
RLAPI unsigned char *DecodeDataBase64(const char *text, int *outputSize); // Decode Base64 string (expected NULL terminated), memory must be MemFree()
-RLAPI unsigned int ComputeCRC32(unsigned char *data, int dataSize); // Compute CRC32 hash code
-RLAPI unsigned int *ComputeMD5(unsigned char *data, int dataSize); // Compute MD5 hash code, returns static int[4] (16 bytes)
-RLAPI unsigned int *ComputeSHA1(unsigned char *data, int dataSize); // Compute SHA1 hash code, returns static int[5] (20 bytes)
+RLAPI unsigned int ComputeCRC32(unsigned char *data, int dataSize); // Compute CRC32 hash code
+RLAPI unsigned int *ComputeMD5(unsigned char *data, int dataSize); // Compute MD5 hash code, returns static int[4] (16 bytes)
+RLAPI unsigned int *ComputeSHA1(unsigned char *data, int dataSize); // Compute SHA1 hash code, returns static int[5] (20 bytes)
+RLAPI unsigned int *ComputeSHA256(unsigned char *data, int dataSize); // Compute SHA256 hash code, returns static int[8] (32 bytes)
// Automation events functionality
RLAPI AutomationEventList LoadAutomationEventList(const char *fileName); // Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS
diff --git a/src/rcore.c b/src/rcore.c
index b9098db02..f87b68783 100644
--- a/src/rcore.c
+++ b/src/rcore.c
@@ -162,15 +162,19 @@
// Platform specific defines to handle GetApplicationDirectory()
#if (defined(_WIN32) && !defined(PLATFORM_DESKTOP_RGFW)) || (defined(_MSC_VER) && defined(PLATFORM_DESKTOP_RGFW))
- #ifndef MAX_PATH
- #define MAX_PATH 1025
- #endif
+
struct HINSTANCE__;
+#if defined(__cplusplus)
+extern "C" {
+#endif
__declspec(dllimport) unsigned long __stdcall GetModuleFileNameA(struct HINSTANCE__ *hModule, char *lpFilename, unsigned long nSize);
__declspec(dllimport) unsigned long __stdcall GetModuleFileNameW(struct HINSTANCE__ *hModule, wchar_t *lpFilename, unsigned long nSize);
__declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default);
__declspec(dllimport) unsigned int __stdcall timeBeginPeriod(unsigned int uPeriod);
__declspec(dllimport) unsigned int __stdcall timeEndPeriod(unsigned int uPeriod);
+#if defined(__cplusplus)
+}
+#endif
#elif defined(__linux__)
#include
#elif defined(__FreeBSD__)
@@ -2330,8 +2334,8 @@ const char *GetApplicationDirectory(void)
int len = 0;
#if defined(UNICODE)
unsigned short widePath[MAX_PATH];
- len = GetModuleFileNameW(NULL, widePath, MAX_PATH);
- len = WideCharToMultiByte(0, 0, widePath, len, appDir, MAX_PATH, NULL, NULL);
+ len = GetModuleFileNameW(NULL, (wchar_t *)widePath, MAX_PATH);
+ len = WideCharToMultiByte(0, 0, (wchar_t *)widePath, len, appDir, MAX_PATH, NULL, NULL);
#else
len = GetModuleFileNameA(NULL, appDir, MAX_PATH);
#endif
@@ -3075,11 +3079,113 @@ unsigned int *ComputeSHA1(unsigned char *data, int dataSize)
hash[4] += e;
}
- free(msg);
+ RL_FREE(msg);
return hash;
}
+// Compute SHA-256 hash code
+// NOTE: Returns a static int[8] array (32 bytes)
+unsigned int *ComputeSHA256(unsigned char *data, int dataSize)
+{
+ #define ROTATE_RIGHT(x, c) ((x >> c) | (x << ((sizeof(unsigned int) * 8) - c)))
+ #define SHA256_A0(x) (ROTATE_RIGHT(x, 7) ^ ROTATE_RIGHT(x, 18) ^ (x >> 3))
+ #define SHA256_A1(x) (ROTATE_RIGHT(x, 17) ^ ROTATE_RIGHT(x, 19) ^ (x >> 10))
+
+ static const unsigned int k[64] = {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+ };
+
+ static unsigned int hash[8];
+ hash[0] = 0x6A09e667;
+ hash[1] = 0xbb67ae85;
+ hash[2] = 0x3c6ef372;
+ hash[3] = 0xa54ff53a;
+ hash[4] = 0x510e527f;
+ hash[5] = 0x9b05688c;
+ hash[6] = 0x1f83d9ab;
+ hash[7] = 0x5be0cd19;
+
+ const unsigned long long int bitLen = ((unsigned long long int)dataSize)*8;
+ unsigned long long int paddedSize = dataSize + sizeof(dataSize);
+ paddedSize += (64 - (paddedSize%64));
+ unsigned char *buffer = RL_CALLOC(paddedSize, sizeof(unsigned char));
+
+ memcpy(buffer, data, dataSize);
+ buffer[dataSize] = 0x80;
+ for (int i = 1; i <= sizeof(bitLen); i++)
+ buffer[(paddedSize - sizeof(bitLen)) + (i - 1)] = (bitLen >> (8*(sizeof(bitLen) - i))) & 0xFF;
+
+ for (unsigned long long int blockN = 0; blockN < paddedSize/64; blockN++)
+ {
+ unsigned int a = hash[0];
+ unsigned int b = hash[1];
+ unsigned int c = hash[2];
+ unsigned int d = hash[3];
+ unsigned int e = hash[4];
+ unsigned int f = hash[5];
+ unsigned int g = hash[6];
+ unsigned int h = hash[7];
+
+ unsigned char *block = buffer + (blockN*64);
+ unsigned int w[64];
+ for (int i = 0; i < 16; i++)
+ {
+ w[i] =
+ ((unsigned int)block[i*4 + 0] << 24) |
+ ((unsigned int)block[i*4 + 1] << 16) |
+ ((unsigned int)block[i*4 + 2] << 8) |
+ ((unsigned int)block[i*4 + 3]);
+ }
+ for (int t = 16; t < 64; t++) w[t] = SHA256_A1(w[t - 2]) + w[t - 7] + SHA256_A0(w[t - 15]) + w[t - 16];
+
+ for (unsigned long long int t = 0; t < 64; t++)
+ {
+ unsigned int e1 = (ROTATE_RIGHT(e, 6) ^ ROTATE_RIGHT(e, 11) ^ ROTATE_RIGHT(e, 25));
+ unsigned int ch = ((e & f) ^ (~e & g));
+ unsigned int t1 = (h + e1 + ch + k[t] + w[t]);
+ unsigned int e0 = (ROTATE_RIGHT(a, 2) ^ ROTATE_RIGHT(a, 13) ^ ROTATE_RIGHT(a, 22));
+ unsigned int maj = ((a & b) ^ (a & c) ^ (b & c));
+ unsigned int t2 = e0 + maj;
+
+ h = g;
+ g = f;
+ f = e;
+ e = d + t1;
+ d = c;
+ c = b;
+ b = a;
+ a = t1 + t2;
+ }
+
+ hash[0] += a;
+ hash[1] += b;
+ hash[2] += c;
+ hash[3] += d;
+ hash[4] += e;
+ hash[5] += f;
+ hash[6] += g;
+ hash[7] += h;
+ }
+ RL_FREE(buffer);
+ return hash;
+}
+
//----------------------------------------------------------------------------------
// Module Functions Definition: Automation Events Recording and Playing
//----------------------------------------------------------------------------------
diff --git a/src/rgestures.h b/src/rgestures.h
index 389df64a1..f601a4790 100644
--- a/src/rgestures.h
+++ b/src/rgestures.h
@@ -232,8 +232,8 @@ typedef struct {
// Global Variables Definition
//----------------------------------------------------------------------------------
static GesturesData GESTURES = {
- .Touch.firstId = -1,
.current = GESTURE_NONE, // No current gesture detected
+ .Touch.firstId = -1,
.enabledFlags = 0b0000001111111111 // All gestures supported by default
};
diff --git a/src/rlgl.h b/src/rlgl.h
index ecd3795a9..9cf8ebefb 100644
--- a/src/rlgl.h
+++ b/src/rlgl.h
@@ -3750,7 +3750,7 @@ void *rlReadTexturePixels(unsigned int id, int width, int height, int format)
#if defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
// Copy framebuffer pixel data to internal buffer
-void rlCopyFramebuffer(int x, int y, int width, int height, int format, void* pixels)
+void rlCopyFramebuffer(int x, int y, int width, int height, int format, void *pixels)
{
unsigned int glInternalFormat, glFormat, glType;
rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType); // Get OpenGL texture format
diff --git a/src/rmodels.c b/src/rmodels.c
index 1e7599004..3a5cc9004 100644
--- a/src/rmodels.c
+++ b/src/rmodels.c
@@ -2352,6 +2352,8 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, int frame)
Mesh mesh = model.meshes[m];
Vector3 animVertex = { 0 };
Vector3 animNormal = { 0 };
+ Matrix boneMatrix = { 0 };
+ Matrix InverseBoneMatrix = { 0 };
int boneId = 0;
int boneCounter = 0;
float boneWeight = 0.0;
@@ -2359,47 +2361,50 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, int frame)
const int vValues = mesh.vertexCount*3;
// Skip if missing bone data, causes segfault without on some models
- if ((mesh.boneWeights == NULL) || (mesh.boneIds == NULL)) continue;
+ if ((mesh.boneWeights == NULL) || (mesh.boneIds == NULL)) continue;
- for (int vCounter = 0; vCounter < vValues; vCounter += 3)
- {
- mesh.animVertices[vCounter] = 0;
- mesh.animVertices[vCounter + 1] = 0;
- mesh.animVertices[vCounter + 2] = 0;
- if (mesh.animNormals != NULL)
- {
- mesh.animNormals[vCounter] = 0;
- mesh.animNormals[vCounter + 1] = 0;
- mesh.animNormals[vCounter + 2] = 0;
- }
+ // Iterates over 4 bones per vertex
+ for (int j = 0; j < 4; j++, boneCounter++)
+ {
+ boneWeight = mesh.boneWeights[boneCounter];
+ boneId = mesh.boneIds[boneCounter];
- // Iterates over 4 bones per vertex
- for (int j = 0; j < 4; j++, boneCounter++)
- {
- boneWeight = mesh.boneWeights[boneCounter];
- boneId = mesh.boneIds[boneCounter];
+ // Early stop when no transformation will be applied
+ if (boneWeight == 0.0f) continue;
- // Early stop when no transformation will be applied
- if (boneWeight == 0.0f) continue;
- animVertex = (Vector3){ mesh.vertices[vCounter], mesh.vertices[vCounter + 1], mesh.vertices[vCounter + 2] };
- animVertex = Vector3Transform(animVertex,model.meshes[m].boneMatrices[boneId]);
- mesh.animVertices[vCounter] += animVertex.x*boneWeight;
- mesh.animVertices[vCounter+1] += animVertex.y*boneWeight;
- mesh.animVertices[vCounter+2] += animVertex.z*boneWeight;
- updated = true;
+ boneMatrix = model.meshes[m].boneMatrices[boneId];
+ InverseBoneMatrix = MatrixTranspose(MatrixInvert(boneMatrix));
- // Normals processing
- // NOTE: We use meshes.baseNormals (default normal) to calculate meshes.normals (animated normals)
- if ((mesh.normals != NULL) && (mesh.animNormals != NULL ))
- {
- animNormal = (Vector3){ mesh.normals[vCounter], mesh.normals[vCounter + 1], mesh.normals[vCounter + 2] };
- animNormal = Vector3Transform(animNormal, MatrixTranspose(MatrixInvert(model.meshes[m].boneMatrices[boneId])));
- mesh.animNormals[vCounter] += animNormal.x*boneWeight;
- mesh.animNormals[vCounter + 1] += animNormal.y*boneWeight;
- mesh.animNormals[vCounter + 2] += animNormal.z*boneWeight;
- }
- }
- }
+ for (int vCounter = 0; vCounter < vValues; vCounter += 3)
+ {
+ mesh.animVertices[vCounter] = 0;
+ mesh.animVertices[vCounter + 1] = 0;
+ mesh.animVertices[vCounter + 2] = 0;
+ if (mesh.animNormals != NULL)
+ {
+ mesh.animNormals[vCounter] = 0;
+ mesh.animNormals[vCounter + 1] = 0;
+ mesh.animNormals[vCounter + 2] = 0;
+ }
+ animVertex = (Vector3){ mesh.vertices[vCounter], mesh.vertices[vCounter + 1], mesh.vertices[vCounter + 2] };
+ animVertex = Vector3Transform(animVertex, boneMatrix);
+ mesh.animVertices[vCounter] += animVertex.x*boneWeight;
+ mesh.animVertices[vCounter+1] += animVertex.y*boneWeight;
+ mesh.animVertices[vCounter+2] += animVertex.z*boneWeight;
+ updated = true;
+
+ // Normals processing
+ // NOTE: We use meshes.baseNormals (default normal) to calculate meshes.normals (animated normals)
+ if ((mesh.normals != NULL) && (mesh.animNormals != NULL))
+ {
+ animNormal = (Vector3){ mesh.normals[vCounter], mesh.normals[vCounter + 1], mesh.normals[vCounter + 2] };
+ animNormal = Vector3Transform(animNormal, InverseBoneMatrix);
+ mesh.animNormals[vCounter] += animNormal.x*boneWeight;
+ mesh.animNormals[vCounter + 1] += animNormal.y*boneWeight;
+ mesh.animNormals[vCounter + 2] += animNormal.z*boneWeight;
+ }
+ }
+ }
if (updated)
{
@@ -5174,7 +5179,7 @@ static cgltf_result LoadFileGLTFCallback(const struct cgltf_memory_options *memo
// Release file data callback for cgltf
static void ReleaseFileGLTFCallback(const struct cgltf_memory_options *memoryOptions, const struct cgltf_file_options *fileOptions, void *data)
{
- UnloadFileData(data);
+ UnloadFileData((unsigned char *)data);
}
// Load image from different glTF provided methods (uri, path, buffer_view)
@@ -6135,7 +6140,7 @@ static bool GetPoseAtTimeGLTF(cgltf_interpolation_type interpolationType, cgltf_
float tmp[3] = { 0.0f };
cgltf_accessor_read_float(output, keyframe, tmp, 3);
Vector3 v1 = {tmp[0], tmp[1], tmp[2]};
- Vector3 *r = data;
+ Vector3 *r = (Vector3 *)data;
*r = v1;
} break;
@@ -6146,7 +6151,7 @@ static bool GetPoseAtTimeGLTF(cgltf_interpolation_type interpolationType, cgltf_
Vector3 v1 = {tmp[0], tmp[1], tmp[2]};
cgltf_accessor_read_float(output, keyframe+1, tmp, 3);
Vector3 v2 = {tmp[0], tmp[1], tmp[2]};
- Vector3 *r = data;
+ Vector3 *r = (Vector3 *)data;
*r = Vector3Lerp(v1, v2, t);
} break;
@@ -6161,7 +6166,7 @@ static bool GetPoseAtTimeGLTF(cgltf_interpolation_type interpolationType, cgltf_
Vector3 v2 = {tmp[0], tmp[1], tmp[2]};
cgltf_accessor_read_float(output, 3*(keyframe+1), tmp, 3);
Vector3 tangent2 = {tmp[0], tmp[1], tmp[2]};
- Vector3 *r = data;
+ Vector3 *r = (Vector3 *)data;
*r = Vector3CubicHermite(v1, tangent1, v2, tangent2, t);
} break;
@@ -6178,7 +6183,7 @@ static bool GetPoseAtTimeGLTF(cgltf_interpolation_type interpolationType, cgltf_
float tmp[4] = { 0.0f };
cgltf_accessor_read_float(output, keyframe, tmp, 4);
Vector4 v1 = {tmp[0], tmp[1], tmp[2], tmp[3]};
- Vector4 *r = data;
+ Vector4 *r = (Vector4 *)data;
*r = v1;
} break;
@@ -6189,7 +6194,7 @@ static bool GetPoseAtTimeGLTF(cgltf_interpolation_type interpolationType, cgltf_
Vector4 v1 = {tmp[0], tmp[1], tmp[2], tmp[3]};
cgltf_accessor_read_float(output, keyframe+1, tmp, 4);
Vector4 v2 = {tmp[0], tmp[1], tmp[2], tmp[3]};
- Vector4 *r = data;
+ Vector4 *r = (Vector4 *)data;
*r = QuaternionSlerp(v1, v2, t);
} break;
@@ -6204,7 +6209,7 @@ static bool GetPoseAtTimeGLTF(cgltf_interpolation_type interpolationType, cgltf_
Vector4 v2 = {tmp[0], tmp[1], tmp[2], tmp[3]};
cgltf_accessor_read_float(output, 3*(keyframe+1), tmp, 4);
Vector4 inTangent2 = {tmp[0], tmp[1], tmp[2], 0.0f};
- Vector4 *r = data;
+ Vector4 *r = (Vector4 *)data;
v1 = QuaternionNormalize(v1);
v2 = QuaternionNormalize(v2);
diff --git a/src/rtext.c b/src/rtext.c
index ce9f381c4..9951dc66d 100644
--- a/src/rtext.c
+++ b/src/rtext.c
@@ -1731,7 +1731,7 @@ char *TextReplace(const char *text, const char *search, const char *replacement)
// - 'text' points to the remainder of text after "end of replace"
while (count--)
{
- insertPoint = strstr(text, search);
+ insertPoint = (char *)strstr(text, search);
lastReplacePos = (int)(insertPoint - text);
temp = strncpy(temp, text, lastReplacePos) + lastReplacePos;
temp = strcpy(temp, replacement) + replaceLen;
@@ -1887,7 +1887,7 @@ int TextFindIndex(const char *text, const char *search)
{
int position = -1;
- char *ptr = strstr(text, search);
+ char *ptr = (char *)strstr(text, search);
if (ptr != NULL) position = (int)(ptr - text);
@@ -1954,6 +1954,7 @@ char *TextToPascal(const char *text)
{
j++;
if ((text[j] >= 'a') && (text[j] <= 'z')) buffer[i] = text[j] - 32;
+ else if ((text[j] >= '0') && (text[j] <= '9')) buffer[i] = text[j];
}
}
}
diff --git a/src/rtextures.c b/src/rtextures.c
index a85467d8c..ddaee2939 100644
--- a/src/rtextures.c
+++ b/src/rtextures.c
@@ -1039,7 +1039,7 @@ Image GenImagePerlinNoise(int width, int height, int offsetX, int offsetY, float
// We need to normalize the data from [-1..1] to [0..1]
float np = (p + 1.0f)/2.0f;
- int intensity = (int)(np*255.0f);
+ unsigned char intensity = (unsigned char)(np*255.0f);
pixels[y*width + x] = (Color){ intensity, intensity, intensity, 255 };
}
}
@@ -1103,7 +1103,8 @@ Image GenImageCellular(int width, int height, int tileSize)
int intensity = (int)(minDistance*256.0f/tileSize);
if (intensity > 255) intensity = 255;
- pixels[y*width + x] = (Color){ intensity, intensity, intensity, 255 };
+ unsigned char intensityUC = (unsigned char)intensity;
+ pixels[y*width + x] = (Color){ intensityUC, intensityUC, intensityUC, 255 };
}
}
@@ -2405,7 +2406,7 @@ void ImageMipmaps(Image *image)
image->data = temp;
// Pointer to allocated memory point where store next mipmap level data
- unsigned char *nextmip = image->data;
+ unsigned char *nextmip = (unsigned char *)image->data;
mipWidth = image->width;
mipHeight = image->height;
diff --git a/src/utils.c b/src/utils.c
index 5ccbc4fa9..123c7b0b9 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -374,7 +374,7 @@ char *LoadFileText(const char *fileName)
// WARNING: \r\n is converted to \n on reading, so,
// read bytes count gets reduced by the number of lines
- if (count < size) text = RL_REALLOC(text, count + 1);
+ if (count < size) text = (char *)RL_REALLOC(text, count + 1);
// Zero-terminate the string
text[count] = '\0';
diff --git a/tools/parser/Makefile b/tools/parser/Makefile
deleted file mode 100644
index ecfdb44ba..000000000
--- a/tools/parser/Makefile
+++ /dev/null
@@ -1,44 +0,0 @@
-EXTENSION?=txt
-FORMAT?=DEFAULT
-.PHONY: all parse clean raylib_api
-
-
-raylib_parser: raylib_parser.c
- cc raylib_parser.c -o raylib_parser
-
-raylib_api: ../../src/raylib.h raylib_parser
- FORMAT=DEFAULT EXTENSION=txt $(MAKE) raylib_api.txt
- FORMAT=JSON EXTENSION=json $(MAKE) raylib_api.json
- FORMAT=XML EXTENSION=xml $(MAKE) raylib_api.xml
- FORMAT=LUA EXTENSION=lua $(MAKE) raylib_api.lua
-
-raylib_api.$(EXTENSION): ../../src/raylib.h raylib_parser
- ./raylib_parser -i ../../src/raylib.h -o raylib_api.$(EXTENSION) -f $(FORMAT) -d RLAPI
-
-raymath_api.$(EXTENSION): ../../src/raymath.h raylib_parser
- ./raylib_parser -i ../../src/raymath.h -o raymath_api.$(EXTENSION) -f $(FORMAT) -d RMAPI
-
-rlgl_api.$(EXTENSION): ../../src/rlgl.h raylib_parser
- ./raylib_parser -i ../../src/rlgl.h -o rlgl_api.$(EXTENSION) -f $(FORMAT) -d RLAPI -t "RLGL IMPLEMENTATION"
-
-reasings_api.$(EXTENSION): ../../examples/others/reasings.h raylib_parser
- ./raylib_parser -i ../../examples/others/reasings.h -o reasings_api.$(EXTENSION) -f $(FORMAT) -d EASEDEF
-
-raygui_api.$(EXTENSION): ../raygui.h raylib_parser
- ./raylib_parser -i ../raygui.h -o raygui_api.$(EXTENSION) -f $(FORMAT) -d RAYGUIAPI -t "RAYGUI IMPLEMENTATION"
-
-parse: raylib_api.$(EXTENSION) raymath_api.$(EXTENSION) rlgl_api.$(EXTENSION) raygui_api.$(EXTENSION)
-
-
-# `make parse` (and therefore `make all) requires
-# rmem.h, physac.h and raygui.h to exist in the correct directory
-# API files for individual headers can be created likeso, provided the relevant header exists:
-# FORMAT=JSON EXTENSION=json make raygui_api.json
-all: raylib_parser
- FORMAT=DEFAULT EXTENSION=txt $(MAKE) parse
- FORMAT=JSON EXTENSION=json $(MAKE) parse
- FORMAT=XML EXTENSION=xml $(MAKE) parse
- FORMAT=LUA EXTENSION=lua $(MAKE) parse
-
-clean:
- rm -f raylib_parser *.json *.txt *.xml *.lua
diff --git a/tools/rexm/examples_report.md b/tools/rexm/examples_report.md
index bf2dbde8b..e55610a30 100644
--- a/tools/rexm/examples_report.md
+++ b/tools/rexm/examples_report.md
@@ -60,6 +60,7 @@ Example elements validated:
| core_render_texture | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| core_undo_redo | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| core_input_actions | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_directory_files | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shapes_basic_shapes | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shapes_bouncing_ball | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shapes_bullet_hell | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
@@ -73,6 +74,7 @@ Example elements validated:
| shapes_easings_ball | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shapes_easings_box | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shapes_easings_rectangles | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_recursive_tree | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shapes_ring_drawing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shapes_circle_sector_drawing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shapes_rounded_rectangle_drawing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
@@ -82,7 +84,9 @@ Example elements validated:
| shapes_digital_clock | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shapes_double_pendulum | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shapes_dashed_line | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_triangle_strip | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shapes_vector_angle | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_pie_chart | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| textures_logo_raylib | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| textures_srcrec_dstrec | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| textures_image_drawing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
@@ -123,6 +127,7 @@ Example elements validated:
| text_3d_drawing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| text_codepoints_loading | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| text_inline_styling | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| text_words_alignment | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| models_animation_playing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| models_billboard_rendering | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| models_box_collisions | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
@@ -192,3 +197,9 @@ Example elements validated:
| raylib_opengl_interop | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ |
| embedded_files_loading | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| web_basic_window | ✔ | ❌ | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_kaleidoscope | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_clipboard_text | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_clock_of_clocks | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_mouse_trail | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_simple_particles | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_starfield | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c
index 745a5ba80..2dc295f37 100644
--- a/tools/rexm/rexm.c
+++ b/tools/rexm/rexm.c
@@ -56,7 +56,7 @@
#define SUPPORT_LOG_INFO
#if defined(SUPPORT_LOG_INFO) && defined(_DEBUG)
- #define LOG(...) printf(__VA_ARGS__)
+ #define LOG(...) printf("REXM: "__VA_ARGS__)
#else
#define LOG(...)
#endif
@@ -221,27 +221,12 @@ int main(int argc, char *argv[])
char exRecategory[32] = { 0 }; // Example re-name category: shapes
char exRename[64] = { 0 }; // Example re-name, without extension
+ char exRebuildRequested[16] = { 0 }; // Example category/full rebuild request
+
int opCode = OP_NONE; // Operation code: 0-None(Help), 1-Create, 2-Add, 3-Rename, 4-Remove
+ bool verbose = false; // Flag for verbose log info
- /*
- // Testing code for UpdateSourceMetadata()
- rlExampleInfo test = { 0 };
- strcpy(test.category, "core");
- strcpy(test.name, "core_boring_window");
- test.stars = 4;
- strcpy(test.verCreated, "2.9");
- strcpy(test.verUpdated, "6.0");
- test.yearCreated = 2010;
- test.yearReviewed = 2026;
- strcpy(test.author, "John W. Smith");
- strcpy(test.authorGitHub, "littlejohnny");
-
- char exSourcePath[512] = { 0 };
- strcpy(exSourcePath, TextFormat("%s/core/core_basic_window.c", exBasePath)); // WARNING: Cache path for saving
- UpdateSourceMetadata(exSourcePath, &test);
- */
-
- // Command-line usage mode
+ // Command-line usage mode: command args processing
//--------------------------------------------------------------------------------------
if (argc > 1)
{
@@ -404,24 +389,43 @@ int main(int argc, char *argv[])
else if (argc > 3) LOG("WARNING: Too many arguments provided\n");
else
{
- // Verify example exists in collection to be removed
- char *exColInfo = LoadFileText(exCollectionFilePath);
- if (TextFindIndex(exColInfo, argv[2]) != -1) // Example in the collection
- {
- strcpy(exName, argv[2]); // Register example name for removal
- strncpy(exCategory, exName, TextFindIndex(exName, "_"));
- opCode = OP_BUILD;
+ // Support building not only individual examples but categories and "ALL"
+ if ((strcmp(argv[2], "ALL") == 0) || TextInList(argv[2], exCategories, REXM_MAX_EXAMPLE_CATEGORIES))
+ {
+ // Category/ALL rebuilt requested
+ strcpy(exRebuildRequested, argv[2]);
+ }
+ else
+ {
+ // Verify example exists in collection to be removed
+ char *exColInfo = LoadFileText(exCollectionFilePath);
+ if (TextFindIndex(exColInfo, argv[2]) != -1) // Example in the collection
+ {
+ strcpy(exName, argv[2]); // Register example name for removal
+ strncpy(exCategory, exName, TextFindIndex(exName, "_"));
+ opCode = OP_BUILD;
+ }
+ else LOG("WARNING: BUILD: Example requested not available in the collection\n");
+ UnloadFileText(exColInfo);
}
- else LOG("WARNING: BUILD: Example not available in the collection\n");
- UnloadFileText(exColInfo);
}
}
+
+ // Check for verbose log mode request
+ for (int i = 1; i < argc; i++)
+ {
+ if ((strcmp(argv[i], "-v") == 0) || (strcmp(argv[i], "--verbose") == 0)) verbose = true;
+ }
}
+ // Command-line usage mode: command execution
switch (opCode)
{
case OP_CREATE: // Create: New example from template
{
+ LOG("INFO: Command requested: CREATE\n");
+ LOG("INFO: Example to create: %s\n", exName);
+
// Create: raylib/examples//_example_name.c
char *exText = LoadFileText(exTemplateFilePath);
char *exTextUpdated[6] = { 0 };
@@ -441,6 +445,9 @@ int main(int argc, char *argv[])
}
case OP_ADD: // Add: Example from command-line input filename
{
+ if (opCode != OP_CREATE) LOG("INFO: Command requested: ADD\n");
+ LOG("INFO: Example file to be added: %s\n", inFileName);
+
// Add: raylib/examples//_example_name.c
if (opCode != OP_CREATE) FileCopy(inFileName, TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName));
@@ -640,6 +647,9 @@ int main(int argc, char *argv[])
} break;
case OP_RENAME: // Rename
{
+ LOG("INFO: Command requested: RENAME\n");
+ LOG("INFO: Example to be renamed: %s --> %s\n", exName, exRename);
+
// NOTE: At this point provided values have been validated:
// exName, exCategory, exRename, exRecategory
if (strcmp(exCategory, exRecategory) == 0)
@@ -751,6 +761,9 @@ int main(int argc, char *argv[])
} break;
case OP_REMOVE: // Remove
{
+ LOG("INFO: Command requested: REMOVE\n");
+ LOG("INFO: Example to be removed: %s\n", exName);
+
// Remove example from collection for files update
//------------------------------------------------------------------------------------------------
char *exCollectionList = LoadFileText(exCollectionFilePath);
@@ -829,10 +842,70 @@ int main(int argc, char *argv[])
FileRemove(TextFormat("%s/%s/%s.wasm", exWebPath, exCategory, exName));
FileRemove(TextFormat("%s/%s/%s.js", exWebPath, exCategory, exName));
+ } break;
+ case OP_BUILD:
+ {
+ LOG("INFO: Command requested: BUILD\n");
+ LOG("INFO: Example to be built: %s\n", exRebuildRequested);
+
+ if ((strcmp(exRebuildRequested, "others") != 0) &&
+ (strcmp(exCategory, "others") != 0)) // Skipping "others" category for rebuild: Special needs
+ {
+ int exRebuildCount = 0;
+ rlExampleInfo *exRebuildList = LoadExamplesData(exCollectionFilePath, exRebuildRequested, false, &exRebuildCount);
+
+ // Build: raylib.com/examples//_example_name.html
+ // Build: raylib.com/examples//_example_name.data
+ // Build: raylib.com/examples//_example_name.wasm
+ // Build: raylib.com/examples//_example_name.js
+
+#if defined(_WIN32)
+ // Set required environment variables
+ //putenv(TextFormat("RAYLIB_DIR=%s\\..", exBasePath));
+ putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin");
+ //putenv("MAKE=mingw32-make");
+ //ChangeDirectory(exBasePath);
+#endif
+ for (int i = 0; i < exRebuildCount; i++)
+ {
+ // Build example for PLATFORM_DESKTOP
+#if defined(_WIN32)
+ system(TextFormat("mingw32-make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exRebuildList[i].category, exRebuildList[i].name));
+#else
+ system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exRebuildList[i].category, exRebuildList[i].name));
+#endif
+
+ // Build example for PLATFORM_WEB
+#if defined(_WIN32)
+ system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exRebuildList[i].category, exRebuildList[i].name));
+#else
+ system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exRebuildList[i].category, exRebuildList[i].name));
+#endif
+ // Update generated .html metadata
+ UpdateWebMetadata(TextFormat("%s/%s/%s.html", exBasePath, exRebuildList[i].category, exRebuildList[i].name),
+ TextFormat("%s/%s/%s.c", exBasePath, exRebuildList[i].category, exRebuildList[i].name));
+
+ // Copy results to web side
+ FileCopy(TextFormat("%s/%s/%s.html", exBasePath, exRebuildList[i].category, exRebuildList[i].name),
+ TextFormat("%s/%s/%s.html", exWebPath, exRebuildList[i].category, exRebuildList[i].name));
+ FileCopy(TextFormat("%s/%s/%s.data", exBasePath, exRebuildList[i].category, exRebuildList[i].name),
+ TextFormat("%s/%s/%s.data", exWebPath, exRebuildList[i].category, exRebuildList[i].name));
+ FileCopy(TextFormat("%s/%s/%s.wasm", exBasePath, exRebuildList[i].category, exRebuildList[i].name),
+ TextFormat("%s/%s/%s.wasm", exWebPath, exRebuildList[i].category, exRebuildList[i].name));
+ FileCopy(TextFormat("%s/%s/%s.js", exBasePath, exRebuildList[i].category, exRebuildList[i].name),
+ TextFormat("%s/%s/%s.js", exWebPath, exRebuildList[i].category, exRebuildList[i].name));
+ }
+
+ UnloadExamplesData(exRebuildList);
+ }
+ else LOG("WARNING: [others] category examples should be build manually, they could have specific build requirements\n");
+
} break;
case OP_VALIDATE: // Validate: report and actions
case OP_UPDATE:
{
+ LOG("INFO: Command requested: %s\n", (opCode == OP_VALIDATE)? "VALIDATE" : "UPDATE");
+ LOG("INFO: Example collection is being %s\n", (opCode == OP_VALIDATE)? "validated" : "validated and updated");
/*
// Validation flags available:
VALID_MISSING_C
@@ -1296,48 +1369,6 @@ int main(int argc, char *argv[])
//------------------------------------------------------------------------------------------------
} break;
- case OP_BUILD:
- {
- // Build: raylib.com/examples//_example_name.html
- // Build: raylib.com/examples//_example_name.data
- // Build: raylib.com/examples//_example_name.wasm
- // Build: raylib.com/examples//_example_name.js
- if (strcmp(exCategory, "others") != 0) // Skipping "others" category
- {
- // Build example for PLATFORM_DESKTOP
- #if defined(_WIN32)
- //putenv(TextFormat("RAYLIB_DIR=%s\\..", exBasePath));
- putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin");
- //putenv("MAKE=mingw32-make");
- //ChangeDirectory(exBasePath);
- system(TextFormat("mingw32-make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exCategory, exName));
- #else
- system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exCategory, exName));
- #endif
-
- // Build example for PLATFORM_WEB
- #if defined(_WIN32)
- putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin");
- system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName));
- #else
- system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName));
- #endif
-
- // Update generated .html metadata
- UpdateWebMetadata(TextFormat("%s/%s/%s.html", exBasePath, exCategory, exName),
- TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName));
-
- // Copy results to web side
- FileCopy(TextFormat("%s/%s/%s.html", exBasePath, exCategory, exName),
- TextFormat("%s/%s/%s.html", exWebPath, exCategory, exName));
- FileCopy(TextFormat("%s/%s/%s.data", exBasePath, exCategory, exName),
- TextFormat("%s/%s/%s.data", exWebPath, exCategory, exName));
- FileCopy(TextFormat("%s/%s/%s.wasm", exBasePath, exCategory, exName),
- TextFormat("%s/%s/%s.wasm", exWebPath, exCategory, exName));
- FileCopy(TextFormat("%s/%s/%s.js", exBasePath, exCategory, exName),
- TextFormat("%s/%s/%s.js", exWebPath, exCategory, exName));
- }
- } break;
default: // Help
{
// Supported commands:
@@ -1907,8 +1938,7 @@ static int ParseExampleInfoLine(const char *line, rlExampleInfo *entry)
int tokenCount = 0;
char **tokens = TextSplit(line, ';', &tokenCount);
- if (tokenCount != 9)
- LOG("REXM: WARNING: Example collection line contains invalid number of tokens: %i\n", tokenCount);
+ if (tokenCount != 9) LOG("REXM: WARNING: Example collection line contains invalid number of tokens: %i\n", tokenCount);
// Get category and name
strcpy(entry->category, tokens[0]);
diff --git a/tools/parser/LICENSE b/tools/rlparser/LICENSE
similarity index 100%
rename from tools/parser/LICENSE
rename to tools/rlparser/LICENSE
diff --git a/tools/rlparser/Makefile b/tools/rlparser/Makefile
new file mode 100644
index 000000000..a645f7f41
--- /dev/null
+++ b/tools/rlparser/Makefile
@@ -0,0 +1,118 @@
+EXTENSION?=txt
+FORMAT?=DEFAULT
+.PHONY: all parse clean raylib_api
+
+# Determine PLATFORM_OS
+# No uname.exe on MinGW!, but OS=Windows_NT on Windows!
+# ifeq ($(UNAME),Msys) -> Windows
+ifeq ($(OS),Windows_NT)
+ PLATFORM_OS = WINDOWS
+else
+ UNAMEOS = $(shell uname)
+ ifeq ($(UNAMEOS),Linux)
+ PLATFORM_OS = LINUX
+ endif
+ ifeq ($(UNAMEOS),FreeBSD)
+ PLATFORM_OS = BSD
+ endif
+ ifeq ($(UNAMEOS),OpenBSD)
+ PLATFORM_OS = BSD
+ endif
+ ifeq ($(UNAMEOS),NetBSD)
+ PLATFORM_OS = BSD
+ endif
+ ifeq ($(UNAMEOS),DragonFly)
+ PLATFORM_OS = BSD
+ endif
+ ifeq ($(UNAMEOS),Darwin)
+ PLATFORM_OS = OSX
+ endif
+endif
+
+# Define default C compiler: CC
+#------------------------------------------------------------------------------------------------
+CC = gcc
+ifeq ($(PLATFORM_OS),OSX)
+ # OSX default compiler
+ CC = clang
+endif
+ifeq ($(PLATFORM_OS),BSD)
+ # FreeBSD, OpenBSD, NetBSD, DragonFly default compiler
+ CC = clang
+endif
+
+# Define default make program: MAKE
+#------------------------------------------------------------------------------------------------
+MAKE ?= make
+ifeq ($(PLATFORM_OS),WINDOWS)
+ MAKE = mingw32-make
+endif
+
+# Define compiler flags: CFLAGS
+#------------------------------------------------------------------------------------------------
+CFLAGS = -Wall -std=c99
+#CFLAGS += -Wextra -Wmissing-prototypes -Wstrict-prototypes
+
+ifeq ($(BUILD_MODE),DEBUG)
+ CFLAGS += -g -D_DEBUG
+else
+ ifeq ($(PLATFORM_OS),OSX)
+ CFLAGS += -O2
+ else
+ CFLAGS += -s -O2
+ endif
+endif
+ifeq ($(PLATFORM_OS),WINDOWS)
+ # NOTE: The resource .rc file contains windows executable icon and properties
+ CFLAGS += rlparser.rc.data
+endif
+
+# Define processes to execute
+#------------------------------------------------------------------------------------------------
+# rlparser compilation
+rlparser: rlparser.c
+ $(CC) rlparser.c -o rlparser $(CFLAGS)
+
+# rlparser execution: [raylib.h] parse, generating some output files
+raylib_api: ../../src/raylib.h rlparser
+ FORMAT=DEFAULT EXTENSION=txt $(MAKE) raylib_api.txt
+ FORMAT=JSON EXTENSION=json $(MAKE) raylib_api.json
+ FORMAT=XML EXTENSION=xml $(MAKE) raylib_api.xml
+ FORMAT=LUA EXTENSION=lua $(MAKE) raylib_api.lua
+
+# rlparser execution: [raylib.h] parse, generating some output files
+raylib_api.$(EXTENSION): ../../src/raylib.h rlparser
+ ./rlparser -i ../../src/raylib.h -o raylib_api.$(EXTENSION) -f $(FORMAT) -d RLAPI
+
+# rlparser execution: [rlgl.h] parse, generating some output files
+rlgl_api.$(EXTENSION): ../../src/rlgl.h rlparser
+ ./rlparser -i ../../src/rlgl.h -o rlgl_api.$(EXTENSION) -f $(FORMAT) -d RLAPI -t "RLGL IMPLEMENTATION"
+
+# rlparser execution: [raymath.h] parse, generating some output files
+raymath_api.$(EXTENSION): ../../src/raymath.h rlparser
+ ./rlparser -i ../../src/raymath.h -o raymath_api.$(EXTENSION) -f $(FORMAT) -d RMAPI
+
+# rlparser execution: [reasings.h] parse, generating some output files
+reasings_api.$(EXTENSION): ../../examples/others/reasings.h rlparser
+ ./rlparser -i ../../examples/others/reasings.h -o reasings_api.$(EXTENSION) -f $(FORMAT) -d EASEDEF
+
+# rlparser execution: [raygui.h] parse, generating some output files
+raygui_api.$(EXTENSION): ../raygui.h rlparser
+ ./rlparser -i ../raygui.h -o raygui_api.$(EXTENSION) -f $(FORMAT) -d RAYGUIAPI -t "RAYGUI IMPLEMENTATION"
+
+# Target to generate required APIs output files
+parse: raylib_api.$(EXTENSION) raymath_api.$(EXTENSION) rlgl_api.$(EXTENSION) raygui_api.$(EXTENSION)
+
+# "make parse" (and therefore "make all") requires
+# raygui.h and reasings_api.h to exist in the correct directory
+# API files for individual headers can be created likeso, provided the relevant header exists:
+# FORMAT=JSON EXTENSION=json make raygui_api.json
+all: rlparser
+ FORMAT=DEFAULT EXTENSION=txt $(MAKE) parse
+ FORMAT=JSON EXTENSION=json $(MAKE) parse
+ FORMAT=XML EXTENSION=xml $(MAKE) parse
+ FORMAT=LUA EXTENSION=lua $(MAKE) parse
+
+# Clean rlparser and generated output files
+clean:
+ rm -f rlparser *.json *.txt *.xml *.lua
diff --git a/tools/parser/README.md b/tools/rlparser/README.md
similarity index 83%
rename from tools/parser/README.md
rename to tools/rlparser/README.md
index 86cdfdd5b..0e4f9b739 100644
--- a/tools/parser/README.md
+++ b/tools/rlparser/README.md
@@ -1,4 +1,4 @@
-# raylib parser
+# rlparser - raylib parser
This parser scans [`raylib.h`](../src/raylib.h) to get information about `defines`, `structs`, `enums` and `functions`.
All data is separated into parts, usually as strings. The following types are used for data:
@@ -8,16 +8,16 @@ All data is separated into parts, usually as strings. The following types are us
- `struct StructInfo`
- `struct EnumInfo`
-Check `raylib_parser.c` for details about those structs.
+Check `rlparser.c` for details about those structs.
## Command Line
```
//////////////////////////////////////////////////////////////////////////////////
// //
-// raylib API parser //
+// rlparser - raylib header API parser //
// //
-// more info and bugs-report: github.com/raysan5/raylib/parser //
+// more info and bugs-report: github.com/raysan5/raylib/tools/rlparser //
// //
// Copyright (c) 2021-2025 Ramon Santamaria (@raysan5) //
// //
@@ -25,7 +25,7 @@ Check `raylib_parser.c` for details about those structs.
USAGE:
- > raylib_parser [--help] [--input ] [--output ] [--format ]
+ > rlparser [--help] [--input ] [--output ] [--format ]
OPTIONS:
@@ -50,19 +50,19 @@ OPTIONS:
EXAMPLES:
- > raylib_parser --input raylib.h --output api.json
+ > rlparser --input raylib.h --output api.json
Process to generate
- > raylib_parser --output raylib_data.info --format XML
+ > rlparser --output raylib_data.info --format XML
Process to generate as XML text data
- > raylib_parser --input raymath.h --output raymath_data.info --format XML --define RMAPI
+ > rlparser --input raymath.h --output raymath_data.info --format XML --define RMAPI
Process to generate as XML text data
```
## Constraints
-This parser is specifically designed to work with raylib.h, so, it has some constraints:
+`rlparser` is specifically designed to work with `raylib.h`, so, it has some constraints:
- Functions are expected as a single line with the following structure:
```
@@ -91,7 +91,7 @@ This parser is specifically designed to work with raylib.h, so, it has some cons
```
_NOTE: For enums, multiple options are supported:_
-
+
- If value is not provided, ( + 1) is assigned
- Value description can be provided or not
@@ -103,5 +103,7 @@ This parser **does not require `` library**, all data is parsed direct
### LICENSE: zlib/libpng
-raylib-parser is licensed under an unmodified zlib/libpng license, which is an OSI-certified, BSD-like license that allows static linking with closed source software. Check [LICENSE](LICENSE) for further details.
+raylib-parser is licensed under an unmodified zlib/libpng license, which is an OSI-certified, BSD-like license that allows static linking with closed source software.
+
+Check [LICENSE](LICENSE) for further details.
diff --git a/tools/parser/output/raylib_api.json b/tools/rlparser/output/raylib_api.json
similarity index 99%
rename from tools/parser/output/raylib_api.json
rename to tools/rlparser/output/raylib_api.json
index 9714d5d05..c0bc88681 100644
--- a/tools/parser/output/raylib_api.json
+++ b/tools/rlparser/output/raylib_api.json
@@ -4851,6 +4851,21 @@
}
]
},
+ {
+ "name": "ComputeSHA256",
+ "description": "Compute SHA256 hash code, returns static int[8] (32 bytes)",
+ "returnType": "unsigned int *",
+ "params": [
+ {
+ "type": "unsigned char *",
+ "name": "data"
+ },
+ {
+ "type": "int",
+ "name": "dataSize"
+ }
+ ]
+ },
{
"name": "LoadAutomationEventList",
"description": "Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS",
diff --git a/tools/parser/output/raylib_api.lua b/tools/rlparser/output/raylib_api.lua
similarity index 99%
rename from tools/parser/output/raylib_api.lua
rename to tools/rlparser/output/raylib_api.lua
index 75fd06373..5cb3c1d55 100644
--- a/tools/parser/output/raylib_api.lua
+++ b/tools/rlparser/output/raylib_api.lua
@@ -4296,6 +4296,15 @@ return {
{type = "int", name = "dataSize"}
}
},
+ {
+ name = "ComputeSHA256",
+ description = "Compute SHA256 hash code, returns static int[8] (32 bytes)",
+ returnType = "unsigned int *",
+ params = {
+ {type = "unsigned char *", name = "data"},
+ {type = "int", name = "dataSize"}
+ }
+ },
{
name = "LoadAutomationEventList",
description = "Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS",
diff --git a/tools/parser/output/raylib_api.txt b/tools/rlparser/output/raylib_api.txt
similarity index 86%
rename from tools/parser/output/raylib_api.txt
rename to tools/rlparser/output/raylib_api.txt
index 849a97a56..9be8e517c 100644
--- a/tools/parser/output/raylib_api.txt
+++ b/tools/rlparser/output/raylib_api.txt
@@ -993,7 +993,7 @@ Callback 006: AudioCallback() (2 input parameters)
Param[1]: bufferData (type: void *)
Param[2]: frames (type: unsigned int)
-Functions found: 596
+Functions found: 597
Function 001: InitWindow() (3 input parameters)
Name: InitWindow
@@ -1851,148 +1851,154 @@ Function 158: ComputeSHA1() (2 input parameters)
Description: Compute SHA1 hash code, returns static int[5] (20 bytes)
Param[1]: data (type: unsigned char *)
Param[2]: dataSize (type: int)
-Function 159: LoadAutomationEventList() (1 input parameters)
+Function 159: ComputeSHA256() (2 input parameters)
+ Name: ComputeSHA256
+ Return type: unsigned int *
+ Description: Compute SHA256 hash code, returns static int[8] (32 bytes)
+ Param[1]: data (type: unsigned char *)
+ Param[2]: dataSize (type: int)
+Function 160: LoadAutomationEventList() (1 input parameters)
Name: LoadAutomationEventList
Return type: AutomationEventList
Description: Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS
Param[1]: fileName (type: const char *)
-Function 160: UnloadAutomationEventList() (1 input parameters)
+Function 161: UnloadAutomationEventList() (1 input parameters)
Name: UnloadAutomationEventList
Return type: void
Description: Unload automation events list from file
Param[1]: list (type: AutomationEventList)
-Function 161: ExportAutomationEventList() (2 input parameters)
+Function 162: ExportAutomationEventList() (2 input parameters)
Name: ExportAutomationEventList
Return type: bool
Description: Export automation events list as text file
Param[1]: list (type: AutomationEventList)
Param[2]: fileName (type: const char *)
-Function 162: SetAutomationEventList() (1 input parameters)
+Function 163: SetAutomationEventList() (1 input parameters)
Name: SetAutomationEventList
Return type: void
Description: Set automation event list to record to
Param[1]: list (type: AutomationEventList *)
-Function 163: SetAutomationEventBaseFrame() (1 input parameters)
+Function 164: SetAutomationEventBaseFrame() (1 input parameters)
Name: SetAutomationEventBaseFrame
Return type: void
Description: Set automation event internal base frame to start recording
Param[1]: frame (type: int)
-Function 164: StartAutomationEventRecording() (0 input parameters)
+Function 165: StartAutomationEventRecording() (0 input parameters)
Name: StartAutomationEventRecording
Return type: void
Description: Start recording automation events (AutomationEventList must be set)
No input parameters
-Function 165: StopAutomationEventRecording() (0 input parameters)
+Function 166: StopAutomationEventRecording() (0 input parameters)
Name: StopAutomationEventRecording
Return type: void
Description: Stop recording automation events
No input parameters
-Function 166: PlayAutomationEvent() (1 input parameters)
+Function 167: PlayAutomationEvent() (1 input parameters)
Name: PlayAutomationEvent
Return type: void
Description: Play a recorded automation event
Param[1]: event (type: AutomationEvent)
-Function 167: IsKeyPressed() (1 input parameters)
+Function 168: IsKeyPressed() (1 input parameters)
Name: IsKeyPressed
Return type: bool
Description: Check if a key has been pressed once
Param[1]: key (type: int)
-Function 168: IsKeyPressedRepeat() (1 input parameters)
+Function 169: IsKeyPressedRepeat() (1 input parameters)
Name: IsKeyPressedRepeat
Return type: bool
Description: Check if a key has been pressed again
Param[1]: key (type: int)
-Function 169: IsKeyDown() (1 input parameters)
+Function 170: IsKeyDown() (1 input parameters)
Name: IsKeyDown
Return type: bool
Description: Check if a key is being pressed
Param[1]: key (type: int)
-Function 170: IsKeyReleased() (1 input parameters)
+Function 171: IsKeyReleased() (1 input parameters)
Name: IsKeyReleased
Return type: bool
Description: Check if a key has been released once
Param[1]: key (type: int)
-Function 171: IsKeyUp() (1 input parameters)
+Function 172: IsKeyUp() (1 input parameters)
Name: IsKeyUp
Return type: bool
Description: Check if a key is NOT being pressed
Param[1]: key (type: int)
-Function 172: GetKeyPressed() (0 input parameters)
+Function 173: GetKeyPressed() (0 input parameters)
Name: GetKeyPressed
Return type: int
Description: Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty
No input parameters
-Function 173: GetCharPressed() (0 input parameters)
+Function 174: GetCharPressed() (0 input parameters)
Name: GetCharPressed
Return type: int
Description: Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty
No input parameters
-Function 174: GetKeyName() (1 input parameters)
+Function 175: GetKeyName() (1 input parameters)
Name: GetKeyName
Return type: const char *
Description: Get name of a QWERTY key on the current keyboard layout (eg returns string 'q' for KEY_A on an AZERTY keyboard)
Param[1]: key (type: int)
-Function 175: SetExitKey() (1 input parameters)
+Function 176: SetExitKey() (1 input parameters)
Name: SetExitKey
Return type: void
Description: Set a custom key to exit program (default is ESC)
Param[1]: key (type: int)
-Function 176: IsGamepadAvailable() (1 input parameters)
+Function 177: IsGamepadAvailable() (1 input parameters)
Name: IsGamepadAvailable
Return type: bool
Description: Check if a gamepad is available
Param[1]: gamepad (type: int)
-Function 177: GetGamepadName() (1 input parameters)
+Function 178: GetGamepadName() (1 input parameters)
Name: GetGamepadName
Return type: const char *
Description: Get gamepad internal name id
Param[1]: gamepad (type: int)
-Function 178: IsGamepadButtonPressed() (2 input parameters)
+Function 179: IsGamepadButtonPressed() (2 input parameters)
Name: IsGamepadButtonPressed
Return type: bool
Description: Check if a gamepad button has been pressed once
Param[1]: gamepad (type: int)
Param[2]: button (type: int)
-Function 179: IsGamepadButtonDown() (2 input parameters)
+Function 180: IsGamepadButtonDown() (2 input parameters)
Name: IsGamepadButtonDown
Return type: bool
Description: Check if a gamepad button is being pressed
Param[1]: gamepad (type: int)
Param[2]: button (type: int)
-Function 180: IsGamepadButtonReleased() (2 input parameters)
+Function 181: IsGamepadButtonReleased() (2 input parameters)
Name: IsGamepadButtonReleased
Return type: bool
Description: Check if a gamepad button has been released once
Param[1]: gamepad (type: int)
Param[2]: button (type: int)
-Function 181: IsGamepadButtonUp() (2 input parameters)
+Function 182: IsGamepadButtonUp() (2 input parameters)
Name: IsGamepadButtonUp
Return type: bool
Description: Check if a gamepad button is NOT being pressed
Param[1]: gamepad (type: int)
Param[2]: button (type: int)
-Function 182: GetGamepadButtonPressed() (0 input parameters)
+Function 183: GetGamepadButtonPressed() (0 input parameters)
Name: GetGamepadButtonPressed
Return type: int
Description: Get the last gamepad button pressed
No input parameters
-Function 183: GetGamepadAxisCount() (1 input parameters)
+Function 184: GetGamepadAxisCount() (1 input parameters)
Name: GetGamepadAxisCount
Return type: int
Description: Get axis count for a gamepad
Param[1]: gamepad (type: int)
-Function 184: GetGamepadAxisMovement() (2 input parameters)
+Function 185: GetGamepadAxisMovement() (2 input parameters)
Name: GetGamepadAxisMovement
Return type: float
Description: Get movement value for a gamepad axis
Param[1]: gamepad (type: int)
Param[2]: axis (type: int)
-Function 185: SetGamepadMappings() (1 input parameters)
+Function 186: SetGamepadMappings() (1 input parameters)
Name: SetGamepadMappings
Return type: int
Description: Set internal gamepad mappings (SDL_GameControllerDB)
Param[1]: mappings (type: const char *)
-Function 186: SetGamepadVibration() (4 input parameters)
+Function 187: SetGamepadVibration() (4 input parameters)
Name: SetGamepadVibration
Return type: void
Description: Set gamepad vibration for both motors (duration in seconds)
@@ -2000,151 +2006,151 @@ Function 186: SetGamepadVibration() (4 input parameters)
Param[2]: leftMotor (type: float)
Param[3]: rightMotor (type: float)
Param[4]: duration (type: float)
-Function 187: IsMouseButtonPressed() (1 input parameters)
+Function 188: IsMouseButtonPressed() (1 input parameters)
Name: IsMouseButtonPressed
Return type: bool
Description: Check if a mouse button has been pressed once
Param[1]: button (type: int)
-Function 188: IsMouseButtonDown() (1 input parameters)
+Function 189: IsMouseButtonDown() (1 input parameters)
Name: IsMouseButtonDown
Return type: bool
Description: Check if a mouse button is being pressed
Param[1]: button (type: int)
-Function 189: IsMouseButtonReleased() (1 input parameters)
+Function 190: IsMouseButtonReleased() (1 input parameters)
Name: IsMouseButtonReleased
Return type: bool
Description: Check if a mouse button has been released once
Param[1]: button (type: int)
-Function 190: IsMouseButtonUp() (1 input parameters)
+Function 191: IsMouseButtonUp() (1 input parameters)
Name: IsMouseButtonUp
Return type: bool
Description: Check if a mouse button is NOT being pressed
Param[1]: button (type: int)
-Function 191: GetMouseX() (0 input parameters)
+Function 192: GetMouseX() (0 input parameters)
Name: GetMouseX
Return type: int
Description: Get mouse position X
No input parameters
-Function 192: GetMouseY() (0 input parameters)
+Function 193: GetMouseY() (0 input parameters)
Name: GetMouseY
Return type: int
Description: Get mouse position Y
No input parameters
-Function 193: GetMousePosition() (0 input parameters)
+Function 194: GetMousePosition() (0 input parameters)
Name: GetMousePosition
Return type: Vector2
Description: Get mouse position XY
No input parameters
-Function 194: GetMouseDelta() (0 input parameters)
+Function 195: GetMouseDelta() (0 input parameters)
Name: GetMouseDelta
Return type: Vector2
Description: Get mouse delta between frames
No input parameters
-Function 195: SetMousePosition() (2 input parameters)
+Function 196: SetMousePosition() (2 input parameters)
Name: SetMousePosition
Return type: void
Description: Set mouse position XY
Param[1]: x (type: int)
Param[2]: y (type: int)
-Function 196: SetMouseOffset() (2 input parameters)
+Function 197: SetMouseOffset() (2 input parameters)
Name: SetMouseOffset
Return type: void
Description: Set mouse offset
Param[1]: offsetX (type: int)
Param[2]: offsetY (type: int)
-Function 197: SetMouseScale() (2 input parameters)
+Function 198: SetMouseScale() (2 input parameters)
Name: SetMouseScale
Return type: void
Description: Set mouse scaling
Param[1]: scaleX (type: float)
Param[2]: scaleY (type: float)
-Function 198: GetMouseWheelMove() (0 input parameters)
+Function 199: GetMouseWheelMove() (0 input parameters)
Name: GetMouseWheelMove
Return type: float
Description: Get mouse wheel movement for X or Y, whichever is larger
No input parameters
-Function 199: GetMouseWheelMoveV() (0 input parameters)
+Function 200: GetMouseWheelMoveV() (0 input parameters)
Name: GetMouseWheelMoveV
Return type: Vector2
Description: Get mouse wheel movement for both X and Y
No input parameters
-Function 200: SetMouseCursor() (1 input parameters)
+Function 201: SetMouseCursor() (1 input parameters)
Name: SetMouseCursor
Return type: void
Description: Set mouse cursor
Param[1]: cursor (type: int)
-Function 201: GetTouchX() (0 input parameters)
+Function 202: GetTouchX() (0 input parameters)
Name: GetTouchX
Return type: int
Description: Get touch position X for touch point 0 (relative to screen size)
No input parameters
-Function 202: GetTouchY() (0 input parameters)
+Function 203: GetTouchY() (0 input parameters)
Name: GetTouchY
Return type: int
Description: Get touch position Y for touch point 0 (relative to screen size)
No input parameters
-Function 203: GetTouchPosition() (1 input parameters)
+Function 204: GetTouchPosition() (1 input parameters)
Name: GetTouchPosition
Return type: Vector2
Description: Get touch position XY for a touch point index (relative to screen size)
Param[1]: index (type: int)
-Function 204: GetTouchPointId() (1 input parameters)
+Function 205: GetTouchPointId() (1 input parameters)
Name: GetTouchPointId
Return type: int
Description: Get touch point identifier for given index
Param[1]: index (type: int)
-Function 205: GetTouchPointCount() (0 input parameters)
+Function 206: GetTouchPointCount() (0 input parameters)
Name: GetTouchPointCount
Return type: int
Description: Get number of touch points
No input parameters
-Function 206: SetGesturesEnabled() (1 input parameters)
+Function 207: SetGesturesEnabled() (1 input parameters)
Name: SetGesturesEnabled
Return type: void
Description: Enable a set of gestures using flags
Param[1]: flags (type: unsigned int)
-Function 207: IsGestureDetected() (1 input parameters)
+Function 208: IsGestureDetected() (1 input parameters)
Name: IsGestureDetected
Return type: bool
Description: Check if a gesture have been detected
Param[1]: gesture (type: unsigned int)
-Function 208: GetGestureDetected() (0 input parameters)
+Function 209: GetGestureDetected() (0 input parameters)
Name: GetGestureDetected
Return type: int
Description: Get latest detected gesture
No input parameters
-Function 209: GetGestureHoldDuration() (0 input parameters)
+Function 210: GetGestureHoldDuration() (0 input parameters)
Name: GetGestureHoldDuration
Return type: float
Description: Get gesture hold time in seconds
No input parameters
-Function 210: GetGestureDragVector() (0 input parameters)
+Function 211: GetGestureDragVector() (0 input parameters)
Name: GetGestureDragVector
Return type: Vector2
Description: Get gesture drag vector
No input parameters
-Function 211: GetGestureDragAngle() (0 input parameters)
+Function 212: GetGestureDragAngle() (0 input parameters)
Name: GetGestureDragAngle
Return type: float
Description: Get gesture drag angle
No input parameters
-Function 212: GetGesturePinchVector() (0 input parameters)
+Function 213: GetGesturePinchVector() (0 input parameters)
Name: GetGesturePinchVector
Return type: Vector2
Description: Get gesture pinch delta
No input parameters
-Function 213: GetGesturePinchAngle() (0 input parameters)
+Function 214: GetGesturePinchAngle() (0 input parameters)
Name: GetGesturePinchAngle
Return type: float
Description: Get gesture pinch angle
No input parameters
-Function 214: UpdateCamera() (2 input parameters)
+Function 215: UpdateCamera() (2 input parameters)
Name: UpdateCamera
Return type: void
Description: Update camera position for selected mode
Param[1]: camera (type: Camera *)
Param[2]: mode (type: int)
-Function 215: UpdateCameraPro() (4 input parameters)
+Function 216: UpdateCameraPro() (4 input parameters)
Name: UpdateCameraPro
Return type: void
Description: Update camera movement/rotation
@@ -2152,36 +2158,36 @@ Function 215: UpdateCameraPro() (4 input parameters)
Param[2]: movement (type: Vector3)
Param[3]: rotation (type: Vector3)
Param[4]: zoom (type: float)
-Function 216: SetShapesTexture() (2 input parameters)
+Function 217: SetShapesTexture() (2 input parameters)
Name: SetShapesTexture
Return type: void
Description: Set texture and rectangle to be used on shapes drawing
Param[1]: texture (type: Texture2D)
Param[2]: source (type: Rectangle)
-Function 217: GetShapesTexture() (0 input parameters)
+Function 218: GetShapesTexture() (0 input parameters)
Name: GetShapesTexture
Return type: Texture2D
Description: Get texture that is used for shapes drawing
No input parameters
-Function 218: GetShapesTextureRectangle() (0 input parameters)
+Function 219: GetShapesTextureRectangle() (0 input parameters)
Name: GetShapesTextureRectangle
Return type: Rectangle
Description: Get texture source rectangle that is used for shapes drawing
No input parameters
-Function 219: DrawPixel() (3 input parameters)
+Function 220: DrawPixel() (3 input parameters)
Name: DrawPixel
Return type: void
Description: Draw a pixel using geometry [Can be slow, use with care]
Param[1]: posX (type: int)
Param[2]: posY (type: int)
Param[3]: color (type: Color)
-Function 220: DrawPixelV() (2 input parameters)
+Function 221: DrawPixelV() (2 input parameters)
Name: DrawPixelV
Return type: void
Description: Draw a pixel using geometry (Vector version) [Can be slow, use with care]
Param[1]: position (type: Vector2)
Param[2]: color (type: Color)
-Function 221: DrawLine() (5 input parameters)
+Function 222: DrawLine() (5 input parameters)
Name: DrawLine
Return type: void
Description: Draw a line
@@ -2190,14 +2196,14 @@ Function 221: DrawLine() (5 input parameters)
Param[3]: endPosX (type: int)
Param[4]: endPosY (type: int)
Param[5]: color (type: Color)
-Function 222: DrawLineV() (3 input parameters)
+Function 223: DrawLineV() (3 input parameters)
Name: DrawLineV
Return type: void
Description: Draw a line (using gl lines)
Param[1]: startPos (type: Vector2)
Param[2]: endPos (type: Vector2)
Param[3]: color (type: Color)
-Function 223: DrawLineEx() (4 input parameters)
+Function 224: DrawLineEx() (4 input parameters)
Name: DrawLineEx
Return type: void
Description: Draw a line (using triangles/quads)
@@ -2205,14 +2211,14 @@ Function 223: DrawLineEx() (4 input parameters)
Param[2]: endPos (type: Vector2)
Param[3]: thick (type: float)
Param[4]: color (type: Color)
-Function 224: DrawLineStrip() (3 input parameters)
+Function 225: DrawLineStrip() (3 input parameters)
Name: DrawLineStrip
Return type: void
Description: Draw lines sequence (using gl lines)
Param[1]: points (type: const Vector2 *)
Param[2]: pointCount (type: int)
Param[3]: color (type: Color)
-Function 225: DrawLineBezier() (4 input parameters)
+Function 226: DrawLineBezier() (4 input parameters)
Name: DrawLineBezier
Return type: void
Description: Draw line segment cubic-bezier in-out interpolation
@@ -2220,7 +2226,7 @@ Function 225: DrawLineBezier() (4 input parameters)
Param[2]: endPos (type: Vector2)
Param[3]: thick (type: float)
Param[4]: color (type: Color)
-Function 226: DrawLineDashed() (5 input parameters)
+Function 227: DrawLineDashed() (5 input parameters)
Name: DrawLineDashed
Return type: void
Description: Draw a dashed line
@@ -2229,7 +2235,7 @@ Function 226: DrawLineDashed() (5 input parameters)
Param[3]: dashSize (type: int)
Param[4]: spaceSize (type: int)
Param[5]: color (type: Color)
-Function 227: DrawCircle() (4 input parameters)
+Function 228: DrawCircle() (4 input parameters)
Name: DrawCircle
Return type: void
Description: Draw a color-filled circle
@@ -2237,7 +2243,7 @@ Function 227: DrawCircle() (4 input parameters)
Param[2]: centerY (type: int)
Param[3]: radius (type: float)
Param[4]: color (type: Color)
-Function 228: DrawCircleSector() (6 input parameters)
+Function 229: DrawCircleSector() (6 input parameters)
Name: DrawCircleSector
Return type: void
Description: Draw a piece of a circle
@@ -2247,7 +2253,7 @@ Function 228: DrawCircleSector() (6 input parameters)
Param[4]: endAngle (type: float)
Param[5]: segments (type: int)
Param[6]: color (type: Color)
-Function 229: DrawCircleSectorLines() (6 input parameters)
+Function 230: DrawCircleSectorLines() (6 input parameters)
Name: DrawCircleSectorLines
Return type: void
Description: Draw circle sector outline
@@ -2257,7 +2263,7 @@ Function 229: DrawCircleSectorLines() (6 input parameters)
Param[4]: endAngle (type: float)
Param[5]: segments (type: int)
Param[6]: color (type: Color)
-Function 230: DrawCircleGradient() (5 input parameters)
+Function 231: DrawCircleGradient() (5 input parameters)
Name: DrawCircleGradient
Return type: void
Description: Draw a gradient-filled circle
@@ -2266,14 +2272,14 @@ Function 230: DrawCircleGradient() (5 input parameters)
Param[3]: radius (type: float)
Param[4]: inner (type: Color)
Param[5]: outer (type: Color)
-Function 231: DrawCircleV() (3 input parameters)
+Function 232: DrawCircleV() (3 input parameters)
Name: DrawCircleV
Return type: void
Description: Draw a color-filled circle (Vector version)
Param[1]: center (type: Vector2)
Param[2]: radius (type: float)
Param[3]: color (type: Color)
-Function 232: DrawCircleLines() (4 input parameters)
+Function 233: DrawCircleLines() (4 input parameters)
Name: DrawCircleLines
Return type: void
Description: Draw circle outline
@@ -2281,14 +2287,14 @@ Function 232: DrawCircleLines() (4 input parameters)
Param[2]: centerY (type: int)
Param[3]: radius (type: float)
Param[4]: color (type: Color)
-Function 233: DrawCircleLinesV() (3 input parameters)
+Function 234: DrawCircleLinesV() (3 input parameters)
Name: DrawCircleLinesV
Return type: void
Description: Draw circle outline (Vector version)
Param[1]: center (type: Vector2)
Param[2]: radius (type: float)
Param[3]: color (type: Color)
-Function 234: DrawEllipse() (5 input parameters)
+Function 235: DrawEllipse() (5 input parameters)
Name: DrawEllipse
Return type: void
Description: Draw ellipse
@@ -2297,7 +2303,7 @@ Function 234: DrawEllipse() (5 input parameters)
Param[3]: radiusH (type: float)
Param[4]: radiusV (type: float)
Param[5]: color (type: Color)
-Function 235: DrawEllipseV() (4 input parameters)
+Function 236: DrawEllipseV() (4 input parameters)
Name: DrawEllipseV
Return type: void
Description: Draw ellipse (Vector version)
@@ -2305,7 +2311,7 @@ Function 235: DrawEllipseV() (4 input parameters)
Param[2]: radiusH (type: float)
Param[3]: radiusV (type: float)
Param[4]: color (type: Color)
-Function 236: DrawEllipseLines() (5 input parameters)
+Function 237: DrawEllipseLines() (5 input parameters)
Name: DrawEllipseLines
Return type: void
Description: Draw ellipse outline
@@ -2314,7 +2320,7 @@ Function 236: DrawEllipseLines() (5 input parameters)
Param[3]: radiusH (type: float)
Param[4]: radiusV (type: float)
Param[5]: color (type: Color)
-Function 237: DrawEllipseLinesV() (4 input parameters)
+Function 238: DrawEllipseLinesV() (4 input parameters)
Name: DrawEllipseLinesV
Return type: void
Description: Draw ellipse outline (Vector version)
@@ -2322,7 +2328,7 @@ Function 237: DrawEllipseLinesV() (4 input parameters)
Param[2]: radiusH (type: float)
Param[3]: radiusV (type: float)
Param[4]: color (type: Color)
-Function 238: DrawRing() (7 input parameters)
+Function 239: DrawRing() (7 input parameters)
Name: DrawRing
Return type: void
Description: Draw ring
@@ -2333,7 +2339,7 @@ Function 238: DrawRing() (7 input parameters)
Param[5]: endAngle (type: float)
Param[6]: segments (type: int)
Param[7]: color (type: Color)
-Function 239: DrawRingLines() (7 input parameters)
+Function 240: DrawRingLines() (7 input parameters)
Name: DrawRingLines
Return type: void
Description: Draw ring outline
@@ -2344,7 +2350,7 @@ Function 239: DrawRingLines() (7 input parameters)
Param[5]: endAngle (type: float)
Param[6]: segments (type: int)
Param[7]: color (type: Color)
-Function 240: DrawRectangle() (5 input parameters)
+Function 241: DrawRectangle() (5 input parameters)
Name: DrawRectangle
Return type: void
Description: Draw a color-filled rectangle
@@ -2353,20 +2359,20 @@ Function 240: DrawRectangle() (5 input parameters)
Param[3]: width (type: int)
Param[4]: height (type: int)
Param[5]: color (type: Color)
-Function 241: DrawRectangleV() (3 input parameters)
+Function 242: DrawRectangleV() (3 input parameters)
Name: DrawRectangleV
Return type: void
Description: Draw a color-filled rectangle (Vector version)
Param[1]: position (type: Vector2)
Param[2]: size (type: Vector2)
Param[3]: color (type: Color)
-Function 242: DrawRectangleRec() (2 input parameters)
+Function 243: DrawRectangleRec() (2 input parameters)
Name: DrawRectangleRec
Return type: void
Description: Draw a color-filled rectangle
Param[1]: rec (type: Rectangle)
Param[2]: color (type: Color)
-Function 243: DrawRectanglePro() (4 input parameters)
+Function 244: DrawRectanglePro() (4 input parameters)
Name: DrawRectanglePro
Return type: void
Description: Draw a color-filled rectangle with pro parameters
@@ -2374,7 +2380,7 @@ Function 243: DrawRectanglePro() (4 input parameters)
Param[2]: origin (type: Vector2)
Param[3]: rotation (type: float)
Param[4]: color (type: Color)
-Function 244: DrawRectangleGradientV() (6 input parameters)
+Function 245: DrawRectangleGradientV() (6 input parameters)
Name: DrawRectangleGradientV
Return type: void
Description: Draw a vertical-gradient-filled rectangle
@@ -2384,7 +2390,7 @@ Function 244: DrawRectangleGradientV() (6 input parameters)
Param[4]: height (type: int)
Param[5]: top (type: Color)
Param[6]: bottom (type: Color)
-Function 245: DrawRectangleGradientH() (6 input parameters)
+Function 246: DrawRectangleGradientH() (6 input parameters)
Name: DrawRectangleGradientH
Return type: void
Description: Draw a horizontal-gradient-filled rectangle
@@ -2394,7 +2400,7 @@ Function 245: DrawRectangleGradientH() (6 input parameters)
Param[4]: height (type: int)
Param[5]: left (type: Color)
Param[6]: right (type: Color)
-Function 246: DrawRectangleGradientEx() (5 input parameters)
+Function 247: DrawRectangleGradientEx() (5 input parameters)
Name: DrawRectangleGradientEx
Return type: void
Description: Draw a gradient-filled rectangle with custom vertex colors
@@ -2403,7 +2409,7 @@ Function 246: DrawRectangleGradientEx() (5 input parameters)
Param[3]: bottomLeft (type: Color)
Param[4]: bottomRight (type: Color)
Param[5]: topRight (type: Color)
-Function 247: DrawRectangleLines() (5 input parameters)
+Function 248: DrawRectangleLines() (5 input parameters)
Name: DrawRectangleLines
Return type: void
Description: Draw rectangle outline
@@ -2412,14 +2418,14 @@ Function 247: DrawRectangleLines() (5 input parameters)
Param[3]: width (type: int)
Param[4]: height (type: int)
Param[5]: color (type: Color)
-Function 248: DrawRectangleLinesEx() (3 input parameters)
+Function 249: DrawRectangleLinesEx() (3 input parameters)
Name: DrawRectangleLinesEx
Return type: void
Description: Draw rectangle outline with extended parameters
Param[1]: rec (type: Rectangle)
Param[2]: lineThick (type: float)
Param[3]: color (type: Color)
-Function 249: DrawRectangleRounded() (4 input parameters)
+Function 250: DrawRectangleRounded() (4 input parameters)
Name: DrawRectangleRounded
Return type: void
Description: Draw rectangle with rounded edges
@@ -2427,7 +2433,7 @@ Function 249: DrawRectangleRounded() (4 input parameters)
Param[2]: roundness (type: float)
Param[3]: segments (type: int)
Param[4]: color (type: Color)
-Function 250: DrawRectangleRoundedLines() (4 input parameters)
+Function 251: DrawRectangleRoundedLines() (4 input parameters)
Name: DrawRectangleRoundedLines
Return type: void
Description: Draw rectangle lines with rounded edges
@@ -2435,7 +2441,7 @@ Function 250: DrawRectangleRoundedLines() (4 input parameters)
Param[2]: roundness (type: float)
Param[3]: segments (type: int)
Param[4]: color (type: Color)
-Function 251: DrawRectangleRoundedLinesEx() (5 input parameters)
+Function 252: DrawRectangleRoundedLinesEx() (5 input parameters)
Name: DrawRectangleRoundedLinesEx
Return type: void
Description: Draw rectangle with rounded edges outline
@@ -2444,7 +2450,7 @@ Function 251: DrawRectangleRoundedLinesEx() (5 input parameters)
Param[3]: segments (type: int)
Param[4]: lineThick (type: float)
Param[5]: color (type: Color)
-Function 252: DrawTriangle() (4 input parameters)
+Function 253: DrawTriangle() (4 input parameters)
Name: DrawTriangle
Return type: void
Description: Draw a color-filled triangle (vertex in counter-clockwise order!)
@@ -2452,7 +2458,7 @@ Function 252: DrawTriangle() (4 input parameters)
Param[2]: v2 (type: Vector2)
Param[3]: v3 (type: Vector2)
Param[4]: color (type: Color)
-Function 253: DrawTriangleLines() (4 input parameters)
+Function 254: DrawTriangleLines() (4 input parameters)
Name: DrawTriangleLines
Return type: void
Description: Draw triangle outline (vertex in counter-clockwise order!)
@@ -2460,21 +2466,21 @@ Function 253: DrawTriangleLines() (4 input parameters)
Param[2]: v2 (type: Vector2)
Param[3]: v3 (type: Vector2)
Param[4]: color (type: Color)
-Function 254: DrawTriangleFan() (3 input parameters)
+Function 255: DrawTriangleFan() (3 input parameters)
Name: DrawTriangleFan
Return type: void
Description: Draw a triangle fan defined by points (first vertex is the center)
Param[1]: points (type: const Vector2 *)
Param[2]: pointCount (type: int)
Param[3]: color (type: Color)
-Function 255: DrawTriangleStrip() (3 input parameters)
+Function 256: DrawTriangleStrip() (3 input parameters)
Name: DrawTriangleStrip
Return type: void
Description: Draw a triangle strip defined by points
Param[1]: points (type: const Vector2 *)
Param[2]: pointCount (type: int)
Param[3]: color (type: Color)
-Function 256: DrawPoly() (5 input parameters)
+Function 257: DrawPoly() (5 input parameters)
Name: DrawPoly
Return type: void
Description: Draw a regular polygon (Vector version)
@@ -2483,7 +2489,7 @@ Function 256: DrawPoly() (5 input parameters)
Param[3]: radius (type: float)
Param[4]: rotation (type: float)
Param[5]: color (type: Color)
-Function 257: DrawPolyLines() (5 input parameters)
+Function 258: DrawPolyLines() (5 input parameters)
Name: DrawPolyLines
Return type: void
Description: Draw a polygon outline of n sides
@@ -2492,7 +2498,7 @@ Function 257: DrawPolyLines() (5 input parameters)
Param[3]: radius (type: float)
Param[4]: rotation (type: float)
Param[5]: color (type: Color)
-Function 258: DrawPolyLinesEx() (6 input parameters)
+Function 259: DrawPolyLinesEx() (6 input parameters)
Name: DrawPolyLinesEx
Return type: void
Description: Draw a polygon outline of n sides with extended parameters
@@ -2502,7 +2508,7 @@ Function 258: DrawPolyLinesEx() (6 input parameters)
Param[4]: rotation (type: float)
Param[5]: lineThick (type: float)
Param[6]: color (type: Color)
-Function 259: DrawSplineLinear() (4 input parameters)
+Function 260: DrawSplineLinear() (4 input parameters)
Name: DrawSplineLinear
Return type: void
Description: Draw spline: Linear, minimum 2 points
@@ -2510,7 +2516,7 @@ Function 259: DrawSplineLinear() (4 input parameters)
Param[2]: pointCount (type: int)
Param[3]: thick (type: float)
Param[4]: color (type: Color)
-Function 260: DrawSplineBasis() (4 input parameters)
+Function 261: DrawSplineBasis() (4 input parameters)
Name: DrawSplineBasis
Return type: void
Description: Draw spline: B-Spline, minimum 4 points
@@ -2518,7 +2524,7 @@ Function 260: DrawSplineBasis() (4 input parameters)
Param[2]: pointCount (type: int)
Param[3]: thick (type: float)
Param[4]: color (type: Color)
-Function 261: DrawSplineCatmullRom() (4 input parameters)
+Function 262: DrawSplineCatmullRom() (4 input parameters)
Name: DrawSplineCatmullRom
Return type: void
Description: Draw spline: Catmull-Rom, minimum 4 points
@@ -2526,7 +2532,7 @@ Function 261: DrawSplineCatmullRom() (4 input parameters)
Param[2]: pointCount (type: int)
Param[3]: thick (type: float)
Param[4]: color (type: Color)
-Function 262: DrawSplineBezierQuadratic() (4 input parameters)
+Function 263: DrawSplineBezierQuadratic() (4 input parameters)
Name: DrawSplineBezierQuadratic
Return type: void
Description: Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...]
@@ -2534,7 +2540,7 @@ Function 262: DrawSplineBezierQuadratic() (4 input parameters)
Param[2]: pointCount (type: int)
Param[3]: thick (type: float)
Param[4]: color (type: Color)
-Function 263: DrawSplineBezierCubic() (4 input parameters)
+Function 264: DrawSplineBezierCubic() (4 input parameters)
Name: DrawSplineBezierCubic
Return type: void
Description: Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...]
@@ -2542,7 +2548,7 @@ Function 263: DrawSplineBezierCubic() (4 input parameters)
Param[2]: pointCount (type: int)
Param[3]: thick (type: float)
Param[4]: color (type: Color)
-Function 264: DrawSplineSegmentLinear() (4 input parameters)
+Function 265: DrawSplineSegmentLinear() (4 input parameters)
Name: DrawSplineSegmentLinear
Return type: void
Description: Draw spline segment: Linear, 2 points
@@ -2550,7 +2556,7 @@ Function 264: DrawSplineSegmentLinear() (4 input parameters)
Param[2]: p2 (type: Vector2)
Param[3]: thick (type: float)
Param[4]: color (type: Color)
-Function 265: DrawSplineSegmentBasis() (6 input parameters)
+Function 266: DrawSplineSegmentBasis() (6 input parameters)
Name: DrawSplineSegmentBasis
Return type: void
Description: Draw spline segment: B-Spline, 4 points
@@ -2560,7 +2566,7 @@ Function 265: DrawSplineSegmentBasis() (6 input parameters)
Param[4]: p4 (type: Vector2)
Param[5]: thick (type: float)
Param[6]: color (type: Color)
-Function 266: DrawSplineSegmentCatmullRom() (6 input parameters)
+Function 267: DrawSplineSegmentCatmullRom() (6 input parameters)
Name: DrawSplineSegmentCatmullRom
Return type: void
Description: Draw spline segment: Catmull-Rom, 4 points
@@ -2570,7 +2576,7 @@ Function 266: DrawSplineSegmentCatmullRom() (6 input parameters)
Param[4]: p4 (type: Vector2)
Param[5]: thick (type: float)
Param[6]: color (type: Color)
-Function 267: DrawSplineSegmentBezierQuadratic() (5 input parameters)
+Function 268: DrawSplineSegmentBezierQuadratic() (5 input parameters)
Name: DrawSplineSegmentBezierQuadratic
Return type: void
Description: Draw spline segment: Quadratic Bezier, 2 points, 1 control point
@@ -2579,7 +2585,7 @@ Function 267: DrawSplineSegmentBezierQuadratic() (5 input parameters)
Param[3]: p3 (type: Vector2)
Param[4]: thick (type: float)
Param[5]: color (type: Color)
-Function 268: DrawSplineSegmentBezierCubic() (6 input parameters)
+Function 269: DrawSplineSegmentBezierCubic() (6 input parameters)
Name: DrawSplineSegmentBezierCubic
Return type: void
Description: Draw spline segment: Cubic Bezier, 2 points, 2 control points
@@ -2589,14 +2595,14 @@ Function 268: DrawSplineSegmentBezierCubic() (6 input parameters)
Param[4]: p4 (type: Vector2)
Param[5]: thick (type: float)
Param[6]: color (type: Color)
-Function 269: GetSplinePointLinear() (3 input parameters)
+Function 270: GetSplinePointLinear() (3 input parameters)
Name: GetSplinePointLinear
Return type: Vector2
Description: Get (evaluate) spline point: Linear
Param[1]: startPos (type: Vector2)
Param[2]: endPos (type: Vector2)
Param[3]: t (type: float)
-Function 270: GetSplinePointBasis() (5 input parameters)
+Function 271: GetSplinePointBasis() (5 input parameters)
Name: GetSplinePointBasis
Return type: Vector2
Description: Get (evaluate) spline point: B-Spline
@@ -2605,7 +2611,7 @@ Function 270: GetSplinePointBasis() (5 input parameters)
Param[3]: p3 (type: Vector2)
Param[4]: p4 (type: Vector2)
Param[5]: t (type: float)
-Function 271: GetSplinePointCatmullRom() (5 input parameters)
+Function 272: GetSplinePointCatmullRom() (5 input parameters)
Name: GetSplinePointCatmullRom
Return type: Vector2
Description: Get (evaluate) spline point: Catmull-Rom
@@ -2614,7 +2620,7 @@ Function 271: GetSplinePointCatmullRom() (5 input parameters)
Param[3]: p3 (type: Vector2)
Param[4]: p4 (type: Vector2)
Param[5]: t (type: float)
-Function 272: GetSplinePointBezierQuad() (4 input parameters)
+Function 273: GetSplinePointBezierQuad() (4 input parameters)
Name: GetSplinePointBezierQuad
Return type: Vector2
Description: Get (evaluate) spline point: Quadratic Bezier
@@ -2622,7 +2628,7 @@ Function 272: GetSplinePointBezierQuad() (4 input parameters)
Param[2]: c2 (type: Vector2)
Param[3]: p3 (type: Vector2)
Param[4]: t (type: float)
-Function 273: GetSplinePointBezierCubic() (5 input parameters)
+Function 274: GetSplinePointBezierCubic() (5 input parameters)
Name: GetSplinePointBezierCubic
Return type: Vector2
Description: Get (evaluate) spline point: Cubic Bezier
@@ -2631,13 +2637,13 @@ Function 273: GetSplinePointBezierCubic() (5 input parameters)
Param[3]: c3 (type: Vector2)
Param[4]: p4 (type: Vector2)
Param[5]: t (type: float)
-Function 274: CheckCollisionRecs() (2 input parameters)
+Function 275: CheckCollisionRecs() (2 input parameters)
Name: CheckCollisionRecs
Return type: bool
Description: Check collision between two rectangles
Param[1]: rec1 (type: Rectangle)
Param[2]: rec2 (type: Rectangle)
-Function 275: CheckCollisionCircles() (4 input parameters)
+Function 276: CheckCollisionCircles() (4 input parameters)
Name: CheckCollisionCircles
Return type: bool
Description: Check collision between two circles
@@ -2645,14 +2651,14 @@ Function 275: CheckCollisionCircles() (4 input parameters)
Param[2]: radius1 (type: float)
Param[3]: center2 (type: Vector2)
Param[4]: radius2 (type: float)
-Function 276: CheckCollisionCircleRec() (3 input parameters)
+Function 277: CheckCollisionCircleRec() (3 input parameters)
Name: CheckCollisionCircleRec
Return type: bool
Description: Check collision between circle and rectangle
Param[1]: center (type: Vector2)
Param[2]: radius (type: float)
Param[3]: rec (type: Rectangle)
-Function 277: CheckCollisionCircleLine() (4 input parameters)
+Function 278: CheckCollisionCircleLine() (4 input parameters)
Name: CheckCollisionCircleLine
Return type: bool
Description: Check if circle collides with a line created betweeen two points [p1] and [p2]
@@ -2660,20 +2666,20 @@ Function 277: CheckCollisionCircleLine() (4 input parameters)
Param[2]: radius (type: float)
Param[3]: p1 (type: Vector2)
Param[4]: p2 (type: Vector2)
-Function 278: CheckCollisionPointRec() (2 input parameters)
+Function 279: CheckCollisionPointRec() (2 input parameters)
Name: CheckCollisionPointRec
Return type: bool
Description: Check if point is inside rectangle
Param[1]: point (type: Vector2)
Param[2]: rec (type: Rectangle)
-Function 279: CheckCollisionPointCircle() (3 input parameters)
+Function 280: CheckCollisionPointCircle() (3 input parameters)
Name: CheckCollisionPointCircle
Return type: bool
Description: Check if point is inside circle
Param[1]: point (type: Vector2)
Param[2]: center (type: Vector2)
Param[3]: radius (type: float)
-Function 280: CheckCollisionPointTriangle() (4 input parameters)
+Function 281: CheckCollisionPointTriangle() (4 input parameters)
Name: CheckCollisionPointTriangle
Return type: bool
Description: Check if point is inside a triangle
@@ -2681,7 +2687,7 @@ Function 280: CheckCollisionPointTriangle() (4 input parameters)
Param[2]: p1 (type: Vector2)
Param[3]: p2 (type: Vector2)
Param[4]: p3 (type: Vector2)
-Function 281: CheckCollisionPointLine() (4 input parameters)
+Function 282: CheckCollisionPointLine() (4 input parameters)
Name: CheckCollisionPointLine
Return type: bool
Description: Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold]
@@ -2689,14 +2695,14 @@ Function 281: CheckCollisionPointLine() (4 input parameters)
Param[2]: p1 (type: Vector2)
Param[3]: p2 (type: Vector2)
Param[4]: threshold (type: int)
-Function 282: CheckCollisionPointPoly() (3 input parameters)
+Function 283: CheckCollisionPointPoly() (3 input parameters)
Name: CheckCollisionPointPoly
Return type: bool
Description: Check if point is within a polygon described by array of vertices
Param[1]: point (type: Vector2)
Param[2]: points (type: const Vector2 *)
Param[3]: pointCount (type: int)
-Function 283: CheckCollisionLines() (5 input parameters)
+Function 284: CheckCollisionLines() (5 input parameters)
Name: CheckCollisionLines
Return type: bool
Description: Check the collision between two lines defined by two points each, returns collision point by reference
@@ -2705,18 +2711,18 @@ Function 283: CheckCollisionLines() (5 input parameters)
Param[3]: startPos2 (type: Vector2)
Param[4]: endPos2 (type: Vector2)
Param[5]: collisionPoint (type: Vector2 *)
-Function 284: GetCollisionRec() (2 input parameters)
+Function 285: GetCollisionRec() (2 input parameters)
Name: GetCollisionRec
Return type: Rectangle
Description: Get collision rectangle for two rectangles collision
Param[1]: rec1 (type: Rectangle)
Param[2]: rec2 (type: Rectangle)
-Function 285: LoadImage() (1 input parameters)
+Function 286: LoadImage() (1 input parameters)
Name: LoadImage
Return type: Image
Description: Load image from file into CPU memory (RAM)
Param[1]: fileName (type: const char *)
-Function 286: LoadImageRaw() (5 input parameters)
+Function 287: LoadImageRaw() (5 input parameters)
Name: LoadImageRaw
Return type: Image
Description: Load image from RAW file data
@@ -2725,13 +2731,13 @@ Function 286: LoadImageRaw() (5 input parameters)
Param[3]: height (type: int)
Param[4]: format (type: int)
Param[5]: headerSize (type: int)
-Function 287: LoadImageAnim() (2 input parameters)
+Function 288: LoadImageAnim() (2 input parameters)
Name: LoadImageAnim
Return type: Image
Description: Load image sequence from file (frames appended to image.data)
Param[1]: fileName (type: const char *)
Param[2]: frames (type: int *)
-Function 288: LoadImageAnimFromMemory() (4 input parameters)
+Function 289: LoadImageAnimFromMemory() (4 input parameters)
Name: LoadImageAnimFromMemory
Return type: Image
Description: Load image sequence from memory buffer
@@ -2739,60 +2745,60 @@ Function 288: LoadImageAnimFromMemory() (4 input parameters)
Param[2]: fileData (type: const unsigned char *)
Param[3]: dataSize (type: int)
Param[4]: frames (type: int *)
-Function 289: LoadImageFromMemory() (3 input parameters)
+Function 290: LoadImageFromMemory() (3 input parameters)
Name: LoadImageFromMemory
Return type: Image
Description: Load image from memory buffer, fileType refers to extension: i.e. '.png'
Param[1]: fileType (type: const char *)
Param[2]: fileData (type: const unsigned char *)
Param[3]: dataSize (type: int)
-Function 290: LoadImageFromTexture() (1 input parameters)
+Function 291: LoadImageFromTexture() (1 input parameters)
Name: LoadImageFromTexture
Return type: Image
Description: Load image from GPU texture data
Param[1]: texture (type: Texture2D)
-Function 291: LoadImageFromScreen() (0 input parameters)
+Function 292: LoadImageFromScreen() (0 input parameters)
Name: LoadImageFromScreen
Return type: Image
Description: Load image from screen buffer and (screenshot)
No input parameters
-Function 292: IsImageValid() (1 input parameters)
+Function 293: IsImageValid() (1 input parameters)
Name: IsImageValid
Return type: bool
Description: Check if an image is valid (data and parameters)
Param[1]: image (type: Image)
-Function 293: UnloadImage() (1 input parameters)
+Function 294: UnloadImage() (1 input parameters)
Name: UnloadImage
Return type: void
Description: Unload image from CPU memory (RAM)
Param[1]: image (type: Image)
-Function 294: ExportImage() (2 input parameters)
+Function 295: ExportImage() (2 input parameters)
Name: ExportImage
Return type: bool
Description: Export image data to file, returns true on success
Param[1]: image (type: Image)
Param[2]: fileName (type: const char *)
-Function 295: ExportImageToMemory() (3 input parameters)
+Function 296: ExportImageToMemory() (3 input parameters)
Name: ExportImageToMemory
Return type: unsigned char *
Description: Export image to memory buffer
Param[1]: image (type: Image)
Param[2]: fileType (type: const char *)
Param[3]: fileSize (type: int *)
-Function 296: ExportImageAsCode() (2 input parameters)
+Function 297: ExportImageAsCode() (2 input parameters)
Name: ExportImageAsCode
Return type: bool
Description: Export image as code file defining an array of bytes, returns true on success
Param[1]: image (type: Image)
Param[2]: fileName (type: const char *)
-Function 297: GenImageColor() (3 input parameters)
+Function 298: GenImageColor() (3 input parameters)
Name: GenImageColor
Return type: Image
Description: Generate image: plain color
Param[1]: width (type: int)
Param[2]: height (type: int)
Param[3]: color (type: Color)
-Function 298: GenImageGradientLinear() (5 input parameters)
+Function 299: GenImageGradientLinear() (5 input parameters)
Name: GenImageGradientLinear
Return type: Image
Description: Generate image: linear gradient, direction in degrees [0..360], 0=Vertical gradient
@@ -2801,7 +2807,7 @@ Function 298: GenImageGradientLinear() (5 input parameters)
Param[3]: direction (type: int)
Param[4]: start (type: Color)
Param[5]: end (type: Color)
-Function 299: GenImageGradientRadial() (5 input parameters)
+Function 300: GenImageGradientRadial() (5 input parameters)
Name: GenImageGradientRadial
Return type: Image
Description: Generate image: radial gradient
@@ -2810,7 +2816,7 @@ Function 299: GenImageGradientRadial() (5 input parameters)
Param[3]: density (type: float)
Param[4]: inner (type: Color)
Param[5]: outer (type: Color)
-Function 300: GenImageGradientSquare() (5 input parameters)
+Function 301: GenImageGradientSquare() (5 input parameters)
Name: GenImageGradientSquare
Return type: Image
Description: Generate image: square gradient
@@ -2819,7 +2825,7 @@ Function 300: GenImageGradientSquare() (5 input parameters)
Param[3]: density (type: float)
Param[4]: inner (type: Color)
Param[5]: outer (type: Color)
-Function 301: GenImageChecked() (6 input parameters)
+Function 302: GenImageChecked() (6 input parameters)
Name: GenImageChecked
Return type: Image
Description: Generate image: checked
@@ -2829,14 +2835,14 @@ Function 301: GenImageChecked() (6 input parameters)
Param[4]: checksY (type: int)
Param[5]: col1 (type: Color)
Param[6]: col2 (type: Color)
-Function 302: GenImageWhiteNoise() (3 input parameters)
+Function 303: GenImageWhiteNoise() (3 input parameters)
Name: GenImageWhiteNoise
Return type: Image
Description: Generate image: white noise
Param[1]: width (type: int)
Param[2]: height (type: int)
Param[3]: factor (type: float)
-Function 303: GenImagePerlinNoise() (5 input parameters)
+Function 304: GenImagePerlinNoise() (5 input parameters)
Name: GenImagePerlinNoise
Return type: Image
Description: Generate image: perlin noise
@@ -2845,45 +2851,45 @@ Function 303: GenImagePerlinNoise() (5 input parameters)
Param[3]: offsetX (type: int)
Param[4]: offsetY (type: int)
Param[5]: scale (type: float)
-Function 304: GenImageCellular() (3 input parameters)
+Function 305: GenImageCellular() (3 input parameters)
Name: GenImageCellular
Return type: Image
Description: Generate image: cellular algorithm, bigger tileSize means bigger cells
Param[1]: width (type: int)
Param[2]: height (type: int)
Param[3]: tileSize (type: int)
-Function 305: GenImageText() (3 input parameters)
+Function 306: GenImageText() (3 input parameters)
Name: GenImageText
Return type: Image
Description: Generate image: grayscale image from text data
Param[1]: width (type: int)
Param[2]: height (type: int)
Param[3]: text (type: const char *)
-Function 306: ImageCopy() (1 input parameters)
+Function 307: ImageCopy() (1 input parameters)
Name: ImageCopy
Return type: Image
Description: Create an image duplicate (useful for transformations)
Param[1]: image (type: Image)
-Function 307: ImageFromImage() (2 input parameters)
+Function 308: ImageFromImage() (2 input parameters)
Name: ImageFromImage
Return type: Image
Description: Create an image from another image piece
Param[1]: image (type: Image)
Param[2]: rec (type: Rectangle)
-Function 308: ImageFromChannel() (2 input parameters)
+Function 309: ImageFromChannel() (2 input parameters)
Name: ImageFromChannel
Return type: Image
Description: Create an image from a selected channel of another image (GRAYSCALE)
Param[1]: image (type: Image)
Param[2]: selectedChannel (type: int)
-Function 309: ImageText() (3 input parameters)
+Function 310: ImageText() (3 input parameters)
Name: ImageText
Return type: Image
Description: Create an image from text (default font)
Param[1]: text (type: const char *)
Param[2]: fontSize (type: int)
Param[3]: color (type: Color)
-Function 310: ImageTextEx() (5 input parameters)
+Function 311: ImageTextEx() (5 input parameters)
Name: ImageTextEx
Return type: Image
Description: Create an image from text (custom sprite font)
@@ -2892,76 +2898,76 @@ Function 310: ImageTextEx() (5 input parameters)
Param[3]: fontSize (type: float)
Param[4]: spacing (type: float)
Param[5]: tint (type: Color)
-Function 311: ImageFormat() (2 input parameters)
+Function 312: ImageFormat() (2 input parameters)
Name: ImageFormat
Return type: void
Description: Convert image data to desired format
Param[1]: image (type: Image *)
Param[2]: newFormat (type: int)
-Function 312: ImageToPOT() (2 input parameters)
+Function 313: ImageToPOT() (2 input parameters)
Name: ImageToPOT
Return type: void
Description: Convert image to POT (power-of-two)
Param[1]: image (type: Image *)
Param[2]: fill (type: Color)
-Function 313: ImageCrop() (2 input parameters)
+Function 314: ImageCrop() (2 input parameters)
Name: ImageCrop
Return type: void
Description: Crop an image to a defined rectangle
Param[1]: image (type: Image *)
Param[2]: crop (type: Rectangle)
-Function 314: ImageAlphaCrop() (2 input parameters)
+Function 315: ImageAlphaCrop() (2 input parameters)
Name: ImageAlphaCrop
Return type: void
Description: Crop image depending on alpha value
Param[1]: image (type: Image *)
Param[2]: threshold (type: float)
-Function 315: ImageAlphaClear() (3 input parameters)
+Function 316: ImageAlphaClear() (3 input parameters)
Name: ImageAlphaClear
Return type: void
Description: Clear alpha channel to desired color
Param[1]: image (type: Image *)
Param[2]: color (type: Color)
Param[3]: threshold (type: float)
-Function 316: ImageAlphaMask() (2 input parameters)
+Function 317: ImageAlphaMask() (2 input parameters)
Name: ImageAlphaMask
Return type: void
Description: Apply alpha mask to image
Param[1]: image (type: Image *)
Param[2]: alphaMask (type: Image)
-Function 317: ImageAlphaPremultiply() (1 input parameters)
+Function 318: ImageAlphaPremultiply() (1 input parameters)
Name: ImageAlphaPremultiply
Return type: void
Description: Premultiply alpha channel
Param[1]: image (type: Image *)
-Function 318: ImageBlurGaussian() (2 input parameters)
+Function 319: ImageBlurGaussian() (2 input parameters)
Name: ImageBlurGaussian
Return type: void
Description: Apply Gaussian blur using a box blur approximation
Param[1]: image (type: Image *)
Param[2]: blurSize (type: int)
-Function 319: ImageKernelConvolution() (3 input parameters)
+Function 320: ImageKernelConvolution() (3 input parameters)
Name: ImageKernelConvolution
Return type: void
Description: Apply custom square convolution kernel to image
Param[1]: image (type: Image *)
Param[2]: kernel (type: const float *)
Param[3]: kernelSize (type: int)
-Function 320: ImageResize() (3 input parameters)
+Function 321: ImageResize() (3 input parameters)
Name: ImageResize
Return type: void
Description: Resize image (Bicubic scaling algorithm)
Param[1]: image (type: Image *)
Param[2]: newWidth (type: int)
Param[3]: newHeight (type: int)
-Function 321: ImageResizeNN() (3 input parameters)
+Function 322: ImageResizeNN() (3 input parameters)
Name: ImageResizeNN
Return type: void
Description: Resize image (Nearest-Neighbor scaling algorithm)
Param[1]: image (type: Image *)
Param[2]: newWidth (type: int)
Param[3]: newHeight (type: int)
-Function 322: ImageResizeCanvas() (6 input parameters)
+Function 323: ImageResizeCanvas() (6 input parameters)
Name: ImageResizeCanvas
Return type: void
Description: Resize canvas and fill with color
@@ -2971,12 +2977,12 @@ Function 322: ImageResizeCanvas() (6 input parameters)
Param[4]: offsetX (type: int)
Param[5]: offsetY (type: int)
Param[6]: fill (type: Color)
-Function 323: ImageMipmaps() (1 input parameters)
+Function 324: ImageMipmaps() (1 input parameters)
Name: ImageMipmaps
Return type: void
Description: Compute all mipmap levels for a provided image
Param[1]: image (type: Image *)
-Function 324: ImageDither() (5 input parameters)
+Function 325: ImageDither() (5 input parameters)
Name: ImageDither
Return type: void
Description: Dither image data to 16bpp or lower (Floyd-Steinberg dithering)
@@ -2985,109 +2991,109 @@ Function 324: ImageDither() (5 input parameters)
Param[3]: gBpp (type: int)
Param[4]: bBpp (type: int)
Param[5]: aBpp (type: int)
-Function 325: ImageFlipVertical() (1 input parameters)
+Function 326: ImageFlipVertical() (1 input parameters)
Name: ImageFlipVertical
Return type: void
Description: Flip image vertically
Param[1]: image (type: Image *)
-Function 326: ImageFlipHorizontal() (1 input parameters)
+Function 327: ImageFlipHorizontal() (1 input parameters)
Name: ImageFlipHorizontal
Return type: void
Description: Flip image horizontally
Param[1]: image (type: Image *)
-Function 327: ImageRotate() (2 input parameters)
+Function 328: ImageRotate() (2 input parameters)
Name: ImageRotate
Return type: void
Description: Rotate image by input angle in degrees (-359 to 359)
Param[1]: image (type: Image *)
Param[2]: degrees (type: int)
-Function 328: ImageRotateCW() (1 input parameters)
+Function 329: ImageRotateCW() (1 input parameters)
Name: ImageRotateCW
Return type: void
Description: Rotate image clockwise 90deg
Param[1]: image (type: Image *)
-Function 329: ImageRotateCCW() (1 input parameters)
+Function 330: ImageRotateCCW() (1 input parameters)
Name: ImageRotateCCW
Return type: void
Description: Rotate image counter-clockwise 90deg
Param[1]: image (type: Image *)
-Function 330: ImageColorTint() (2 input parameters)
+Function 331: ImageColorTint() (2 input parameters)
Name: ImageColorTint
Return type: void
Description: Modify image color: tint
Param[1]: image (type: Image *)
Param[2]: color (type: Color)
-Function 331: ImageColorInvert() (1 input parameters)
+Function 332: ImageColorInvert() (1 input parameters)
Name: ImageColorInvert
Return type: void
Description: Modify image color: invert
Param[1]: image (type: Image *)
-Function 332: ImageColorGrayscale() (1 input parameters)
+Function 333: ImageColorGrayscale() (1 input parameters)
Name: ImageColorGrayscale
Return type: void
Description: Modify image color: grayscale
Param[1]: image (type: Image *)
-Function 333: ImageColorContrast() (2 input parameters)
+Function 334: ImageColorContrast() (2 input parameters)
Name: ImageColorContrast
Return type: void
Description: Modify image color: contrast (-100 to 100)
Param[1]: image (type: Image *)
Param[2]: contrast (type: float)
-Function 334: ImageColorBrightness() (2 input parameters)
+Function 335: ImageColorBrightness() (2 input parameters)
Name: ImageColorBrightness
Return type: void
Description: Modify image color: brightness (-255 to 255)
Param[1]: image (type: Image *)
Param[2]: brightness (type: int)
-Function 335: ImageColorReplace() (3 input parameters)
+Function 336: ImageColorReplace() (3 input parameters)
Name: ImageColorReplace
Return type: void
Description: Modify image color: replace color
Param[1]: image (type: Image *)
Param[2]: color (type: Color)
Param[3]: replace (type: Color)
-Function 336: LoadImageColors() (1 input parameters)
+Function 337: LoadImageColors() (1 input parameters)
Name: LoadImageColors
Return type: Color *
Description: Load color data from image as a Color array (RGBA - 32bit)
Param[1]: image (type: Image)
-Function 337: LoadImagePalette() (3 input parameters)
+Function 338: LoadImagePalette() (3 input parameters)
Name: LoadImagePalette
Return type: Color *
Description: Load colors palette from image as a Color array (RGBA - 32bit)
Param[1]: image (type: Image)
Param[2]: maxPaletteSize (type: int)
Param[3]: colorCount (type: int *)
-Function 338: UnloadImageColors() (1 input parameters)
+Function 339: UnloadImageColors() (1 input parameters)
Name: UnloadImageColors
Return type: void
Description: Unload color data loaded with LoadImageColors()
Param[1]: colors (type: Color *)
-Function 339: UnloadImagePalette() (1 input parameters)
+Function 340: UnloadImagePalette() (1 input parameters)
Name: UnloadImagePalette
Return type: void
Description: Unload colors palette loaded with LoadImagePalette()
Param[1]: colors (type: Color *)
-Function 340: GetImageAlphaBorder() (2 input parameters)
+Function 341: GetImageAlphaBorder() (2 input parameters)
Name: GetImageAlphaBorder
Return type: Rectangle
Description: Get image alpha border rectangle
Param[1]: image (type: Image)
Param[2]: threshold (type: float)
-Function 341: GetImageColor() (3 input parameters)
+Function 342: GetImageColor() (3 input parameters)
Name: GetImageColor
Return type: Color
Description: Get image pixel color at (x, y) position
Param[1]: image (type: Image)
Param[2]: x (type: int)
Param[3]: y (type: int)
-Function 342: ImageClearBackground() (2 input parameters)
+Function 343: ImageClearBackground() (2 input parameters)
Name: ImageClearBackground
Return type: void
Description: Clear image background with given color
Param[1]: dst (type: Image *)
Param[2]: color (type: Color)
-Function 343: ImageDrawPixel() (4 input parameters)
+Function 344: ImageDrawPixel() (4 input parameters)
Name: ImageDrawPixel
Return type: void
Description: Draw pixel within an image
@@ -3095,14 +3101,14 @@ Function 343: ImageDrawPixel() (4 input parameters)
Param[2]: posX (type: int)
Param[3]: posY (type: int)
Param[4]: color (type: Color)
-Function 344: ImageDrawPixelV() (3 input parameters)
+Function 345: ImageDrawPixelV() (3 input parameters)
Name: ImageDrawPixelV
Return type: void
Description: Draw pixel within an image (Vector version)
Param[1]: dst (type: Image *)
Param[2]: position (type: Vector2)
Param[3]: color (type: Color)
-Function 345: ImageDrawLine() (6 input parameters)
+Function 346: ImageDrawLine() (6 input parameters)
Name: ImageDrawLine
Return type: void
Description: Draw line within an image
@@ -3112,7 +3118,7 @@ Function 345: ImageDrawLine() (6 input parameters)
Param[4]: endPosX (type: int)
Param[5]: endPosY (type: int)
Param[6]: color (type: Color)
-Function 346: ImageDrawLineV() (4 input parameters)
+Function 347: ImageDrawLineV() (4 input parameters)
Name: ImageDrawLineV
Return type: void
Description: Draw line within an image (Vector version)
@@ -3120,7 +3126,7 @@ Function 346: ImageDrawLineV() (4 input parameters)
Param[2]: start (type: Vector2)
Param[3]: end (type: Vector2)
Param[4]: color (type: Color)
-Function 347: ImageDrawLineEx() (5 input parameters)
+Function 348: ImageDrawLineEx() (5 input parameters)
Name: ImageDrawLineEx
Return type: void
Description: Draw a line defining thickness within an image
@@ -3129,7 +3135,7 @@ Function 347: ImageDrawLineEx() (5 input parameters)
Param[3]: end (type: Vector2)
Param[4]: thick (type: int)
Param[5]: color (type: Color)
-Function 348: ImageDrawCircle() (5 input parameters)
+Function 349: ImageDrawCircle() (5 input parameters)
Name: ImageDrawCircle
Return type: void
Description: Draw a filled circle within an image
@@ -3138,7 +3144,7 @@ Function 348: ImageDrawCircle() (5 input parameters)
Param[3]: centerY (type: int)
Param[4]: radius (type: int)
Param[5]: color (type: Color)
-Function 349: ImageDrawCircleV() (4 input parameters)
+Function 350: ImageDrawCircleV() (4 input parameters)
Name: ImageDrawCircleV
Return type: void
Description: Draw a filled circle within an image (Vector version)
@@ -3146,7 +3152,7 @@ Function 349: ImageDrawCircleV() (4 input parameters)
Param[2]: center (type: Vector2)
Param[3]: radius (type: int)
Param[4]: color (type: Color)
-Function 350: ImageDrawCircleLines() (5 input parameters)
+Function 351: ImageDrawCircleLines() (5 input parameters)
Name: ImageDrawCircleLines
Return type: void
Description: Draw circle outline within an image
@@ -3155,7 +3161,7 @@ Function 350: ImageDrawCircleLines() (5 input parameters)
Param[3]: centerY (type: int)
Param[4]: radius (type: int)
Param[5]: color (type: Color)
-Function 351: ImageDrawCircleLinesV() (4 input parameters)
+Function 352: ImageDrawCircleLinesV() (4 input parameters)
Name: ImageDrawCircleLinesV
Return type: void
Description: Draw circle outline within an image (Vector version)
@@ -3163,7 +3169,7 @@ Function 351: ImageDrawCircleLinesV() (4 input parameters)
Param[2]: center (type: Vector2)
Param[3]: radius (type: int)
Param[4]: color (type: Color)
-Function 352: ImageDrawRectangle() (6 input parameters)
+Function 353: ImageDrawRectangle() (6 input parameters)
Name: ImageDrawRectangle
Return type: void
Description: Draw rectangle within an image
@@ -3173,7 +3179,7 @@ Function 352: ImageDrawRectangle() (6 input parameters)
Param[4]: width (type: int)
Param[5]: height (type: int)
Param[6]: color (type: Color)
-Function 353: ImageDrawRectangleV() (4 input parameters)
+Function 354: ImageDrawRectangleV() (4 input parameters)
Name: ImageDrawRectangleV
Return type: void
Description: Draw rectangle within an image (Vector version)
@@ -3181,14 +3187,14 @@ Function 353: ImageDrawRectangleV() (4 input parameters)
Param[2]: position (type: Vector2)
Param[3]: size (type: Vector2)
Param[4]: color (type: Color)
-Function 354: ImageDrawRectangleRec() (3 input parameters)
+Function 355: ImageDrawRectangleRec() (3 input parameters)
Name: ImageDrawRectangleRec
Return type: void
Description: Draw rectangle within an image
Param[1]: dst (type: Image *)
Param[2]: rec (type: Rectangle)
Param[3]: color (type: Color)
-Function 355: ImageDrawRectangleLines() (4 input parameters)
+Function 356: ImageDrawRectangleLines() (4 input parameters)
Name: ImageDrawRectangleLines
Return type: void
Description: Draw rectangle lines within an image
@@ -3196,7 +3202,7 @@ Function 355: ImageDrawRectangleLines() (4 input parameters)
Param[2]: rec (type: Rectangle)
Param[3]: thick (type: int)
Param[4]: color (type: Color)
-Function 356: ImageDrawTriangle() (5 input parameters)
+Function 357: ImageDrawTriangle() (5 input parameters)
Name: ImageDrawTriangle
Return type: void
Description: Draw triangle within an image
@@ -3205,7 +3211,7 @@ Function 356: ImageDrawTriangle() (5 input parameters)
Param[3]: v2 (type: Vector2)
Param[4]: v3 (type: Vector2)
Param[5]: color (type: Color)
-Function 357: ImageDrawTriangleEx() (7 input parameters)
+Function 358: ImageDrawTriangleEx() (7 input parameters)
Name: ImageDrawTriangleEx
Return type: void
Description: Draw triangle with interpolated colors within an image
@@ -3216,7 +3222,7 @@ Function 357: ImageDrawTriangleEx() (7 input parameters)
Param[5]: c1 (type: Color)
Param[6]: c2 (type: Color)
Param[7]: c3 (type: Color)
-Function 358: ImageDrawTriangleLines() (5 input parameters)
+Function 359: ImageDrawTriangleLines() (5 input parameters)
Name: ImageDrawTriangleLines
Return type: void
Description: Draw triangle outline within an image
@@ -3225,7 +3231,7 @@ Function 358: ImageDrawTriangleLines() (5 input parameters)
Param[3]: v2 (type: Vector2)
Param[4]: v3 (type: Vector2)
Param[5]: color (type: Color)
-Function 359: ImageDrawTriangleFan() (4 input parameters)
+Function 360: ImageDrawTriangleFan() (4 input parameters)
Name: ImageDrawTriangleFan
Return type: void
Description: Draw a triangle fan defined by points within an image (first vertex is the center)
@@ -3233,7 +3239,7 @@ Function 359: ImageDrawTriangleFan() (4 input parameters)
Param[2]: points (type: const Vector2 *)
Param[3]: pointCount (type: int)
Param[4]: color (type: Color)
-Function 360: ImageDrawTriangleStrip() (4 input parameters)
+Function 361: ImageDrawTriangleStrip() (4 input parameters)
Name: ImageDrawTriangleStrip
Return type: void
Description: Draw a triangle strip defined by points within an image
@@ -3241,7 +3247,7 @@ Function 360: ImageDrawTriangleStrip() (4 input parameters)
Param[2]: points (type: const Vector2 *)
Param[3]: pointCount (type: int)
Param[4]: color (type: Color)
-Function 361: ImageDraw() (5 input parameters)
+Function 362: ImageDraw() (5 input parameters)
Name: ImageDraw
Return type: void
Description: Draw a source image within a destination image (tint applied to source)
@@ -3250,7 +3256,7 @@ Function 361: ImageDraw() (5 input parameters)
Param[3]: srcRec (type: Rectangle)
Param[4]: dstRec (type: Rectangle)
Param[5]: tint (type: Color)
-Function 362: ImageDrawText() (6 input parameters)
+Function 363: ImageDrawText() (6 input parameters)
Name: ImageDrawText
Return type: void
Description: Draw text (using default font) within an image (destination)
@@ -3260,7 +3266,7 @@ Function 362: ImageDrawText() (6 input parameters)
Param[4]: posY (type: int)
Param[5]: fontSize (type: int)
Param[6]: color (type: Color)
-Function 363: ImageDrawTextEx() (7 input parameters)
+Function 364: ImageDrawTextEx() (7 input parameters)
Name: ImageDrawTextEx
Return type: void
Description: Draw text (custom sprite font) within an image (destination)
@@ -3271,79 +3277,79 @@ Function 363: ImageDrawTextEx() (7 input parameters)
Param[5]: fontSize (type: float)
Param[6]: spacing (type: float)
Param[7]: tint (type: Color)
-Function 364: LoadTexture() (1 input parameters)
+Function 365: LoadTexture() (1 input parameters)
Name: LoadTexture
Return type: Texture2D
Description: Load texture from file into GPU memory (VRAM)
Param[1]: fileName (type: const char *)
-Function 365: LoadTextureFromImage() (1 input parameters)
+Function 366: LoadTextureFromImage() (1 input parameters)
Name: LoadTextureFromImage
Return type: Texture2D
Description: Load texture from image data
Param[1]: image (type: Image)
-Function 366: LoadTextureCubemap() (2 input parameters)
+Function 367: LoadTextureCubemap() (2 input parameters)
Name: LoadTextureCubemap
Return type: TextureCubemap
Description: Load cubemap from image, multiple image cubemap layouts supported
Param[1]: image (type: Image)
Param[2]: layout (type: int)
-Function 367: LoadRenderTexture() (2 input parameters)
+Function 368: LoadRenderTexture() (2 input parameters)
Name: LoadRenderTexture
Return type: RenderTexture2D
Description: Load texture for rendering (framebuffer)
Param[1]: width (type: int)
Param[2]: height (type: int)
-Function 368: IsTextureValid() (1 input parameters)
+Function 369: IsTextureValid() (1 input parameters)
Name: IsTextureValid
Return type: bool
Description: Check if a texture is valid (loaded in GPU)
Param[1]: texture (type: Texture2D)
-Function 369: UnloadTexture() (1 input parameters)
+Function 370: UnloadTexture() (1 input parameters)
Name: UnloadTexture
Return type: void
Description: Unload texture from GPU memory (VRAM)
Param[1]: texture (type: Texture2D)
-Function 370: IsRenderTextureValid() (1 input parameters)
+Function 371: IsRenderTextureValid() (1 input parameters)
Name: IsRenderTextureValid
Return type: bool
Description: Check if a render texture is valid (loaded in GPU)
Param[1]: target (type: RenderTexture2D)
-Function 371: UnloadRenderTexture() (1 input parameters)
+Function 372: UnloadRenderTexture() (1 input parameters)
Name: UnloadRenderTexture
Return type: void
Description: Unload render texture from GPU memory (VRAM)
Param[1]: target (type: RenderTexture2D)
-Function 372: UpdateTexture() (2 input parameters)
+Function 373: UpdateTexture() (2 input parameters)
Name: UpdateTexture
Return type: void
Description: Update GPU texture with new data (pixels should be able to fill texture)
Param[1]: texture (type: Texture2D)
Param[2]: pixels (type: const void *)
-Function 373: UpdateTextureRec() (3 input parameters)
+Function 374: UpdateTextureRec() (3 input parameters)
Name: UpdateTextureRec
Return type: void
Description: Update GPU texture rectangle with new data (pixels and rec should fit in texture)
Param[1]: texture (type: Texture2D)
Param[2]: rec (type: Rectangle)
Param[3]: pixels (type: const void *)
-Function 374: GenTextureMipmaps() (1 input parameters)
+Function 375: GenTextureMipmaps() (1 input parameters)
Name: GenTextureMipmaps
Return type: void
Description: Generate GPU mipmaps for a texture
Param[1]: texture (type: Texture2D *)
-Function 375: SetTextureFilter() (2 input parameters)
+Function 376: SetTextureFilter() (2 input parameters)
Name: SetTextureFilter
Return type: void
Description: Set texture scaling filter mode
Param[1]: texture (type: Texture2D)
Param[2]: filter (type: int)
-Function 376: SetTextureWrap() (2 input parameters)
+Function 377: SetTextureWrap() (2 input parameters)
Name: SetTextureWrap
Return type: void
Description: Set texture wrapping mode
Param[1]: texture (type: Texture2D)
Param[2]: wrap (type: int)
-Function 377: DrawTexture() (4 input parameters)
+Function 378: DrawTexture() (4 input parameters)
Name: DrawTexture
Return type: void
Description: Draw a Texture2D
@@ -3351,14 +3357,14 @@ Function 377: DrawTexture() (4 input parameters)
Param[2]: posX (type: int)
Param[3]: posY (type: int)
Param[4]: tint (type: Color)
-Function 378: DrawTextureV() (3 input parameters)
+Function 379: DrawTextureV() (3 input parameters)
Name: DrawTextureV
Return type: void
Description: Draw a Texture2D with position defined as Vector2
Param[1]: texture (type: Texture2D)
Param[2]: position (type: Vector2)
Param[3]: tint (type: Color)
-Function 379: DrawTextureEx() (5 input parameters)
+Function 380: DrawTextureEx() (5 input parameters)
Name: DrawTextureEx
Return type: void
Description: Draw a Texture2D with extended parameters
@@ -3367,7 +3373,7 @@ Function 379: DrawTextureEx() (5 input parameters)
Param[3]: rotation (type: float)
Param[4]: scale (type: float)
Param[5]: tint (type: Color)
-Function 380: DrawTextureRec() (4 input parameters)
+Function 381: DrawTextureRec() (4 input parameters)
Name: DrawTextureRec
Return type: void
Description: Draw a part of a texture defined by a rectangle
@@ -3375,7 +3381,7 @@ Function 380: DrawTextureRec() (4 input parameters)
Param[2]: source (type: Rectangle)
Param[3]: position (type: Vector2)
Param[4]: tint (type: Color)
-Function 381: DrawTexturePro() (6 input parameters)
+Function 382: DrawTexturePro() (6 input parameters)
Name: DrawTexturePro
Return type: void
Description: Draw a part of a texture defined by a rectangle with 'pro' parameters
@@ -3385,7 +3391,7 @@ Function 381: DrawTexturePro() (6 input parameters)
Param[4]: origin (type: Vector2)
Param[5]: rotation (type: float)
Param[6]: tint (type: Color)
-Function 382: DrawTextureNPatch() (6 input parameters)
+Function 383: DrawTextureNPatch() (6 input parameters)
Name: DrawTextureNPatch
Return type: void
Description: Draws a texture (or part of it) that stretches or shrinks nicely
@@ -3395,119 +3401,119 @@ Function 382: DrawTextureNPatch() (6 input parameters)
Param[4]: origin (type: Vector2)
Param[5]: rotation (type: float)
Param[6]: tint (type: Color)
-Function 383: ColorIsEqual() (2 input parameters)
+Function 384: ColorIsEqual() (2 input parameters)
Name: ColorIsEqual
Return type: bool
Description: Check if two colors are equal
Param[1]: col1 (type: Color)
Param[2]: col2 (type: Color)
-Function 384: Fade() (2 input parameters)
+Function 385: Fade() (2 input parameters)
Name: Fade
Return type: Color
Description: Get color with alpha applied, alpha goes from 0.0f to 1.0f
Param[1]: color (type: Color)
Param[2]: alpha (type: float)
-Function 385: ColorToInt() (1 input parameters)
+Function 386: ColorToInt() (1 input parameters)
Name: ColorToInt
Return type: int
Description: Get hexadecimal value for a Color (0xRRGGBBAA)
Param[1]: color (type: Color)
-Function 386: ColorNormalize() (1 input parameters)
+Function 387: ColorNormalize() (1 input parameters)
Name: ColorNormalize
Return type: Vector4
Description: Get Color normalized as float [0..1]
Param[1]: color (type: Color)
-Function 387: ColorFromNormalized() (1 input parameters)
+Function 388: ColorFromNormalized() (1 input parameters)
Name: ColorFromNormalized
Return type: Color
Description: Get Color from normalized values [0..1]
Param[1]: normalized (type: Vector4)
-Function 388: ColorToHSV() (1 input parameters)
+Function 389: ColorToHSV() (1 input parameters)
Name: ColorToHSV
Return type: Vector3
Description: Get HSV values for a Color, hue [0..360], saturation/value [0..1]
Param[1]: color (type: Color)
-Function 389: ColorFromHSV() (3 input parameters)
+Function 390: ColorFromHSV() (3 input parameters)
Name: ColorFromHSV
Return type: Color
Description: Get a Color from HSV values, hue [0..360], saturation/value [0..1]
Param[1]: hue (type: float)
Param[2]: saturation (type: float)
Param[3]: value (type: float)
-Function 390: ColorTint() (2 input parameters)
+Function 391: ColorTint() (2 input parameters)
Name: ColorTint
Return type: Color
Description: Get color multiplied with another color
Param[1]: color (type: Color)
Param[2]: tint (type: Color)
-Function 391: ColorBrightness() (2 input parameters)
+Function 392: ColorBrightness() (2 input parameters)
Name: ColorBrightness
Return type: Color
Description: Get color with brightness correction, brightness factor goes from -1.0f to 1.0f
Param[1]: color (type: Color)
Param[2]: factor (type: float)
-Function 392: ColorContrast() (2 input parameters)
+Function 393: ColorContrast() (2 input parameters)
Name: ColorContrast
Return type: Color
Description: Get color with contrast correction, contrast values between -1.0f and 1.0f
Param[1]: color (type: Color)
Param[2]: contrast (type: float)
-Function 393: ColorAlpha() (2 input parameters)
+Function 394: ColorAlpha() (2 input parameters)
Name: ColorAlpha
Return type: Color
Description: Get color with alpha applied, alpha goes from 0.0f to 1.0f
Param[1]: color (type: Color)
Param[2]: alpha (type: float)
-Function 394: ColorAlphaBlend() (3 input parameters)
+Function 395: ColorAlphaBlend() (3 input parameters)
Name: ColorAlphaBlend
Return type: Color
Description: Get src alpha-blended into dst color with tint
Param[1]: dst (type: Color)
Param[2]: src (type: Color)
Param[3]: tint (type: Color)
-Function 395: ColorLerp() (3 input parameters)
+Function 396: ColorLerp() (3 input parameters)
Name: ColorLerp
Return type: Color
Description: Get color lerp interpolation between two colors, factor [0.0f..1.0f]
Param[1]: color1 (type: Color)
Param[2]: color2 (type: Color)
Param[3]: factor (type: float)
-Function 396: GetColor() (1 input parameters)
+Function 397: GetColor() (1 input parameters)
Name: GetColor
Return type: Color
Description: Get Color structure from hexadecimal value
Param[1]: hexValue (type: unsigned int)
-Function 397: GetPixelColor() (2 input parameters)
+Function 398: GetPixelColor() (2 input parameters)
Name: GetPixelColor
Return type: Color
Description: Get Color from a source pixel pointer of certain format
Param[1]: srcPtr (type: void *)
Param[2]: format (type: int)
-Function 398: SetPixelColor() (3 input parameters)
+Function 399: SetPixelColor() (3 input parameters)
Name: SetPixelColor
Return type: void
Description: Set color formatted into destination pixel pointer
Param[1]: dstPtr (type: void *)
Param[2]: color (type: Color)
Param[3]: format (type: int)
-Function 399: GetPixelDataSize() (3 input parameters)
+Function 400: GetPixelDataSize() (3 input parameters)
Name: GetPixelDataSize
Return type: int
Description: Get pixel data size in bytes for certain format
Param[1]: width (type: int)
Param[2]: height (type: int)
Param[3]: format (type: int)
-Function 400: GetFontDefault() (0 input parameters)
+Function 401: GetFontDefault() (0 input parameters)
Name: GetFontDefault
Return type: Font
Description: Get the default Font
No input parameters
-Function 401: LoadFont() (1 input parameters)
+Function 402: LoadFont() (1 input parameters)
Name: LoadFont
Return type: Font
Description: Load font from file into GPU memory (VRAM)
Param[1]: fileName (type: const char *)
-Function 402: LoadFontEx() (4 input parameters)
+Function 403: LoadFontEx() (4 input parameters)
Name: LoadFontEx
Return type: Font
Description: Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set, font size is provided in pixels height
@@ -3515,14 +3521,14 @@ Function 402: LoadFontEx() (4 input parameters)
Param[2]: fontSize (type: int)
Param[3]: codepoints (type: const int *)
Param[4]: codepointCount (type: int)
-Function 403: LoadFontFromImage() (3 input parameters)
+Function 404: LoadFontFromImage() (3 input parameters)
Name: LoadFontFromImage
Return type: Font
Description: Load font from Image (XNA style)
Param[1]: image (type: Image)
Param[2]: key (type: Color)
Param[3]: firstChar (type: int)
-Function 404: LoadFontFromMemory() (6 input parameters)
+Function 405: LoadFontFromMemory() (6 input parameters)
Name: LoadFontFromMemory
Return type: Font
Description: Load font from memory buffer, fileType refers to extension: i.e. '.ttf'
@@ -3532,12 +3538,12 @@ Function 404: LoadFontFromMemory() (6 input parameters)
Param[4]: fontSize (type: int)
Param[5]: codepoints (type: const int *)
Param[6]: codepointCount (type: int)
-Function 405: IsFontValid() (1 input parameters)
+Function 406: IsFontValid() (1 input parameters)
Name: IsFontValid
Return type: bool
Description: Check if a font is valid (font data loaded, WARNING: GPU texture not checked)
Param[1]: font (type: Font)
-Function 406: LoadFontData() (7 input parameters)
+Function 407: LoadFontData() (7 input parameters)
Name: LoadFontData
Return type: GlyphInfo *
Description: Load font data for further use
@@ -3548,7 +3554,7 @@ Function 406: LoadFontData() (7 input parameters)
Param[5]: codepointCount (type: int)
Param[6]: type (type: int)
Param[7]: glyphCount (type: int *)
-Function 407: GenImageFontAtlas() (6 input parameters)
+Function 408: GenImageFontAtlas() (6 input parameters)
Name: GenImageFontAtlas
Return type: Image
Description: Generate image font atlas using chars info
@@ -3558,30 +3564,30 @@ Function 407: GenImageFontAtlas() (6 input parameters)
Param[4]: fontSize (type: int)
Param[5]: padding (type: int)
Param[6]: packMethod (type: int)
-Function 408: UnloadFontData() (2 input parameters)
+Function 409: UnloadFontData() (2 input parameters)
Name: UnloadFontData
Return type: void
Description: Unload font chars info data (RAM)
Param[1]: glyphs (type: GlyphInfo *)
Param[2]: glyphCount (type: int)
-Function 409: UnloadFont() (1 input parameters)
+Function 410: UnloadFont() (1 input parameters)
Name: UnloadFont
Return type: void
Description: Unload font from GPU memory (VRAM)
Param[1]: font (type: Font)
-Function 410: ExportFontAsCode() (2 input parameters)
+Function 411: ExportFontAsCode() (2 input parameters)
Name: ExportFontAsCode
Return type: bool
Description: Export font as code file, returns true on success
Param[1]: font (type: Font)
Param[2]: fileName (type: const char *)
-Function 411: DrawFPS() (2 input parameters)
+Function 412: DrawFPS() (2 input parameters)
Name: DrawFPS
Return type: void
Description: Draw current FPS
Param[1]: posX (type: int)
Param[2]: posY (type: int)
-Function 412: DrawText() (5 input parameters)
+Function 413: DrawText() (5 input parameters)
Name: DrawText
Return type: void
Description: Draw text (using default font)
@@ -3590,7 +3596,7 @@ Function 412: DrawText() (5 input parameters)
Param[3]: posY (type: int)
Param[4]: fontSize (type: int)
Param[5]: color (type: Color)
-Function 413: DrawTextEx() (6 input parameters)
+Function 414: DrawTextEx() (6 input parameters)
Name: DrawTextEx
Return type: void
Description: Draw text using font and additional parameters
@@ -3600,7 +3606,7 @@ Function 413: DrawTextEx() (6 input parameters)
Param[4]: fontSize (type: float)
Param[5]: spacing (type: float)
Param[6]: tint (type: Color)
-Function 414: DrawTextPro() (8 input parameters)
+Function 415: DrawTextPro() (8 input parameters)
Name: DrawTextPro
Return type: void
Description: Draw text using Font and pro parameters (rotation)
@@ -3612,7 +3618,7 @@ Function 414: DrawTextPro() (8 input parameters)
Param[6]: fontSize (type: float)
Param[7]: spacing (type: float)
Param[8]: tint (type: Color)
-Function 415: DrawTextCodepoint() (5 input parameters)
+Function 416: DrawTextCodepoint() (5 input parameters)
Name: DrawTextCodepoint
Return type: void
Description: Draw one character (codepoint)
@@ -3621,7 +3627,7 @@ Function 415: DrawTextCodepoint() (5 input parameters)
Param[3]: position (type: Vector2)
Param[4]: fontSize (type: float)
Param[5]: tint (type: Color)
-Function 416: DrawTextCodepoints() (7 input parameters)
+Function 417: DrawTextCodepoints() (7 input parameters)
Name: DrawTextCodepoints
Return type: void
Description: Draw multiple character (codepoint)
@@ -3632,18 +3638,18 @@ Function 416: DrawTextCodepoints() (7 input parameters)
Param[5]: fontSize (type: float)
Param[6]: spacing (type: float)
Param[7]: tint (type: Color)
-Function 417: SetTextLineSpacing() (1 input parameters)
+Function 418: SetTextLineSpacing() (1 input parameters)
Name: SetTextLineSpacing
Return type: void
Description: Set vertical line spacing when drawing with line-breaks
Param[1]: spacing (type: int)
-Function 418: MeasureText() (2 input parameters)
+Function 419: MeasureText() (2 input parameters)
Name: MeasureText
Return type: int
Description: Measure string width for default font
Param[1]: text (type: const char *)
Param[2]: fontSize (type: int)
-Function 419: MeasureTextEx() (4 input parameters)
+Function 420: MeasureTextEx() (4 input parameters)
Name: MeasureTextEx
Return type: Vector2
Description: Measure string size for Font
@@ -3651,137 +3657,137 @@ Function 419: MeasureTextEx() (4 input parameters)
Param[2]: text (type: const char *)
Param[3]: fontSize (type: float)
Param[4]: spacing (type: float)
-Function 420: GetGlyphIndex() (2 input parameters)
+Function 421: GetGlyphIndex() (2 input parameters)
Name: GetGlyphIndex
Return type: int
Description: Get glyph index position in font for a codepoint (unicode character), fallback to '?' if not found
Param[1]: font (type: Font)
Param[2]: codepoint (type: int)
-Function 421: GetGlyphInfo() (2 input parameters)
+Function 422: GetGlyphInfo() (2 input parameters)
Name: GetGlyphInfo
Return type: GlyphInfo
Description: Get glyph font info data for a codepoint (unicode character), fallback to '?' if not found
Param[1]: font (type: Font)
Param[2]: codepoint (type: int)
-Function 422: GetGlyphAtlasRec() (2 input parameters)
+Function 423: GetGlyphAtlasRec() (2 input parameters)
Name: GetGlyphAtlasRec
Return type: Rectangle
Description: Get glyph rectangle in font atlas for a codepoint (unicode character), fallback to '?' if not found
Param[1]: font (type: Font)
Param[2]: codepoint (type: int)
-Function 423: LoadUTF8() (2 input parameters)
+Function 424: LoadUTF8() (2 input parameters)
Name: LoadUTF8
Return type: char *
Description: Load UTF-8 text encoded from codepoints array
Param[1]: codepoints (type: const int *)
Param[2]: length (type: int)
-Function 424: UnloadUTF8() (1 input parameters)
+Function 425: UnloadUTF8() (1 input parameters)
Name: UnloadUTF8
Return type: void
Description: Unload UTF-8 text encoded from codepoints array
Param[1]: text (type: char *)
-Function 425: LoadCodepoints() (2 input parameters)
+Function 426: LoadCodepoints() (2 input parameters)
Name: LoadCodepoints
Return type: int *
Description: Load all codepoints from a UTF-8 text string, codepoints count returned by parameter
Param[1]: text (type: const char *)
Param[2]: count (type: int *)
-Function 426: UnloadCodepoints() (1 input parameters)
+Function 427: UnloadCodepoints() (1 input parameters)
Name: UnloadCodepoints
Return type: void
Description: Unload codepoints data from memory
Param[1]: codepoints (type: int *)
-Function 427: GetCodepointCount() (1 input parameters)
+Function 428: GetCodepointCount() (1 input parameters)
Name: GetCodepointCount
Return type: int
Description: Get total number of codepoints in a UTF-8 encoded string
Param[1]: text (type: const char *)
-Function 428: GetCodepoint() (2 input parameters)
+Function 429: GetCodepoint() (2 input parameters)
Name: GetCodepoint
Return type: int
Description: Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
Param[1]: text (type: const char *)
Param[2]: codepointSize (type: int *)
-Function 429: GetCodepointNext() (2 input parameters)
+Function 430: GetCodepointNext() (2 input parameters)
Name: GetCodepointNext
Return type: int
Description: Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
Param[1]: text (type: const char *)
Param[2]: codepointSize (type: int *)
-Function 430: GetCodepointPrevious() (2 input parameters)
+Function 431: GetCodepointPrevious() (2 input parameters)
Name: GetCodepointPrevious
Return type: int
Description: Get previous codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
Param[1]: text (type: const char *)
Param[2]: codepointSize (type: int *)
-Function 431: CodepointToUTF8() (2 input parameters)
+Function 432: CodepointToUTF8() (2 input parameters)
Name: CodepointToUTF8
Return type: const char *
Description: Encode one codepoint into UTF-8 byte array (array length returned as parameter)
Param[1]: codepoint (type: int)
Param[2]: utf8Size (type: int *)
-Function 432: LoadTextLines() (2 input parameters)
+Function 433: LoadTextLines() (2 input parameters)
Name: LoadTextLines
Return type: char **
Description: Load text as separate lines ('\n')
Param[1]: text (type: const char *)
Param[2]: count (type: int *)
-Function 433: UnloadTextLines() (2 input parameters)
+Function 434: UnloadTextLines() (2 input parameters)
Name: UnloadTextLines
Return type: void
Description: Unload text lines
Param[1]: text (type: char **)
Param[2]: lineCount (type: int)
-Function 434: TextCopy() (2 input parameters)
+Function 435: TextCopy() (2 input parameters)
Name: TextCopy
Return type: int
Description: Copy one string to another, returns bytes copied
Param[1]: dst (type: char *)
Param[2]: src (type: const char *)
-Function 435: TextIsEqual() (2 input parameters)
+Function 436: TextIsEqual() (2 input parameters)
Name: TextIsEqual
Return type: bool
Description: Check if two text string are equal
Param[1]: text1 (type: const char *)
Param[2]: text2 (type: const char *)
-Function 436: TextLength() (1 input parameters)
+Function 437: TextLength() (1 input parameters)
Name: TextLength
Return type: unsigned int
Description: Get text length, checks for '\0' ending
Param[1]: text (type: const char *)
-Function 437: TextFormat() (2 input parameters)
+Function 438: TextFormat() (2 input parameters)
Name: TextFormat
Return type: const char *
Description: Text formatting with variables (sprintf() style)
Param[1]: text (type: const char *)
Param[2]: args (type: ...)
-Function 438: TextSubtext() (3 input parameters)
+Function 439: TextSubtext() (3 input parameters)
Name: TextSubtext
Return type: const char *
Description: Get a piece of a text string
Param[1]: text (type: const char *)
Param[2]: position (type: int)
Param[3]: length (type: int)
-Function 439: TextRemoveSpaces() (1 input parameters)
+Function 440: TextRemoveSpaces() (1 input parameters)
Name: TextRemoveSpaces
Return type: const char *
Description: Remove text spaces, concat words
Param[1]: text (type: const char *)
-Function 440: GetTextBetween() (3 input parameters)
+Function 441: GetTextBetween() (3 input parameters)
Name: GetTextBetween
Return type: char *
Description: Get text between two strings
Param[1]: text (type: const char *)
Param[2]: begin (type: const char *)
Param[3]: end (type: const char *)
-Function 441: TextReplace() (3 input parameters)
+Function 442: TextReplace() (3 input parameters)
Name: TextReplace
Return type: char *
Description: Replace text string (WARNING: memory must be freed!)
Param[1]: text (type: const char *)
Param[2]: search (type: const char *)
Param[3]: replacement (type: const char *)
-Function 442: TextReplaceBetween() (4 input parameters)
+Function 443: TextReplaceBetween() (4 input parameters)
Name: TextReplaceBetween
Return type: char *
Description: Replace text between two specific strings (WARNING: memory must be freed!)
@@ -3789,89 +3795,89 @@ Function 442: TextReplaceBetween() (4 input parameters)
Param[2]: begin (type: const char *)
Param[3]: end (type: const char *)
Param[4]: replacement (type: const char *)
-Function 443: TextInsert() (3 input parameters)
+Function 444: TextInsert() (3 input parameters)
Name: TextInsert
Return type: char *
Description: Insert text in a position (WARNING: memory must be freed!)
Param[1]: text (type: const char *)
Param[2]: insert (type: const char *)
Param[3]: position (type: int)
-Function 444: TextJoin() (3 input parameters)
+Function 445: TextJoin() (3 input parameters)
Name: TextJoin
Return type: char *
Description: Join text strings with delimiter
Param[1]: textList (type: char **)
Param[2]: count (type: int)
Param[3]: delimiter (type: const char *)
-Function 445: TextSplit() (3 input parameters)
+Function 446: TextSplit() (3 input parameters)
Name: TextSplit
Return type: char **
Description: Split text into multiple strings, using MAX_TEXTSPLIT_COUNT static strings
Param[1]: text (type: const char *)
Param[2]: delimiter (type: char)
Param[3]: count (type: int *)
-Function 446: TextAppend() (3 input parameters)
+Function 447: TextAppend() (3 input parameters)
Name: TextAppend
Return type: void
Description: Append text at specific position and move cursor
Param[1]: text (type: char *)
Param[2]: append (type: const char *)
Param[3]: position (type: int *)
-Function 447: TextFindIndex() (2 input parameters)
+Function 448: TextFindIndex() (2 input parameters)
Name: TextFindIndex
Return type: int
Description: Find first text occurrence within a string, -1 if not found
Param[1]: text (type: const char *)
Param[2]: search (type: const char *)
-Function 448: TextToUpper() (1 input parameters)
+Function 449: TextToUpper() (1 input parameters)
Name: TextToUpper
Return type: char *
Description: Get upper case version of provided string
Param[1]: text (type: const char *)
-Function 449: TextToLower() (1 input parameters)
+Function 450: TextToLower() (1 input parameters)
Name: TextToLower
Return type: char *
Description: Get lower case version of provided string
Param[1]: text (type: const char *)
-Function 450: TextToPascal() (1 input parameters)
+Function 451: TextToPascal() (1 input parameters)
Name: TextToPascal
Return type: char *
Description: Get Pascal case notation version of provided string
Param[1]: text (type: const char *)
-Function 451: TextToSnake() (1 input parameters)
+Function 452: TextToSnake() (1 input parameters)
Name: TextToSnake
Return type: char *
Description: Get Snake case notation version of provided string
Param[1]: text (type: const char *)
-Function 452: TextToCamel() (1 input parameters)
+Function 453: TextToCamel() (1 input parameters)
Name: TextToCamel
Return type: char *
Description: Get Camel case notation version of provided string
Param[1]: text (type: const char *)
-Function 453: TextToInteger() (1 input parameters)
+Function 454: TextToInteger() (1 input parameters)
Name: TextToInteger
Return type: int
Description: Get integer value from text
Param[1]: text (type: const char *)
-Function 454: TextToFloat() (1 input parameters)
+Function 455: TextToFloat() (1 input parameters)
Name: TextToFloat
Return type: float
Description: Get float value from text
Param[1]: text (type: const char *)
-Function 455: DrawLine3D() (3 input parameters)
+Function 456: DrawLine3D() (3 input parameters)
Name: DrawLine3D
Return type: void
Description: Draw a line in 3D world space
Param[1]: startPos (type: Vector3)
Param[2]: endPos (type: Vector3)
Param[3]: color (type: Color)
-Function 456: DrawPoint3D() (2 input parameters)
+Function 457: DrawPoint3D() (2 input parameters)
Name: DrawPoint3D
Return type: void
Description: Draw a point in 3D space, actually a small line
Param[1]: position (type: Vector3)
Param[2]: color (type: Color)
-Function 457: DrawCircle3D() (5 input parameters)
+Function 458: DrawCircle3D() (5 input parameters)
Name: DrawCircle3D
Return type: void
Description: Draw a circle in 3D world space
@@ -3880,7 +3886,7 @@ Function 457: DrawCircle3D() (5 input parameters)
Param[3]: rotationAxis (type: Vector3)
Param[4]: rotationAngle (type: float)
Param[5]: color (type: Color)
-Function 458: DrawTriangle3D() (4 input parameters)
+Function 459: DrawTriangle3D() (4 input parameters)
Name: DrawTriangle3D
Return type: void
Description: Draw a color-filled triangle (vertex in counter-clockwise order!)
@@ -3888,14 +3894,14 @@ Function 458: DrawTriangle3D() (4 input parameters)
Param[2]: v2 (type: Vector3)
Param[3]: v3 (type: Vector3)
Param[4]: color (type: Color)
-Function 459: DrawTriangleStrip3D() (3 input parameters)
+Function 460: DrawTriangleStrip3D() (3 input parameters)
Name: DrawTriangleStrip3D
Return type: void
Description: Draw a triangle strip defined by points
Param[1]: points (type: const Vector3 *)
Param[2]: pointCount (type: int)
Param[3]: color (type: Color)
-Function 460: DrawCube() (5 input parameters)
+Function 461: DrawCube() (5 input parameters)
Name: DrawCube
Return type: void
Description: Draw cube
@@ -3904,14 +3910,14 @@ Function 460: DrawCube() (5 input parameters)
Param[3]: height (type: float)
Param[4]: length (type: float)
Param[5]: color (type: Color)
-Function 461: DrawCubeV() (3 input parameters)
+Function 462: DrawCubeV() (3 input parameters)
Name: DrawCubeV
Return type: void
Description: Draw cube (Vector version)
Param[1]: position (type: Vector3)
Param[2]: size (type: Vector3)
Param[3]: color (type: Color)
-Function 462: DrawCubeWires() (5 input parameters)
+Function 463: DrawCubeWires() (5 input parameters)
Name: DrawCubeWires
Return type: void
Description: Draw cube wires
@@ -3920,21 +3926,21 @@ Function 462: DrawCubeWires() (5 input parameters)
Param[3]: height (type: float)
Param[4]: length (type: float)
Param[5]: color (type: Color)
-Function 463: DrawCubeWiresV() (3 input parameters)
+Function 464: DrawCubeWiresV() (3 input parameters)
Name: DrawCubeWiresV
Return type: void
Description: Draw cube wires (Vector version)
Param[1]: position (type: Vector3)
Param[2]: size (type: Vector3)
Param[3]: color (type: Color)
-Function 464: DrawSphere() (3 input parameters)
+Function 465: DrawSphere() (3 input parameters)
Name: DrawSphere
Return type: void
Description: Draw sphere
Param[1]: centerPos (type: Vector3)
Param[2]: radius (type: float)
Param[3]: color (type: Color)
-Function 465: DrawSphereEx() (5 input parameters)
+Function 466: DrawSphereEx() (5 input parameters)
Name: DrawSphereEx
Return type: void
Description: Draw sphere with extended parameters
@@ -3943,7 +3949,7 @@ Function 465: DrawSphereEx() (5 input parameters)
Param[3]: rings (type: int)
Param[4]: slices (type: int)
Param[5]: color (type: Color)
-Function 466: DrawSphereWires() (5 input parameters)
+Function 467: DrawSphereWires() (5 input parameters)
Name: DrawSphereWires
Return type: void
Description: Draw sphere wires
@@ -3952,7 +3958,7 @@ Function 466: DrawSphereWires() (5 input parameters)
Param[3]: rings (type: int)
Param[4]: slices (type: int)
Param[5]: color (type: Color)
-Function 467: DrawCylinder() (6 input parameters)
+Function 468: DrawCylinder() (6 input parameters)
Name: DrawCylinder
Return type: void
Description: Draw a cylinder/cone
@@ -3962,7 +3968,7 @@ Function 467: DrawCylinder() (6 input parameters)
Param[4]: height (type: float)
Param[5]: slices (type: int)
Param[6]: color (type: Color)
-Function 468: DrawCylinderEx() (6 input parameters)
+Function 469: DrawCylinderEx() (6 input parameters)
Name: DrawCylinderEx
Return type: void
Description: Draw a cylinder with base at startPos and top at endPos
@@ -3972,7 +3978,7 @@ Function 468: DrawCylinderEx() (6 input parameters)
Param[4]: endRadius (type: float)
Param[5]: sides (type: int)
Param[6]: color (type: Color)
-Function 469: DrawCylinderWires() (6 input parameters)
+Function 470: DrawCylinderWires() (6 input parameters)
Name: DrawCylinderWires
Return type: void
Description: Draw a cylinder/cone wires
@@ -3982,7 +3988,7 @@ Function 469: DrawCylinderWires() (6 input parameters)
Param[4]: height (type: float)
Param[5]: slices (type: int)
Param[6]: color (type: Color)
-Function 470: DrawCylinderWiresEx() (6 input parameters)
+Function 471: DrawCylinderWiresEx() (6 input parameters)
Name: DrawCylinderWiresEx
Return type: void
Description: Draw a cylinder wires with base at startPos and top at endPos
@@ -3992,7 +3998,7 @@ Function 470: DrawCylinderWiresEx() (6 input parameters)
Param[4]: endRadius (type: float)
Param[5]: sides (type: int)
Param[6]: color (type: Color)
-Function 471: DrawCapsule() (6 input parameters)
+Function 472: DrawCapsule() (6 input parameters)
Name: DrawCapsule
Return type: void
Description: Draw a capsule with the center of its sphere caps at startPos and endPos
@@ -4002,7 +4008,7 @@ Function 471: DrawCapsule() (6 input parameters)
Param[4]: slices (type: int)
Param[5]: rings (type: int)
Param[6]: color (type: Color)
-Function 472: DrawCapsuleWires() (6 input parameters)
+Function 473: DrawCapsuleWires() (6 input parameters)
Name: DrawCapsuleWires
Return type: void
Description: Draw capsule wireframe with the center of its sphere caps at startPos and endPos
@@ -4012,51 +4018,51 @@ Function 472: DrawCapsuleWires() (6 input parameters)
Param[4]: slices (type: int)
Param[5]: rings (type: int)
Param[6]: color (type: Color)
-Function 473: DrawPlane() (3 input parameters)
+Function 474: DrawPlane() (3 input parameters)
Name: DrawPlane
Return type: void
Description: Draw a plane XZ
Param[1]: centerPos (type: Vector3)
Param[2]: size (type: Vector2)
Param[3]: color (type: Color)
-Function 474: DrawRay() (2 input parameters)
+Function 475: DrawRay() (2 input parameters)
Name: DrawRay
Return type: void
Description: Draw a ray line
Param[1]: ray (type: Ray)
Param[2]: color (type: Color)
-Function 475: DrawGrid() (2 input parameters)
+Function 476: DrawGrid() (2 input parameters)
Name: DrawGrid
Return type: void
Description: Draw a grid (centered at (0, 0, 0))
Param[1]: slices (type: int)
Param[2]: spacing (type: float)
-Function 476: LoadModel() (1 input parameters)
+Function 477: LoadModel() (1 input parameters)
Name: LoadModel
Return type: Model
Description: Load model from files (meshes and materials)
Param[1]: fileName (type: const char *)
-Function 477: LoadModelFromMesh() (1 input parameters)
+Function 478: LoadModelFromMesh() (1 input parameters)
Name: LoadModelFromMesh
Return type: Model
Description: Load model from generated mesh (default material)
Param[1]: mesh (type: Mesh)
-Function 478: IsModelValid() (1 input parameters)
+Function 479: IsModelValid() (1 input parameters)
Name: IsModelValid
Return type: bool
Description: Check if a model is valid (loaded in GPU, VAO/VBOs)
Param[1]: model (type: Model)
-Function 479: UnloadModel() (1 input parameters)
+Function 480: UnloadModel() (1 input parameters)
Name: UnloadModel
Return type: void
Description: Unload model (including meshes) from memory (RAM and/or VRAM)
Param[1]: model (type: Model)
-Function 480: GetModelBoundingBox() (1 input parameters)
+Function 481: GetModelBoundingBox() (1 input parameters)
Name: GetModelBoundingBox
Return type: BoundingBox
Description: Compute model bounding box limits (considers all meshes)
Param[1]: model (type: Model)
-Function 481: DrawModel() (4 input parameters)
+Function 482: DrawModel() (4 input parameters)
Name: DrawModel
Return type: void
Description: Draw a model (with texture if set)
@@ -4064,7 +4070,7 @@ Function 481: DrawModel() (4 input parameters)
Param[2]: position (type: Vector3)
Param[3]: scale (type: float)
Param[4]: tint (type: Color)
-Function 482: DrawModelEx() (6 input parameters)
+Function 483: DrawModelEx() (6 input parameters)
Name: DrawModelEx
Return type: void
Description: Draw a model with extended parameters
@@ -4074,7 +4080,7 @@ Function 482: DrawModelEx() (6 input parameters)
Param[4]: rotationAngle (type: float)
Param[5]: scale (type: Vector3)
Param[6]: tint (type: Color)
-Function 483: DrawModelWires() (4 input parameters)
+Function 484: DrawModelWires() (4 input parameters)
Name: DrawModelWires
Return type: void
Description: Draw a model wires (with texture if set)
@@ -4082,7 +4088,7 @@ Function 483: DrawModelWires() (4 input parameters)
Param[2]: position (type: Vector3)
Param[3]: scale (type: float)
Param[4]: tint (type: Color)
-Function 484: DrawModelWiresEx() (6 input parameters)
+Function 485: DrawModelWiresEx() (6 input parameters)
Name: DrawModelWiresEx
Return type: void
Description: Draw a model wires (with texture if set) with extended parameters
@@ -4092,7 +4098,7 @@ Function 484: DrawModelWiresEx() (6 input parameters)
Param[4]: rotationAngle (type: float)
Param[5]: scale (type: Vector3)
Param[6]: tint (type: Color)
-Function 485: DrawModelPoints() (4 input parameters)
+Function 486: DrawModelPoints() (4 input parameters)
Name: DrawModelPoints
Return type: void
Description: Draw a model as points
@@ -4100,7 +4106,7 @@ Function 485: DrawModelPoints() (4 input parameters)
Param[2]: position (type: Vector3)
Param[3]: scale (type: float)
Param[4]: tint (type: Color)
-Function 486: DrawModelPointsEx() (6 input parameters)
+Function 487: DrawModelPointsEx() (6 input parameters)
Name: DrawModelPointsEx
Return type: void
Description: Draw a model as points with extended parameters
@@ -4110,13 +4116,13 @@ Function 486: DrawModelPointsEx() (6 input parameters)
Param[4]: rotationAngle (type: float)
Param[5]: scale (type: Vector3)
Param[6]: tint (type: Color)
-Function 487: DrawBoundingBox() (2 input parameters)
+Function 488: DrawBoundingBox() (2 input parameters)
Name: DrawBoundingBox
Return type: void
Description: Draw bounding box (wires)
Param[1]: box (type: BoundingBox)
Param[2]: color (type: Color)
-Function 488: DrawBillboard() (5 input parameters)
+Function 489: DrawBillboard() (5 input parameters)
Name: DrawBillboard
Return type: void
Description: Draw a billboard texture
@@ -4125,7 +4131,7 @@ Function 488: DrawBillboard() (5 input parameters)
Param[3]: position (type: Vector3)
Param[4]: scale (type: float)
Param[5]: tint (type: Color)
-Function 489: DrawBillboardRec() (6 input parameters)
+Function 490: DrawBillboardRec() (6 input parameters)
Name: DrawBillboardRec
Return type: void
Description: Draw a billboard texture defined by source
@@ -4135,7 +4141,7 @@ Function 489: DrawBillboardRec() (6 input parameters)
Param[4]: position (type: Vector3)
Param[5]: size (type: Vector2)
Param[6]: tint (type: Color)
-Function 490: DrawBillboardPro() (9 input parameters)
+Function 491: DrawBillboardPro() (9 input parameters)
Name: DrawBillboardPro
Return type: void
Description: Draw a billboard texture defined by source and rotation
@@ -4148,13 +4154,13 @@ Function 490: DrawBillboardPro() (9 input parameters)
Param[7]: origin (type: Vector2)
Param[8]: rotation (type: float)
Param[9]: tint (type: Color)
-Function 491: UploadMesh() (2 input parameters)
+Function 492: UploadMesh() (2 input parameters)
Name: UploadMesh
Return type: void
Description: Upload mesh vertex data in GPU and provide VAO/VBO ids
Param[1]: mesh (type: Mesh *)
Param[2]: dynamic (type: bool)
-Function 492: UpdateMeshBuffer() (5 input parameters)
+Function 493: UpdateMeshBuffer() (5 input parameters)
Name: UpdateMeshBuffer
Return type: void
Description: Update mesh vertex data in GPU for a specific buffer index
@@ -4163,19 +4169,19 @@ Function 492: UpdateMeshBuffer() (5 input parameters)
Param[3]: data (type: const void *)
Param[4]: dataSize (type: int)
Param[5]: offset (type: int)
-Function 493: UnloadMesh() (1 input parameters)
+Function 494: UnloadMesh() (1 input parameters)
Name: UnloadMesh
Return type: void
Description: Unload mesh data from CPU and GPU
Param[1]: mesh (type: Mesh)
-Function 494: DrawMesh() (3 input parameters)
+Function 495: DrawMesh() (3 input parameters)
Name: DrawMesh
Return type: void
Description: Draw a 3d mesh with material and transform
Param[1]: mesh (type: Mesh)
Param[2]: material (type: Material)
Param[3]: transform (type: Matrix)
-Function 495: DrawMeshInstanced() (4 input parameters)
+Function 496: DrawMeshInstanced() (4 input parameters)
Name: DrawMeshInstanced
Return type: void
Description: Draw multiple mesh instances with material and different transforms
@@ -4183,35 +4189,35 @@ Function 495: DrawMeshInstanced() (4 input parameters)
Param[2]: material (type: Material)
Param[3]: transforms (type: const Matrix *)
Param[4]: instances (type: int)
-Function 496: GetMeshBoundingBox() (1 input parameters)
+Function 497: GetMeshBoundingBox() (1 input parameters)
Name: GetMeshBoundingBox
Return type: BoundingBox
Description: Compute mesh bounding box limits
Param[1]: mesh (type: Mesh)
-Function 497: GenMeshTangents() (1 input parameters)
+Function 498: GenMeshTangents() (1 input parameters)
Name: GenMeshTangents
Return type: void
Description: Compute mesh tangents
Param[1]: mesh (type: Mesh *)
-Function 498: ExportMesh() (2 input parameters)
+Function 499: ExportMesh() (2 input parameters)
Name: ExportMesh
Return type: bool
Description: Export mesh data to file, returns true on success
Param[1]: mesh (type: Mesh)
Param[2]: fileName (type: const char *)
-Function 499: ExportMeshAsCode() (2 input parameters)
+Function 500: ExportMeshAsCode() (2 input parameters)
Name: ExportMeshAsCode
Return type: bool
Description: Export mesh as code file (.h) defining multiple arrays of vertex attributes
Param[1]: mesh (type: Mesh)
Param[2]: fileName (type: const char *)
-Function 500: GenMeshPoly() (2 input parameters)
+Function 501: GenMeshPoly() (2 input parameters)
Name: GenMeshPoly
Return type: Mesh
Description: Generate polygonal mesh
Param[1]: sides (type: int)
Param[2]: radius (type: float)
-Function 501: GenMeshPlane() (4 input parameters)
+Function 502: GenMeshPlane() (4 input parameters)
Name: GenMeshPlane
Return type: Mesh
Description: Generate plane mesh (with subdivisions)
@@ -4219,42 +4225,42 @@ Function 501: GenMeshPlane() (4 input parameters)
Param[2]: length (type: float)
Param[3]: resX (type: int)
Param[4]: resZ (type: int)
-Function 502: GenMeshCube() (3 input parameters)
+Function 503: GenMeshCube() (3 input parameters)
Name: GenMeshCube
Return type: Mesh
Description: Generate cuboid mesh
Param[1]: width (type: float)
Param[2]: height (type: float)
Param[3]: length (type: float)
-Function 503: GenMeshSphere() (3 input parameters)
+Function 504: GenMeshSphere() (3 input parameters)
Name: GenMeshSphere
Return type: Mesh
Description: Generate sphere mesh (standard sphere)
Param[1]: radius (type: float)
Param[2]: rings (type: int)
Param[3]: slices (type: int)
-Function 504: GenMeshHemiSphere() (3 input parameters)
+Function 505: GenMeshHemiSphere() (3 input parameters)
Name: GenMeshHemiSphere
Return type: Mesh
Description: Generate half-sphere mesh (no bottom cap)
Param[1]: radius (type: float)
Param[2]: rings (type: int)
Param[3]: slices (type: int)
-Function 505: GenMeshCylinder() (3 input parameters)
+Function 506: GenMeshCylinder() (3 input parameters)
Name: GenMeshCylinder
Return type: Mesh
Description: Generate cylinder mesh
Param[1]: radius (type: float)
Param[2]: height (type: float)
Param[3]: slices (type: int)
-Function 506: GenMeshCone() (3 input parameters)
+Function 507: GenMeshCone() (3 input parameters)
Name: GenMeshCone
Return type: Mesh
Description: Generate cone/pyramid mesh
Param[1]: radius (type: float)
Param[2]: height (type: float)
Param[3]: slices (type: int)
-Function 507: GenMeshTorus() (4 input parameters)
+Function 508: GenMeshTorus() (4 input parameters)
Name: GenMeshTorus
Return type: Mesh
Description: Generate torus mesh
@@ -4262,7 +4268,7 @@ Function 507: GenMeshTorus() (4 input parameters)
Param[2]: size (type: float)
Param[3]: radSeg (type: int)
Param[4]: sides (type: int)
-Function 508: GenMeshKnot() (4 input parameters)
+Function 509: GenMeshKnot() (4 input parameters)
Name: GenMeshKnot
Return type: Mesh
Description: Generate trefoil knot mesh
@@ -4270,91 +4276,91 @@ Function 508: GenMeshKnot() (4 input parameters)
Param[2]: size (type: float)
Param[3]: radSeg (type: int)
Param[4]: sides (type: int)
-Function 509: GenMeshHeightmap() (2 input parameters)
+Function 510: GenMeshHeightmap() (2 input parameters)
Name: GenMeshHeightmap
Return type: Mesh
Description: Generate heightmap mesh from image data
Param[1]: heightmap (type: Image)
Param[2]: size (type: Vector3)
-Function 510: GenMeshCubicmap() (2 input parameters)
+Function 511: GenMeshCubicmap() (2 input parameters)
Name: GenMeshCubicmap
Return type: Mesh
Description: Generate cubes-based map mesh from image data
Param[1]: cubicmap (type: Image)
Param[2]: cubeSize (type: Vector3)
-Function 511: LoadMaterials() (2 input parameters)
+Function 512: LoadMaterials() (2 input parameters)
Name: LoadMaterials
Return type: Material *
Description: Load materials from model file
Param[1]: fileName (type: const char *)
Param[2]: materialCount (type: int *)
-Function 512: LoadMaterialDefault() (0 input parameters)
+Function 513: LoadMaterialDefault() (0 input parameters)
Name: LoadMaterialDefault
Return type: Material
Description: Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps)
No input parameters
-Function 513: IsMaterialValid() (1 input parameters)
+Function 514: IsMaterialValid() (1 input parameters)
Name: IsMaterialValid
Return type: bool
Description: Check if a material is valid (shader assigned, map textures loaded in GPU)
Param[1]: material (type: Material)
-Function 514: UnloadMaterial() (1 input parameters)
+Function 515: UnloadMaterial() (1 input parameters)
Name: UnloadMaterial
Return type: void
Description: Unload material from GPU memory (VRAM)
Param[1]: material (type: Material)
-Function 515: SetMaterialTexture() (3 input parameters)
+Function 516: SetMaterialTexture() (3 input parameters)
Name: SetMaterialTexture
Return type: void
Description: Set texture for a material map type (MATERIAL_MAP_DIFFUSE, MATERIAL_MAP_SPECULAR...)
Param[1]: material (type: Material *)
Param[2]: mapType (type: int)
Param[3]: texture (type: Texture2D)
-Function 516: SetModelMeshMaterial() (3 input parameters)
+Function 517: SetModelMeshMaterial() (3 input parameters)
Name: SetModelMeshMaterial
Return type: void
Description: Set material for a mesh
Param[1]: model (type: Model *)
Param[2]: meshId (type: int)
Param[3]: materialId (type: int)
-Function 517: LoadModelAnimations() (2 input parameters)
+Function 518: LoadModelAnimations() (2 input parameters)
Name: LoadModelAnimations
Return type: ModelAnimation *
Description: Load model animations from file
Param[1]: fileName (type: const char *)
Param[2]: animCount (type: int *)
-Function 518: UpdateModelAnimation() (3 input parameters)
+Function 519: UpdateModelAnimation() (3 input parameters)
Name: UpdateModelAnimation
Return type: void
Description: Update model animation pose (CPU)
Param[1]: model (type: Model)
Param[2]: anim (type: ModelAnimation)
Param[3]: frame (type: int)
-Function 519: UpdateModelAnimationBones() (3 input parameters)
+Function 520: UpdateModelAnimationBones() (3 input parameters)
Name: UpdateModelAnimationBones
Return type: void
Description: Update model animation mesh bone matrices (GPU skinning)
Param[1]: model (type: Model)
Param[2]: anim (type: ModelAnimation)
Param[3]: frame (type: int)
-Function 520: UnloadModelAnimation() (1 input parameters)
+Function 521: UnloadModelAnimation() (1 input parameters)
Name: UnloadModelAnimation
Return type: void
Description: Unload animation data
Param[1]: anim (type: ModelAnimation)
-Function 521: UnloadModelAnimations() (2 input parameters)
+Function 522: UnloadModelAnimations() (2 input parameters)
Name: UnloadModelAnimations
Return type: void
Description: Unload animation array data
Param[1]: animations (type: ModelAnimation *)
Param[2]: animCount (type: int)
-Function 522: IsModelAnimationValid() (2 input parameters)
+Function 523: IsModelAnimationValid() (2 input parameters)
Name: IsModelAnimationValid
Return type: bool
Description: Check model animation skeleton match
Param[1]: model (type: Model)
Param[2]: anim (type: ModelAnimation)
-Function 523: CheckCollisionSpheres() (4 input parameters)
+Function 524: CheckCollisionSpheres() (4 input parameters)
Name: CheckCollisionSpheres
Return type: bool
Description: Check collision between two spheres
@@ -4362,40 +4368,40 @@ Function 523: CheckCollisionSpheres() (4 input parameters)
Param[2]: radius1 (type: float)
Param[3]: center2 (type: Vector3)
Param[4]: radius2 (type: float)
-Function 524: CheckCollisionBoxes() (2 input parameters)
+Function 525: CheckCollisionBoxes() (2 input parameters)
Name: CheckCollisionBoxes
Return type: bool
Description: Check collision between two bounding boxes
Param[1]: box1 (type: BoundingBox)
Param[2]: box2 (type: BoundingBox)
-Function 525: CheckCollisionBoxSphere() (3 input parameters)
+Function 526: CheckCollisionBoxSphere() (3 input parameters)
Name: CheckCollisionBoxSphere
Return type: bool
Description: Check collision between box and sphere
Param[1]: box (type: BoundingBox)
Param[2]: center (type: Vector3)
Param[3]: radius (type: float)
-Function 526: GetRayCollisionSphere() (3 input parameters)
+Function 527: GetRayCollisionSphere() (3 input parameters)
Name: GetRayCollisionSphere
Return type: RayCollision
Description: Get collision info between ray and sphere
Param[1]: ray (type: Ray)
Param[2]: center (type: Vector3)
Param[3]: radius (type: float)
-Function 527: GetRayCollisionBox() (2 input parameters)
+Function 528: GetRayCollisionBox() (2 input parameters)
Name: GetRayCollisionBox
Return type: RayCollision
Description: Get collision info between ray and box
Param[1]: ray (type: Ray)
Param[2]: box (type: BoundingBox)
-Function 528: GetRayCollisionMesh() (3 input parameters)
+Function 529: GetRayCollisionMesh() (3 input parameters)
Name: GetRayCollisionMesh
Return type: RayCollision
Description: Get collision info between ray and mesh
Param[1]: ray (type: Ray)
Param[2]: mesh (type: Mesh)
Param[3]: transform (type: Matrix)
-Function 529: GetRayCollisionTriangle() (4 input parameters)
+Function 530: GetRayCollisionTriangle() (4 input parameters)
Name: GetRayCollisionTriangle
Return type: RayCollision
Description: Get collision info between ray and triangle
@@ -4403,7 +4409,7 @@ Function 529: GetRayCollisionTriangle() (4 input parameters)
Param[2]: p1 (type: Vector3)
Param[3]: p2 (type: Vector3)
Param[4]: p3 (type: Vector3)
-Function 530: GetRayCollisionQuad() (5 input parameters)
+Function 531: GetRayCollisionQuad() (5 input parameters)
Name: GetRayCollisionQuad
Return type: RayCollision
Description: Get collision info between ray and quad
@@ -4412,158 +4418,158 @@ Function 530: GetRayCollisionQuad() (5 input parameters)
Param[3]: p2 (type: Vector3)
Param[4]: p3 (type: Vector3)
Param[5]: p4 (type: Vector3)
-Function 531: InitAudioDevice() (0 input parameters)
+Function 532: InitAudioDevice() (0 input parameters)
Name: InitAudioDevice
Return type: void
Description: Initialize audio device and context
No input parameters
-Function 532: CloseAudioDevice() (0 input parameters)
+Function 533: CloseAudioDevice() (0 input parameters)
Name: CloseAudioDevice
Return type: void
Description: Close the audio device and context
No input parameters
-Function 533: IsAudioDeviceReady() (0 input parameters)
+Function 534: IsAudioDeviceReady() (0 input parameters)
Name: IsAudioDeviceReady
Return type: bool
Description: Check if audio device has been initialized successfully
No input parameters
-Function 534: SetMasterVolume() (1 input parameters)
+Function 535: SetMasterVolume() (1 input parameters)
Name: SetMasterVolume
Return type: void
Description: Set master volume (listener)
Param[1]: volume (type: float)
-Function 535: GetMasterVolume() (0 input parameters)
+Function 536: GetMasterVolume() (0 input parameters)
Name: GetMasterVolume
Return type: float
Description: Get master volume (listener)
No input parameters
-Function 536: LoadWave() (1 input parameters)
+Function 537: LoadWave() (1 input parameters)
Name: LoadWave
Return type: Wave
Description: Load wave data from file
Param[1]: fileName (type: const char *)
-Function 537: LoadWaveFromMemory() (3 input parameters)
+Function 538: LoadWaveFromMemory() (3 input parameters)
Name: LoadWaveFromMemory
Return type: Wave
Description: Load wave from memory buffer, fileType refers to extension: i.e. '.wav'
Param[1]: fileType (type: const char *)
Param[2]: fileData (type: const unsigned char *)
Param[3]: dataSize (type: int)
-Function 538: IsWaveValid() (1 input parameters)
+Function 539: IsWaveValid() (1 input parameters)
Name: IsWaveValid
Return type: bool
Description: Checks if wave data is valid (data loaded and parameters)
Param[1]: wave (type: Wave)
-Function 539: LoadSound() (1 input parameters)
+Function 540: LoadSound() (1 input parameters)
Name: LoadSound
Return type: Sound
Description: Load sound from file
Param[1]: fileName (type: const char *)
-Function 540: LoadSoundFromWave() (1 input parameters)
+Function 541: LoadSoundFromWave() (1 input parameters)
Name: LoadSoundFromWave
Return type: Sound
Description: Load sound from wave data
Param[1]: wave (type: Wave)
-Function 541: LoadSoundAlias() (1 input parameters)
+Function 542: LoadSoundAlias() (1 input parameters)
Name: LoadSoundAlias
Return type: Sound
Description: Create a new sound that shares the same sample data as the source sound, does not own the sound data
Param[1]: source (type: Sound)
-Function 542: IsSoundValid() (1 input parameters)
+Function 543: IsSoundValid() (1 input parameters)
Name: IsSoundValid
Return type: bool
Description: Checks if a sound is valid (data loaded and buffers initialized)
Param[1]: sound (type: Sound)
-Function 543: UpdateSound() (3 input parameters)
+Function 544: UpdateSound() (3 input parameters)
Name: UpdateSound
Return type: void
Description: Update sound buffer with new data (data and frame count should fit in sound)
Param[1]: sound (type: Sound)
Param[2]: data (type: const void *)
Param[3]: sampleCount (type: int)
-Function 544: UnloadWave() (1 input parameters)
+Function 545: UnloadWave() (1 input parameters)
Name: UnloadWave
Return type: void
Description: Unload wave data
Param[1]: wave (type: Wave)
-Function 545: UnloadSound() (1 input parameters)
+Function 546: UnloadSound() (1 input parameters)
Name: UnloadSound
Return type: void
Description: Unload sound
Param[1]: sound (type: Sound)
-Function 546: UnloadSoundAlias() (1 input parameters)
+Function 547: UnloadSoundAlias() (1 input parameters)
Name: UnloadSoundAlias
Return type: void
Description: Unload a sound alias (does not deallocate sample data)
Param[1]: alias (type: Sound)
-Function 547: ExportWave() (2 input parameters)
+Function 548: ExportWave() (2 input parameters)
Name: ExportWave
Return type: bool
Description: Export wave data to file, returns true on success
Param[1]: wave (type: Wave)
Param[2]: fileName (type: const char *)
-Function 548: ExportWaveAsCode() (2 input parameters)
+Function 549: ExportWaveAsCode() (2 input parameters)
Name: ExportWaveAsCode
Return type: bool
Description: Export wave sample data to code (.h), returns true on success
Param[1]: wave (type: Wave)
Param[2]: fileName (type: const char *)
-Function 549: PlaySound() (1 input parameters)
+Function 550: PlaySound() (1 input parameters)
Name: PlaySound
Return type: void
Description: Play a sound
Param[1]: sound (type: Sound)
-Function 550: StopSound() (1 input parameters)
+Function 551: StopSound() (1 input parameters)
Name: StopSound
Return type: void
Description: Stop playing a sound
Param[1]: sound (type: Sound)
-Function 551: PauseSound() (1 input parameters)
+Function 552: PauseSound() (1 input parameters)
Name: PauseSound
Return type: void
Description: Pause a sound
Param[1]: sound (type: Sound)
-Function 552: ResumeSound() (1 input parameters)
+Function 553: ResumeSound() (1 input parameters)
Name: ResumeSound
Return type: void
Description: Resume a paused sound
Param[1]: sound (type: Sound)
-Function 553: IsSoundPlaying() (1 input parameters)
+Function 554: IsSoundPlaying() (1 input parameters)
Name: IsSoundPlaying
Return type: bool
Description: Check if a sound is currently playing
Param[1]: sound (type: Sound)
-Function 554: SetSoundVolume() (2 input parameters)
+Function 555: SetSoundVolume() (2 input parameters)
Name: SetSoundVolume
Return type: void
Description: Set volume for a sound (1.0 is max level)
Param[1]: sound (type: Sound)
Param[2]: volume (type: float)
-Function 555: SetSoundPitch() (2 input parameters)
+Function 556: SetSoundPitch() (2 input parameters)
Name: SetSoundPitch
Return type: void
Description: Set pitch for a sound (1.0 is base level)
Param[1]: sound (type: Sound)
Param[2]: pitch (type: float)
-Function 556: SetSoundPan() (2 input parameters)
+Function 557: SetSoundPan() (2 input parameters)
Name: SetSoundPan
Return type: void
Description: Set pan for a sound (0.5 is center)
Param[1]: sound (type: Sound)
Param[2]: pan (type: float)
-Function 557: WaveCopy() (1 input parameters)
+Function 558: WaveCopy() (1 input parameters)
Name: WaveCopy
Return type: Wave
Description: Copy a wave to a new wave
Param[1]: wave (type: Wave)
-Function 558: WaveCrop() (3 input parameters)
+Function 559: WaveCrop() (3 input parameters)
Name: WaveCrop
Return type: void
Description: Crop a wave to defined frames range
Param[1]: wave (type: Wave *)
Param[2]: initFrame (type: int)
Param[3]: finalFrame (type: int)
-Function 559: WaveFormat() (4 input parameters)
+Function 560: WaveFormat() (4 input parameters)
Name: WaveFormat
Return type: void
Description: Convert wave data to desired format
@@ -4571,203 +4577,203 @@ Function 559: WaveFormat() (4 input parameters)
Param[2]: sampleRate (type: int)
Param[3]: sampleSize (type: int)
Param[4]: channels (type: int)
-Function 560: LoadWaveSamples() (1 input parameters)
+Function 561: LoadWaveSamples() (1 input parameters)
Name: LoadWaveSamples
Return type: float *
Description: Load samples data from wave as a 32bit float data array
Param[1]: wave (type: Wave)
-Function 561: UnloadWaveSamples() (1 input parameters)
+Function 562: UnloadWaveSamples() (1 input parameters)
Name: UnloadWaveSamples
Return type: void
Description: Unload samples data loaded with LoadWaveSamples()
Param[1]: samples (type: float *)
-Function 562: LoadMusicStream() (1 input parameters)
+Function 563: LoadMusicStream() (1 input parameters)
Name: LoadMusicStream
Return type: Music
Description: Load music stream from file
Param[1]: fileName (type: const char *)
-Function 563: LoadMusicStreamFromMemory() (3 input parameters)
+Function 564: LoadMusicStreamFromMemory() (3 input parameters)
Name: LoadMusicStreamFromMemory
Return type: Music
Description: Load music stream from data
Param[1]: fileType (type: const char *)
Param[2]: data (type: const unsigned char *)
Param[3]: dataSize (type: int)
-Function 564: IsMusicValid() (1 input parameters)
+Function 565: IsMusicValid() (1 input parameters)
Name: IsMusicValid
Return type: bool
Description: Checks if a music stream is valid (context and buffers initialized)
Param[1]: music (type: Music)
-Function 565: UnloadMusicStream() (1 input parameters)
+Function 566: UnloadMusicStream() (1 input parameters)
Name: UnloadMusicStream
Return type: void
Description: Unload music stream
Param[1]: music (type: Music)
-Function 566: PlayMusicStream() (1 input parameters)
+Function 567: PlayMusicStream() (1 input parameters)
Name: PlayMusicStream
Return type: void
Description: Start music playing
Param[1]: music (type: Music)
-Function 567: IsMusicStreamPlaying() (1 input parameters)
+Function 568: IsMusicStreamPlaying() (1 input parameters)
Name: IsMusicStreamPlaying
Return type: bool
Description: Check if music is playing
Param[1]: music (type: Music)
-Function 568: UpdateMusicStream() (1 input parameters)
+Function 569: UpdateMusicStream() (1 input parameters)
Name: UpdateMusicStream
Return type: void
Description: Updates buffers for music streaming
Param[1]: music (type: Music)
-Function 569: StopMusicStream() (1 input parameters)
+Function 570: StopMusicStream() (1 input parameters)
Name: StopMusicStream
Return type: void
Description: Stop music playing
Param[1]: music (type: Music)
-Function 570: PauseMusicStream() (1 input parameters)
+Function 571: PauseMusicStream() (1 input parameters)
Name: PauseMusicStream
Return type: void
Description: Pause music playing
Param[1]: music (type: Music)
-Function 571: ResumeMusicStream() (1 input parameters)
+Function 572: ResumeMusicStream() (1 input parameters)
Name: ResumeMusicStream
Return type: void
Description: Resume playing paused music
Param[1]: music (type: Music)
-Function 572: SeekMusicStream() (2 input parameters)
+Function 573: SeekMusicStream() (2 input parameters)
Name: SeekMusicStream
Return type: void
Description: Seek music to a position (in seconds)
Param[1]: music (type: Music)
Param[2]: position (type: float)
-Function 573: SetMusicVolume() (2 input parameters)
+Function 574: SetMusicVolume() (2 input parameters)
Name: SetMusicVolume
Return type: void
Description: Set volume for music (1.0 is max level)
Param[1]: music (type: Music)
Param[2]: volume (type: float)
-Function 574: SetMusicPitch() (2 input parameters)
+Function 575: SetMusicPitch() (2 input parameters)
Name: SetMusicPitch
Return type: void
Description: Set pitch for a music (1.0 is base level)
Param[1]: music (type: Music)
Param[2]: pitch (type: float)
-Function 575: SetMusicPan() (2 input parameters)
+Function 576: SetMusicPan() (2 input parameters)
Name: SetMusicPan
Return type: void
Description: Set pan for a music (0.5 is center)
Param[1]: music (type: Music)
Param[2]: pan (type: float)
-Function 576: GetMusicTimeLength() (1 input parameters)
+Function 577: GetMusicTimeLength() (1 input parameters)
Name: GetMusicTimeLength
Return type: float
Description: Get music time length (in seconds)
Param[1]: music (type: Music)
-Function 577: GetMusicTimePlayed() (1 input parameters)
+Function 578: GetMusicTimePlayed() (1 input parameters)
Name: GetMusicTimePlayed
Return type: float
Description: Get current music time played (in seconds)
Param[1]: music (type: Music)
-Function 578: LoadAudioStream() (3 input parameters)
+Function 579: LoadAudioStream() (3 input parameters)
Name: LoadAudioStream
Return type: AudioStream
Description: Load audio stream (to stream raw audio pcm data)
Param[1]: sampleRate (type: unsigned int)
Param[2]: sampleSize (type: unsigned int)
Param[3]: channels (type: unsigned int)
-Function 579: IsAudioStreamValid() (1 input parameters)
+Function 580: IsAudioStreamValid() (1 input parameters)
Name: IsAudioStreamValid
Return type: bool
Description: Checks if an audio stream is valid (buffers initialized)
Param[1]: stream (type: AudioStream)
-Function 580: UnloadAudioStream() (1 input parameters)
+Function 581: UnloadAudioStream() (1 input parameters)
Name: UnloadAudioStream
Return type: void
Description: Unload audio stream and free memory
Param[1]: stream (type: AudioStream)
-Function 581: UpdateAudioStream() (3 input parameters)
+Function 582: UpdateAudioStream() (3 input parameters)
Name: UpdateAudioStream
Return type: void
Description: Update audio stream buffers with data
Param[1]: stream (type: AudioStream)
Param[2]: data (type: const void *)
Param[3]: frameCount (type: int)
-Function 582: IsAudioStreamProcessed() (1 input parameters)
+Function 583: IsAudioStreamProcessed() (1 input parameters)
Name: IsAudioStreamProcessed
Return type: bool
Description: Check if any audio stream buffers requires refill
Param[1]: stream (type: AudioStream)
-Function 583: PlayAudioStream() (1 input parameters)
+Function 584: PlayAudioStream() (1 input parameters)
Name: PlayAudioStream
Return type: void
Description: Play audio stream
Param[1]: stream (type: AudioStream)
-Function 584: PauseAudioStream() (1 input parameters)
+Function 585: PauseAudioStream() (1 input parameters)
Name: PauseAudioStream
Return type: void
Description: Pause audio stream
Param[1]: stream (type: AudioStream)
-Function 585: ResumeAudioStream() (1 input parameters)
+Function 586: ResumeAudioStream() (1 input parameters)
Name: ResumeAudioStream
Return type: void
Description: Resume audio stream
Param[1]: stream (type: AudioStream)
-Function 586: IsAudioStreamPlaying() (1 input parameters)
+Function 587: IsAudioStreamPlaying() (1 input parameters)
Name: IsAudioStreamPlaying
Return type: bool
Description: Check if audio stream is playing
Param[1]: stream (type: AudioStream)
-Function 587: StopAudioStream() (1 input parameters)
+Function 588: StopAudioStream() (1 input parameters)
Name: StopAudioStream
Return type: void
Description: Stop audio stream
Param[1]: stream (type: AudioStream)
-Function 588: SetAudioStreamVolume() (2 input parameters)
+Function 589: SetAudioStreamVolume() (2 input parameters)
Name: SetAudioStreamVolume
Return type: void
Description: Set volume for audio stream (1.0 is max level)
Param[1]: stream (type: AudioStream)
Param[2]: volume (type: float)
-Function 589: SetAudioStreamPitch() (2 input parameters)
+Function 590: SetAudioStreamPitch() (2 input parameters)
Name: SetAudioStreamPitch
Return type: void
Description: Set pitch for audio stream (1.0 is base level)
Param[1]: stream (type: AudioStream)
Param[2]: pitch (type: float)
-Function 590: SetAudioStreamPan() (2 input parameters)
+Function 591: SetAudioStreamPan() (2 input parameters)
Name: SetAudioStreamPan
Return type: void
Description: Set pan for audio stream (0.5 is centered)
Param[1]: stream (type: AudioStream)
Param[2]: pan (type: float)
-Function 591: SetAudioStreamBufferSizeDefault() (1 input parameters)
+Function 592: SetAudioStreamBufferSizeDefault() (1 input parameters)
Name: SetAudioStreamBufferSizeDefault
Return type: void
Description: Default size for new audio streams
Param[1]: size (type: int)
-Function 592: SetAudioStreamCallback() (2 input parameters)
+Function 593: SetAudioStreamCallback() (2 input parameters)
Name: SetAudioStreamCallback
Return type: void
Description: Audio thread callback to request new data
Param[1]: stream (type: AudioStream)
Param[2]: callback (type: AudioCallback)
-Function 593: AttachAudioStreamProcessor() (2 input parameters)
+Function 594: AttachAudioStreamProcessor() (2 input parameters)
Name: AttachAudioStreamProcessor
Return type: void
Description: Attach audio stream processor to stream, receives frames x 2 samples as 'float' (stereo)
Param[1]: stream (type: AudioStream)
Param[2]: processor (type: AudioCallback)
-Function 594: DetachAudioStreamProcessor() (2 input parameters)
+Function 595: DetachAudioStreamProcessor() (2 input parameters)
Name: DetachAudioStreamProcessor
Return type: void
Description: Detach audio stream processor from stream
Param[1]: stream (type: AudioStream)
Param[2]: processor (type: AudioCallback)
-Function 595: AttachAudioMixedProcessor() (1 input parameters)
+Function 596: AttachAudioMixedProcessor() (1 input parameters)
Name: AttachAudioMixedProcessor
Return type: void
Description: Attach audio stream processor to the entire audio pipeline, receives frames x 2 samples as 'float' (stereo)
Param[1]: processor (type: AudioCallback)
-Function 596: DetachAudioMixedProcessor() (1 input parameters)
+Function 597: DetachAudioMixedProcessor() (1 input parameters)
Name: DetachAudioMixedProcessor
Return type: void
Description: Detach audio stream processor from the entire audio pipeline
diff --git a/tools/parser/output/raylib_api.xml b/tools/rlparser/output/raylib_api.xml
similarity index 99%
rename from tools/parser/output/raylib_api.xml
rename to tools/rlparser/output/raylib_api.xml
index 59f2d4a50..96dbdbf64 100644
--- a/tools/parser/output/raylib_api.xml
+++ b/tools/rlparser/output/raylib_api.xml
@@ -679,7 +679,7 @@
-
+
@@ -1168,6 +1168,10 @@
+
+
+
+
diff --git a/tools/rlparser/rlparser b/tools/rlparser/rlparser
new file mode 100755
index 000000000..b68032c02
Binary files /dev/null and b/tools/rlparser/rlparser differ
diff --git a/tools/parser/raylib_parser.c b/tools/rlparser/rlparser.c
similarity index 96%
rename from tools/parser/raylib_parser.c
rename to tools/rlparser/rlparser.c
index 4b5fe1625..d5b03fa01 100644
--- a/tools/parser/raylib_parser.c
+++ b/tools/rlparser/rlparser.c
@@ -1,28 +1,28 @@
/**********************************************************************************************
- raylib API parser
+ rlparser - raylib header API parser, extracts API information as separate tokens
This parser scans raylib.h to get API information about defines, structs, aliases, enums, callbacks and functions.
All data is divided into pieces, usually as strings. The following types are used for data:
-
- struct DefineInfo
- struct StructInfo
- struct AliasInfo
- struct EnumInfo
- struct FunctionInfo
+
+ WARNING: This parser is specifically designed to work with raylib.h, and has some contraints
+ in that regards. Still, it can also work with other header files that follow same file structure
+ conventions as raylib.h: rlgl.h, raymath.h, raygui.h, reasings.h
CONSTRAINTS:
-
This parser is specifically designed to work with raylib.h, so, it has some constraints:
- Functions are expected as a single line with the following structure:
-
( , );
- Be careful with functions broken into several lines, it breaks the process!
+ WARNING: Be careful with functions broken into several lines, it breaks the process!
- Structures are expected as several lines with the following form:
-
typedef struct {
;
@@ -31,7 +31,6 @@
} ;
- Enums are expected as several lines with the following form:
-
typedef enum {
= ,
@@ -45,7 +44,6 @@
- Value description can be provided or not
OTHER NOTES:
-
- This parser could work with other C header files if mentioned constraints are followed.
- This parser does not require library, all data is parsed directly from char buffers.
@@ -82,7 +80,7 @@
// Types and Structures Definition
//----------------------------------------------------------------------------------
-// Type of parsed define
+// Define value type
typedef enum {
UNKNOWN = 0,
MACRO,
@@ -103,7 +101,7 @@ typedef enum {
// Define info data
typedef struct DefineInfo {
char name[64]; // Define name
- int type; // Define type
+ int type; // Define type: enum DefineType
char value[256]; // Define value
char desc[128]; // Define description
bool isHex; // Define is hex number (for types INT, LONG)
@@ -171,7 +169,7 @@ static char apiDefine[32] = { 0 }; // Functions define (i.e. RLAPI for r
static char truncAfter[32] = { 0 }; // Truncate marker (i.e. "RLGL IMPLEMENTATION" for rlgl.h)
static int outputFormat = DEFAULT;
-// NOTE: Max length depends on OS, in Windows MAX_PATH = 256
+// NOTE: Filename max length depends on OS, in Windows MAX_PATH = 256
static char inFileName[512] = { 0 }; // Input file name (required in case of drag & drop over executable)
static char outFileName[512] = { 0 }; // Output file name (required for file save/export)
@@ -181,15 +179,17 @@ static char outFileName[512] = { 0 }; // Output file name (required for fi
static void ShowCommandLineInfo(void); // Show command line usage info
static void ProcessCommandLine(int argc, char *argv[]); // Process command line input
-static char *LoadFileText(const char *fileName, int *length);
-static char **GetTextLines(const char *buffer, int length, int *linesCount);
-static void GetDataTypeAndName(const char *typeName, int typeNameLen, char *type, char *name);
-static void GetDescription(const char *source, char *description);
+static char *LoadFileText(const char *fileName, int *length); // Load text file - UnloadFileText() required!
+static void UnloadFileText(char *text); // Unload text data
+static char **LoadTextLines(const char *buffer, int length, int *lineCount); // Load all lines from a text buffer (expecting lines ending with '\n') - UnloadTextLines() required
+static void UnloadTextLines(char **lines, int lineCount); // Unload text lines data
+static void GetDataTypeAndName(const char *typeName, int typeNameLen, char *type, char *name); // Get data type and name from a string containing both (i.e function param and struct fields)
+static void GetDescription(const char *source, char *description); // Get description comment from a line, do nothing if no comment in line
static void MoveArraySize(char *name, char *type); // Move array size from name to type
static unsigned int TextLength(const char *text); // Get text length in bytes, check for \0 character
static bool IsTextEqual(const char *text1, const char *text2, unsigned int count);
static int TextFindIndex(const char *text, const char *find); // Find first text occurrence within a string
-static void MemoryCopy(void *dest, const void *src, unsigned int count);
+static void MemoryCopy(void *dest, const void *src, unsigned int count); // Memory copy, memcpy() replacement to avoid
static char *EscapeBackslashes(char *text); // Replace '\' by "\\" when exporting to JSON and XML
static const char *StrDefineType(DefineType type); // Get string of define type
@@ -219,21 +219,21 @@ int main(int argc, char* argv[])
}
// Preprocess buffer to get separate lines
- // NOTE: GetTextLines() also removes leading spaces/tabs
- int linesCount = 0;
- char **lines = GetTextLines(buffer, length, &linesCount);
+ // NOTE: LoadTextLines() also removes leading spaces/tabs
+ int lineCount = 0;
+ char **lines = LoadTextLines(buffer, length, &lineCount);
- // Truncate lines
+ // Truncate lines (if required)
if (truncAfter[0] != '\0')
{
int newCount = -1;
- for (int i = 0; i < linesCount; i++)
+ for (int i = 0; i < lineCount; i++)
{
if (newCount > -1) free(lines[i]);
else if (TextFindIndex(lines[i], truncAfter) > -1) newCount = i;
}
- if (newCount > -1) linesCount = newCount;
- printf("Number of truncated text lines: %i\n", linesCount);
+ if (newCount > -1) lineCount = newCount;
+ printf("Number of truncated text lines: %i\n", lineCount);
}
// Defines line indices
@@ -256,9 +256,8 @@ int main(int argc, char* argv[])
// Prepare required lines for parsing
//----------------------------------------------------------------------------------
-
// Read define lines
- for (int i = 0; i < linesCount; i++)
+ for (int i = 0; i < lineCount; i++)
{
int j = 0;
while ((lines[i][j] == ' ') || (lines[i][j] == '\t')) j++; // skip spaces and tabs in the begining
@@ -273,7 +272,7 @@ int main(int argc, char* argv[])
}
// Read struct lines
- for (int i = 0; i < linesCount; i++)
+ for (int i = 0; i < lineCount; i++)
{
// Find structs
// starting with "typedef struct ... {" or "typedef struct ... ; \n struct ... {"
@@ -300,7 +299,7 @@ int main(int argc, char* argv[])
}
// Read alias lines
- for (int i = 0; i < linesCount; i++)
+ for (int i = 0; i < lineCount; i++)
{
// Find aliases (lines with "typedef ... ...;")
if (IsTextEqual(lines[i], "typedef", 7))
@@ -322,7 +321,7 @@ int main(int argc, char* argv[])
}
// Read enum lines
- for (int i = 0; i < linesCount; i++)
+ for (int i = 0; i < lineCount; i++)
{
// Read enum line
if (IsTextEqual(lines[i], "typedef enum {", 14) && (lines[i][TextLength(lines[i])-1] != ';')) // ignore inline enums
@@ -335,7 +334,7 @@ int main(int argc, char* argv[])
}
// Read callback lines
- for (int i = 0; i < linesCount; i++)
+ for (int i = 0; i < lineCount; i++)
{
// Find callbacks (lines with "typedef ... (* ... )( ... );")
if (IsTextEqual(lines[i], "typedef", 7))
@@ -361,7 +360,7 @@ int main(int argc, char* argv[])
}
// Read function lines
- for (int i = 0; i < linesCount; i++)
+ for (int i = 0; i < lineCount; i++)
{
// Read function line (starting with `define`, i.e. for raylib.h "RLAPI")
if (IsTextEqual(lines[i], apiDefine, TextLength(apiDefine)))
@@ -373,14 +372,13 @@ int main(int argc, char* argv[])
// At this point we have all raylib defines, structs, aliases, enums, callbacks, functions lines data to start parsing
- free(buffer); // Unload text buffer
+ UnloadFileText(buffer); // Unload text buffer
// Parsing raylib data
//----------------------------------------------------------------------------------
-
// Define info data
- defines = (DefineInfo *)calloc(MAX_DEFINES_TO_PARSE, sizeof(DefineInfo));
int defineIndex = 0;
+ defines = (DefineInfo *)calloc(MAX_DEFINES_TO_PARSE, sizeof(DefineInfo));
for (int i = 0; i < defineCount; i++)
{
@@ -1040,8 +1038,7 @@ int main(int argc, char* argv[])
}
free(funcLines);
- for (int i = 0; i < linesCount; i++) free(lines[i]);
- free(lines);
+ UnloadTextLines(lines, lineCount);
// At this point, all raylib data has been parsed!
//----------------------------------------------------------------------------------
@@ -1052,6 +1049,11 @@ int main(int argc, char* argv[])
// callbacks[] -> We have all the callbacks decomposed into pieces for further analysis
// funcs[] -> We have all the functions decomposed into pieces for further analysis
+ // Export data as required
+ // NOTE: We are exporting data in several common formats (JSON, XML, LUA...) for convenience
+ // but this data can be directly used to create bindings for other languages modifying this
+ // small parser for every binding need, there is no need to use (and re-parse) the
+ // generated files... despite it seems that's the usual approach...
printf("\nInput file: %s", inFileName);
printf("\nOutput file: %s", outFileName);
if (outputFormat == DEFAULT) printf("\nOutput format: DEFAULT\n\n");
@@ -1073,22 +1075,21 @@ int main(int argc, char* argv[])
//----------------------------------------------------------------------------------
// Module Functions Definition
//----------------------------------------------------------------------------------
-
// Show command line usage info
static void ShowCommandLineInfo(void)
{
printf("\n//////////////////////////////////////////////////////////////////////////////////\n");
printf("// //\n");
- printf("// raylib API parser //\n");
+ printf("// rlparser - raylib header API parser //\n");
printf("// //\n");
- printf("// more info and bugs-report: github.com/raysan5/raylib/parser //\n");
+ printf("// more info and bugs-report: github.com/raysan5/raylib/tools/rlparser //\n");
printf("// //\n");
printf("// Copyright (c) 2021-2025 Ramon Santamaria (@raysan5) //\n");
printf("// //\n");
printf("//////////////////////////////////////////////////////////////////////////////////\n\n");
printf("USAGE:\n\n");
- printf(" > raylib_parser [--help] [--input ] [--output ] [--format ]\n");
+ printf(" > rlparser [--help] [--input ] [--output ] [--format ]\n");
printf("\nOPTIONS:\n\n");
printf(" -h, --help : Show tool version and command line usage help\n\n");
@@ -1105,11 +1106,11 @@ static void ShowCommandLineInfo(void)
printf(" NOTE: If not specified, the full input file is parsed.\n\n");
printf("\nEXAMPLES:\n\n");
- printf(" > raylib_parser --input raylib.h --output api.json\n");
+ printf(" > rlparser --input raylib.h --output api.json\n");
printf(" Process to generate \n\n");
- printf(" > raylib_parser --output raylib_data.info --format XML\n");
+ printf(" > rlparser --output raylib_data.info --format XML\n");
printf(" Process to generate as XML text data\n\n");
- printf(" > raylib_parser --input raymath.h --output raymath_data.info --format XML --define RMAPI\n");
+ printf(" > rlparser --input raymath.h --output raymath_data.info --format XML --define RMAPI\n");
printf(" Process to generate as XML text data\n\n");
}
@@ -1221,8 +1222,14 @@ static char *LoadFileText(const char *fileName, int *length)
return text;
}
+// Unload text data
+static void UnloadFileText(char *text)
+{
+ free(text);
+}
+
// Get all lines from a text buffer (expecting lines ending with '\n')
-static char **GetTextLines(const char *buffer, int length, int *linesCount)
+static char **LoadTextLines(const char *buffer, int length, int *lineCount)
{
// Get the number of lines in the text
int count = 0;
@@ -1237,7 +1244,7 @@ static char **GetTextLines(const char *buffer, int length, int *linesCount)
for (int i = 0; (i < count) || (bufferPtr[0] != '\0'); i++)
{
- lines[i] = (char *)calloc(MAX_LINE_LENGTH, sizeof(char));
+ lines[i] = (char *)calloc(MAX_LINE_LENGTH, sizeof(char)); // MAX_LINE_LENGTH=1024
// Remove line leading spaces
// Find last index of space/tab character
@@ -1254,10 +1261,17 @@ static char **GetTextLines(const char *buffer, int length, int *linesCount)
bufferPtr += (index + j + 1);
}
- *linesCount = count;
+ *lineCount = count;
return lines;
}
+// Unload text lines data
+static void UnloadTextLines(char **lines, int lineCount)
+{
+ for (int i = 0; i < lineCount; i++) free(lines[i]);
+ free(lines);
+}
+
// Get data type and name from a string containing both
// NOTE: Useful to parse function parameters and struct fields
static void GetDataTypeAndName(const char *typeName, int typeNameLen, char *type, char *name)
diff --git a/tools/rlparser/rlparser.ico b/tools/rlparser/rlparser.ico
new file mode 100644
index 000000000..37f2af6b6
Binary files /dev/null and b/tools/rlparser/rlparser.ico differ
diff --git a/tools/rlparser/rlparser.rc b/tools/rlparser/rlparser.rc
new file mode 100644
index 000000000..a5bb5b7ad
--- /dev/null
+++ b/tools/rlparser/rlparser.rc
@@ -0,0 +1,24 @@
+IDI_APP_ICON ICON "rlparser.ico"
+1 VERSIONINFO
+FILEVERSION 5,5,0,0
+PRODUCTVERSION 5,5,0,0
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904E4" // English US
+ BEGIN
+ VALUE "CompanyName", "raylib technologies"
+ VALUE "FileDescription", "rlparser | raylib header API parser"
+ VALUE "FileVersion", "1.0"
+ VALUE "InternalName", "rlparser"
+ VALUE "LegalCopyright", "(c) 2025 Ramon Santamaria (@raysan5)"
+ VALUE "OriginalFilename", "rlparser"
+ VALUE "ProductName", "rlparser"
+ VALUE "ProductVersion", "1.0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1252 // English US
+ END
+END
\ No newline at end of file
diff --git a/tools/rlparser/rlparser.rc.data b/tools/rlparser/rlparser.rc.data
new file mode 100644
index 000000000..1b5cc0c02
Binary files /dev/null and b/tools/rlparser/rlparser.rc.data differ