diff --git a/.github/workflows/build_windows.yml b/.github/workflows/build_windows.yml
index 9e87b5870..7a92c208a 100644
--- a/.github/workflows/build_windows.yml
+++ b/.github/workflows/build_windows.yml
@@ -40,10 +40,10 @@ jobs:
ziptarget: "win64"
- compiler: msvc16
ARCH: "x86"
- VSARCHPATH: "Win32"
+ VSARCHPATH: "Win32"
ziptarget: "win32"
- compiler: msvc16
- ARCH: "x64"
+ ARCH: "x64"
VSARCHPATH: "x64"
ziptarget: "win64"
- compiler: msvc16
@@ -61,7 +61,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@master
-
+
- name: Setup Release Version
run: |
echo "RELEASE_NAME=raylib-${{ github.event.release.tag_name }}_${{ matrix.ziptarget }}_${{ matrix.compiler }}" >> $GITHUB_ENV
@@ -69,7 +69,7 @@ jobs:
if: github.event_name == 'release' && github.event.action == 'published'
- name: Setup Environment
- run: |
+ run: |
dir
mkdir build
cd build
@@ -98,7 +98,7 @@ jobs:
if: |
matrix.compiler == 'mingw-w64' &&
matrix.arch == 'i686'
-
+
- name: Build Library (MinGW-w64 64bit)
run: |
cd src
@@ -144,7 +144,7 @@ jobs:
with:
name: ${{ env.RELEASE_NAME }}.zip
path: ./build/${{ env.RELEASE_NAME }}.zip
-
+
- name: Upload Artifact to Release
uses: softprops/action-gh-release@v1
with:
diff --git a/examples/Makefile b/examples/Makefile
index eb6725756..ef7cb5948 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -519,6 +519,7 @@ CORE = \
core/core_directory_files \
core/core_drop_files \
core/core_high_dpi \
+ core/core_highdpi_testbed \
core/core_input_actions \
core/core_input_gamepad \
core/core_input_gestures \
@@ -528,13 +529,15 @@ CORE = \
core/core_input_mouse_wheel \
core/core_input_multitouch \
core/core_input_virtual_controls \
- core/core_monitor_change \
+ core/core_monitor_detector \
core/core_random_sequence \
core/core_random_values \
core/core_render_texture \
core/core_scissor_test \
+ core/core_screen_recording \
core/core_smooth_pixelperfect \
core/core_storage_values \
+ core/core_text_file_loading \
core/core_undo_redo \
core/core_vr_simulator \
core/core_window_flags \
@@ -570,7 +573,7 @@ SHAPES = \
shapes/shapes_rounded_rectangle_drawing \
shapes/shapes_simple_particles \
shapes/shapes_splines_drawing \
- shapes/shapes_starfield \
+ shapes/shapes_starfield_effect \
shapes/shapes_top_down_lights \
shapes/shapes_triangle_strip \
shapes/shapes_vector_angle
@@ -630,7 +633,6 @@ MODELS = \
models/models_cubicmap_rendering \
models/models_first_person_maze \
models/models_geometric_shapes \
- models/models_geometry_textures_cube \
models/models_heightmap_rendering \
models/models_loading \
models/models_loading_gltf \
@@ -641,6 +643,7 @@ MODELS = \
models/models_orthographic_projection \
models/models_point_rendering \
models/models_rlgl_solar_system \
+ models/models_rotating_cube \
models/models_skybox_rendering \
models/models_tesseract_view \
models/models_textured_cube \
@@ -661,6 +664,7 @@ SHADERS = \
shaders/shaders_hybrid_rendering \
shaders/shaders_julia_set \
shaders/shaders_lightmap_rendering \
+ shaders/shaders_mandelbrot_set \
shaders/shaders_mesh_instancing \
shaders/shaders_model_shader \
shaders/shaders_multi_sample2d \
diff --git a/examples/Makefile.Web b/examples/Makefile.Web
index e365a5fee..5d4f3ffab 100644
--- a/examples/Makefile.Web
+++ b/examples/Makefile.Web
@@ -519,6 +519,7 @@ CORE = \
core/core_directory_files \
core/core_drop_files \
core/core_high_dpi \
+ core/core_highdpi_testbed \
core/core_input_actions \
core/core_input_gamepad \
core/core_input_gestures \
@@ -528,13 +529,15 @@ CORE = \
core/core_input_mouse_wheel \
core/core_input_multitouch \
core/core_input_virtual_controls \
- core/core_monitor_change \
+ core/core_monitor_detector \
core/core_random_sequence \
core/core_random_values \
core/core_render_texture \
core/core_scissor_test \
+ core/core_screen_recording \
core/core_smooth_pixelperfect \
core/core_storage_values \
+ core/core_text_file_loading \
core/core_undo_redo \
core/core_vr_simulator \
core/core_window_flags \
@@ -570,7 +573,7 @@ SHAPES = \
shapes/shapes_rounded_rectangle_drawing \
shapes/shapes_simple_particles \
shapes/shapes_splines_drawing \
- shapes/shapes_starfield \
+ shapes/shapes_starfield_effect \
shapes/shapes_top_down_lights \
shapes/shapes_triangle_strip \
shapes/shapes_vector_angle
@@ -630,7 +633,6 @@ MODELS = \
models/models_cubicmap_rendering \
models/models_first_person_maze \
models/models_geometric_shapes \
- models/models_geometry_textures_cube \
models/models_heightmap_rendering \
models/models_loading \
models/models_loading_gltf \
@@ -641,6 +643,7 @@ MODELS = \
models/models_orthographic_projection \
models/models_point_rendering \
models/models_rlgl_solar_system \
+ models/models_rotating_cube \
models/models_skybox_rendering \
models/models_tesseract_view \
models/models_textured_cube \
@@ -661,6 +664,7 @@ SHADERS = \
shaders/shaders_hybrid_rendering \
shaders/shaders_julia_set \
shaders/shaders_lightmap_rendering \
+ shaders/shaders_mandelbrot_set \
shaders/shaders_mesh_instancing \
shaders/shaders_model_shader \
shaders/shaders_multi_sample2d \
@@ -761,6 +765,9 @@ core/core_drop_files: core/core_drop_files.c
core/core_high_dpi: core/core_high_dpi.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+core/core_highdpi_testbed: core/core_highdpi_testbed.c
+ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+
core/core_input_actions: core/core_input_actions.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
@@ -790,7 +797,7 @@ core/core_input_multitouch: core/core_input_multitouch.c
core/core_input_virtual_controls: core/core_input_virtual_controls.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
-core/core_monitor_change: core/core_monitor_change.c
+core/core_monitor_detector: core/core_monitor_detector.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
core/core_random_sequence: core/core_random_sequence.c
@@ -805,12 +812,19 @@ core/core_render_texture: core/core_render_texture.c
core/core_scissor_test: core/core_scissor_test.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+core/core_screen_recording: core/core_screen_recording.c
+ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+
core/core_smooth_pixelperfect: core/core_smooth_pixelperfect.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
core/core_storage_values: core/core_storage_values.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+core/core_text_file_loading: core/core_text_file_loading.c
+ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
+ --preload-file core/resources/text_file.txt@resources/text_file.txt
+
core/core_undo_redo: core/core_undo_redo.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
@@ -912,7 +926,7 @@ shapes/shapes_simple_particles: shapes/shapes_simple_particles.c
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
+shapes/shapes_starfield_effect: shapes/shapes_starfield_effect.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
shapes/shapes_top_down_lights: shapes/shapes_top_down_lights.c
@@ -1146,10 +1160,6 @@ models/models_first_person_maze: models/models_first_person_maze.c
models/models_geometric_shapes: models/models_geometric_shapes.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
-models/models_geometry_textures_cube: models/models_geometry_textures_cube.c
- $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
- --preload-file models/resources/cubicmap_atlas.png@resources/cubicmap_atlas.png
-
models/models_heightmap_rendering: models/models_heightmap_rendering.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file models/resources/heightmap.png@resources/heightmap.png
@@ -1193,6 +1203,10 @@ models/models_point_rendering: models/models_point_rendering.c
models/models_rlgl_solar_system: models/models_rlgl_solar_system.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+models/models_rotating_cube: models/models_rotating_cube.c
+ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
+ --preload-file models/resources/cubicmap_atlas.png@resources/cubicmap_atlas.png
+
models/models_skybox_rendering: models/models_skybox_rendering.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file models/resources/shaders/glsl100/skybox.vs@resources/shaders/glsl100/skybox.vs \
@@ -1294,6 +1308,10 @@ shaders/shaders_lightmap_rendering: shaders/shaders_lightmap_rendering.c
--preload-file shaders/resources/cubicmap_atlas.png@resources/cubicmap_atlas.png \
--preload-file shaders/resources/spark_flame.png@resources/spark_flame.png
+shaders/shaders_mandelbrot_set: shaders/shaders_mandelbrot_set.c
+ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
+ --preload-file shaders/resources/shaders/glsl100/mandelbrot_set.fs@resources/shaders/glsl100/mandelbrot_set.fs
+
shaders/shaders_mesh_instancing: shaders/shaders_mesh_instancing.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file shaders/resources/shaders/glsl100/lighting_instancing.vs@resources/shaders/glsl100/lighting_instancing.vs \
diff --git a/examples/README.md b/examples/README.md
index e8b6ba4bf..19d110344 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: 183]
+## EXAMPLES COLLECTION [TOTAL: 187]
-### category: core [42]
+### category: core [45]
Examples using raylib[core](../src/rcore.c) platform functionality like window creation, inputs, drawing modes and system functionality.
@@ -49,7 +49,7 @@ Examples using raylib[core](../src/rcore.c) platform functionality like window c
| [core_window_flags](core/core_window_flags.c) |
| ⭐⭐⭐☆ | 3.5 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
| [core_window_letterbox](core/core_window_letterbox.c) |
| ⭐⭐☆☆ | 2.5 | 4.0 | [Anata](https://github.com/anatagawa) |
| [core_window_should_close](core/core_window_should_close.c) |
| ⭐☆☆☆ | 4.2 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
-| [core_monitor_change](core/core_monitor_change.c) |
| ⭐☆☆☆ | 5.5 | 5.6 | [Maicon Santana](https://github.com/maiconpintoabreu) |
+| [core_monitor_detector](core/core_monitor_detector.c) |
| ⭐☆☆☆ | 5.5 | 5.6 | [Maicon Santana](https://github.com/maiconpintoabreu) |
| [core_custom_logging](core/core_custom_logging.c) |
| ⭐⭐⭐☆ | 2.5 | 2.5 | [Pablo Marcos Oltra](https://github.com/pamarcos) |
| [core_drop_files](core/core_drop_files.c) |
| ⭐⭐☆☆ | 1.3 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
| [core_random_values](core/core_random_values.c) |
| ⭐☆☆☆ | 1.1 | 1.1 | [Ramon Santamaria](https://github.com/raysan5) |
@@ -66,7 +66,10 @@ Examples using raylib[core](../src/rcore.c) platform functionality like window c
| [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_highdpi_testbed](core/core_highdpi_testbed.c) |
| ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
+| [core_screen_recording](core/core_screen_recording.c) |
| ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
| [core_clipboard_text](core/core_clipboard_text.c) |
| ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Robin](https://github.com/RobinsAviary) |
+| [core_text_file_loading](core/core_text_file_loading.c) |
| ⭐☆☆☆ | 5.5 | 5.6 | [Aanjishnu Bhattacharyya](https://github.com/NimComPoo-04) |
### category: shapes [31]
@@ -99,12 +102,12 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes](
| [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_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) |
+| [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_effect](shapes/shapes_starfield_effect.c) |
| ⭐⭐☆☆ | 5.5 | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) |
### category: textures [26]
@@ -191,9 +194,9 @@ Examples using raylib models functionality, including models loading/generation
| [models_bone_socket](models/models_bone_socket.c) |
| ⭐⭐⭐⭐️ | 4.5 | 4.5 | [iP](https://github.com/ipzaur) |
| [models_tesseract_view](models/models_tesseract_view.c) |
| ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Timothy van der Valk](https://github.com/arceryz) |
| [models_basic_voxel](models/models_basic_voxel.c) |
| ⭐⭐☆☆ | 5.5 | 5.5 | [Tim Little](https://github.com/timlittle) |
-| [models_geometry_textures_cube](models/models_geometry_textures_cube.c) |
| ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Jopestpe](https://github.com/jopestpe) |
+| [models_rotating_cube](models/models_rotating_cube.c) |
| ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Jopestpe](https://github.com/jopestpe) |
-### category: shaders [30]
+### category: shaders [31]
Examples using raylib shaders functionality, including shaders loading, parameters configuration and drawing using them (model shaders and postprocessing shaders). This functionality is directly provided by raylib [rlgl](../src/rlgl.c) module.
@@ -229,6 +232,7 @@ Examples using raylib shaders functionality, including shaders loading, paramete
| [shaders_lightmap_rendering](shaders/shaders_lightmap_rendering.c) |
| ⭐⭐⭐☆ | 4.5 | 4.5 | [Jussi Viitala](https://github.com/nullstare) |
| [shaders_rounded_rectangle](shaders/shaders_rounded_rectangle.c) |
| ⭐⭐⭐☆ | 5.5 | 5.5 | [Anstro Pleuton](https://github.com/anstropleuton) |
| [shaders_depth_rendering](shaders/shaders_depth_rendering.c) |
| ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [Luís Almeida](https://github.com/luis605) |
+| [shaders_mandelbrot_set](shaders/shaders_mandelbrot_set.c) |
| ⭐⭐⭐☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) |
### category: audio [8]
diff --git a/examples/core/core_3d_camera_first_person.c b/examples/core/core_3d_camera_first_person.c
index 8f4dc70fb..64368c4aa 100644
--- a/examples/core/core_3d_camera_first_person.c
+++ b/examples/core/core_3d_camera_first_person.c
@@ -119,7 +119,6 @@ int main(void)
// Some default standard keyboard/mouse inputs are hardcoded to simplify use
// For advanced camera controls, it's recommended to compute camera movement manually
UpdateCamera(&camera, cameraMode); // Update camera
-
/*
// Camera PRO usage example (EXPERIMENTAL)
// This new camera function allows custom movement/rotation values to be directly provided
diff --git a/examples/core/core_highdpi_testbed.c b/examples/core/core_highdpi_testbed.c
new file mode 100644
index 000000000..5cd2a7dc7
--- /dev/null
+++ b/examples/core/core_highdpi_testbed.c
@@ -0,0 +1,70 @@
+/*******************************************************************************************
+*
+* raylib [core] example - highdpi testbed
+*
+* Example complexity rating: [★☆☆☆] 1/4
+*
+* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
+*
+* Example contributed by Ramon Santamaria (@raysan5) 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 Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [core] example - highdpi testbed");
+
+ // TODO: Load resources / Initialize variables at this point
+
+ SetTargetFPS(60);
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ // TODO: Update variables / Implement example logic at this point
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ // TODO: Draw everything that requires to be drawn at this point
+
+ DrawLineEx((Vector2){ 0, 0 }, (Vector2){ screenWidth, screenHeight }, 2.0f, RED);
+ DrawLineEx((Vector2){ 0, screenHeight }, (Vector2){ screenWidth, 0 }, 2.0f, RED);
+ DrawText("example base code template", 260, 400, 20, LIGHTGRAY);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+
+ // TODO: Unload all loaded resources at this point
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
diff --git a/examples/core/core_highdpi_testbed.png b/examples/core/core_highdpi_testbed.png
new file mode 100644
index 000000000..da99bbb0d
Binary files /dev/null and b/examples/core/core_highdpi_testbed.png differ
diff --git a/examples/core/core_monitor_change.c b/examples/core/core_monitor_detector.c
similarity index 96%
rename from examples/core/core_monitor_change.c
rename to examples/core/core_monitor_detector.c
index 3286ba22d..0e94f6895 100644
--- a/examples/core/core_monitor_change.c
+++ b/examples/core/core_monitor_detector.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] example - monitor change
+* raylib [core] example - monitor detector
*
* Example complexity rating: [★☆☆☆] 1/4
*
@@ -19,8 +19,8 @@
#define MAX_MONITORS 10
-// Monitor Details
-typedef struct Monitor {
+// Monitor info
+typedef struct MonitorInfo {
Vector2 position;
const char *name;
int width;
@@ -28,7 +28,7 @@ typedef struct Monitor {
int physicalWidth;
int physicalHeight;
int refreshRate;
-} Monitor;
+} MonitorInfo;
//------------------------------------------------------------------------------------
// Program main entry point
@@ -40,9 +40,9 @@ int main(void)
const int screenWidth = 800;
const int screenHeight = 450;
- Monitor monitors[MAX_MONITORS] = { 0 };
+ MonitorInfo monitors[MAX_MONITORS] = { 0 };
- InitWindow(screenWidth, screenHeight, "raylib [core] example - monitor change");
+ InitWindow(screenWidth, screenHeight, "raylib [core] example - monitor detector");
int currentMonitorIndex = GetCurrentMonitor();
int monitorCount = 0;
@@ -67,7 +67,7 @@ int main(void)
monitorCount = GetMonitorCount();
for (int i = 0; i < monitorCount; i++)
{
- monitors[i] = (Monitor){
+ monitors[i] = (MonitorInfo){
GetMonitorPosition(i),
GetMonitorName(i),
GetMonitorWidth(i),
diff --git a/examples/core/core_monitor_change.png b/examples/core/core_monitor_detector.png
similarity index 100%
rename from examples/core/core_monitor_change.png
rename to examples/core/core_monitor_detector.png
diff --git a/examples/core/core_render_texture.c b/examples/core/core_render_texture.c
index 47dc66e0f..e30220a73 100644
--- a/examples/core/core_render_texture.c
+++ b/examples/core/core_render_texture.c
@@ -26,7 +26,7 @@ int main(void)
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [core] example - render texture");
-
+
// Define a render texture to render
int renderTextureWidth = 300;
int renderTextureHeight = 300;
@@ -62,14 +62,14 @@ int main(void)
//-----------------------------------------------------
// Draw our scene to the render texture
BeginTextureMode(target);
-
+
ClearBackground(SKYBLUE);
-
+
DrawRectangle(0, 0, 20, 20, RED);
DrawCircleV(ballPosition, (float)ballRadius, MAROON);
-
+
EndTextureMode();
-
+
// Draw render texture to main framebuffer
BeginDrawing();
@@ -77,14 +77,14 @@ int main(void)
// Draw our render texture with rotation applied
// 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,
+ // NOTE 2: We flip vertically the texture setting negative source rectangle height
+ DrawTexturePro(target.texture,
(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);
-
+
DrawFPS(10, 10);
diff --git a/examples/core/core_screen_recording.c b/examples/core/core_screen_recording.c
new file mode 100644
index 000000000..43c90eec5
--- /dev/null
+++ b/examples/core/core_screen_recording.c
@@ -0,0 +1,70 @@
+/*******************************************************************************************
+*
+* raylib [core] example - screen recording
+*
+* Example complexity rating: [★☆☆☆] 1/4
+*
+* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
+*
+* Example contributed by Ramon Santamaria (@raysan5) 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 Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [core] example - screen recording");
+
+ // TODO: Load resources / Initialize variables at this point
+
+ SetTargetFPS(60);
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ // TODO: Update variables / Implement example logic at this point
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ // TODO: Draw everything that requires to be drawn at this point
+
+ DrawLineEx((Vector2){ 0, 0 }, (Vector2){ screenWidth, screenHeight }, 2.0f, RED);
+ DrawLineEx((Vector2){ 0, screenHeight }, (Vector2){ screenWidth, 0 }, 2.0f, RED);
+ DrawText("example base code template", 260, 400, 20, LIGHTGRAY);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+
+ // TODO: Unload all loaded resources at this point
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
diff --git a/examples/core/core_screen_recording.png b/examples/core/core_screen_recording.png
new file mode 100644
index 000000000..da99bbb0d
Binary files /dev/null and b/examples/core/core_screen_recording.png differ
diff --git a/examples/core/core_text_file_loading.c b/examples/core/core_text_file_loading.c
new file mode 100644
index 000000000..033fd4dc6
--- /dev/null
+++ b/examples/core/core_text_file_loading.c
@@ -0,0 +1,164 @@
+/*******************************************************************************************
+*
+* raylib [core] example - text file loading
+*
+* Example complexity rating: [★☆☆☆] 1/4
+*
+* Example originally created with raylib 5.5, last time updated with raylib 5.6
+*
+* Example contributed by Aanjishnu Bhattacharyya (@NimComPoo-04) 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) 0 Aanjishnu Bhattacharyya (@NimComPoo-04)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#include "raymath.h" // Required for: Lerp()
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [core] example - text file loading");
+
+ // Setting up the camera
+ Camera2D cam = {
+ .offset = {0, 0},
+ .target = {0, 0},
+ .rotation = 0,
+ .zoom = 1
+ };
+
+ // Loading text file from resources/text_file.txt
+ const char *fileName = "resources/text_file.txt";
+ char *text = LoadFileText(fileName);
+
+ // Loading all the text lines
+ int lineCount = 0;
+ char **lines = LoadTextLines(text, &lineCount);
+
+ // Stylistic choises
+ int fontSize = 20;
+ int textTop = 25 + fontSize; // Top of the screen from where the text is rendered
+ int wrapWidth = screenWidth - 20;
+
+ // Wrap the lines as needed
+ for (int i = 0; i < lineCount; i++)
+ {
+ int j = 0;
+ int lastSpace = 0; // Keeping track of last valid space to insert '\n'
+ int lastWrapStart = 0; // Keeping track of the start of this wrapped line.
+
+ while (lines[i][j] != '\0')
+ {
+ if (lines[i][j] == ' ')
+ {
+ // Making a C Style string by adding a '\0' at the required location so that we can use the MeasureText function
+ lines[i][j] = '\0';
+
+ // Checking if the text has crossed the wrapWidth, then going back and inserting a newline
+ if (MeasureText(lines[i] + lastWrapStart, fontSize) > wrapWidth)
+ {
+ lines[i][lastSpace] = '\n';
+
+ // Since we added a newline the place of wrap changed so we update our lastWrapStart
+ lastWrapStart = lastSpace + 1;
+ }
+
+ lines[i][j] = ' '; // Resetting the space back
+ lastSpace = j; // Since we encountered a new space we update our last encountered space location
+ }
+
+ j++;
+ }
+ }
+
+ // Calculating the total height so that we can show a scrollbar
+ int textHeight = 0;
+
+ for (int i = 0; i < lineCount; i++)
+ {
+ Vector2 size = MeasureTextEx(GetFontDefault(), lines[i], fontSize, 2);
+ textHeight += size.y + 10;
+ }
+
+ // A simple scrollbar on the side to show how far we have red into the file
+ Rectangle scrollBar = {
+ .x = screenWidth - 5,
+ .y = 0,
+ .width = 5,
+ .height = screenHeight*100/(textHeight - screenHeight) // Scrollbar height is just a percentage
+ };
+
+ SetTargetFPS(60);
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ float scroll = GetMouseWheelMove();
+ cam.target.y -= scroll*fontSize*1.5f; // Choosing an arbitrary speed for scroll
+
+ if (cam.target.y < 0) cam.target.y = 0; // Snapping to 0 if we go too far back
+
+ // Ensuring that the camera does not scroll past all text
+ if (cam.target.y > textHeight - screenHeight + textTop)
+ cam.target.y = textHeight - screenHeight + textTop;
+
+ // Computing the position of the scrollBar depending on the percentage of text covered
+ scrollBar.y = Lerp(textTop, screenHeight - scrollBar.height, (cam.target.y - textTop)/(textHeight - screenHeight));
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ BeginMode2D(cam);
+ // Going through all the read lines
+ for (int i = 0, t = textTop; i < lineCount; i++)
+ {
+ // Each time we go through and calculate the height of the text to move the cursor appropriately
+ Vector2 size = MeasureTextEx(GetFontDefault(), lines[i], fontSize, 2);
+
+ DrawText(lines[i], 10, t, fontSize, RED);
+
+ // Inserting extra space for real newlines,
+ // wrapped lines are rendered closer together
+ t += size.y + 10;
+ }
+ EndMode2D();
+
+ // Header displaying which file is being read currently
+ DrawRectangle(0, 0, screenWidth, textTop - 10, BEIGE);
+ DrawText(TextFormat("File: %s", fileName), 10, 10, fontSize, MAROON);
+
+ DrawRectangleRec(scrollBar, MAROON);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ UnloadTextLines(lines, lineCount);
+ UnloadFileText(text);
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
diff --git a/examples/core/core_text_file_loading.png b/examples/core/core_text_file_loading.png
new file mode 100644
index 000000000..ac4101210
Binary files /dev/null and b/examples/core/core_text_file_loading.png differ
diff --git a/examples/core/resources/text_file.txt b/examples/core/resources/text_file.txt
new file mode 100644
index 000000000..72b1a8bce
--- /dev/null
+++ b/examples/core/resources/text_file.txt
@@ -0,0 +1,18 @@
+Starting of the Lorem ipsum dolor sit amet file
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque at interdum ex, et iaculis quam. Mauris consectetur, magna vel malesuada aliquam, mauris enim venenatis arcu, nec cursus orci ante a massa. Curabitur libero elit, cursus eu odio eget, suscipit rhoncus nibh. Nam justo elit, ullamcorper eget dolor et, ullamcorper tristique nulla. Nullam sagittis dolor in tristique tincidunt. Duis ac porttitor erat, a molestie sapien. Aliquam finibus in ipsum quis venenatis.
+Mauris odio lorem, pharetra ut egestas quis, tristique eu mauris. Cras sed gravida velit. Suspendisse potenti. Suspendisse lobortis eleifend fermentum. Donec eu dolor est. Etiam ac felis eu ligula auctor feugiat eu quis diam. Sed eleifend id nibh porta viverra. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi at tristique dui, nec pretium est. Mauris mollis massa quis massa aliquet efficitur. Phasellus posuere, elit id tempus consequat, massa ante scelerisque odio, finibus gravida elit tellus eget lectus.
+Donec rutrum sagittis ligula a auctor. Aliquam aliquet tincidunt pulvinar. Aenean a porta ex. Aenean at sagittis nulla. Morbi congue luctus est nec gravida. In hac habitasse platea dictumst. Praesent commodo efficitur congue. Duis interdum enim in pharetra dapibus. Proin vestibulum finibus mauris vitae mollis.
+Sed ultricies sed enim vel interdum. Nullam nec sagittis est, quis lobortis nunc. Donec auctor elementum velit vel pulvinar. Sed quis efficitur felis, at mollis elit. Integer id elit ante. Ut gravida ante vitae erat scelerisque scelerisque vel in massa. Praesent varius massa eu purus feugiat, non venenatis urna rhoncus. Pellentesque vehicula, tellus eu venenatis efficitur, libero eros lobortis justo, at ultricies lacus diam non libero. Sed metus nulla, consectetur in justo vitae, mollis maximus orci. Vestibulum dapibus ultrices leo, et facilisis odio molestie a. Phasellus facilisis vitae lorem quis viverra. Etiam imperdiet urna dolor, quis interdum ligula tristique id. Aliquam id dapibus enim.
+Curabitur congue elit in magna tristique, sit amet porta quam viverra. Integer nec placerat libero. Praesent sem dolor, tristique eu augue non, ultricies mollis nibh. Fusce finibus, lorem sollicitudin eleifend gravida, eros quam tempus leo, ut iaculis libero ex vitae libero. Sed placerat fringilla accumsan. Nulla laoreet cursus justo nec elementum. Proin facilisis lobortis velit, a sollicitudin leo mollis eu. Aenean et leo est.
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque at interdum ex, et iaculis quam. Mauris consectetur, magna vel malesuada aliquam, mauris enim venenatis arcu, nec cursus orci ante a massa. Curabitur libero elit, cursus eu odio eget, suscipit rhoncus nibh. Nam justo elit, ullamcorper eget dolor et, ullamcorper tristique nulla. Nullam sagittis dolor in tristique tincidunt. Duis ac porttitor erat, a molestie sapien. Aliquam finibus in ipsum quis venenatis.
+Mauris odio lorem, pharetra ut egestas quis, tristique eu mauris. Cras sed gravida velit. Suspendisse potenti. Suspendisse lobortis eleifend fermentum. Donec eu dolor est. Etiam ac felis eu ligula auctor feugiat eu quis diam. Sed eleifend id nibh porta viverra. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi at tristique dui, nec pretium est. Mauris mollis massa quis massa aliquet efficitur. Phasellus posuere, elit id tempus consequat, massa ante scelerisque odio, finibus gravida elit tellus eget lectus.
+Donec rutrum sagittis ligula a auctor. Aliquam aliquet tincidunt pulvinar. Aenean a porta ex. Aenean at sagittis nulla. Morbi congue luctus est nec gravida. In hac habitasse platea dictumst. Praesent commodo efficitur congue. Duis interdum enim in pharetra dapibus. Proin vestibulum finibus mauris vitae mollis.
+Sed ultricies sed enim vel interdum. Nullam nec sagittis est, quis lobortis nunc. Donec auctor elementum velit vel pulvinar. Sed quis efficitur felis, at mollis elit. Integer id elit ante. Ut gravida ante vitae erat scelerisque scelerisque vel in massa. Praesent varius massa eu purus feugiat, non venenatis urna rhoncus. Pellentesque vehicula, tellus eu venenatis efficitur, libero eros lobortis justo, at ultricies lacus diam non libero. Sed metus nulla, consectetur in justo vitae, mollis maximus orci. Vestibulum dapibus ultrices leo, et facilisis odio molestie a. Phasellus facilisis vitae lorem quis viverra. Etiam imperdiet urna dolor, quis interdum ligula tristique id. Aliquam id dapibus enim.
+wrapping text from the last available space wrapping text from the last available space wrapping text from the last available space
+Curabitur congue elit in magna tristique, sit amet porta quam viverra. Integer nec placerat libero. Praesent sem dolor, tristique eu augue non, ultricies mollis nibh. Fusce finibus, lorem sollicitudin eleifend gravida, eros quam tempus leo, ut iaculis libero ex vitae libero. Sed placerat fringilla accumsan. Nulla laoreet cursus justo nec elementum. Proin facilisis lobortis velit, a sollicitudin leo mollis eu. Aenean et leo est.
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque at interdum ex, et iaculis quam. Mauris consectetur, magna vel malesuada aliquam, mauris enim venenatis arcu, nec cursus orci ante a massa. Curabitur libero elit, cursus eu odio eget, suscipit rhoncus nibh. Nam justo elit, ullamcorper eget dolor et, ullamcorper tristique nulla. Nullam sagittis dolor in tristique tincidunt. Duis ac porttitor erat, a molestie sapien. Aliquam finibus in ipsum quis venenatis.
+Mauris odio lorem, pharetra ut egestas quis, tristique eu mauris. Cras sed gravida velit. Suspendisse potenti. Suspendisse lobortis eleifend fermentum. Donec eu dolor est. Etiam ac felis eu ligula auctor feugiat eu quis diam. Sed eleifend id nibh porta viverra. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi at tristique dui, nec pretium est. Mauris mollis massa quis massa aliquet efficitur. Phasellus posuere, elit id tempus consequat, massa ante scelerisque odio, finibus gravida elit tellus eget lectus.
+Donec rutrum sagittis ligula a auctor. Aliquam aliquet tincidunt pulvinar. Aenean a porta ex. Aenean at sagittis nulla. Morbi congue luctus est nec gravida. In hac habitasse platea dictumst. Praesent commodo efficitur congue. Duis interdum enim in pharetra dapibus. Proin vestibulum finibus mauris vitae mollis.
+Sed ultricies sed enim vel interdum. Nullam nec sagittis est, quis lobortis nunc. Donec auctor elementum velit vel pulvinar. Sed quis efficitur felis, at mollis elit. Integer id elit ante. Ut gravida ante vitae erat scelerisque scelerisque vel in massa. Praesent varius massa eu purus feugiat, non venenatis urna rhoncus. Pellentesque vehicula, tellus eu venenatis efficitur, libero eros lobortis justo, at ultricies lacus diam non libero. Sed metus nulla, consectetur in justo vitae, mollis maximus orci. Vestibulum dapibus ultrices leo, et facilisis odio molestie a. Phasellus facilisis vitae lorem quis viverra. Etiam imperdiet urna dolor, quis interdum ligula tristique id. Aliquam id dapibus enim.
+Curabitur congue elit in magna tristique, sit amet porta quam viverra. Integer nec placerat libero. Praesent sem dolor, tristique eu augue non, ultricies mollis nibh. Fusce finibus, lorem sollicitudin eleifend gravida, eros quam tempus leo, ut iaculis libero ex vitae libero. Sed placerat fringilla accumsan. Nulla laoreet cursus justo nec elementum. Proin facilisis lobortis velit, a sollicitudin leo mollis eu. Aenean et leo est.
+Ending of the Lorem ipsum dolor sit amet file
diff --git a/examples/examples_list.txt b/examples/examples_list.txt
index b86a4bc02..2a1b9c0b7 100644
--- a/examples/examples_list.txt
+++ b/examples/examples_list.txt
@@ -31,7 +31,7 @@ core;core_world_screen;★★☆☆;1.3;1.4;2015;2025;"Ramon Santamaria";@raysan
core;core_window_flags;★★★☆;3.5;3.5;2020;2025;"Ramon Santamaria";@raysan5
core;core_window_letterbox;★★☆☆;2.5;4.0;2019;2025;"Anata";@anatagawa
core;core_window_should_close;★☆☆☆;4.2;4.2;2013;2025;"Ramon Santamaria";@raysan5
-core;core_monitor_change;★☆☆☆;5.5;5.6;2025;2025;"Maicon Santana";@maiconpintoabreu
+core;core_monitor_detector;★☆☆☆;5.5;5.6;2025;2025;"Maicon Santana";@maiconpintoabreu
core;core_custom_logging;★★★☆;2.5;2.5;2018;2025;"Pablo Marcos Oltra";@pamarcos
core;core_drop_files;★★☆☆;1.3;4.2;2015;2025;"Ramon Santamaria";@raysan5
core;core_random_values;★☆☆☆;1.1;1.1;2014;2025;"Ramon Santamaria";@raysan5
@@ -48,6 +48,9 @@ core;core_render_texture;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamari
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
+core;core_highdpi_testbed;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5
+core;core_screen_recording;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5
+core;core_clipboard_text;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Robin";@RobinsAviary
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
@@ -73,7 +76,12 @@ shapes;shapes_double_pendulum;★★☆☆;5.5;5.5;2025;2025;"JoeCheong";@Joeche
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
+shapes;shapes_pie_chart;★★★☆;5.5;5.6;2025;2025;"Gideon Serfontein";@GideonSerf
+shapes;shapes_kaleidoscope;★★☆☆;5.5;5.6;2025;2025;"Hugo ARNAL";@hugoarnal
+shapes;shapes_clock_of_clocks;★★☆☆;5.5;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates
+shapes;shapes_mouse_trail;★☆☆☆;5.6;5.6-dev;2025;2025;"Balamurugan R";@Bala050814
+shapes;shapes_simple_particles;★★☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
+shapes;shapes_starfield_effect;★★☆☆;5.5;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates
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
@@ -139,7 +147,7 @@ models;models_animation_gpu_skinning;★★★☆;4.5;4.5;2024;2025;"Daniel Hold
models;models_bone_socket;★★★★;4.5;4.5;2024;2025;"iP";@ipzaur
models;models_tesseract_view;★★☆☆;5.6-dev;5.6-dev;2024;2025;"Timothy van der Valk";@arceryz
models;models_basic_voxel;★★☆☆;5.5;5.5;2025;2025;"Tim Little";@timlittle
-models;models_geometry_textures_cube;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Jopestpe";@jopestpe
+models;models_rotating_cube;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Jopestpe";@jopestpe
shaders;shaders_ascii_rendering;★★☆☆;5.5;5.6;2025;2025;"Maicon Santana";@maiconpintoabreu
shaders;shaders_basic_lighting;★★★★;3.0;4.2;2019;2025;"Chris Camacho";@chriscamacho
shaders;shaders_model_shader;★★☆☆;1.3;3.7;2014;2025;"Ramon Santamaria";@raysan5
@@ -184,9 +192,5 @@ 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
+core;core_text_file_loading;★☆☆☆;5.5;5.6;0;0;"Aanjishnu Bhattacharyya";@NimComPoo-04
+shaders;shaders_mandelbrot_set;★★★☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
diff --git a/examples/models/models_geometry_textures_cube.c b/examples/models/models_rotating_cube.c
similarity index 84%
rename from examples/models/models_geometry_textures_cube.c
rename to examples/models/models_rotating_cube.c
index 9441c7fd4..930dae516 100644
--- a/examples/models/models_geometry_textures_cube.c
+++ b/examples/models/models_rotating_cube.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [models] example - geometry textures cube
+* raylib [models] example - rotating cube
*
* Example complexity rating: [★☆☆☆] 1/4
*
@@ -27,11 +27,11 @@ int main(void)
const int screenWidth = 800;
const int screenHeight = 450;
- InitWindow(screenWidth, screenHeight, "raylib [models] example - geometry textures cube");
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - rotating cube");
// Define the camera to look into our 3d world
Camera camera = { 0 };
- camera.position = (Vector3){ 0.0f, 0.0f, 4.0f };
+ camera.position = (Vector3){ 0.0f, 3.0f, 3.0f };
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
camera.fovy = 45.0f;
@@ -58,6 +58,7 @@ int main(void)
// Update
//----------------------------------------------------------------------------------
rotation += 1.0f;
+ //----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
@@ -67,7 +68,11 @@ int main(void)
BeginMode3D(camera);
- DrawModelEx(model, (Vector3){0,0,0}, (Vector3){0.5f,1,0}, rotation, (Vector3){1,1,1}, WHITE);
+ // Draw model defining: position, size, rotation-axis, rotation (degrees), size, and tint-color
+ DrawModelEx(model, (Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.5f, 1.0f, 0.0f },
+ rotation, (Vector3){ 1.0f, 1.0f, 1.0f }, WHITE);
+
+ DrawGrid(10, 1.0f);
EndMode3D();
@@ -81,6 +86,7 @@ int main(void)
//--------------------------------------------------------------------------------------
UnloadTexture(texture); // Unload texture
UnloadModel(model); // Unload model
+
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
diff --git a/examples/models/models_geometry_textures_cube.png b/examples/models/models_rotating_cube.png
similarity index 100%
rename from examples/models/models_geometry_textures_cube.png
rename to examples/models/models_rotating_cube.png
diff --git a/examples/others/web_basic_window.png b/examples/others/web_basic_window.png
new file mode 100644
index 000000000..346184417
Binary files /dev/null and b/examples/others/web_basic_window.png differ
diff --git a/examples/shaders/resources/shaders/glsl100/mandelbrot_set.fs b/examples/shaders/resources/shaders/glsl100/mandelbrot_set.fs
new file mode 100644
index 000000000..fb6dee8b3
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl100/mandelbrot_set.fs
@@ -0,0 +1,62 @@
+#version 100
+
+#define PI 3.1415926535897932384626433832795
+
+precision highp float;
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+uniform vec2 offset; // Offset of the scale
+uniform float zoom; // Zoom of the scale
+// NOTE: Maximum number of shader for-loop iterations depend on GPU,
+// For example, on RasperryPi for this examply only supports up to 60
+uniform int maxIterations; // Max iterations per pixel
+
+const float max = 4.0; // We consider infinite as 4.0: if a point reaches a distance of 4.0 it will escape to infinity
+const float max2 = max*max; // Square of max to avoid computing square root
+
+// WebGL shaders for loop iteration limit only const
+const int maxIterationsLimit = 20000;
+
+void main()
+{
+ // The pixel coordinates are scaled so they are on the mandelbrot scale
+ // NOTE: fragTexCoord already comes as normalized screen coordinates but offset must be normalized before scaling and zoom
+ vec2 c = vec2((fragTexCoord.x - 0.5)*2.5, (fragTexCoord.y - 0.5)*1.5)/zoom;
+ c.x += offset.x;
+ c.y += offset.y;
+ float a = 0.0;
+ float b = 0.0;
+
+ // The Mandelbrot set is a two-dimensional set defined in the complex plane on which the iteration of the function
+ // Fc(z) = z^2 + c on the complex numbers c from the plane does not diverge to infinity starting at z = 0
+ // Here: z = a + bi. Iterations: z -> z^2 + c = (a + bi)^2 + (c.x + c.yi) = (a^2 - b^2 + c.x) + (2ab + c.y)i
+
+ for (int iter = 0; iter < maxIterationsLimit; ++iter)
+ {
+ float aa = a*a;
+ float bb = b*b;
+ if (iter >= maxIterations)
+ {
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
+ return;
+ }
+ if (aa + bb > max2)
+ {
+ float normR = float(iter - (iter/55)*55)/55.0;
+ float normG = float(iter - (iter/69)*69)/69.0;
+ float normB = float(iter - (iter/40)*40)/40.0;
+
+ gl_FragColor = vec4(sin(normR*PI), sin(normG*PI), sin(normB*PI), 1.0);
+ return;
+ }
+
+ float twoab = 2.0*a*b;
+ a = aa - bb + c.x;
+ b = twoab + c.y;
+ }
+
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
+}
diff --git a/examples/shaders/resources/shaders/glsl120/mandelbrot_set.fs b/examples/shaders/resources/shaders/glsl120/mandelbrot_set.fs
new file mode 100644
index 000000000..5da3ef437
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/mandelbrot_set.fs
@@ -0,0 +1,59 @@
+#version 120
+
+#define PI 3.1415926535897932384626433832795
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+uniform vec2 offset; // Offset of the scale
+uniform float zoom; // Zoom of the scale
+// NOTE: Maximum number of shader for-loop iterations depend on GPU,
+// For example, on RasperryPi for this examply only supports up to 60
+uniform int maxIterations; // Max iterations per pixel
+
+const float max = 4.0; // We consider infinite as 4.0: if a point reaches a distance of 4.0 it will escape to infinity
+const float max2 = max*max; // Square of max to avoid computing square root
+
+void main()
+{
+ // The pixel coordinates are scaled so they are on the mandelbrot scale
+ // NOTE: fragTexCoord already comes as normalized screen coordinates but offset must be normalized before scaling and zoom
+ vec2 c = vec2((fragTexCoord.x - 0.5)*2.5, (fragTexCoord.y - 0.5)*1.5)/zoom;
+ c.x += offset.x;
+ c.y += offset.y;
+ float a = 0.0;
+ float b = 0.0;
+
+ // The Mandelbrot set is a two-dimensional set defined in the complex plane on which the iteration of the function
+ // Fc(z) = z^2 + c on the complex numbers c from the plane does not diverge to infinity starting at z = 0
+ // Here: z = a + bi. Iterations: z -> z^2 + c = (a + bi)^2 + (c.x + c.yi) = (a^2 - b^2 + c.x) + (2ab + c.y)i
+
+ int iter = 0;
+ while (iter < maxIterations)
+ {
+ float aa = a*a;
+ float bb = b*b;
+ if (aa + bb > max2)
+ break;
+
+ float twoab = 2.0*a*b;
+ a = aa - bb + c.x;
+ b = twoab + c.y;
+
+ ++iter;
+ }
+
+ if (iter >= maxIterations)
+ {
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
+ }
+ else
+ {
+ float normR = float(iter - (iter/55)*55)/55.0;
+ float normG = float(iter - (iter/69)*69)/69.0;
+ float normB = float(iter - (iter/40)*40)/40.0;
+
+ gl_FragColor = vec4(sin(normR*PI), sin(normG*PI), sin(normB*PI), 1.0);
+ }
+}
diff --git a/examples/shaders/resources/shaders/glsl330/mandelbrot_set.fs b/examples/shaders/resources/shaders/glsl330/mandelbrot_set.fs
new file mode 100644
index 000000000..bde74565f
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl330/mandelbrot_set.fs
@@ -0,0 +1,58 @@
+#version 330
+
+#define PI 3.1415926535897932384626433832795
+
+// Input vertex attributes (from vertex shader)
+in vec2 fragTexCoord;
+in vec4 fragColor;
+
+// Output fragment color
+out vec4 finalColor;
+
+uniform vec2 offset; // Offset of the scale
+uniform float zoom; // Zoom of the scale
+uniform int maxIterations; // Max iterations per pixel
+
+const float max = 4.0; // We consider infinite as 4.0: if a point reaches a distance of 4.0 it will escape to infinity
+const float max2 = max*max; // Square of max to avoid computing square root
+
+void main()
+{
+ // The pixel coordinates are scaled so they are on the mandelbrot scale
+ // NOTE: fragTexCoord already comes as normalized screen coordinates but offset must be normalized before scaling and zoom
+ vec2 c = vec2((fragTexCoord.x - 0.5)*2.5, (fragTexCoord.y - 0.5)*1.5)/zoom;
+ c.x += offset.x;
+ c.y += offset.y;
+ float a = 0.0;
+ float b = 0.0;
+
+ // The Mandelbrot set is a two-dimensional set defined in the complex plane on which the iteration of the function
+ // Fc(z) = z^2 + c on the complex numbers c from the plane does not diverge to infinity starting at z = 0
+ // Here: z = a + bi. Iterations: z -> z^2 + c = (a + bi)^2 + (c.x + c.yi) = (a^2 - b^2 + c.x) + (2ab + c.y)i
+
+ int iter = 0;
+ for (iter = 0; iter < maxIterations; ++iter)
+ {
+ float aa = a*a;
+ float bb = b*b;
+ if (aa + bb > max2)
+ break;
+
+ float twoab = 2.0*a*b;
+ a = aa - bb + c.x;
+ b = twoab + c.y;
+ }
+
+ if (iter >= maxIterations)
+ {
+ finalColor = vec4(0.0, 0.0, 0.0, 1.0);
+ }
+ else
+ {
+ float normR = float(iter%55)/55.0;
+ float normG = float(iter%69)/69.0;
+ float normB = float(iter%40)/40.0;
+
+ finalColor = vec4(sin(normR*PI), sin(normG*PI), sin(normB*PI), 1.0);
+ }
+}
diff --git a/examples/shaders/shaders_mandelbrot_set.c b/examples/shaders/shaders_mandelbrot_set.c
new file mode 100644
index 000000000..a373c518a
--- /dev/null
+++ b/examples/shaders/shaders_mandelbrot_set.c
@@ -0,0 +1,229 @@
+/*******************************************************************************************
+*
+* raylib [shaders] example - mandelbrot set
+*
+* Example complexity rating: [★★★☆] 3/4
+*
+* NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support,
+* OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version
+*
+* NOTE: Shaders used in this example are #version 330 (OpenGL 3.3)
+*
+* Example originally created with raylib 5.6, last time updated with raylib 5.6
+*
+* Example contributed by Jordi Santonja (@JordSant)
+* Based on previous work by Josh Colclough (@joshcol9232)
+*
+* 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
+
+#if defined(PLATFORM_DESKTOP)
+ #define GLSL_VERSION 330
+#else // PLATFORM_ANDROID, PLATFORM_WEB
+ #define GLSL_VERSION 100
+#endif
+
+// A few good interesting places
+const float pointsOfInterest[6][3] =
+{
+ { -1.76826775f, -0.00422996283f, 28435.9238f },
+ { 0.322004497f, -0.0357099883f, 56499.7266f },
+ { -0.748880744f, -0.0562955774f, 9237.59082f },
+ { -1.78385007f, -0.0156200649f, 14599.5283f },
+ { -0.0985441282f, -0.924688697f, 26259.8535f },
+ { 0.317785531f, -0.0322612226f, 29297.9258f },
+};
+
+const int screenWidth = 800;
+const int screenHeight = 450;
+const float zoomSpeed = 1.01f;
+const float offsetSpeedMul = 2.0f;
+
+const float startingZoom = 0.6f;
+const float startingOffset[2] = { -0.5f, 0.0f };
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ InitWindow(screenWidth, screenHeight, "raylib [shaders] example - mandelbrot set");
+
+ // Load mandelbrot set shader
+ // NOTE: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader
+ Shader shader = LoadShader(0, TextFormat("resources/shaders/glsl%i/mandelbrot_set.fs", GLSL_VERSION));
+
+ // Create a RenderTexture2D to be used for render to texture
+ RenderTexture2D target = LoadRenderTexture(GetScreenWidth(), GetScreenHeight());
+
+ // Offset and zoom to draw the mandelbrot set at. (centered on screen and default size)
+ float offset[2] = { startingOffset[0], startingOffset[1] };
+ float zoom = startingZoom;
+ // Depending on the zoom the mximum number of iterations must be adapted to get more detail as we zzoom in
+ // The solution is not perfect, so a control has been added to increase/decrease the number of iterations with UP/DOWN keys
+#if defined(PLATFORM_DESKTOP)
+ int maxIterations = 333;
+ float maxIterationsMultiplier = 166.5f;
+#else
+ int maxIterations = 43;
+ float maxIterationsMultiplier = 22.0f;
+#endif
+
+ // Get variable (uniform) locations on the shader to connect with the program
+ // NOTE: If uniform variable could not be found in the shader, function returns -1
+ int zoomLoc = GetShaderLocation(shader, "zoom");
+ int offsetLoc = GetShaderLocation(shader, "offset");
+ int maxIterationsLoc = GetShaderLocation(shader, "maxIterations");
+
+ // Upload the shader uniform values!
+ SetShaderValue(shader, zoomLoc, &zoom, SHADER_UNIFORM_FLOAT);
+ SetShaderValue(shader, offsetLoc, offset, SHADER_UNIFORM_VEC2);
+ SetShaderValue(shader, maxIterationsLoc, &maxIterations, SHADER_UNIFORM_INT);
+
+ bool showControls = true; // Show controls
+
+ 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
+ //----------------------------------------------------------------------------------
+ bool updateShader = false;
+
+ // Press [1 - 6] to reset c to a point of interest
+ if (IsKeyPressed(KEY_ONE) ||
+ IsKeyPressed(KEY_TWO) ||
+ IsKeyPressed(KEY_THREE) ||
+ IsKeyPressed(KEY_FOUR) ||
+ IsKeyPressed(KEY_FIVE) ||
+ IsKeyPressed(KEY_SIX))
+ {
+ int interestIndex = 0;
+ if (IsKeyPressed(KEY_ONE)) interestIndex = 0;
+ else if (IsKeyPressed(KEY_TWO)) interestIndex = 1;
+ else if (IsKeyPressed(KEY_THREE)) interestIndex = 2;
+ else if (IsKeyPressed(KEY_FOUR)) interestIndex = 3;
+ else if (IsKeyPressed(KEY_FIVE)) interestIndex = 4;
+ else if (IsKeyPressed(KEY_SIX)) interestIndex = 5;
+
+ offset[0] = pointsOfInterest[interestIndex][0];
+ offset[1] = pointsOfInterest[interestIndex][1];
+ zoom = pointsOfInterest[interestIndex][2];
+ updateShader = true;
+ }
+
+ // If "R" is pressed, reset zoom and offset
+ if (IsKeyPressed(KEY_R))
+ {
+ offset[0] = startingOffset[0];
+ offset[1] = startingOffset[1];
+ zoom = startingZoom;
+ updateShader = true;
+ }
+
+ if (IsKeyPressed(KEY_F1)) showControls = !showControls; // Toggle whether or not to show controls
+
+ // Change number of max iterations with UP and DOWN keys
+ // WARNING: Increasing the number of max iterations greatly impacts performance
+ if (IsKeyPressed(KEY_UP))
+ {
+ maxIterationsMultiplier *= 1.4f;
+ updateShader = true;
+ }
+ else if (IsKeyPressed(KEY_DOWN))
+ {
+ maxIterationsMultiplier /= 1.4f;
+ updateShader = true;
+ }
+
+ // If either left or right button is pressed, zoom in/out
+ if (IsMouseButtonDown(MOUSE_BUTTON_LEFT) || IsMouseButtonDown(MOUSE_BUTTON_RIGHT))
+ {
+ // Change zoom. If Mouse left -> zoom in. Mouse right -> zoom out
+ zoom *= IsMouseButtonDown(MOUSE_BUTTON_LEFT)? zoomSpeed : (1.0f/zoomSpeed);
+
+ const Vector2 mousePos = GetMousePosition();
+ Vector2 offsetVelocity;
+ // Find the velocity at which to change the camera. Take the distance of the mouse
+ // From the center of the screen as the direction, and adjust magnitude based on the current zoom
+ offsetVelocity.x = (mousePos.x/(float)screenWidth - 0.5f)*offsetSpeedMul/zoom;
+ offsetVelocity.y = (mousePos.y/(float)screenHeight - 0.5f)*offsetSpeedMul/zoom;
+
+ // Apply move velocity to camera
+ offset[0] += GetFrameTime()*offsetVelocity.x;
+ offset[1] += GetFrameTime()*offsetVelocity.y;
+
+ updateShader = true;
+ }
+
+ // In case a parameter has been changed, update the shader values
+ if (updateShader)
+ {
+ // As we zoom in, increase the number of max iterations to get more detail
+ // Aproximate formula, but it works-ish
+ maxIterations = (int)(sqrtf(2.0f*sqrtf(fabsf(1.0f - sqrtf(37.5f*zoom))))*maxIterationsMultiplier);
+
+ // Update the shader uniform values!
+ SetShaderValue(shader, zoomLoc, &zoom, SHADER_UNIFORM_FLOAT);
+ SetShaderValue(shader, offsetLoc, offset, SHADER_UNIFORM_VEC2);
+ SetShaderValue(shader, maxIterationsLoc, &maxIterations, SHADER_UNIFORM_INT);
+ }
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ // Using a render texture to draw Mandelbrot set
+ BeginTextureMode(target); // Enable drawing to texture
+ ClearBackground(BLACK); // Clear the render texture
+
+ // Draw a rectangle in shader mode to be used as shader canvas
+ // NOTE: Rectangle uses font white character texture coordinates,
+ // So shader can not be applied here directly because input vertexTexCoord
+ // Do not represent full screen coordinates (space where want to apply shader)
+ DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), BLACK);
+ EndTextureMode();
+
+ BeginDrawing();
+ ClearBackground(BLACK); // Clear screen background
+
+ // Draw the saved texture and rendered mandelbrot set with shader
+ // NOTE: We do not invert texture on Y, already considered inside shader
+ BeginShaderMode(shader);
+ // WARNING: If FLAG_WINDOW_HIGHDPI is enabled, HighDPI monitor scaling should be considered
+ // When rendering the RenderTexture2D to fit in the HighDPI scaled Window
+ DrawTextureEx(target.texture, (Vector2){ 0.0f, 0.0f }, 0.0f, 1.0f, WHITE);
+ EndShaderMode();
+
+ if (showControls)
+ {
+ DrawText("Press Mouse buttons right/left to zoom in/out and move", 10, 15, 10, RAYWHITE);
+ DrawText("Press F1 to toggle these controls", 10, 30, 10, RAYWHITE);
+ DrawText("Press [1 - 6] to change point of interest", 10, 45, 10, RAYWHITE);
+ DrawText("Press UP | DOWN to change number of iterations", 10, 60, 10, RAYWHITE);
+ DrawText("Press R to recenter the camera", 10, 75, 10, RAYWHITE);
+ }
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ UnloadShader(shader); // Unload shader
+ UnloadRenderTexture(target); // Unload render texture
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
diff --git a/examples/shaders/shaders_mandelbrot_set.png b/examples/shaders/shaders_mandelbrot_set.png
new file mode 100644
index 000000000..6d112931d
Binary files /dev/null and b/examples/shaders/shaders_mandelbrot_set.png differ
diff --git a/examples/shapes/shapes_lines_drawing.c b/examples/shapes/shapes_lines_drawing.c
new file mode 100644
index 000000000..9347acaf3
--- /dev/null
+++ b/examples/shapes/shapes_lines_drawing.c
@@ -0,0 +1,146 @@
+/*******************************************************************************************
+*
+* raylib [shapes] example - lines drawing
+*
+* Example complexity rating: [★☆☆☆] 1/4
+*
+* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6
+*
+* 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-2025 Robin (@RobinsAviary)
+*
+********************************************************************************************/
+
+#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 - lines drawing");
+
+ // Hint text that shows before you click the screen
+ bool startText = true;
+
+ // The mouse's position on the previous frame
+ Vector2 mousePositionPrevious = GetMousePosition();
+
+ // The canvas to draw lines on
+ RenderTexture canvas = LoadRenderTexture(screenWidth, screenHeight);
+
+ // The background color of the canvas
+ const Color backgroundColor = RAYWHITE;
+
+ // The line's thickness
+ float lineThickness = 8.0f;
+ // The lines hue (in HSV, from 0-360)
+ float lineHue = 0.0f;
+
+ // Clear the canvas to the background color
+ BeginTextureMode(canvas);
+ ClearBackground(backgroundColor);
+ EndTextureMode();
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ // Disable the hint text once the user clicks
+ if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && startText)
+ {
+ startText = false;
+ }
+
+ // Clear the canvas when the user middle-clicks
+ if (IsMouseButtonPressed(MOUSE_BUTTON_MIDDLE))
+ {
+ BeginTextureMode(canvas);
+ ClearBackground(backgroundColor);
+ EndTextureMode();
+ }
+
+ // Store whether the left and right buttons are down
+ bool leftButtonDown = IsMouseButtonDown(MOUSE_BUTTON_LEFT);
+ bool rightButtonDown = IsMouseButtonDown(MOUSE_BUTTON_RIGHT);
+
+ if (leftButtonDown || rightButtonDown)
+ {
+ // The color for the line
+ Color drawColor;
+
+ if (leftButtonDown)
+ {
+ // Increase the hue value by the distance our cursor has moved since the last frame (divided by 3)
+ lineHue += Vector2Distance(mousePositionPrevious, GetMousePosition())/3.0f;
+
+ // While the hue is >=360, subtract it to bring it down into the range 0-360
+ // This is more visually accurate than resetting to zero
+ while (lineHue >= 360.0f)
+ {
+ lineHue -= 360.0f;
+ }
+
+ // Create the final color
+ drawColor = ColorFromHSV(lineHue, 1.0f, 1.0f);
+ }
+ else if (rightButtonDown)
+ {
+ // Use the background color as an "eraser"
+ drawColor = backgroundColor;
+ }
+
+ // Draw the line onto the canvas
+ BeginTextureMode(canvas);
+ // Circles act as "caps", smoothing corners
+ DrawCircleV(mousePositionPrevious, lineThickness/2.0f, drawColor);
+ DrawCircleV(GetMousePosition(), lineThickness/2.0f, drawColor);
+ DrawLineEx(mousePositionPrevious, GetMousePosition(), lineThickness, drawColor);
+ EndTextureMode();
+ }
+
+ // Update line thickness based on mousewheel
+ lineThickness += GetMouseWheelMove();
+ lineThickness = Clamp(lineThickness, 1.0, 500.0f);
+
+ // Update mouse's previous position
+ mousePositionPrevious = GetMousePosition();
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+ // Draw the render texture to the screen, flipped vertically to make it appear top-side up
+ DrawTextureRec(canvas.texture, (Rectangle){ 0.0f, 0.0f, (float)canvas.texture.width,(float)-canvas.texture.height }, Vector2Zero(), WHITE);
+
+ // Draw the preview circle
+ if (!leftButtonDown) DrawCircleLinesV(GetMousePosition(), lineThickness/2.0f, (Color){ 127, 127, 127, 127 });
+
+ // Draw the hint text
+ if (startText) DrawText("try clicking and dragging!", 275, 215, 20, LIGHTGRAY);
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ // Unload the canvas render texture
+ UnloadRenderTexture(canvas);
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
\ No newline at end of file
diff --git a/examples/shapes/shapes_lines_drawing.png b/examples/shapes/shapes_lines_drawing.png
new file mode 100644
index 000000000..59ef65934
Binary files /dev/null and b/examples/shapes/shapes_lines_drawing.png differ
diff --git a/examples/shapes/shapes_mouse_trail.c b/examples/shapes/shapes_mouse_trail.c
index ad1166548..e0e5a3c1d 100644
--- a/examples/shapes/shapes_mouse_trail.c
+++ b/examples/shapes/shapes_mouse_trail.c
@@ -6,16 +6,17 @@
*
* Example originally created with raylib 5.6
*
-* Example contributed by [Balamurugan R] (@[Bala050814]]) and reviewed by [Ray] (@raysan5)
+* Example contributed by Balamurugan R (@Bala050814]) and reviewed by Ramon Santamaria (@raysan5)
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
-* Copyright (c) 2024 [Balamurugan R] (@[Bala050814])
+* Copyright (c) 2025 Balamurugan R (@Bala050814)
*
********************************************************************************************/
#include "raylib.h"
+
#include "raymath.h"
// Define the maximum number of positions to store in the trail
@@ -46,14 +47,14 @@ int main(void)
//----------------------------------------------------------------------------------
Vector2 mousePosition = GetMousePosition();
- // 1. Shift all existing positions backward by one slot in the array
- // The last element (the oldest position) is dropped.
+ // 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)
+ // Store the new, current mouse position at the start of the array (Index 0)
trailPositions[0] = mousePosition;
//----------------------------------------------------------------------------------
@@ -61,24 +62,23 @@ int main(void)
//----------------------------------------------------------------------------------
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
+ // 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)
+ 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);
+ Color trailColor = Fade(SKYBLUE, ratio*0.5f + 0.5f);
// Size effect: oldest positions are smaller
- float trailRadius = 15.0f * ratio;
+ float trailRadius = 15.0f*ratio;
DrawCircleV(trailPositions[i], trailRadius, trailColor);
}
@@ -87,8 +87,7 @@ int main(void)
// 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);
+ DrawText("Move the mouse to see the trail effect!", 10, screenHeight - 30, 20, LIGHTGRAY);
EndDrawing();
//----------------------------------------------------------------------------------
@@ -96,9 +95,6 @@ int main(void)
// De-Initialization
//--------------------------------------------------------------------------------------
-
- // No resources loaded, nothing to unload.
-
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
diff --git a/examples/shapes/shapes_pie_chart.c b/examples/shapes/shapes_pie_chart.c
index 1fa938905..566e3a4d1 100644
--- a/examples/shapes/shapes_pie_chart.c
+++ b/examples/shapes/shapes_pie_chart.c
@@ -2,7 +2,7 @@
*
* raylib [shapes] example - pie chart
*
-* Example complexity rating: [★☆☆☆] 1/4
+* Example complexity rating: [★★★☆] 3/4
*
* Example originally created with raylib 5.5, last time updated with raylib 5.6
*
@@ -22,6 +22,8 @@
#define RAYGUI_IMPLEMENTATION
#include "raygui.h"
+#define MAX_PIE_SLICES 10 // Max pie slices
+
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
@@ -34,15 +36,14 @@ int main(void)
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - pie chart");
- #define MAX_SLICES 10
int sliceCount = 7;
float donutInnerRadius = 25.0f;
- 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};
+ float values[MAX_PIE_SLICES] = { 300.0f, 100.0f, 450.0f, 350.0f, 600.0f, 380.0f, 750.0f }; // Initial slice values
+ char labels[MAX_PIE_SLICES][32] = { 0 };
+ bool editingLabel[MAX_PIE_SLICES] = { 0 };
- for (int i = 0; i < MAX_SLICES; i++)
- snprintf(labels[i], 32, "Slice %i", i + 1);
+ for (int i = 0; i < MAX_PIE_SLICES; i++)
+ snprintf(labels[i], 32, "Slice %02i", i + 1);
bool showValues = true;
bool showPercentages = false;
@@ -50,7 +51,32 @@ int main(void)
int hoveredSlice = -1;
Rectangle scrollPanelBounds = {0};
Vector2 scrollContentOffset = {0};
- Rectangle view = {0};
+ Rectangle view = { 0 };
+
+ // 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;
+
+ // Total value for percentage calculations
+ float totalValue = 0.0f;
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
@@ -60,32 +86,9 @@ int main(void)
{
// 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];
+ totalValue = 0.0f;
+ for (int i = 0; i < sliceCount; i++) totalValue += values[i];
// Check for mouse hover over slices
hoveredSlice = -1; // Reset hovered slice
@@ -94,23 +97,24 @@ int main(void)
{
float dx = mousePos.x - center.x;
float dy = mousePos.y - center.y;
- float distance = sqrtf(dx * dx + dy * dy);
+ 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 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))
+ float sweep = (totalValue > 0)? (values[i]/totalValue)*360.0f : 0.0f;
+
+ if ((angle >= currentAngle) && (angle < (currentAngle + sweep)))
{
hoveredSlice = i;
break;
}
+
currentAngle += sweep;
}
}
@@ -120,116 +124,96 @@ int main(void)
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
- ClearBackground(RAYWHITE);
+ 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)
+ // Draw the pie chart on the canvas
+ float startAngle = 0.0f;
+ for (int i = 0; i < sliceCount; i++)
{
- 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';
+ float sweepAngle = (totalValue > 0)? (values[i]/totalValue)*360.0f : 0.0f;
+ float midAngle = startAngle + sweepAngle/2.0f; // Middle angle for label positioning
- 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);
- }
+ 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 += 20.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] = { 0 };
+ 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, 20, 1);
+ float labelRadius = radius*0.7f;
+ Vector2 labelPos = { center.x + cosf(midAngle*DEG2RAD)*labelRadius - textSize.x/2.0f,
+ center.y + sinf(midAngle*DEG2RAD)*labelRadius - textSize.y/2.0f };
+ DrawText(labelText, (int)labelPos.x, (int)labelPos.y, 20, WHITE);
+ }
- if(showDonut)
- {
// Draw inner circle to create donut effect
- DrawCircle(center.x, center.y, donutInnerRadius, RAYWHITE);
+ // TODO: This is a hacky solution, better use DrawRing()
+ if (showDonut) DrawCircle(center.x, center.y, donutInnerRadius, RAYWHITE);
+
+ startAngle += sweepAngle;
}
- startAngle += sweepAngle;
- }
- //------------------------------------------------------------------------------
+ // UI control panel
+ DrawRectangleRec(panelRect, Fade(LIGHTGRAY, 0.5f));
+ DrawRectangleLinesEx(panelRect, 1.0f, GRAY);
- // UI control panel
- //------------------------------------------------------------------------------
- DrawRectangleRec(panelRect, Fade(LIGHTGRAY, 0.5f));
- DrawRectangleLinesEx(panelRect, 1.0f, GRAY);
+ GuiSpinner((Rectangle){ panelPos.x + 95, (float)panelPos.y + 12, 125, 25 }, "Slices ", &sliceCount, 1, MAX_PIE_SLICES, false);
+ GuiCheckBox((Rectangle){ panelPos.x + 20, (float)panelPos.y + 12 + 40, 20, 20 }, "Show Values", &showValues);
+ GuiCheckBox((Rectangle){ panelPos.x + 20, (float)panelPos.y + 12 + 70, 20, 20 }, "Show Percentages", &showPercentages);
+ GuiCheckBox((Rectangle){ panelPos.x + 20, (float)panelPos.y + 12 + 100, 20, 20 }, "Make Donut", &showDonut);
- int currentY = (int)panelPos.y + 12; // Start a bit lower for margin
+ if (showDonut) GuiDisable();
+ GuiSliderBar((Rectangle){ panelPos.x + 80, (float)panelPos.y + 12 + 130, panelRect.width - 100, 30 },
+ "Inner Radius", NULL, &donutInnerRadius, 5.0f, radius - 10.0f);
+ GuiEnable();
- GuiSpinner((Rectangle){ panelPos.x + 95, (float)currentY, 125, 25 }, "Slices ", &sliceCount, 1, MAX_SLICES, false);
- currentY += 40;
+ GuiLine((Rectangle){ panelPos.x + 10, (float)panelPos.y + 12 + 170, panelRect.width - 20, 1 }, NULL);
- GuiCheckBox((Rectangle){ panelPos.x + 20, (float)currentY, 20, 20 }, "Show Values", &showValues);
- currentY += 30;
+ // Scrollable area for slice editors
+ scrollPanelBounds = (Rectangle){
+ panelPos.x + panelMargin,
+ (float)panelPos.y + 12 + 190,
+ panelRect.width - panelMargin*2,
+ panelRect.y + panelRect.height - panelPos.y + 12 + 190 - panelMargin
+ };
+ int contentHeight = sliceCount*35;
- GuiCheckBox((Rectangle){ panelPos.x + 20, (float)currentY, 20, 20 }, "Show Percentages", &showPercentages);
- currentY += 30;
+ GuiScrollPanel(scrollPanelBounds, NULL,
+ (Rectangle){ 0, 0, panelRect.width - 25, (float)contentHeight },
+ &scrollContentOffset, &view);
- GuiCheckBox((Rectangle){ panelPos.x + 20, (float)currentY, 20, 20 }, "Make Donut", &showDonut);
- currentY += 30;
+ const float contentX = view.x + scrollContentOffset.x; // Left of content
+ const float contentY = view.y + scrollContentOffset.y; // Top of content
- if(showDonut)
- {
- GuiSliderBar((Rectangle){ panelPos.x + 80, (float)currentY, panelRect.width - 100, 30 },
- "Inner Radius", NULL, &donutInnerRadius, 5.0f, radius - 10.0f);
- currentY += 40;
- }
+ BeginScissorMode((int)view.x, (int)view.y, (int)view.width, (int)view.height);
- GuiLine((Rectangle){ panelPos.x + 10, (float)currentY, panelRect.width - 20, 1 }, NULL);
- currentY += 20;
+ 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);
- // 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;
+ // Label textbox
+ if (GuiTextBox((Rectangle){ contentX + 45, (float)rowY, 75, 30 }, labels[i], 32, editingLabel[i])) editingLabel[i] = !editingLabel[i];
- GuiScrollPanel(scrollPanelBounds, NULL,
- (Rectangle){ 0, 0, panelRect.width - 25, (float)contentHeight },
- &scrollContentOffset, &view);
+ GuiSliderBar((Rectangle){ contentX + 130, (float)rowY, 110, 30 }, NULL, NULL, &values[i], 0.0f, 1000.0f);
+ }
- 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();
+ EndScissorMode();
EndDrawing();
//----------------------------------------------------------------------------------
diff --git a/examples/shapes/shapes_recursive_tree.c b/examples/shapes/shapes_recursive_tree.c
index 4d0042419..e9cadd8ec 100644
--- a/examples/shapes/shapes_recursive_tree.c
+++ b/examples/shapes/shapes_recursive_tree.c
@@ -31,11 +31,6 @@ typedef struct {
float length;
} Branch;
-//----------------------------------------------------------------------------------
-// Module Functions Declaration
-//----------------------------------------------------------------------------------
-static Vector2 CalculateBranchEnd(Vector2 start, float angle, float length);
-
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
@@ -64,13 +59,12 @@ int main(void)
{
// Update
//----------------------------------------------------------------------------------
-
float theta = angle*DEG2RAD;
int maxBranches = (int)(powf(2, floorf(treeDepth)));
- Branch branches[1024] = { 0 };
+ Branch branches[1030] = { 0 };
int count = 0;
- Vector2 initialEnd = CalculateBranchEnd(start, 0.0f, length);
+ Vector2 initialEnd = { start.x + length*sinf(0.0f), start.y - length*cosf(0.0f) };
branches[count++] = (Branch){start, initialEnd, 0.0f, length};
for (int i = 0; i < count; i++)
@@ -84,14 +78,16 @@ int main(void)
{
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};
+ float angle1 = branch.angle + theta;
+ Vector2 branchEnd1 = { branchStart.x + nextLength*sinf(angle1), branchStart.y - nextLength*cosf(angle1) };
+ branches[count++] = (Branch){branchStart, branchEnd1, angle1, nextLength};
+
+ float angle2 = branch.angle - theta;
+ Vector2 branchEnd2 = { branchStart.x + nextLength*sinf(angle2), branchStart.y - nextLength*cosf(angle2) };
+ branches[count++] = (Branch){branchStart, branchEnd2, angle2, nextLength};
}
}
-
+ //----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
@@ -103,8 +99,8 @@ int main(void)
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);
+ if (bezier) DrawLineBezier(branch.start, branch.end, thick, RED);
+ else DrawLineEx(branch.start, branch.end, thick, RED);
}
}
@@ -133,9 +129,4 @@ int main(void)
//--------------------------------------------------------------------------------------
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_simple_particles.c b/examples/shapes/shapes_simple_particles.c
index 5bef0917a..c5d9612c3 100644
--- a/examples/shapes/shapes_simple_particles.c
+++ b/examples/shapes/shapes_simple_particles.c
@@ -2,7 +2,7 @@
*
* raylib [shapes] example - simple particles
*
-* Example complexity rating: [★☆☆☆] 1/4
+* Example complexity rating: [★★☆☆] 2/4
*
* Example originally created with raylib 5.6, last time updated with raylib 5.6
*
@@ -20,7 +20,7 @@
#include // Required for: calloc(), free()
#include // Required for: cosf(), sinf()
-#define MAX_PARTICLES 3000 // Max number particles
+#define MAX_PARTICLES 3000 // Max number of particles
//----------------------------------------------------------------------------------
// Types and Structures Definition
@@ -74,7 +74,7 @@ int main(void)
// 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;
@@ -100,6 +100,7 @@ int main(void)
// Update the parameters of each particle
UpdateParticles(&circularBuffer, screenWidth, screenHeight);
+
// Remove dead particles from the circular buffer
UpdateCircularBuffer(&circularBuffer);
@@ -217,46 +218,53 @@ static void UpdateParticles(CircularBuffer *circularBuffer, int screenWidth, int
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;
+ } 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;
+
+ // If alpha transparent, particle dies
+ if (circularBuffer->buffer[i].color.a < 4) 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;
+
+ // If radius too small, particle dies
+ if (circularBuffer->buffer[i].radius <= 0.02f) 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))
+
+ 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)
+ while ((circularBuffer->tail != circularBuffer->head) && !circularBuffer->buffer[circularBuffer->tail].alive)
{
circularBuffer->tail = (circularBuffer->tail + 1)%MAX_PARTICLES;
}
diff --git a/examples/shapes/shapes_starfield.c b/examples/shapes/shapes_starfield_effect.c
similarity index 66%
rename from examples/shapes/shapes_starfield.c
rename to examples/shapes/shapes_starfield_effect.c
index df543d066..8dd90fe0b 100644
--- a/examples/shapes/shapes_starfield.c
+++ b/examples/shapes/shapes_starfield_effect.c
@@ -1,8 +1,8 @@
/*******************************************************************************************
*
-* raylib [shapes] example - starfield
+* raylib [shapes] example - starfield effect
*
-* Example complexity rating: [★☆☆☆] 1/4
+* Example complexity rating: [★★☆☆] 2/4
*
* Example originally created with raylib 5.5, last time updated with raylib 5.6-dev
*
@@ -31,7 +31,7 @@ int main(void)
const int screenWidth = 800;
const int screenHeight = 450;
- InitWindow(screenWidth, screenHeight, "raylib [shapes] example - starfield");
+ InitWindow(screenWidth, screenHeight, "raylib [shapes] example - starfield effect");
Color bgColor = ColorLerp(DARKBLUE, BLACK, 0.69f);
@@ -45,9 +45,10 @@ int main(void)
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);
+ for (int i = 0; i < STAR_COUNT; i++)
+ {
+ stars[i].x = GetRandomValue(-screenWidth*0.5f, screenWidth*0.5f);
+ stars[i].y = GetRandomValue(-screenHeight*0.5f, screenHeight*0.5f);
stars[i].z = 1.0f;
}
@@ -59,39 +60,36 @@ int main(void)
{
// 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;
- }
- }
+ // Change speed based on mouse
+ float mouseMove = GetMouseWheelMove();
+ if ((int)mouseMove != 0) speed += 2.0f*mouseMove/9.0f;
+ if (speed < 0.0f) speed = 0.1f;
+ else if (speed > 2.0f) speed = 2.0f;
// Toggle lines / points with space bar
- if (IsKeyPressed(KEY_SPACE)) {
- drawLines = !drawLines;
- }
+ if (IsKeyPressed(KEY_SPACE)) drawLines = !drawLines;
float dt = GetFrameTime();
- for (int i = 0; i < STAR_COUNT; i++) {
+ for (int i = 0; i < STAR_COUNT; i++)
+ {
// Update star's timer
- stars[i].z -= dt * speed;
+ 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,
+ starsScreenPos[i] = (Vector2){
+ screenWidth*0.5f + stars[i].x/stars[i].z,
+ screenHeight*0.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);
+ 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*0.5f, screenWidth*0.5f);
+ stars[i].y = GetRandomValue(-screenHeight*0.5f, screenHeight*0.5f);
stars[i].z = 1.0f;
}
}
-
-
//----------------------------------------------------------------------------------
// Draw
@@ -100,42 +98,47 @@ int main(void)
ClearBackground(bgColor);
- for (int i = 0; i < STAR_COUNT; i++) {
- if (drawLines) {
+ 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) {
+ 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,
+ Vector2 startPos = (Vector2){
+ screenWidth*0.5f + stars[i].x/t,
+ screenHeight*0.5f + stars[i].y/t,
};
+
// Draw a line connecting the old point to the current point
DrawLineV(startPos, starsScreenPos[i], RAYWHITE);
}
}
- else {
+ 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);
}
}
+ DrawText(TextFormat("[MOUSE WHEEL] Current Speed: %.0f", 9.0f*speed/2.0f), 10, 40, 20, RAYWHITE);
+ DrawText(TextFormat("[SPACE] Current draw mode: %s", drawLines ? "Lines" : "Circles"), 10, 70, 20, 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
//--------------------------------------------------------------------------------------
diff --git a/examples/shapes/shapes_starfield.png b/examples/shapes/shapes_starfield_effect.png
similarity index 100%
rename from examples/shapes/shapes_starfield.png
rename to examples/shapes/shapes_starfield_effect.png
diff --git a/examples/shapes/shapes_triangle_strip.c b/examples/shapes/shapes_triangle_strip.c
index d8b5faeea..3172e1f7f 100644
--- a/examples/shapes/shapes_triangle_strip.c
+++ b/examples/shapes/shapes_triangle_strip.c
@@ -33,7 +33,7 @@ int main(void)
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - triangle strip");
- Vector2 points[120] = { 0 };
+ Vector2 points[122] = { 0 };
Vector2 center = { (screenWidth/2.0f) - 125.f, screenHeight/2.0f };
float segments = 6.0f;
float insideRadius = 100.0f;
@@ -69,17 +69,22 @@ int main(void)
ClearBackground(RAYWHITE);
- for (int i = 0, i2 = 0; i < pointCount; i++, i2 += 2)
+ for (int i = 0; i < pointCount; i++)
{
- 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);
+ Vector2 a = points[i*2];
+ Vector2 b = points[i*2 + 1];
+ Vector2 c = points[i*2 + 2];
+ Vector2 d = points[i*2 + 3];
- 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);
+ float angle1 = i*angleStep;
+ DrawTriangle(c, b, a, ColorFromHSV(angle1*RAD2DEG, 1.0f, 1.0f));
+ DrawTriangle(d, b, c, ColorFromHSV((angle1 + angleStep/2)*RAD2DEG, 1.0f, 1.0f));
+
+ if (outline)
+ {
+ DrawTriangleLines(a, b, c, BLACK);
+ DrawTriangleLines(c, b, d, BLACK);
+ }
}
DrawLine(580, 0, 580, GetScreenHeight(), (Color){ 218, 218, 218, 255 });
diff --git a/projects/VS2022/examples/core_highdpi_testbed.vcxproj b/projects/VS2022/examples/core_highdpi_testbed.vcxproj
new file mode 100644
index 000000000..d50de0d6e
--- /dev/null
+++ b/projects/VS2022/examples/core_highdpi_testbed.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
+
+
+
+ {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}
+ Win32Proj
+ core_highdpi_testbed
+ 10.0
+ core_highdpi_testbed
+
+
+
+ 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_monitor_change.vcxproj b/projects/VS2022/examples/core_monitor_detector.vcxproj
similarity index 99%
rename from projects/VS2022/examples/core_monitor_change.vcxproj
rename to projects/VS2022/examples/core_monitor_detector.vcxproj
index 07921bef3..bafb1b15c 100644
--- a/projects/VS2022/examples/core_monitor_change.vcxproj
+++ b/projects/VS2022/examples/core_monitor_detector.vcxproj
@@ -53,9 +53,9 @@
{FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}
Win32Proj
- core_monitor_change
+ core_monitor_detector
10.0
- core_monitor_change
+ core_monitor_detector
@@ -553,7 +553,7 @@
-
+
diff --git a/projects/VS2022/examples/core_screen_recording.vcxproj b/projects/VS2022/examples/core_screen_recording.vcxproj
new file mode 100644
index 000000000..7b5856dbd
--- /dev/null
+++ b/projects/VS2022/examples/core_screen_recording.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
+
+
+
+ {9DE2FC01-A839-4F89-8319-9071D4C54821}
+ Win32Proj
+ core_screen_recording
+ 10.0
+ core_screen_recording
+
+
+
+ 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_text_file_loading.vcxproj b/projects/VS2022/examples/core_text_file_loading.vcxproj
new file mode 100644
index 000000000..15324701d
--- /dev/null
+++ b/projects/VS2022/examples/core_text_file_loading.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
+
+
+
+ {2F578155-D51F-4C03-AB7F-5C5122CA46CC}
+ Win32Proj
+ core_text_file_loading
+ 10.0
+ core_text_file_loading
+
+
+
+ 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/models_geometry_textures_cube.vcxproj b/projects/VS2022/examples/models_rotating_cube.vcxproj
similarity index 99%
rename from projects/VS2022/examples/models_geometry_textures_cube.vcxproj
rename to projects/VS2022/examples/models_rotating_cube.vcxproj
index 77fcd94d4..ebf5f10f7 100644
--- a/projects/VS2022/examples/models_geometry_textures_cube.vcxproj
+++ b/projects/VS2022/examples/models_rotating_cube.vcxproj
@@ -53,9 +53,9 @@
{A4662163-83E7-4309-8CAA-B0BF13655FE6}
Win32Proj
- models_geometry_textures_cube
+ models_rotating_cube
10.0
- models_geometry_textures_cube
+ models_rotating_cube
@@ -553,7 +553,7 @@
-
+
diff --git a/projects/VS2022/examples/shaders_mandelbrot_set.vcxproj b/projects/VS2022/examples/shaders_mandelbrot_set.vcxproj
new file mode 100644
index 000000000..4ed5581e1
--- /dev/null
+++ b/projects/VS2022/examples/shaders_mandelbrot_set.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
+
+
+
+ {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}
+ Win32Proj
+ shaders_mandelbrot_set
+ 10.0
+ shaders_mandelbrot_set
+
+
+
+ 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\shaders
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shaders
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shaders
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shaders
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shaders
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shaders
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shaders
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shaders
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shaders
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shaders
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shaders
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\shaders
+ 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_starfield.vcxproj b/projects/VS2022/examples/shapes_starfield_effect.vcxproj
similarity index 99%
rename from projects/VS2022/examples/shapes_starfield.vcxproj
rename to projects/VS2022/examples/shapes_starfield_effect.vcxproj
index 5cfc0a6d3..794ec633e 100644
--- a/projects/VS2022/examples/shapes_starfield.vcxproj
+++ b/projects/VS2022/examples/shapes_starfield_effect.vcxproj
@@ -53,9 +53,9 @@
{EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}
Win32Proj
- shapes_starfield
+ shapes_starfield_effect
10.0
- shapes_starfield
+ shapes_starfield_effect
@@ -553,7 +553,7 @@
-
+
diff --git a/projects/VS2022/raylib.sln b/projects/VS2022/raylib.sln
index 5a784adbe..ec35ed5e5 100644
--- a/projects/VS2022/raylib.sln
+++ b/projects/VS2022/raylib.sln
@@ -357,11 +357,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_basic_voxel", "examp
EndProject
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", "{A4662163-83E7-4309-8CAA-B0BF13655FE6}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_rotating_cube", "examples\models_rotating_cube.vcxproj", "{A4662163-83E7-4309-8CAA-B0BF13655FE6}"
EndProject
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", "{FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_monitor_detector", "examples\core_monitor_detector.vcxproj", "{FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "web_basic_window", "examples\web_basic_window.vcxproj", "{A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}"
EndProject
@@ -385,7 +385,15 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_clock_of_clocks", "e
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}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_starfield_effect", "examples\shapes_starfield_effect.vcxproj", "{EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_highdpi_testbed", "examples\core_highdpi_testbed.vcxproj", "{1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_screen_recording", "examples\core_screen_recording.vcxproj", "{9DE2FC01-A839-4F89-8319-9071D4C54821}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_text_file_loading", "examples\core_text_file_loading.vcxproj", "{2F578155-D51F-4C03-AB7F-5C5122CA46CC}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_mandelbrot_set", "examples\shaders_mandelbrot_set.vcxproj", "{1C829D1A-892C-451C-AF0B-AC65C85F5CC6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -4793,6 +4801,102 @@ Global
{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
+ {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
+ {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
+ {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug|ARM64.Build.0 = Debug|ARM64
+ {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug|x64.ActiveCfg = Debug|x64
+ {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug|x64.Build.0 = Debug|x64
+ {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug|x86.ActiveCfg = Debug|Win32
+ {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug|x86.Build.0 = Debug|Win32
+ {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
+ {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
+ {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release|ARM64.ActiveCfg = Release|ARM64
+ {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release|ARM64.Build.0 = Release|ARM64
+ {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release|x64.ActiveCfg = Release|x64
+ {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release|x64.Build.0 = Release|x64
+ {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release|x86.ActiveCfg = Release|Win32
+ {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release|x86.Build.0 = Release|Win32
+ {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
+ {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
+ {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug|ARM64.Build.0 = Debug|ARM64
+ {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug|x64.ActiveCfg = Debug|x64
+ {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug|x64.Build.0 = Debug|x64
+ {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug|x86.ActiveCfg = Debug|Win32
+ {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug|x86.Build.0 = Debug|Win32
+ {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
+ {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
+ {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release|ARM64.ActiveCfg = Release|ARM64
+ {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release|ARM64.Build.0 = Release|ARM64
+ {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release|x64.ActiveCfg = Release|x64
+ {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release|x64.Build.0 = Release|x64
+ {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release|x86.ActiveCfg = Release|Win32
+ {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release|x86.Build.0 = Release|Win32
+ {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
+ {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
+ {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug|ARM64.Build.0 = Debug|ARM64
+ {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug|x64.ActiveCfg = Debug|x64
+ {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug|x64.Build.0 = Debug|x64
+ {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug|x86.ActiveCfg = Debug|Win32
+ {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug|x86.Build.0 = Debug|Win32
+ {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
+ {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
+ {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release|ARM64.ActiveCfg = Release|ARM64
+ {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release|ARM64.Build.0 = Release|ARM64
+ {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release|x64.ActiveCfg = Release|x64
+ {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release|x64.Build.0 = Release|x64
+ {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release|x86.ActiveCfg = Release|Win32
+ {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release|x86.Build.0 = Release|Win32
+ {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
+ {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
+ {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug|ARM64.Build.0 = Debug|ARM64
+ {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug|x64.ActiveCfg = Debug|x64
+ {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug|x64.Build.0 = Debug|x64
+ {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug|x86.ActiveCfg = Debug|Win32
+ {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug|x86.Build.0 = Debug|Win32
+ {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
+ {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
+ {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release|ARM64.ActiveCfg = Release|ARM64
+ {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release|ARM64.Build.0 = Release|ARM64
+ {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release|x64.ActiveCfg = Release|x64
+ {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release|x64.Build.0 = Release|x64
+ {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release|x86.ActiveCfg = Release|Win32
+ {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -4960,7 +5064,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} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A}
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
{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}
@@ -4988,6 +5092,10 @@ Global
{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}
+ {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
+ {9DE2FC01-A839-4F89-8319-9071D4C54821} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
+ {2F578155-D51F-4C03-AB7F-5C5122CA46CC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
+ {1C829D1A-892C-451C-AF0B-AC65C85F5CC6} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29}
diff --git a/src/external/rlsw.h b/src/external/rlsw.h
index 49050f848..904bf1210 100644
--- a/src/external/rlsw.h
+++ b/src/external/rlsw.h
@@ -6,7 +6,7 @@
* rlsw is a custom OpenGL 1.1-style implementation on software, intended to provide all
* functionality available on rlgl.h library used by raylib, becoming a direct software
* rendering replacement for OpenGL 1.1 backend and allowing to run raylib on GPU-less
-* devices when required.
+* devices when required
*
* FEATURES:
* - Rendering to custom internal framebuffer with multiple color modes supported:
@@ -2892,8 +2892,8 @@ static inline bool sw_quad_is_axis_aligned(void)
float dx = v1[0] - v0[0];
float dy = v1[1] - v0[1];
- if (fabsf(dx) > 1e-6f && fabsf(dy) < 1e-6f) horizontal++;
- else if (fabsf(dy) > 1e-6f && fabsf(dx) < 1e-6f) vertical++;
+ if ((fabsf(dx) > 1e-6f) && (fabsf(dy) < 1e-6f)) horizontal++;
+ else if ((fabsf(dy) > 1e-6f) && (fabsf(dx) < 1e-6f)) vertical++;
else return false; // Diagonal edge -> not axis-aligned
}
@@ -2933,8 +2933,8 @@ static inline void sw_quad_sort_cw(const sw_vertex_t* *output)
// Separate vertices based on Y-coordinate
for (int i = 0; i < 4; i++)
{
- if (input[i].screen[1] == minY && topCount < 2) top[topCount++] = &input[i];
- else if (input[i].screen[1] == maxY && bottomCount < 2) bottom[bottomCount++] = &input[i];
+ if ((input[i].screen[1] == minY) && (topCount < 2)) top[topCount++] = &input[i];
+ else if ((input[i].screen[1] == maxY) && (bottomCount < 2)) bottom[bottomCount++] = &input[i];
}
// If we don't have enough top/bottom vertices (e.g., Y values are all different),
@@ -2960,7 +2960,7 @@ static inline void sw_quad_sort_cw(const sw_vertex_t* *output)
}
// Sort bottom vertices by X (left to right)
- if (bottomCount == 2 && bottom[0]->screen[0] > bottom[1]->screen[0])
+ if ((bottomCount == 2) && (bottom[0]->screen[0] > bottom[1]->screen[0]))
{
const sw_vertex_t *temp = bottom[0];
bottom[0] = bottom[1];
@@ -2997,7 +2997,7 @@ static inline void FUNC_NAME(void)
int width = xMax - xMin; \
int height = yMax - yMin; \
\
- if (width == 0 || height == 0) return; \
+ if ((width == 0) || (height == 0)) return; \
\
float wRcp = (width > 0.0f)? 1.0f/width : 0.0f; \
float hRcp = (height > 0.0f)? 1.0f/height : 0.0f; \
@@ -3157,7 +3157,7 @@ static inline void sw_quad_render(void)
if (RLSW.vertexCounter < 3) return;
- if (RLSW.vertexCounter == 4 && sw_quad_is_axis_aligned())
+ if ((RLSW.vertexCounter == 4) && sw_quad_is_axis_aligned())
{
if (SW_STATE_CHECK(SW_STATE_TEXTURE_2D | SW_STATE_DEPTH_TEST | SW_STATE_BLEND)) sw_quad_raster_axis_aligned_TEX_DEPTH_BLEND();
else if (SW_STATE_CHECK(SW_STATE_DEPTH_TEST | SW_STATE_BLEND)) sw_quad_raster_axis_aligned_DEPTH_BLEND();
@@ -3304,7 +3304,7 @@ static inline void FUNC_NAME(const sw_vertex_t *v0, const sw_vertex_t *v1) \
int dy = y2 - y1; \
\
/* Handling of lines that are more horizontal or vertical */ \
- if (dx == 0 && dy == 0) \
+ if ((dx == 0) && (dy == 0)) \
{ \
/* TODO: A point should be rendered here */ \
return; \
@@ -3444,7 +3444,7 @@ void FUNC_NAME(const sw_vertex_t *v1, const sw_vertex_t *v2) \
\
RASTER_FUNC(v1, v2); \
\
- if (dx != 0 && abs(dy/dx) < 1) \
+ if ((dx != 0) && (abs(dy/dx) < 1)) \
{ \
int wy = (int)((RLSW.lineWidth - 1.0f)*abs(dx)/sqrtf(dx*dx + dy*dy)); \
wy >>= 1; \
@@ -3551,13 +3551,13 @@ static inline void FUNC_NAME(int x, int y, float z, const float color[4]) \
{ \
if (CHECK_BOUNDS == 1) \
{ \
- if (x < RLSW.vpMin[0] || x >= RLSW.vpMax[0]) return; \
- if (y < RLSW.vpMin[1] || y >= RLSW.vpMax[1]) return; \
+ if ((x < RLSW.vpMin[0]) || (x >= RLSW.vpMax[0])) return; \
+ if ((y < RLSW.vpMin[1]) || (y >= RLSW.vpMax[1])) return; \
} \
else if (CHECK_BOUNDS == SW_SCISSOR_TEST) \
{ \
- if (x < RLSW.scMin[0] || x >= RLSW.scMax[0]) return; \
- if (y < RLSW.scMin[1] || y >= RLSW.scMax[1]) return; \
+ if ((x < RLSW.scMin[0]) || (x >= RLSW.scMax[0])) return; \
+ if ((y < RLSW.scMin[1]) || (y >= RLSW.scMax[1])) return; \
} \
\
int offset = y*RLSW.framebuffer.width + x; \
@@ -3718,12 +3718,12 @@ static inline bool sw_is_texture_valid(uint32_t id)
static inline bool sw_is_texture_filter_valid(int filter)
{
- return (filter == SW_NEAREST || filter == SW_LINEAR);
+ return ((filter == SW_NEAREST) || (filter == SW_LINEAR));
}
static inline bool sw_is_texture_wrap_valid(int wrap)
{
- return (wrap == SW_REPEAT || wrap == SW_CLAMP);
+ return ((wrap == SW_REPEAT) || (wrap == SW_CLAMP));
}
static inline bool sw_is_draw_mode_valid(int mode)
@@ -4392,7 +4392,7 @@ void swRotatef(float angle, float x, float y, float z)
float lengthSq = x*x + y*y + z*z;
- if (lengthSq != 1.0f && lengthSq != 0.0f)
+ if ((lengthSq != 1.0f) && (lengthSq != 0.0f))
{
float invLength = 1.0f/sqrtf(lengthSq);
x *= invLength;
diff --git a/src/platforms/rcore_android.c b/src/platforms/rcore_android.c
index 6ecc41888..47dcce32b 100644
--- a/src/platforms/rcore_android.c
+++ b/src/platforms/rcore_android.c
@@ -461,7 +461,7 @@ int GetCurrentMonitor(void)
if (display == NULL)
{
TRACELOG(LOG_ERROR, "GetCurrentMonitor() couldn't get the display object");
- }
+ }
else
{
jclass displayClass = (*env)->FindClass(env, "android/view/Display");
diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c
index 729ca308c..5dde1df67 100644
--- a/src/platforms/rcore_desktop_glfw.c
+++ b/src/platforms/rcore_desktop_glfw.c
@@ -1048,6 +1048,7 @@ Image GetClipboardImage(void)
void ShowCursor(void)
{
glfwSetInputMode(platform.handle, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
+
CORE.Input.Mouse.cursorHidden = false;
}
@@ -1055,6 +1056,7 @@ void ShowCursor(void)
void HideCursor(void)
{
glfwSetInputMode(platform.handle, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
+
CORE.Input.Mouse.cursorHidden = true;
}
@@ -1075,13 +1077,10 @@ void EnableCursor(void)
void DisableCursor(void)
{
// Reset mouse position within the window area before disabling cursor
- SetMousePosition(CORE.Window.screen.width, CORE.Window.screen.height);
+ SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2);
glfwSetInputMode(platform.handle, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
- // Set cursor position in the middle
- SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2);
-
if (glfwRawMouseMotionSupported()) glfwSetInputMode(platform.handle, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE);
CORE.Input.Mouse.cursorLocked = true;
diff --git a/src/platforms/rcore_desktop_rgfw.c b/src/platforms/rcore_desktop_rgfw.c
index 52ec6ac94..86842140d 100644
--- a/src/platforms/rcore_desktop_rgfw.c
+++ b/src/platforms/rcore_desktop_rgfw.c
@@ -80,7 +80,7 @@ void CloseWindow(void);
#define CloseWindow CloseWindow_win32
#define ShowCursor __imp_ShowCursor
#define _APISETSTRING_
-
+
#undef MAX_PATH
#if defined(__cplusplus)
@@ -262,7 +262,7 @@ static int RGFW_gpConvTable[18] = {
[RGFW_gamepadRight] = GAMEPAD_BUTTON_LEFT_FACE_RIGHT,
[RGFW_gamepadDown] = GAMEPAD_BUTTON_LEFT_FACE_DOWN,
[RGFW_gamepadLeft] = GAMEPAD_BUTTON_LEFT_FACE_LEFT,
- [RGFW_gamepadL3] = GAMEPAD_BUTTON_LEFT_THUMB,
+ [RGFW_gamepadL3] = GAMEPAD_BUTTON_LEFT_THUMB,
[RGFW_gamepadR3] = GAMEPAD_BUTTON_RIGHT_THUMB,
};
@@ -933,7 +933,7 @@ void PollInputEvents(void)
// because ProcessGestureEvent() is just called on an event, not every frame
UpdateGestures();
#endif
-
+
// Reset keys/chars pressed registered
CORE.Input.Keyboard.keyPressedQueueCount = 0;
CORE.Input.Keyboard.charPressedQueueCount = 0;
@@ -1025,7 +1025,7 @@ void PollInputEvents(void)
CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char));
strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event->droppedFiles[i]);
-
+
CORE.Window.dropFileCount++;
}
else if (CORE.Window.dropFileCount < 1024)
@@ -1229,7 +1229,7 @@ void PollInputEvents(void)
int button = (axis == GAMEPAD_AXIS_LEFT_TRIGGER)? GAMEPAD_BUTTON_LEFT_TRIGGER_2 : GAMEPAD_BUTTON_RIGHT_TRIGGER_2;
int pressed = (value > 0.1f);
CORE.Input.Gamepad.currentButtonState[event->gamepad][button] = pressed;
-
+
if (pressed) CORE.Input.Gamepad.lastButtonPressed = button;
else if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0;
}
@@ -1345,7 +1345,7 @@ int InitPlatform(void)
// TODO: Is this needed by raylib now?
// If so, rcore_desktop_sdl should be updated too
//SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);
-
+
if (CORE.Window.flags & FLAG_VSYNC_HINT) RGFW_window_swapInterval(platform.window, 1);
RGFW_window_makeCurrent(platform.window);
diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c
index 6655db460..e135cd848 100644
--- a/src/platforms/rcore_desktop_sdl.c
+++ b/src/platforms/rcore_desktop_sdl.c
@@ -104,7 +104,6 @@ typedef struct {
SDL_GameController *gamepad[MAX_GAMEPADS];
SDL_JoystickID gamepadId[MAX_GAMEPADS]; // Joystick instance ids, they do not start from 0
SDL_Cursor *cursor;
- bool cursorRelative;
} PlatformData;
//----------------------------------------------------------------------------------
@@ -838,7 +837,11 @@ void SetWindowPosition(int x, int y)
void SetWindowMonitor(int monitor)
{
const int monitorCount = SDL_GetNumVideoDisplays();
+#if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure
+ if ((monitor > 0) && (monitor <= monitorCount))
+#else
if ((monitor >= 0) && (monitor < monitorCount))
+#endif
{
// NOTE:
// 1. SDL started supporting moving exclusive fullscreen windows between displays on SDL3,
@@ -962,7 +965,11 @@ int GetCurrentMonitor(void)
Vector2 GetMonitorPosition(int monitor)
{
const int monitorCount = SDL_GetNumVideoDisplays();
+#if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure
+ if ((monitor > 0) && (monitor <= monitorCount))
+#else
if ((monitor >= 0) && (monitor < monitorCount))
+#endif
{
SDL_Rect displayBounds;
@@ -986,7 +993,11 @@ int GetMonitorWidth(int monitor)
int width = 0;
const int monitorCount = SDL_GetNumVideoDisplays();
+#if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure
+ if ((monitor > 0) && (monitor <= monitorCount))
+#else
if ((monitor >= 0) && (monitor < monitorCount))
+#endif
{
SDL_DisplayMode mode;
SDL_GetCurrentDisplayMode(monitor, &mode);
@@ -1003,7 +1014,11 @@ int GetMonitorHeight(int monitor)
int height = 0;
const int monitorCount = SDL_GetNumVideoDisplays();
+#if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure
+ if ((monitor > 0) && (monitor <= monitorCount))
+#else
if ((monitor >= 0) && (monitor < monitorCount))
+#endif
{
SDL_DisplayMode mode;
SDL_GetCurrentDisplayMode(monitor, &mode);
@@ -1020,7 +1035,11 @@ int GetMonitorPhysicalWidth(int monitor)
int width = 0;
const int monitorCount = SDL_GetNumVideoDisplays();
+#if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure
+ if ((monitor > 0) && (monitor <= monitorCount))
+#else
if ((monitor >= 0) && (monitor < monitorCount))
+#endif
{
float ddpi = 0.0f;
SDL_GetDisplayDPI(monitor, &ddpi, NULL, NULL);
@@ -1040,7 +1059,11 @@ int GetMonitorPhysicalHeight(int monitor)
int height = 0;
const int monitorCount = SDL_GetNumVideoDisplays();
+#if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure
+ if ((monitor > 0) && (monitor <= monitorCount))
+#else
if ((monitor >= 0) && (monitor < monitorCount))
+#endif
{
float ddpi = 0.0f;
SDL_GetDisplayDPI(monitor, &ddpi, NULL, NULL);
@@ -1060,7 +1083,11 @@ int GetMonitorRefreshRate(int monitor)
int refresh = 0;
const int monitorCount = SDL_GetNumVideoDisplays();
+#if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure
+ if ((monitor > 0) && (monitor <= monitorCount))
+#else
if ((monitor >= 0) && (monitor < monitorCount))
+#endif
{
SDL_DisplayMode mode;
SDL_GetCurrentDisplayMode(monitor, &mode);
@@ -1076,7 +1103,14 @@ const char *GetMonitorName(int monitor)
{
const int monitorCount = SDL_GetNumVideoDisplays();
- if ((monitor >= 0) && (monitor < monitorCount)) return SDL_GetDisplayName(monitor);
+#if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure
+ if ((monitor > 0) && (monitor <= monitorCount))
+#else
+ if ((monitor >= 0) && (monitor < monitorCount))
+#endif
+ {
+ return SDL_GetDisplayName(monitor);
+ }
else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor");
return "";
@@ -1209,13 +1243,13 @@ void EnableCursor(void)
SDL_SetRelativeMouseMode(SDL_FALSE);
#if defined(USING_VERSION_SDL3)
- // SDL_ShowCursor() has been split into three functions: SDL_ShowCursor(), SDL_HideCursor(), and SDL_CursorVisible()
+ // NOTE: SDL_ShowCursor() has been split into three functions:
+ // SDL_ShowCursor(), SDL_HideCursor(), and SDL_CursorVisible()
SDL_ShowCursor();
#else
SDL_ShowCursor(SDL_ENABLE);
#endif
- platform.cursorRelative = false;
CORE.Input.Mouse.cursorLocked = false;
}
@@ -1224,7 +1258,6 @@ void DisableCursor(void)
{
SDL_SetRelativeMouseMode(SDL_TRUE);
- platform.cursorRelative = true;
CORE.Input.Mouse.cursorLocked = true;
}
@@ -1332,7 +1365,7 @@ void PollInputEvents(void)
CORE.Input.Mouse.currentWheelMove.y = 0;
// Register previous mouse position
- if (platform.cursorRelative) CORE.Input.Mouse.currentPosition = (Vector2){ 0.0f, 0.0f };
+ if (CORE.Input.Mouse.cursorLocked) CORE.Input.Mouse.currentPosition = (Vector2){ 0.0f, 0.0f };
else CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
// Reset last gamepad button/axis registered state
@@ -1634,7 +1667,7 @@ void PollInputEvents(void)
} break;
case SDL_MOUSEMOTION:
{
- if (platform.cursorRelative)
+ if (CORE.Input.Mouse.cursorLocked)
{
CORE.Input.Mouse.currentPosition.x = (float)event.motion.xrel;
CORE.Input.Mouse.currentPosition.y = (float)event.motion.yrel;
diff --git a/src/platforms/rcore_desktop_win32.c b/src/platforms/rcore_desktop_win32.c
index 3ccd4d3bd..9b66f8c4b 100644
--- a/src/platforms/rcore_desktop_win32.c
+++ b/src/platforms/rcore_desktop_win32.c
@@ -84,29 +84,31 @@
// Types and Structures Definition
//----------------------------------------------------------------------------------
-// NOTE: appScreenSize is the last screen size requested by the app,
-// the backend must keep the client area this size (after DPI scaling is applied)
+// NOTE: appScreenSize is the last screen size requested by the app,
+// the backend must keep the client area this size (after DPI scaling is applied)
// when the window isn't fullscreen/maximized/minimized
typedef struct {
HWND hwnd; // Window handler
HDC hdc; // Graphic context handler
HGLRC glContext; // OpenGL context handler
+
// Software renderer variables
HDC hdcmem; // Memory graphic context handler
HBITMAP hbitmap; // GDI bitmap handler
unsigned int *pixels; // Pointer to pixel data buffer (BGRA format)
- LARGE_INTEGER timerFrequency;
unsigned int appScreenWidth;
unsigned int appScreenHeight;
unsigned int desiredFlags;
- bool cursorEnabled;
+
+ LARGE_INTEGER timerFrequency;
} PlatformData;
// Define WGL function pointer types (no wglext.h needed)
typedef HGLRC (WINAPI *PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC, HGLRC, const int *);
typedef BOOL (WINAPI *PFNWGLCHOOSEPIXELFORMATARBPROC)(HDC, const int *, const FLOAT *, UINT, int *, UINT *);
typedef BOOL (WINAPI *PFNWGLSWAPINTERVALEXTPROC)(int);
+typedef const char *(WINAPI *PFNWGLGETEXTENSIONSSTRINGARBPROC)(HDC hdc);
//----------------------------------------------------------------------------------
// Global Variables Definition
@@ -119,6 +121,7 @@ static PlatformData platform = { 0 }; // Platform specific data
static PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL;
static PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = NULL;
static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
+static PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = NULL;
// --------------------------------------------------------------------------------
// This part of the file contains pure functions that never access global state
@@ -133,12 +136,12 @@ static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
// Defines and Macros
//----------------------------------------------------------------------------------
#define A_TO_W_ALLOCA(outWstr, inAnsi) do { \
- size_t len = AToWLen(inAnsi); \
- outWstr = (WCHAR *)alloca(sizeof(WCHAR)*(len + 1)); \
- AToWCopy(outWstr, len, inAnsi); \
- outWstr[len] = 0; \
+ size_t outLen = AToWLen(inAnsi); \
+ outWstr = (WCHAR *)alloca(sizeof(WCHAR)*(outLen + 1)); \
+ AToWCopy(inAnsi, outWstr, outLen); \
+ outWstr[outLen] = 0; \
} while (0)
-
+
#define STYLE_MASK_ALL 0xffffffff
#define STYLE_MASK_READONLY (WS_MINIMIZE | WS_MAXIMIZE)
#define STYLE_MASK_WRITABLE (~STYLE_MASK_READONLY)
@@ -150,7 +153,7 @@ static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
#define WINDOW_STYLE_EX 0
-#define CLASS_NAME L"RaylibWindow"
+#define CLASS_NAME L"raylibWindow"
#define FLAG_MASK_OPTIONAL (FLAG_VSYNC_HINT)
#define FLAG_MASK_REQUIRED ~(FLAG_MASK_OPTIONAL)
@@ -196,93 +199,86 @@ static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004
+#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
-typedef enum { MIZED_NONE, MIZED_MIN, MIZED_MAX } Mized;
-
+// Maximize-minimize request types
typedef enum {
- UPDATE_WINDOW_FIRST,
- UPDATE_WINDOW_NORMAL,
-} UpdateWindowKind;
-
-typedef enum {
- SANITIZE_FLAGS_FIRST,
- SANITIZE_FLAGS_NORMAL,
-} SanitizeFlagsKind;
-
-typedef struct {
- HMONITOR needle;
- int index;
- int matchIndex;
- RECT rect;
-} FindMonitorContext;
+ MIZED_NONE,
+ MIZED_MIN,
+ MIZED_MAX
+} Mized;
+// Flag operations
+// NOTE: Some ops need to be deferred
typedef struct {
DWORD set;
DWORD clear;
} FlagsOp;
+// Monitor info type
+typedef struct {
+ HMONITOR needle;
+ int index;
+ int matchIndex;
+ RECT rect;
+} MonitorInfo;
+
//----------------------------------------------------------------------------------
// Module Internal Functions Declaration
//----------------------------------------------------------------------------------
-static size_t AToWLen(const char *a)
+// Get ASCII to WCHAR length
+static size_t AToWLen(const char *ascii)
{
- int sizeNeeded = MultiByteToWideChar(CP_UTF8, 0, a, -1, NULL, 0);
-
- if (sizeNeeded < 0) TRACELOG(LOG_ERROR, "Failed to calculate wide length, result=%d, error=%u", sizeNeeded, GetLastError());
+ int sizeNeeded = MultiByteToWideChar(CP_UTF8, 0, ascii, -1, NULL, 0);
+
+ if (sizeNeeded < 0) TRACELOG(LOG_ERROR, "WIN32: Failed to calculate wide length [ERROR: %u]", GetLastError());
return sizeNeeded;
}
-static void AToWCopy(wchar_t *outPtr, size_t outLen, const char *a)
+
+// Copy ASCII to WCHAR string
+static void AToWCopy(const char *ascii, wchar_t *outPtr, size_t outLen)
{
- int size = MultiByteToWideChar(CP_UTF8, 0, a, -1, outPtr, (int)outLen);
- if (size != outLen) TRACELOG(LOG_WARNING, "WIN32: Convert %zu UTF-8 chars to WCHAR but converted %zu", outLen, size);
+ int size = MultiByteToWideChar(CP_UTF8, 0, ascii, -1, outPtr, (int)outLen);
+ if (size != outLen) TRACELOG(LOG_WARNING, "WIN32: Failed to convert %i UTF-8 chars to WCHAR, converted %i chars", outLen, size);
}
static bool DecoratedFromStyle(DWORD style)
{
if (style & STYLE_FLAGS_UNDECORATED_ON)
{
- if (style & STYLE_FLAGS_UNDECORATED_OFF) TRACELOG(LOG_ERROR, "FLAGS: Style 0x%x has both undecorated on/off flags", style);
+ if (style & STYLE_FLAGS_UNDECORATED_OFF) TRACELOG(LOG_ERROR, "WIN32: FLAGS: Style 0x%x has both undecorated on/off flags", style);
return false; // Not decorated
}
DWORD masked = (style & STYLE_FLAGS_UNDECORATED_OFF);
- if (STYLE_FLAGS_UNDECORATED_OFF != masked) TRACELOG(LOG_ERROR, "FLAGS: Style 0x%x is missing these flags 0x%x", masked, masked ^ STYLE_FLAGS_UNDECORATED_OFF);
+ if (STYLE_FLAGS_UNDECORATED_OFF != masked) TRACELOG(LOG_ERROR, "WIN32: FLAGS: Style 0x%x is missing flags 0x%x", masked, masked ^ STYLE_FLAGS_UNDECORATED_OFF);
return true; // Decorated
}
-static Mized MizedFromStyle(DWORD style)
-{
- // Minimized takes precedence over maximized
- if (style & WS_MINIMIZE) return MIZED_MIN;
- if (style & WS_MAXIMIZE) return MIZED_MAX;
- return MIZED_NONE;
-}
-
-static Mized MizedFromFlags(unsigned flags)
-{
- // minimized takes precedence over maximized
- if (FLAG_CHECK(flags, FLAG_WINDOW_MINIMIZED)) return MIZED_MIN;
- if (flags & FLAG_WINDOW_MAXIMIZED) return MIZED_MAX;
- return MIZED_NONE;
-}
-
+// Get window style from required flags
static DWORD MakeWindowStyle(unsigned flags)
{
- // we don't need this since we don't have any child windows, but I guess
+ // We don't need this since we don't have any child windows, but I guess
// it improves efficiency, plus, windows adds this flag automatically anyway
// so it keeps our flags in sync with the OS
- DWORD style = WS_CLIPSIBLINGS ;
-
+ DWORD style = WS_CLIPSIBLINGS;
+
style |= (flags & FLAG_WINDOW_HIDDEN)? 0 : WS_VISIBLE;
style |= (flags & FLAG_WINDOW_RESIZABLE)? STYLE_FLAGS_RESIZABLE : 0;
style |= (flags & FLAG_WINDOW_UNDECORATED)? STYLE_FLAGS_UNDECORATED_ON : STYLE_FLAGS_UNDECORATED_OFF;
- switch (MizedFromFlags(flags))
+ // Minimized takes precedence over maximized
+ int mized = MIZED_NONE;
+ if (FLAG_CHECK(flags, FLAG_WINDOW_MINIMIZED)) mized = MIZED_MIN;
+ if (flags & FLAG_WINDOW_MAXIMIZED) mized = MIZED_MAX;
+
+ switch (mized)
{
case MIZED_NONE: break;
case MIZED_MIN: style |= WS_MINIMIZE; break;
@@ -293,15 +289,13 @@ static DWORD MakeWindowStyle(unsigned flags)
return style;
}
-// Enforces that the actual window/platform state is in sync with raylib's flags
+// Check flags state, enforces that the actual window/platform state is in sync with raylib's flags
static void CheckFlags(const char *context, HWND hwnd, DWORD flags, DWORD expectedStyle, DWORD styleCheckMask)
{
- //TRACELOG(LOG_INFO, "Verifying Flags 0x%x Style 0x%x Mask 0x%x", flags, expectedStyle & styleCheckMask, styleCheckMask);
-
DWORD styleFromFlags = MakeWindowStyle(flags);
if ((styleFromFlags & styleCheckMask) != (expectedStyle & styleCheckMask))
{
- TRACELOG(LOG_ERROR, "%s: window flags (0x%x) produced style 0x%x which != expected 0x%x (diff=0x%x, mask=0x%x)",
+ TRACELOG(LOG_ERROR, "WIN32: FLAGS: %s: window flags (0x%x) produced style 0x%x which != expected 0x%x (diff=0x%x, mask=0x%x)",
context, flags, styleFromFlags & styleCheckMask, expectedStyle & styleCheckMask,
(styleFromFlags & styleCheckMask) ^ (expectedStyle & styleCheckMask), styleCheckMask);
}
@@ -310,7 +304,7 @@ static void CheckFlags(const char *context, HWND hwnd, DWORD flags, DWORD expect
LONG actualStyle = (LONG)GetWindowLongPtrW(hwnd, GWL_STYLE);
if ((actualStyle & styleCheckMask) != (expectedStyle & styleCheckMask))
{
- TRACELOG(LOG_ERROR, "%s: expected style 0x%x but got 0x%x (diff=0x%x, mask=0x%x, lasterror=%lu)",
+ TRACELOG(LOG_ERROR, "WIN32: FLAGS: %s: expected style 0x%x but got 0x%x (diff=0x%x, mask=0x%x, lasterror=%lu)",
context, expectedStyle & styleCheckMask, actualStyle & styleCheckMask,
(expectedStyle & styleCheckMask) ^ (actualStyle & styleCheckMask),
styleCheckMask, GetLastError());
@@ -320,7 +314,7 @@ static void CheckFlags(const char *context, HWND hwnd, DWORD flags, DWORD expect
{
bool isIconic = IsIconic(hwnd);
bool styleMinimized = !!(WS_MINIMIZE & actualStyle);
- if (isIconic != styleMinimized) TRACELOG(LOG_ERROR, "IsIconic(%d) != WS_MINIMIZED(%d)", isIconic, styleMinimized);
+ if (isIconic != styleMinimized) TRACELOG(LOG_ERROR, "WIN32: FLAGS: IsIconic(%d) != WS_MINIMIZED(%d)", isIconic, styleMinimized);
}
if (styleCheckMask & WS_MAXIMIZE)
@@ -329,49 +323,32 @@ static void CheckFlags(const char *context, HWND hwnd, DWORD flags, DWORD expect
placement.length = sizeof(placement);
if (!GetWindowPlacement(hwnd, &placement))
{
- TRACELOG(LOG_ERROR, "%s failed, error=%lu", "GetWindowPlacement", GetLastError());
+ TRACELOG(LOG_ERROR, "WIN32: FLAGS: %s failed, error=%lu", "GetWindowPlacement", GetLastError());
}
bool placementMaximized = (placement.showCmd == SW_SHOWMAXIMIZED);
bool styleMaximized = WS_MAXIMIZE & actualStyle;
if (placementMaximized != styleMaximized)
{
- TRACELOG(LOG_ERROR, "maximized state desync, placement maximized=%d (showCmd=%lu) style maximized=%d",
+ TRACELOG(LOG_ERROR, "WIN32: FLAGS: Maximized state desync, placement maximized=%d (showCmd=%lu) style maximized=%d",
placementMaximized, placement.showCmd, styleMaximized);
}
}
}
-static SIZE PxFromPt2(float dpiScale, bool highdpiEnabled, int screenWidth, int screenHeight)
-{
- // Get size in pixels from points
- return (SIZE){
- highdpiEnabled? (int)((float)screenWidth*dpiScale) : screenWidth,
- highdpiEnabled? (int)((float)screenHeight*dpiScale) : screenHeight,
- };
-}
-
-static SIZE GetClientSize(HWND hwnd)
-{
- RECT rect = { 0 };
-
- if (GetClientRect(hwnd, &rect) == 0) TRACELOG(LOG_ERROR, "%s failed, error=%lu", "GetClientRect", GetLastError());
-
- return (SIZE){ rect.right, rect.bottom };
-}
-
+// Calculate window size (with borders, title-bar...) from desired client size (framebuffer size)
static SIZE CalcWindowSize(UINT dpi, SIZE clientSize, DWORD style)
{
RECT rect = { 0, 0, clientSize.cx, clientSize.cy };
-
+
int result = AdjustWindowRectExForDpi(&rect, style, 0, WINDOW_STYLE_EX, dpi);
-
- if (result == 0) TRACELOG(LOG_ERROR, "%s failed, error=%lu", "AdjustWindowRect", GetLastError());
+ if (result == 0) TRACELOG(LOG_ERROR, "WIN32: Failed to adjust window rect [ERROR: %lu]", GetLastError());
return (SIZE){ rect.right - rect.left, rect.bottom - rect.top };
}
-// returns true if the window size was updated, false otherwise
-static bool UpdateWindowSize(UpdateWindowKind kind, HWND hwnd, int width, int height, unsigned flags)
+// Update window size if required
+// NOTE: Returns true if the window size was updated, false otherwise
+static bool UpdateWindowSize(int mode, HWND hwnd, int width, int height, unsigned flags)
{
if (flags & FLAG_WINDOW_MINIMIZED) return false;
@@ -386,10 +363,10 @@ static bool UpdateWindowSize(UpdateWindowKind kind, HWND hwnd, int width, int he
MONITORINFO info = { 0 };
HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY);
info.cbSize = sizeof(info);
- if (!GetMonitorInfoW(monitor, &info)) TRACELOG(LOG_ERROR, "%s failed, error=%lu", "GetMonitorInfo", GetLastError());
+ if (!GetMonitorInfoW(monitor, &info)) TRACELOG(LOG_ERROR, "WIN32: Failed to get monitor info [ERROR: %lu]", GetLastError());
RECT windowRect = { 0 };
- if (!GetWindowRect(hwnd, &windowRect)) TRACELOG(LOG_ERROR, "%s failed, error=%lu", "GetWindowRect", GetLastError());
+ if (!GetWindowRect(hwnd, &windowRect)) TRACELOG(LOG_ERROR, "WIN32: Failed to get window rect [ERROR: %lu]", GetLastError());
if ((windowRect.left == info.rcMonitor.left) &&
(windowRect.top == info.rcMonitor.top) &&
@@ -402,33 +379,45 @@ static bool UpdateWindowSize(UpdateWindowKind kind, HWND hwnd, int width, int he
info.rcMonitor.bottom - info.rcMonitor.top,
SWP_NOOWNERZORDER))
{
- TRACELOG(LOG_ERROR, "%s failed, error=%lu", "SetWindowPos", GetLastError());
+ TRACELOG(LOG_ERROR, "WIN32: Failed to set window position [ERROR: %lu]", GetLastError());
}
return true;
}
+ // Get size in pixels from points, considering high-dpi
UINT dpi = GetDpiForWindow(hwnd);
float dpiScale = ((float)dpi)/96.0f;
bool dpiScaling = flags & FLAG_WINDOW_HIGHDPI;
- SIZE desired = PxFromPt2(dpiScale, dpiScaling, width, height);
- SIZE actual = GetClientSize(hwnd);
- if ((actual.cx == desired.cx) || (actual.cy == desired.cy)) return false;
+ SIZE desiredSize = {
+ .cx = dpiScaling? (int)((float)width*dpiScale) : width,
+ .cy = dpiScaling? (int)((float)height*dpiScale) : height
+ };
- TRACELOG(LOG_INFO, "Restoring client size from [%dx%d] to [%dx%d] (dpi:%lu dpiScaling:%d app:%ix%i)",
- actual.cx, actual.cy, desired.cx, desired.cy, dpi, dpiScaling, width, height);
+ // Get client size (framebuffer inside the window)
+ RECT rect = { 0 };
+ GetClientRect(hwnd, &rect);
+ SIZE clientSize = { rect.right, rect.bottom };
- SIZE windowSize = CalcWindowSize(dpi, desired, MakeWindowStyle(flags));
- POINT windowPos = (POINT){ 0, 0 };
+ // If client size is alread desired size, no need to update
+ if ((clientSize.cx == desiredSize.cx) || (clientSize.cy == desiredSize.cy)) return false;
+
+ TRACELOG(LOG_INFO, "WIN32: Restoring client size from [%dx%d] to [%dx%d] (dpi:%lu dpiScaling:%d app:%ix%i)",
+ clientSize.cx, clientSize.cy, desiredSize.cx, desiredSize.cy, dpi, dpiScaling, width, height);
+
+ // Calculate window size from desired framebuffer size and window flags
+ SIZE windowSize = CalcWindowSize(dpi, desiredSize, MakeWindowStyle(flags));
+ POINT windowPos = { 0 };
UINT swpFlags = SWP_NOZORDER | SWP_FRAMECHANGED;
- if (kind == UPDATE_WINDOW_FIRST)
+
+ if (mode == 0) // UPDATE_WINDOW_FIRST
{
HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY);
- if (!monitor) TRACELOG(LOG_ERROR, "%s failed, error=%lu", "MonitorFromWindow", GetLastError());
+ if (!monitor) TRACELOG(LOG_ERROR, "WIN32: Failed to get monitor from window [ERROR: %lu]", GetLastError());
- MONITORINFO info;
+ MONITORINFO info = { 0 };
info.cbSize = sizeof(info);
- if (!GetMonitorInfoW(monitor, &info)) TRACELOG(LOG_ERROR, "%s failed, error=%lu", "GetMonitorInfo", GetLastError());
+ if (!GetMonitorInfoW(monitor, &info)) TRACELOG(LOG_ERROR, "WIN32: Failed to get monitor info [ERROR: %lu]", GetLastError());
#define MAX(a,b) (((a)>(b))? (a):(b))
@@ -446,24 +435,19 @@ static bool UpdateWindowSize(UpdateWindowKind kind, HWND hwnd, int width, int he
//AdjustWindowRectEx(&rc, WS_OVERLAPPEDWINDOW, FALSE, 0);
//SetWindowPos(hwnd, NULL, windowPos.x, windowPos.y, rc.right - rc.left, rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER);
- // Old code
- //if (!SetWindowPos(hwnd, NULL, windowPos.x, windowPos.y, windowSize.cx, windowSize.cy, swpFlags))
- //{
- // TRACELOG(LOG_ERROR, "%s failed, error=%lu", "SetWindowPos", GetLastError());
- //}
-
return true;
}
+// Verify if we are running in Windows 10 version 1703 (Creators Update)
static BOOL IsWindows10Version1703OrGreaterWin32(void)
{
HMODULE ntdll = LoadLibraryW(L"ntdll.dll");
-
- DWORD (*Verify)(RTL_OSVERSIONINFOEXW*, ULONG, ULONGLONG) =
+
+ DWORD (*Verify)(RTL_OSVERSIONINFOEXW*, ULONG, ULONGLONG) =
(DWORD (*)(RTL_OSVERSIONINFOEXW*, ULONG, ULONGLONG))GetProcAddress(ntdll, "RtlVerifyVersionInfo");
if (!Verify)
{
- TRACELOG(LOG_ERROR, "%s failed, error=%lu", "GetProcAddress 'RtlVerifyVersionInfo'", GetLastError());
+ TRACELOG(LOG_ERROR, "WIN32: Failed to verify Windows version [ERROR: %lu]", GetLastError());
return 0;
}
@@ -472,11 +456,12 @@ static BOOL IsWindows10Version1703OrGreaterWin32(void)
osvi.dwMajorVersion = 10;
osvi.dwMinorVersion = 0;
osvi.dwBuildNumber = 15063; // Build 15063 corresponds to Windows 10 version 1703 (Creators Update)
+
DWORDLONG cond = 0;
VER_SET_CONDITION(cond, VER_MAJORVERSION, VER_GREATER_EQUAL);
VER_SET_CONDITION(cond, VER_MINORVERSION, VER_GREATER_EQUAL);
VER_SET_CONDITION(cond, VER_BUILDNUMBER, VER_GREATER_EQUAL);
-
+
return 0 == (*Verify)(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER, cond);
}
@@ -488,8 +473,8 @@ static void *WglGetProcAddress(const char *procname)
if ((proc == NULL) ||
// NOTE: Some GPU drivers could return following
// invalid sentinel values instead of NULL
- (proc == (void *)0x1) ||
- (proc == (void *)0x2) ||
+ (proc == (void *)0x1) ||
+ (proc == (void *)0x2) ||
(proc == (void *)0x3) ||
(proc == (void *)-1))
{
@@ -504,7 +489,8 @@ static void *WglGetProcAddress(const char *procname)
return proc;
}
-static KeyboardKey KeyFromWparam(WPARAM wparam)
+// Get key from wparam (mapping)
+static KeyboardKey GetKeyFromWparam(WPARAM wparam)
{
switch (wparam)
{
@@ -687,6 +673,7 @@ static KeyboardKey KeyFromWparam(WPARAM wparam)
}
}
+// Get cursor name
static LPCWSTR GetCursorName(int cursor)
{
LPCWSTR name = (LPCWSTR)IDC_ARROW;
@@ -710,37 +697,46 @@ static LPCWSTR GetCursorName(int cursor)
return name;
}
-static BOOL CALLBACK CountMonitorsProc(HMONITOR handle, HDC _, LPRECT rect, LPARAM lparam)
+// Count monitors process
+// NOTE: Required by GetMonitorCount()
+static BOOL CALLBACK CountMonitorsProc(HMONITOR handle, HDC hdc, LPRECT rect, LPARAM lparam)
{
int *count = (int *)lparam;
*count += 1;
+
// Always return TRUE to continue the loop, otherwise, the caller
// can't distinguish between stopping the loop and an error
return TRUE;
}
-static BOOL CALLBACK FindMonitorProc(HMONITOR handle, HDC _, LPRECT rect, LPARAM lparam)
+// Find monitor process
+// NOTE: Required by GetCurrentMonitor()
+static BOOL CALLBACK FindMonitorProc(HMONITOR handle, HDC hdc, LPRECT rect, LPARAM lparam)
{
- FindMonitorContext *c = (FindMonitorContext*)lparam;
- if (handle == c->needle)
+ MonitorInfo *monitor = (MonitorInfo *)lparam;
+
+ if (handle == monitor->needle)
{
- c->matchIndex = c->index;
- c->rect = *rect;
+ monitor->matchIndex = monitor->index;
+ monitor->rect = *rect;
}
- c->index += 1;
+ monitor->index += 1;
+
// Always return TRUE to continue the loop, otherwise, the caller
// can't distinguish between stopping the loop and an error
return TRUE;
}
-static void GetStyleChangeFlagOps(DWORD coreWindowFlags, STYLESTRUCT *ss, FlagsOp *deferredFlags)
+// Get style changed required operations flags
+// NOTE: Required for deferred operations
+static void GetStyleChangeFlagOps(DWORD coreWindowFlags, STYLESTRUCT *style, FlagsOp *deferredFlags)
{
// Check window resizable flag change
bool resizable = (coreWindowFlags & FLAG_WINDOW_RESIZABLE);
- bool resizableOld = ((ss->styleOld & STYLE_FLAGS_RESIZABLE) != 0);
- bool resizableNew = ((ss->styleNew & STYLE_FLAGS_RESIZABLE) != 0);
- if (resizable != resizableOld) TRACELOG(LOG_ERROR, "expected resizable %u but got %u", resizable, resizableOld);
+ bool resizableOld = ((style->styleOld & STYLE_FLAGS_RESIZABLE) != 0);
+ bool resizableNew = ((style->styleNew & STYLE_FLAGS_RESIZABLE) != 0);
+ if (resizable != resizableOld) TRACELOG(LOG_ERROR, "WIN32: Expected resizable %u but got %u", resizable, resizableOld);
if (resizableOld != resizableNew)
{
if (resizableNew) deferredFlags->set |= FLAG_WINDOW_RESIZABLE;
@@ -749,9 +745,9 @@ static void GetStyleChangeFlagOps(DWORD coreWindowFlags, STYLESTRUCT *ss, FlagsO
// Check window decorated flag change
bool decorated = (0 == (coreWindowFlags & FLAG_WINDOW_UNDECORATED));
- bool decoratedOld = DecoratedFromStyle(ss->styleOld);
- bool decoratedNew = DecoratedFromStyle(ss->styleNew);
- if (decorated != decoratedOld) TRACELOG(LOG_ERROR, "expected decorated %u but got %u", decorated, decoratedOld);
+ bool decoratedOld = DecoratedFromStyle(style->styleOld);
+ bool decoratedNew = DecoratedFromStyle(style->styleNew);
+ if (decorated != decoratedOld) TRACELOG(LOG_ERROR, "WIN32: Expected decorated %u but got %u", decorated, decoratedOld);
if (decoratedOld != decoratedNew)
{
if (decoratedNew) deferredFlags->clear |= FLAG_WINDOW_UNDECORATED;
@@ -760,9 +756,9 @@ static void GetStyleChangeFlagOps(DWORD coreWindowFlags, STYLESTRUCT *ss, FlagsO
// Check window hidden flag change
bool hidden = (coreWindowFlags & FLAG_WINDOW_HIDDEN);
- bool hiddenOld = ((ss->styleOld & WS_VISIBLE) == 0);
- bool hiddenNew = ((ss->styleNew & WS_VISIBLE) == 0);
- if (hidden != hiddenOld) TRACELOG(LOG_ERROR, "expected hidden %u but got %u", hidden, hiddenOld);
+ bool hiddenOld = ((style->styleOld & WS_VISIBLE) == 0);
+ bool hiddenNew = ((style->styleNew & WS_VISIBLE) == 0);
+ if (hidden != hiddenOld) TRACELOG(LOG_ERROR, "WIN32: Expected hidden %u but got %u", hidden, hiddenOld);
if (hiddenOld != hiddenNew)
{
if (hiddenNew) deferredFlags->set |= FLAG_WINDOW_HIDDEN;
@@ -770,7 +766,9 @@ static void GetStyleChangeFlagOps(DWORD coreWindowFlags, STYLESTRUCT *ss, FlagsO
}
}
-// Call when the window is rezised, returns true if the new window size should update the desired app size
+// Adopt window resize
+// NOTE: Call when the window is rezised, returns true
+// if the new window size should update the desired app size
static bool AdoptWindowResize(unsigned flags)
{
if (flags & FLAG_WINDOW_MINIMIZED) return false;
@@ -778,7 +776,7 @@ static bool AdoptWindowResize(unsigned flags)
if (flags & FLAG_FULLSCREEN_MODE) return false;
if (flags & FLAG_BORDERLESS_WINDOWED_MODE) return false;
if (!(flags & FLAG_WINDOW_RESIZABLE)) return false;
-
+
return true;
}
@@ -805,9 +803,12 @@ static void HandleRawInput(LPARAM lparam);
static void HandleWindowResize(HWND hwnd, int *width, int *height);
static void UpdateWindowStyle(HWND hwnd, unsigned desiredFlags);
-static unsigned SanitizeFlags(SanitizeFlagsKind kind, unsigned flags);
+static unsigned SanitizeFlags(int mode, unsigned flags);
static void UpdateFlags(HWND hwnd, unsigned desiredFlags, int width, int height); // Update window flags
+// Check if OpenGL extension is available
+static bool IsWglExtensionAvailable(HDC hdc, const char *extension);
+
//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
@@ -826,20 +827,14 @@ bool WindowShouldClose(void)
// Toggle fullscreen mode
void ToggleFullscreen(void)
{
- TRACELOG(LOG_WARNING, "ToggleFullscreen not implemented");
+ TRACELOG(LOG_WARNING, "WIN32: Toggle full screen functionality not implemented");
}
// Toggle borderless windowed mode
void ToggleBorderlessWindowed(void)
{
- if (CORE.Window.flags & FLAG_BORDERLESS_WINDOWED_MODE)
- {
- ClearWindowState(FLAG_BORDERLESS_WINDOWED_MODE);
- }
- else
- {
- SetWindowState(FLAG_BORDERLESS_WINDOWED_MODE);
- }
+ if (CORE.Window.flags & FLAG_BORDERLESS_WINDOWED_MODE) ClearWindowState(FLAG_BORDERLESS_WINDOWED_MODE);
+ else SetWindowState(FLAG_BORDERLESS_WINDOWED_MODE);
}
// Set window state: maximized, if resizable
@@ -858,57 +853,123 @@ void MinimizeWindow(void)
void RestoreWindow(void)
{
if ((CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) &&
- (CORE.Window.flags & FLAG_WINDOW_MINIMIZED)
- ) {
- ClearWindowState(FLAG_WINDOW_MINIMIZED);
- }
- else
- {
- ClearWindowState(FLAG_WINDOW_MINIMIZED|FLAG_WINDOW_MAXIMIZED);
- }
+ (CORE.Window.flags & FLAG_WINDOW_MINIMIZED)) ClearWindowState(FLAG_WINDOW_MINIMIZED);
+ else ClearWindowState(FLAG_WINDOW_MINIMIZED | FLAG_WINDOW_MAXIMIZED);
}
// Set window configuration state using flags
void SetWindowState(unsigned int flags)
{
- platform.desiredFlags = SanitizeFlags(SANITIZE_FLAGS_NORMAL, CORE.Window.flags | flags);
+ platform.desiredFlags = SanitizeFlags(1 /*SANITIZE_FLAGS_NORMAL*/, CORE.Window.flags | flags);
UpdateFlags(platform.hwnd, platform.desiredFlags, platform.appScreenWidth, platform.appScreenHeight);
}
// Clear window configuration state flags
void ClearWindowState(unsigned int flags)
{
- platform.desiredFlags = SanitizeFlags(SANITIZE_FLAGS_NORMAL, CORE.Window.flags & ~flags);
+ platform.desiredFlags = SanitizeFlags(1 /*SANITIZE_FLAGS_NORMAL*/, CORE.Window.flags & ~flags);
UpdateFlags(platform.hwnd, platform.desiredFlags, platform.appScreenWidth, platform.appScreenHeight);
}
// Set icon for window
void SetWindowIcon(Image image)
{
- TRACELOG(LOG_WARNING, "SetWindowIcon not implemented");
+ if (!platform.hwnd || (image.data == NULL) || (image.width <= 0) || (image.height <= 0)) return;
+
+ HDC hdc = GetDC(platform.hwnd);
+
+ // Create 32-bit BGRA DIB for color
+ BITMAPV5HEADER bi = { 0 };
+ ZeroMemory(&bi, sizeof(bi));
+ bi.bV5Size = sizeof(bi);
+ bi.bV5Width = image.width;
+ bi.bV5Height = -image.height; // Negative = top-down bitmap
+ bi.bV5Planes = 1;
+ bi.bV5BitCount = 32;
+ bi.bV5Compression = BI_BITFIELDS;
+ bi.bV5RedMask = 0x00FF0000;
+ bi.bV5GreenMask = 0x0000FF00;
+ bi.bV5BlueMask = 0x000000FF;
+ bi.bV5AlphaMask = 0xFF000000;
+
+ unsigned char *targetBits = NULL;
+ HBITMAP hColorBitmap = CreateDIBSection(hdc, (BITMAPINFO *)&bi, DIB_RGB_COLORS, (void **)&targetBits, NULL, 0);
+ if (!hColorBitmap)
+ {
+ ReleaseDC(platform.hwnd, hdc);
+ return;
+ }
+
+ // Copy RGBA > BGRA (Win32 expects BGRA)
+ for (int y = 0; y < image.height; y++)
+ {
+ for (int x = 0; x < image.width; x++)
+ {
+ int i = (y*image.width + x)*4;
+ targetBits[i + 0] = ((unsigned char *)image.data)[i + 2]; // B
+ targetBits[i + 1] = ((unsigned char *)image.data)[i + 1]; // G
+ targetBits[i + 2] = ((unsigned char *)image.data)[i + 0]; // R
+ targetBits[i + 3] = ((unsigned char *)image.data)[i + 3]; // A
+ }
+ }
+
+ // Create mask bitmap (1-bit, all opaque)
+ HBITMAP hMaskBitmap = CreateBitmap(image.width, image.height, 1, 1, NULL);
+
+ // Build icon info
+ ICONINFO ii = { 0 };
+ ZeroMemory(&ii, sizeof(ii));
+ ii.fIcon = TRUE;
+ ii.hbmMask = hMaskBitmap;
+ ii.hbmColor = hColorBitmap;
+
+ HICON hIcon = CreateIconIndirect(&ii);
+
+ // Clean up GDI bitmaps (icon keeps copies internally)
+ DeleteObject(hColorBitmap);
+ DeleteObject(hMaskBitmap);
+ ReleaseDC(platform.hwnd, hdc);
+
+ if (hIcon)
+ {
+ // Set both large and small icons
+ SendMessage(platform.hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
+ SendMessage(platform.hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
+ }
}
// Set icon for window
void SetWindowIcons(Image *images, int count)
{
- TRACELOG(LOG_WARNING, "SetWindowIcons not implemented");
+ // TODO.
}
void SetWindowTitle(const char *title)
{
CORE.Window.title = title;
-
+
WCHAR *titleWide = NULL;
A_TO_W_ALLOCA(titleWide, CORE.Window.title);
-
+
int result = SetWindowTextW(platform.hwnd, titleWide);
- if (result == 0) TRACELOG(LOG_ERROR, "%s failed, error=%lu", "SetWindowText", GetLastError());
+ if (result == 0) TRACELOG(LOG_WARNING, "WIN32: Failed to set window title [ERROR: %lu]", GetLastError());
}
// Set window position on screen (windowed mode)
void SetWindowPosition(int x, int y)
{
- TRACELOG(LOG_WARNING, "SetWindowPosition not implemented");
+ if (platform.hwnd != NULL)
+ {
+ RECT rect = { 0 };
+ if (GetWindowRect(platform.hwnd, &rect))
+ {
+ int width = rect.right - rect.left;
+ int height = rect.bottom - rect.top;
+
+ // Move the window to the new position (keeping size and z-order)
+ SetWindowPos(platform.hwnd, NULL, x, y, width, height, SWP_NOZORDER | SWP_NOACTIVATE);
+ }
+ }
}
// Set monitor for the current window
@@ -962,7 +1023,7 @@ void *GetWindowHandle(void)
int GetMonitorCount(void)
{
int count = 0;
-
+
int result = EnumDisplayMonitors(NULL, NULL, CountMonitorsProc, (LPARAM)&count);
if (result == 0) TRACELOG(LOG_ERROR, "%s failed, error=%lu", "EnumDisplayMonitors", GetLastError());
@@ -975,15 +1036,15 @@ int GetCurrentMonitor(void)
HMONITOR monitor = MonitorFromWindow(platform.hwnd, MONITOR_DEFAULTTOPRIMARY);
if (!monitor) TRACELOG(LOG_ERROR, "%s failed, error=%lu", "MonitorFromWindow", GetLastError());
- FindMonitorContext context;
- context.needle = monitor;
- context.index = 0;
- context.matchIndex = -1;
-
- int result = EnumDisplayMonitors(NULL, NULL, FindMonitorProc, (LPARAM)&context);
+ MonitorInfo info = { 0 };
+ info.needle = monitor;
+ info.index = 0;
+ info.matchIndex = -1;
+
+ int result = EnumDisplayMonitors(NULL, NULL, FindMonitorProc, (LPARAM)&info);
if (result == 0) TRACELOG(LOG_ERROR, "%s failed, error=%lu", "EnumDisplayMonitors", GetLastError());
- return context.matchIndex;
+ return info.matchIndex;
}
// Get selected monitor position
@@ -1066,7 +1127,7 @@ const char *GetClipboardText(void)
Image GetClipboardImage(void)
{
Image image = { 0 };
-
+
TRACELOG(LOG_WARNING, "GetClipboardText not implemented");
return image;
@@ -1075,26 +1136,25 @@ Image GetClipboardImage(void)
// Show mouse cursor
void ShowCursor(void)
{
- CORE.Input.Mouse.cursorHidden = false;
SetCursor(LoadCursorW(NULL, (LPCWSTR)IDC_ARROW));
+ CORE.Input.Mouse.cursorHidden = false;
}
// Hides mouse cursor
void HideCursor(void)
{
- // NOTE: we use SetCursor instead of ShowCursor because it makes it easy
- // to only hide the cursor while it's inside the client area
- CORE.Input.Mouse.cursorHidden = true;
+ // NOTE: We use SetCursor() instead of ShowCursor() because
+ // it makes it easy to only hide the cursor while it's inside the client area
SetCursor(NULL);
+ CORE.Input.Mouse.cursorHidden = true;
}
// Enables cursor (unlock cursor)
void EnableCursor(void)
{
- if (platform.cursorEnabled) TRACELOG(LOG_INFO, "EnableCursor: already enabled");
- else
+ if (CORE.Input.Mouse.cursorLocked)
{
- if (!ClipCursor(NULL)) TRACELOG(LOG_ERROR, "%s failed, error=%lu", "ClipCursor", GetLastError());
+ if (!ClipCursor(NULL)) TRACELOG(LOG_WARNING, "WIN32: Failed to clip cursor [ERROR: %lu]", GetLastError());
RAWINPUTDEVICE rid = { 0 };
rid.usUsagePage = 0x01; // HID_USAGE_PAGE_GENERIC
@@ -1102,18 +1162,17 @@ void EnableCursor(void)
rid.dwFlags = RIDEV_REMOVE; // Add to this window even in background
rid.hwndTarget = NULL;
int result = RegisterRawInputDevices(&rid, 1, sizeof(rid));
- if (result == 0) TRACELOG(LOG_ERROR, "%s failed, error=%lu", "RegisterRawInputDevices", GetLastError());
+ if (result == 0) TRACELOG(LOG_WARNING, "WIN32: Failed to register raw input devices [ERROR: %lu]", GetLastError());
ShowCursor();
- platform.cursorEnabled = true;
- TRACELOG(LOG_INFO, "EnableCursor: enabled");
+ CORE.Input.Mouse.cursorLocked = false;
}
}
// Disables cursor (lock cursor)
void DisableCursor(void)
{
- if (platform.cursorEnabled)
+ if (!CORE.Input.Mouse.cursorLocked)
{
RAWINPUTDEVICE rid = { 0 };
rid.usUsagePage = 0x01; // HID_USAGE_PAGE_GENERIC
@@ -1121,33 +1180,31 @@ void DisableCursor(void)
rid.dwFlags = RIDEV_INPUTSINK; // Add to this window even in background
rid.hwndTarget = platform.hwnd;
int result = RegisterRawInputDevices(&rid, 1, sizeof(rid));
- if (result == 0) TRACELOG(LOG_ERROR, "%s failed, error=%lu", "RegisterRawInputDevices", GetLastError());
+ if (result == 0) TRACELOG(LOG_WARNING, "WIN32: Failed to register raw input devices [ERROR: %lu]", GetLastError());
RECT clientRect = { 0 };
- if (!GetClientRect(platform.hwnd, &clientRect)) TRACELOG(LOG_ERROR, "%s failed, error=%lu", "GetClientRect", GetLastError());
+ if (!GetClientRect(platform.hwnd, &clientRect)) TRACELOG(LOG_WARNING, "WIN32: Failed to get client rectangle [ERROR: %lu]", GetLastError());
POINT topleft = { clientRect.left, clientRect.top };
- if (!ClientToScreen(platform.hwnd, &topleft)) TRACELOG(LOG_ERROR, "%s failed, error=%lu", "ClientToScreen", GetLastError());
+ if (!ClientToScreen(platform.hwnd, &topleft)) TRACELOG(LOG_WARNING, "WIN32: Failed to get client to screen size [ERROR: %lu]", GetLastError());
LONG width = clientRect.right - clientRect.left;
LONG height = clientRect.bottom - clientRect.top;
- TRACELOG(LOG_INFO, "ClipCursor client %d,%d %d,%d (topleft %d,%d)",
+ TRACELOG(LOG_INFO, "WIN32: Clip cursor client rect: [%d,%d %d,%d], top-left: (%d,%d)",
clientRect.left, clientRect.top, clientRect.right, clientRect.bottom, topleft.x, topleft.y);
-
+
LONG centerX = topleft.x + width/2;
LONG centerY = topleft.y + height/2;
RECT clipRect = { centerX, centerY, centerX + 1, centerY + 1 };
- if (!ClipCursor(&clipRect)) TRACELOG(LOG_ERROR, "%s failed, error=%lu", "ClipCursor", GetLastError());
+ if (!ClipCursor(&clipRect)) TRACELOG(LOG_WARNING, "WIN32: Failed to clip cursor [ERROR: %lu]", GetLastError());
CORE.Input.Mouse.previousPosition = (Vector2){ 0, 0 };
CORE.Input.Mouse.currentPosition = (Vector2){ 0, 0 };
HideCursor();
- platform.cursorEnabled = false;
- TRACELOG(LOG_INFO, "DisableCursor: disabled");
+ CORE.Input.Mouse.cursorLocked = true;
}
- else TRACELOG(LOG_INFO, "DisableCursor: already disabled");
}
// Swap back buffer with front buffer (screen drawing)
@@ -1163,8 +1220,8 @@ void SwapScreenBuffer(void)
InvalidateRect(platform.hwnd, NULL, FALSE);
UpdateWindow(platform.hwnd);
#else
- if (!SwapBuffers(platform.hdc)) TRACELOG(LOG_ERROR, "%s failed, error=%lu", "SwapBuffers", GetLastError());
- if (!ValidateRect(platform.hwnd, NULL)) TRACELOG(LOG_ERROR, "%s failed, error=%lu", "ValidateRect", GetLastError());
+ if (!SwapBuffers(platform.hdc)) TRACELOG(LOG_ERROR, "WIN32: Failed to swap buffers [ERROR: %lu]", GetLastError());
+ if (!ValidateRect(platform.hwnd, NULL)) TRACELOG(LOG_ERROR, "WIN32: Failed to validate screen rect [ERROR: %lu]", GetLastError());
#endif
}
@@ -1216,7 +1273,7 @@ void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float d
// Set mouse position XY
void SetMousePosition(int x, int y)
{
- if (platform.cursorEnabled)
+ if (!CORE.Input.Mouse.cursorLocked)
{
CORE.Input.Mouse.currentPosition = (Vector2){ (float)x, (float)y };
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
@@ -1230,7 +1287,7 @@ void SetMouseCursor(int cursor)
{
LPCWSTR cursorName = GetCursorName(cursor);
HCURSOR hcursor = LoadCursorW(NULL, cursorName);
- if (!hcursor) TRACELOG(LOG_ERROR, "LoadCursor %d (win32 %d) failed, error=%lu", cursor, (size_t)cursorName, GetLastError());
+ if (!hcursor) TRACELOG(LOG_ERROR, "WIN32: Failed to load requested cursor [ERROR: %lu]", GetLastError());
SetCursor(hcursor);
CORE.Input.Mouse.cursorHidden = false;
@@ -1289,7 +1346,7 @@ void PollInputEvents(void)
//----------------------------------------------------------------------------------
// Initialize modern OpenGL context
-// NOTE: We need to create a dummy context first to query requried extensions
+// NOTE: We need to create a dummy context first to query required extensions
HGLRC InitOpenGL(HWND hwnd, HDC hdc)
{
// First, create a dummy context to get WGL extensions
@@ -1319,6 +1376,7 @@ HGLRC InitOpenGL(HWND hwnd, HDC hdc)
wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
+ wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
// Setup modern pixel format if extension is available
if (wglChoosePixelFormatARB)
@@ -1353,10 +1411,52 @@ HGLRC InitOpenGL(HWND hwnd, HDC hdc)
HGLRC realContext = NULL;
if (wglCreateContextAttribsARB)
{
+ int glContextVersionMajor = 1;
+ int glContextVersionMinor = 1;
+ int glContextProfile = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
+
+ if (rlGetVersion() == RL_OPENGL_21) // Request OpenGL 2.1 context
+ {
+ glContextVersionMajor = 2;
+ glContextVersionMinor = 1;
+ }
+ else if (rlGetVersion() == RL_OPENGL_33) // Request OpenGL 3.3 context
+ {
+ glContextVersionMajor = 3;
+ glContextVersionMinor = 3;
+ }
+ else if (rlGetVersion() == RL_OPENGL_43) // Request OpenGL 4.3 context
+ {
+ glContextVersionMajor = 4;
+ glContextVersionMinor = 3;
+ }
+ else if (rlGetVersion() == RL_OPENGL_ES_20) // Request OpenGL ES 2.0 context
+ {
+ if (IsWglExtensionAvailable(platform.hdc, "WGL_EXT_create_context_es_profile") ||
+ IsWglExtensionAvailable(platform.hdc, "WGL_EXT_create_context_es2_profile"))
+ {
+ glContextVersionMajor = 2;
+ glContextVersionMinor = 0;
+ glContextProfile = WGL_CONTEXT_ES_PROFILE_BIT_EXT;
+ }
+ else TRACELOG(LOG_WARNING, "GL: OpenGL ES context not supported by GPU");
+ }
+ else if (rlGetVersion() == RL_OPENGL_ES_30) // Request OpenGL ES 3.0 context
+ {
+ if (IsWglExtensionAvailable(platform.hdc, "WGL_EXT_create_context_es_profile") ||
+ IsWglExtensionAvailable(platform.hdc, "WGL_EXT_create_context_es2_profile"))
+ {
+ glContextVersionMajor = 3;
+ glContextVersionMinor = 0;
+ glContextProfile = WGL_CONTEXT_ES_PROFILE_BIT_EXT;
+ }
+ else TRACELOG(LOG_WARNING, "GL: OpenGL ES context not supported by GPU");
+ }
+
int contextAttribs[] = {
- WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
- WGL_CONTEXT_MINOR_VERSION_ARB, 3,
- WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, // WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, WGL_CONTEXT_ES_PROFILE_BIT_EXT (if supported)
+ WGL_CONTEXT_MAJOR_VERSION_ARB, glContextVersionMajor,
+ WGL_CONTEXT_MINOR_VERSION_ARB, glContextVersionMinor,
+ WGL_CONTEXT_PROFILE_MASK_ARB, glContextProfile, // WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, WGL_CONTEXT_ES_PROFILE_BIT_EXT (if supported)
//WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB | WGL_CONTEXT_DEBUG_BIT_ARB [glDebugMessageCallback()]
0 // Terminator
};
@@ -1387,9 +1487,11 @@ HGLRC InitOpenGL(HWND hwnd, HDC hdc)
// Initialize platform: graphics, inputs and more
int InitPlatform(void)
{
- platform.desiredFlags = SanitizeFlags(SANITIZE_FLAGS_FIRST, CORE.Window.flags);
+ int result = 0;
+
platform.appScreenWidth = CORE.Window.screen.width;
platform.appScreenHeight = CORE.Window.screen.height;
+ platform.desiredFlags = SanitizeFlags(0 /*SANITIZE_FLAGS_FIRST*/, CORE.Window.flags);
// NOTE: From this point CORE.Window.flags should always reflect the actual state of the window
CORE.Window.flags = FLAG_WINDOW_HIDDEN | (platform.desiredFlags & FLAG_MASK_NO_UPDATE);
@@ -1400,7 +1502,7 @@ int InitPlatform(void)
if (IsWindows10Version1703OrGreaterWin32())
{
TRACELOG(LOG_INFO, "DpiAware: >=Win10Creators");
- if (!SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2))
+ if (!SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2))
TRACELOG(LOG_ERROR, "%s failed, error %u", "SetProcessDpiAwarenessContext", GetLastError());
}
else
@@ -1411,37 +1513,56 @@ int InitPlatform(void)
}
*/
+ HINSTANCE hInstance = GetModuleHandleW(0);
+
+ // Define window class
WNDCLASSEXW windowClass = {
.cbSize = sizeof(WNDCLASSEXW),
.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC,
.lpfnWndProc = WndProc, // Custom procedure assigned
.cbWndExtra = sizeof(LONG_PTR), // extra space for the Tuple object ptr
- .hInstance = GetModuleHandleW(0),
+ .hInstance = hInstance,
.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW), // TODO: Audit if we want to set this since we're implementing WM_SETCURSOR
- .lpszClassName = CLASS_NAME //L"GLWindowClass";
+ .lpszClassName = CLASS_NAME // Class name: L"raylibWindow"
};
- // Register window class
- if (RegisterClassExW(&windowClass) == 0) TRACELOG(LOG_ERROR, "%s failed, error=%lu", "RegisterClass", GetLastError());
+ // Load user-provided icon if available
+ // NOTE: raylib resource file defaults to GLFW_ICON id, so looking for same identifier
+ windowClass.hIcon = LoadImageW(hInstance, L"GLFW_ICON", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
+ if (!windowClass.hIcon) windowClass.hIcon = LoadImageW(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
-/*
- // TODO: Remove or move this code that sets the display size; should maybe go somewhere in WndProc?
+ // Register window class
+ result = (int)RegisterClassExW(&windowClass);
+ if (result == 0) TRACELOG(LOG_ERROR, "WIN32: Failed to register window class [ERROR: %lu]", GetLastError());
+
+ // Get primary monitor info
POINT primaryTopLeft = { 0 };
HMONITOR monitor = MonitorFromPoint(primaryTopLeft, MONITOR_DEFAULTTOPRIMARY);
if (monitor != NULL)
{
- MONITORINFO info;
+ MONITORINFO info = { 0 };
info.cbSize = sizeof(info);
- if (!GetMonitorInfoW(monitor, &info)) TRACELOG(LOG_WARNING, "%s failed, error: %u", "GetMonitorInfo", GetLastError());
+ result = (int)GetMonitorInfoW(monitor, &info);
+
+ if (result == 0) TRACELOG(LOG_WARNING, "WIN32: DISPLAY: Failed to get monitor info [ERROR: %u]", GetLastError());
else
{
CORE.Window.display.width = info.rcMonitor.right - info.rcMonitor.left;
CORE.Window.display.height = info.rcMonitor.bottom - info.rcMonitor.top;
}
}
- else TRACELOG(LOG_WARNING, "MonitorFromPoint, error: %s", GetLastError());
-*/
-
+ else TRACELOG(LOG_WARNING, "WIN32: DISPLAY: Failed to get primary monitor from point [ERROR: %u]", GetLastError());
+
+ // Adjust the window rectangle so the *client area* matches desired size
+ // NOTE: Window width/height includes borders and title-bar
+ DWORD style = WS_OVERLAPPEDWINDOW;
+ RECT rect = { 0, 0, platform.appScreenWidth, platform.appScreenHeight };
+ AdjustWindowRect(&rect, style, FALSE);
+ //AdjustWindowRectEx(&rect, WS_OVERLAPPEDWINDOW, FALSE, WINDOW_STYLE_EX);
+ //AdjustWindowRectExForDpi(&rect, style, FALSE, WINDOW_STYLE_EX, dpi);
+ int windowWidth = rect.right - rect.left;
+ int windowHeight = rect.bottom - rect.top;
+
// Create window
// NOTE: Title string needs to be converted to WCHAR
WCHAR *titleWide = NULL;
@@ -1454,13 +1575,13 @@ int InitPlatform(void)
titleWide,
MakeWindowStyle(CORE.Window.flags), // WS_OVERLAPPEDWINDOW | WS_VISIBLE
CW_USEDEFAULT, CW_USEDEFAULT,
- platform.appScreenWidth, platform.appScreenHeight, // TODO: Window size [width, height], needs to be updated?
+ windowWidth, windowHeight, // TODO: Window size [width, height], needs to be updated?
NULL, NULL,
GetModuleHandleW(NULL), NULL);
if (!platform.hwnd)
{
- TRACELOG(LOG_ERROR, "%s failed, error=%lu", "CreateWindow", GetLastError());
+ TRACELOG(LOG_ERROR, "WIN32: WINDOW: Failed to create window [ERROR: %lu]", GetLastError());
return -1;
}
@@ -1475,11 +1596,11 @@ int InitPlatform(void)
// Initialize software framebuffer
BITMAPINFO bmi = { 0 };
ZeroMemory(&bmi, sizeof(bmi));
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmi.bmiHeader.biWidth = platform.appScreenWidth;
- bmi.bmiHeader.biHeight = -(int)(platform.appScreenHeight); // Top-down bitmap
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biBitCount = 32; // 32-bit BGRA
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = platform.appScreenWidth;
+ bmi.bmiHeader.biHeight = -(int)(platform.appScreenHeight); // Top-down bitmap
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32; // 32-bit BGRA
bmi.bmiHeader.biCompression = BI_RGB;
platform.hdcmem = CreateCompatibleDC(platform.hdc);
@@ -1499,11 +1620,12 @@ int InitPlatform(void)
}
CORE.Window.ready = true;
-
- // TODO: Should this function be called before or after drawing context is created? --> After swInit() called!
- //UpdateWindowSize(UPDATE_WINDOW_FIRST, platform.hwnd, platform.appScreenWidth, platform.appScreenHeight, platform.desiredFlags);
+
+ // Update flags (in case of deferred state change required)
UpdateFlags(platform.hwnd, platform.desiredFlags, platform.appScreenWidth, platform.appScreenHeight);
+ CORE.Window.render.width = CORE.Window.screen.width;
+ CORE.Window.render.height = CORE.Window.screen.height;
CORE.Window.currentFbo.width = CORE.Window.render.width;
CORE.Window.currentFbo.height = CORE.Window.render.height;
TRACELOG(LOG_INFO, "DISPLAY: Device initialized successfully");
@@ -1512,20 +1634,32 @@ int InitPlatform(void)
TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height);
TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y);
- CORE.Storage.basePath = GetWorkingDirectory();
+ if (rlGetVersion() == RL_OPENGL_11_SOFTWARE) // Using software renderer
+ {
+ TRACELOG(LOG_INFO, "GL: OpenGL device information:");
+ TRACELOG(LOG_INFO, " > Vendor: %s", "raylib");
+ TRACELOG(LOG_INFO, " > Renderer: %s", "rlsw - OpenGL 1.1 Software Renderer");
+ TRACELOG(LOG_INFO, " > Version: %s", "1.0");
+ TRACELOG(LOG_INFO, " > GLSL: %s", "NOT SUPPORTED");
+ }
+ // Initialize timming system
+ //----------------------------------------------------------------------------
LARGE_INTEGER time = { 0 };
QueryPerformanceCounter(&time);
QueryPerformanceFrequency(&platform.timerFrequency);
CORE.Time.base = time.QuadPart;
InitTimer();
-
- // TODO: Enable cursor? -> Use default value as 0
- platform.cursorEnabled = true;
+ //----------------------------------------------------------------------------
+
+ // Initialize storage system
+ //----------------------------------------------------------------------------
+ CORE.Storage.basePath = GetWorkingDirectory();
+ //----------------------------------------------------------------------------
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP: WIN32: Initialized successfully");
-
+
return 0;
}
@@ -1535,7 +1669,7 @@ void ClosePlatform(void)
if (platform.hwnd)
{
int result = DestroyWindow(platform.hwnd);
- if (result == 0) TRACELOG(LOG_WARNING, "WIN32: Error on window destroy: %u", GetLastError());
+ if (result == 0) TRACELOG(LOG_WARNING, "WIN32: WINDOW: Failed on window destroy [ERROR: %u]", GetLastError());
platform.hwnd = NULL;
}
}
@@ -1556,7 +1690,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara
FlagsOp flagsOp = { 0 };
FlagsOp *deferredFlags = &flagsOp;
-
+
// Message processing
//------------------------------------------------------------------------------------
switch (msg)
@@ -1572,13 +1706,13 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara
// Clean up for window destruction
if (rlGetVersion() == RL_OPENGL_11_SOFTWARE) // Using software renderer
{
- if (platform.hdcmem)
+ if (platform.hdcmem)
{
DeleteDC(platform.hdcmem);
platform.hdcmem = NULL;
}
- if (platform.hbitmap)
+ if (platform.hbitmap)
{
DeleteObject(platform.hbitmap); // Clears platform.pixels data
platform.hbitmap = NULL;
@@ -1616,9 +1750,9 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara
if (CORE.Window.flags & FLAG_WINDOW_RESIZABLE)
{
// TODO: Enforce min/max size
- }
- else TRACELOG(LOG_WARNING, "WINDOW: Trying to resize a non-resizable window");
-
+ }
+ else TRACELOG(LOG_WARNING, "WIN32: WINDOW: Trying to resize a non-resizable window");
+
result = TRUE;
} break;
case WM_STYLECHANGING:
@@ -1629,19 +1763,22 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara
GetStyleChangeFlagOps(CORE.Window.flags, ss, deferredFlags);
UINT dpi = GetDpiForWindow(hwnd);
- SIZE clientSize = GetClientSize(hwnd);
+ // Get client size (framebuffer inside the window)
+ RECT rect = { 0 };
+ GetClientRect(hwnd, &rect);
+ SIZE clientSize = { rect.right, rect.bottom };
SIZE oldSize = CalcWindowSize(dpi, clientSize, ss->styleOld);
SIZE newSize = CalcWindowSize(dpi, clientSize, ss->styleNew);
-
+
if (oldSize.cx != newSize.cx || oldSize.cy != newSize.cy)
{
- TRACELOG(LOG_INFO, "resize from style change: %dx%d to %dx%d", oldSize.cx, oldSize.cy, newSize.cx, newSize.cy);
-
+ TRACELOG(LOG_INFO, "WIN32: WINDOW: Resize from style change [%dx%d] to [%dx%d]", oldSize.cx, oldSize.cy, newSize.cx, newSize.cy);
+
if (CORE.Window.flags & FLAG_WINDOW_MAXIMIZED)
{
// looks like windows will automatically "unminimize" a window
// if a style changes modifies it's size
- TRACELOG(LOG_INFO, "style change modifed window size, removing maximized flag");
+ TRACELOG(LOG_INFO, "WIN32: WINDOW: Style change modifed window size, removing maximized flag");
deferredFlags->clear |= FLAG_WINDOW_MAXIMIZED;
}
}
@@ -1650,27 +1787,20 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara
case WM_WINDOWPOSCHANGING:
{
WINDOWPOS *pos = (WINDOWPOS *)lparam;
- if (pos->flags & SWP_SHOWWINDOW)
- {
- //if (pos->flags & SWP_HIDEWINDOW) abort();
- deferredFlags->clear |= FLAG_WINDOW_HIDDEN;
- }
- else if (pos->flags & SWP_HIDEWINDOW)
- {
- deferredFlags->set |= FLAG_WINDOW_HIDDEN;
- }
+ if (pos->flags & SWP_SHOWWINDOW) deferredFlags->clear |= FLAG_WINDOW_HIDDEN;
+ else if (pos->flags & SWP_HIDEWINDOW) deferredFlags->set |= FLAG_WINDOW_HIDDEN;
Mized mized = MIZED_NONE;
bool isIconic = IsIconic(hwnd);
bool styleMinimized = !!(WS_MINIMIZE & GetWindowLongPtrW(hwnd, GWL_STYLE));
- if (isIconic != styleMinimized) TRACELOG(LOG_WARNING, "IsIconic(%d) != WS_MINIMIZED(%d)", isIconic, styleMinimized);
-
+ if (isIconic != styleMinimized) TRACELOG(LOG_WARNING, "WIN32: IsIconic state different from WS_MINIMIZED state");
+
if (isIconic) mized = MIZED_MIN;
else
{
WINDOWPLACEMENT placement;
placement.length = sizeof(placement);
- if (!GetWindowPlacement(hwnd, &placement)) TRACELOG(LOG_ERROR, "%s failed, error=%lu", "GetWindowPlacement", GetLastError());
+ if (!GetWindowPlacement(hwnd, &placement)) TRACELOG(LOG_ERROR, "WIN32: WINDOW: FAiled to get monitor placement [ERROR: %lu]", GetLastError());
if (placement.showCmd == SW_SHOWMAXIMIZED) mized = MIZED_MAX;
}
@@ -1683,19 +1813,13 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara
HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY);
MONITORINFO info;
info.cbSize = sizeof(info);
- if (!GetMonitorInfoW(monitor, &info)) TRACELOG(LOG_ERROR, "%s failed, error=%lu", "GetMonitorInfo", GetLastError());
+ if (!GetMonitorInfoW(monitor, &info)) TRACELOG(LOG_ERROR, "WIN32: MONITOR: Failed to get monitor info [ERROR: %lu]", GetLastError());
if ((pos->x == info.rcMonitor.left) &&
(pos->y == info.rcMonitor.top) &&
(pos->cx == (info.rcMonitor.right - info.rcMonitor.left)) &&
- (pos->cy == (info.rcMonitor.bottom - info.rcMonitor.top)))
- {
- deferredFlags->set |= FLAG_BORDERLESS_WINDOWED_MODE;
- }
- else
- {
- deferredFlags->clear |= FLAG_BORDERLESS_WINDOWED_MODE;
- }
+ (pos->cy == (info.rcMonitor.bottom - info.rcMonitor.top))) deferredFlags->set |= FLAG_BORDERLESS_WINDOWED_MODE;
+ else deferredFlags->clear |= FLAG_BORDERLESS_WINDOWED_MODE;
} break;
case MIZED_MIN:
@@ -1739,29 +1863,30 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara
float dpiScale = ((float)newDpi)/96.0f;
bool dpiScaling = CORE.Window.flags & FLAG_WINDOW_HIGHDPI;
- SIZE desired = PxFromPt2(dpiScale, dpiScaling, platform.appScreenWidth, platform.appScreenHeight);
+ // Get size in pixels from points
+ SIZE desired = {
+ .cx = dpiScaling? (int)((float)platform.appScreenWidth*dpiScale) : platform.appScreenWidth,
+ .cy = dpiScaling? (int)((float)platform.appScreenHeight*dpiScale) : platform.appScreenHeight
+ };
inoutSize->cx = desired.cx;
inoutSize->cy = desired.cy;
-
+
result = TRUE;
} break;
case WM_DPICHANGED:
{
- RECT *suggestedRect = (RECT*)lparam;
+ RECT *suggestedRect = (RECT *)lparam;
+
// Never set the window size to anything other than the suggested rect here
// Doing so can cause a window to stutter between monitors when transitioning between them
- if (!SetWindowPos(hwnd, NULL,
- suggestedRect->left,
- suggestedRect->top,
- suggestedRect->right - suggestedRect->left,
- suggestedRect->bottom - suggestedRect->top,
- SWP_NOZORDER | SWP_NOACTIVATE))
- {
- TRACELOG(LOG_ERROR, "%s failed, error=%lu", "SetWindowPos", GetLastError());
- }
+ int result = (int)SetWindowPos(hwnd, NULL, suggestedRect->left, suggestedRect->top,
+ suggestedRect->right - suggestedRect->left, suggestedRect->bottom - suggestedRect->top, SWP_NOZORDER | SWP_NOACTIVATE);
+ if (result == 0) TRACELOG(LOG_ERROR, "Failed to set window position [ERROR: %lu]", GetLastError());
+
} break;
case WM_SETCURSOR:
{
+ // Called when mouse moves, enters/leaves window...
if (LOWORD(lparam) == HTCLIENT)
{
SetCursor(CORE.Input.Mouse.cursorHidden? NULL : LoadCursorW(NULL, (LPCWSTR)IDC_ARROW));
@@ -1789,7 +1914,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara
} break;
case WM_MOUSEMOVE:
{
- if (platform.cursorEnabled)
+ if (!CORE.Input.Mouse.cursorLocked)
{
CORE.Input.Mouse.currentPosition.x = (float)GET_X_LPARAM(lparam);
CORE.Input.Mouse.currentPosition.y = (float)GET_Y_LPARAM(lparam);
@@ -1804,7 +1929,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara
case WM_RBUTTONUP : HandleMouseButton(MOUSE_BUTTON_RIGHT, 0); break;
case WM_MBUTTONDOWN: HandleMouseButton(MOUSE_BUTTON_MIDDLE, 1); break;
case WM_MBUTTONUP : HandleMouseButton(MOUSE_BUTTON_MIDDLE, 0); break;
- case WM_XBUTTONDOWN:
+ case WM_XBUTTONDOWN:
{
switch (HIWORD(wparam))
{
@@ -1833,37 +1958,29 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara
}
//------------------------------------------------------------------------------------
- // Sanity check
- if (platform.hwnd == hwnd)
- {
- CheckFlags("After WndProc", hwnd, CORE.Window.flags, MakeWindowStyle(CORE.Window.flags), mask);
- }
+ // Sanity check for flags
+ if (platform.hwnd == hwnd) CheckFlags("After WndProc", hwnd, CORE.Window.flags, MakeWindowStyle(CORE.Window.flags), mask);
// Operations to execute after the above check
- if (flagsOp.set & flagsOp.clear)
- {
- TRACELOG(LOG_ERROR, "the flags 0x%x were both set and cleared!", flagsOp.set & flagsOp.clear);
- }
+ if (flagsOp.set & flagsOp.clear) TRACELOG(LOG_WARNING, "WIN32: FLAGS: Flags 0x%x were both set and cleared", flagsOp.set & flagsOp.clear);
DWORD save = CORE.Window.flags;
CORE.Window.flags |= flagsOp.set;
CORE.Window.flags &= ~flagsOp.clear;
- if (save != CORE.Window.flags)
- {
- TRACELOG(LOG_DEBUG, "DeferredFlags: 0x%x > 0x%x (diff 0x%x)", save, CORE.Window.flags, save ^ CORE.Window.flags);
- }
+ if (save != CORE.Window.flags) TRACELOG(LOG_DEBUG, "WIN32: FLAGS: Current deferred flags: 0x%x > 0x%x (diff 0x%x)", save, CORE.Window.flags, save ^ CORE.Window.flags);
return result;
}
+// Handle keyboard input event
static void HandleKey(WPARAM wparam, LPARAM lparam, char state)
{
- KeyboardKey key = KeyFromWparam(wparam);
-
+ KeyboardKey key = GetKeyFromWparam(wparam);
+
// TODO: Use scancode?
//BYTE scancode = lparam >> 16;
//TRACELOG(LOG_INFO, "KEY key=%d vk=%lu scan=%u = %u", key, wparam, scancode, state);
-
+
if (key != KEY_NULL)
{
CORE.Input.Keyboard.currentKeyState[key] = state;
@@ -1875,22 +1992,25 @@ static void HandleKey(WPARAM wparam, LPARAM lparam, char state)
// TODO: Add key to the queue as well?
}
+// Handle mouse button input event
static void HandleMouseButton(int button, char state)
{
+ // Register current mouse button state
CORE.Input.Mouse.currentButtonState[button] = state;
CORE.Input.Touch.currentTouchState[button] = state;
}
+// Handle raw input event
static void HandleRawInput(LPARAM lparam)
{
RAWINPUT input = { 0 };
UINT inputSize = sizeof(input);
UINT size = GetRawInputData((HRAWINPUT)lparam, RID_INPUT, &input, &inputSize, sizeof(RAWINPUTHEADER));
-
- if (size == (UINT)-1) TRACELOG(LOG_ERROR, "%s failed, error=%lu", "GetRawInputData", GetLastError());
-
- if (input.header.dwType != RIM_TYPEMOUSE) TRACELOG(LOG_ERROR, "Unexpected WM_INPUT type %lu", input.header.dwType);
+
+ if (size == (UINT)-1) TRACELOG(LOG_ERROR, "WIN32: Failed to get raw input data [ERROR: %lu]", GetLastError());
+
+ if (input.header.dwType != RIM_TYPEMOUSE) TRACELOG(LOG_ERROR, "WIN32: Unexpected WM_INPUT type %lu", input.header.dwType);
if (input.data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE) TRACELOG(LOG_ERROR, "TODO: handle absolute mouse inputs!");
@@ -1904,16 +2024,19 @@ static void HandleRawInput(LPARAM lparam)
//if (CORE.Input.Mouse.currentPosition.y != 0) abort();
}
+// Handle window resizing event
static void HandleWindowResize(HWND hwnd, int *width, int *height)
{
if (CORE.Window.flags & FLAG_WINDOW_MINIMIZED) return;
- SIZE clientSize = GetClientSize(hwnd);
+ // Get client size (framebuffer inside the window)
+ RECT rect = { 0 };
+ GetClientRect(hwnd, &rect);
+ SIZE clientSize = { rect.right, rect.bottom };
- //TRACELOG(LOG_DEBUG, "WINDOW: New widow client size: [%lux%lu]", clientSize.cx, clientSize.cy);
-
- //CORE.Window.currentFbo.width = clientSize.cx;
- //CORE.Window.currentFbo.height = clientSize.cy;
+ // TODO: Update framebuffer on resize
+ CORE.Window.currentFbo.width = (int)clientSize.cx;
+ CORE.Window.currentFbo.height = (int)clientSize.cy;
//glViewport(0, 0, clientSize.cx, clientSize.cy);
//SetupFramebuffer(0, 0);
@@ -1925,18 +2048,16 @@ static void HandleWindowResize(HWND hwnd, int *width, int *height)
unsigned int screenHeight = highdpi? (unsigned int)(((float)clientSize.cy)/dpiScale) : clientSize.cy;
CORE.Window.screen.width = screenWidth;
CORE.Window.screen.height = screenHeight;
-
+
if (AdoptWindowResize(CORE.Window.flags))
{
- TRACELOG(LOG_DEBUG, "WINDOW: Updating app size to %ix%i from window resize", screenWidth, screenHeight);
+ TRACELOG(LOG_DEBUG, "WIN32: WINDOW: Updating app size to [%ix%i] from window resize", screenWidth, screenHeight);
*width = screenWidth;
*height = screenHeight;
}
- CORE.Window.screenScale = MatrixScale(
- (float)CORE.Window.render.width/CORE.Window.screen.width,
- (float)CORE.Window.render.height/CORE.Window.screen.height,
- 1.0f);
+ CORE.Window.screenScale = MatrixScale( (float)CORE.Window.render.width/CORE.Window.screen.width,
+ (float)CORE.Window.render.height/CORE.Window.screen.height, 1.0f);
}
// Update window style
@@ -1944,22 +2065,28 @@ static void UpdateWindowStyle(HWND hwnd, unsigned desiredFlags)
{
DWORD current = STYLE_MASK_WRITABLE & MakeWindowStyle(CORE.Window.flags);
DWORD desired = STYLE_MASK_WRITABLE & MakeWindowStyle(desiredFlags);
-
+
if (current != desired)
{
SetLastError(0);
DWORD previous = STYLE_MASK_WRITABLE & SetWindowLongPtrW(hwnd, GWL_STYLE, desired);
if (previous != current)
{
- TRACELOG(LOG_ERROR, "SetWindowLong returned writable flags 0x%x but expected 0x%x (diff=0x%x, error=%lu)",
+ TRACELOG(LOG_ERROR, "WIN32: WINDOW: SetWindowLongPtr() returned writable flags 0x%x but expected 0x%x (diff=0x%x, error=%lu)",
previous, current, previous ^ current, GetLastError());
}
CheckFlags("UpdateWindowStyle", hwnd, desiredFlags, desired, STYLE_MASK_WRITABLE);
}
- Mized currentMized = MizedFromStyle(MakeWindowStyle(CORE.Window.flags));
- Mized desiredMized = MizedFromStyle(MakeWindowStyle(desiredFlags));
+ // Minimized takes precedence over maximized
+ Mized currentMized = MIZED_NONE;
+ Mized desiredMized = MIZED_NONE;
+ if (CORE.Window.flags & WS_MINIMIZE) currentMized = MIZED_MIN;
+ else if (CORE.Window.flags & WS_MAXIMIZE) currentMized = MIZED_MAX;
+ if (desiredFlags & WS_MINIMIZE) currentMized = MIZED_MIN;
+ else if (desiredFlags & WS_MAXIMIZE) currentMized = MIZED_MAX;
+
if (currentMized != desiredMized)
{
switch (desiredMized)
@@ -1972,24 +2099,21 @@ static void UpdateWindowStyle(HWND hwnd, unsigned desiredFlags)
}
// Sanitize flags
-static unsigned SanitizeFlags(SanitizeFlagsKind kind, unsigned flags)
+static unsigned SanitizeFlags(int mode, unsigned flags)
{
if ((flags & FLAG_WINDOW_MAXIMIZED) && (flags & FLAG_BORDERLESS_WINDOWED_MODE))
{
- TRACELOG(LOG_INFO, "borderless windows mode is overriding maximized");
+ TRACELOG(LOG_WARNING, "WIN32: WINDOW: Borderless windows mode overriding maximized window flag");
flags &= ~FLAG_WINDOW_MAXIMIZED;
}
- switch (kind)
+ if (mode == 1)
{
- case SANITIZE_FLAGS_FIRST: break;
- case SANITIZE_FLAGS_NORMAL:
- if ((flags & FLAG_MSAA_4X_HINT) && (!(CORE.Window.flags & FLAG_MSAA_4X_HINT)))
- {
- TRACELOG(LOG_WARNING, "WINDOW: MSAA can only be configured before window initialization");
- flags &= ~FLAG_MSAA_4X_HINT;
- }
- break;
+ if ((flags & FLAG_MSAA_4X_HINT) && (!(CORE.Window.flags & FLAG_MSAA_4X_HINT)))
+ {
+ TRACELOG(LOG_WARNING, "WIN32: WINDOW: MSAA can only be configured before window initialization");
+ flags &= ~FLAG_MSAA_4X_HINT;
+ }
}
return flags;
@@ -2018,16 +2142,15 @@ static void UpdateFlags(HWND hwnd, unsigned desiredFlags, int width, int height)
CORE.Window.flags |= (desiredFlags & FLAG_MASK_NO_UPDATE);
int vsync = (CORE.Window.flags & FLAG_VSYNC_HINT)? 1 : 0;
- PFNWGLSWAPINTERVALEXTPROC wglSwapInterval = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
- if (wglSwapInterval)
+ if (wglSwapIntervalEXT)
{
- (*wglSwapInterval)(vsync);
+ (*wglSwapIntervalEXT)(vsync);
if (vsync) CORE.Window.flags |= FLAG_VSYNC_HINT;
else CORE.Window.flags &= ~FLAG_VSYNC_HINT;
}
// TODO: Review all this code...
- DWORD previousStyle;
+ DWORD previousStyle = 0;
for (unsigned attempt = 1; ; attempt++)
{
CheckFlags("UpdateFlags", hwnd, CORE.Window.flags, MakeWindowStyle(CORE.Window.flags), STYLE_MASK_ALL);
@@ -2035,15 +2158,14 @@ static void UpdateFlags(HWND hwnd, unsigned desiredFlags, int width, int height)
bool windowSizeUpdated = false;
if (MakeWindowStyle(CORE.Window.flags) == MakeWindowStyle(desiredFlags))
{
- windowSizeUpdated = UpdateWindowSize(UPDATE_WINDOW_NORMAL, hwnd, width, height, desiredFlags);
+ windowSizeUpdated = UpdateWindowSize(1, hwnd, width, height, desiredFlags);
if ((FLAG_MASK_REQUIRED & desiredFlags) == (FLAG_MASK_REQUIRED & CORE.Window.flags)) break;
}
- if ((attempt > 1) &&
- (previousStyle == MakeWindowStyle(CORE.Window.flags)) &&
- !windowSizeUpdated)
+
+ if ((attempt > 1) && (previousStyle == MakeWindowStyle(CORE.Window.flags)) && !windowSizeUpdated)
{
- TRACELOG(LOG_ERROR, "WINDOW: UpdateFlags() failed after %u attempt(s) wanted 0x%x but is 0x%x (diff=0x%x)",
+ TRACELOG(LOG_ERROR, "WIN32: WINDOW: UpdateFlags() failed after %u attempt(s) wanted 0x%x but is 0x%x (diff=0x%x)",
attempt, desiredFlags, CORE.Window.flags, desiredFlags ^ CORE.Window.flags);
}
@@ -2051,3 +2173,21 @@ static void UpdateFlags(HWND hwnd, unsigned desiredFlags, int width, int height)
UpdateWindowStyle(hwnd, desiredFlags);
}
}
+
+// Check if OpenGL extension is available
+static bool IsWglExtensionAvailable(HDC hdc, const char *extension)
+{
+ bool result = false;
+
+ if (wglGetExtensionsStringARB != NULL)
+ {
+ const char *extList = wglGetExtensionsStringARB(hdc);
+ if (extList != NULL)
+ {
+ // Simple substring search (could use strtok or strstr)
+ if (strstr(extList, extension) != NULL) result = true;
+ }
+ }
+
+ return result;
+}
\ No newline at end of file
diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c
index e067fd82a..a08a76bce 100644
--- a/src/platforms/rcore_drm.c
+++ b/src/platforms/rcore_drm.c
@@ -864,7 +864,7 @@ void SwapScreenBuffer(void)
// Create framebuffer with the correct format
uint32_t fb = 0;
result = drmModeAddFB(platform.fd, width, height, depth, bpp, creq.pitch, creq.handle, &fb);
- if (result != 0)
+ if (result != 0)
{
TRACELOG(LOG_ERROR, "DISPLAY: drmModeAddFB() failed with result: %d (%s)", result, strerror(errno));
struct drm_mode_destroy_dumb dreq = { 0 };
@@ -974,12 +974,12 @@ void SwapScreenBuffer(void)
// Set CRTC with better error handling
result = drmModeSetCrtc(platform.fd, crtcId, fb, 0, 0, &platform.connector->connector_id, 1, mode);
- if (result != 0)
+ if (result != 0)
{
TRACELOG(LOG_ERROR, "DISPLAY: drmModeSetCrtc() failed with result: %d (%s)", result, strerror(errno));
TRACELOG(LOG_ERROR, "DISPLAY: CRTC ID: %u, FB ID: %u, Connector ID: %u", crtcId, fb, platform.connector->connector_id);
TRACELOG(LOG_ERROR, "DISPLAY: Mode: %dx%d@%d", mode->hdisplay, mode->vdisplay, mode->vrefresh);
-
+
drmModeRmFB(platform.fd, fb);
struct drm_mode_destroy_dumb dreq = {0};
dreq.handle = creq.handle;
@@ -1130,11 +1130,12 @@ void PollInputEvents(void)
// Register previous touch states
for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.previousTouchState[i] = CORE.Input.Touch.currentTouchState[i];
- // Reset touch positions
- //for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.position[i] = (Vector2){ 0, 0 };
+ // Reset touch positions to invalid state
+ for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.position[i] = (Vector2){ -1, -1 };
// Map touch position to mouse position for convenience
- CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition;
+ // NOTE: For DRM touchscreen devices, this mapping is disabled to avoid false touch detection
+ // CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition;
// Handle the mouse/touch/gestures events:
PollMouseEvents();
@@ -1228,7 +1229,7 @@ int InitPlatform(void)
}
TRACELOG(LOG_TRACE, "DISPLAY: Connector %i modes detected: %i", i, con->count_modes);
- TRACELOG(LOG_TRACE, "DISPLAY: Connector %i status: %s", i,
+ TRACELOG(LOG_TRACE, "DISPLAY: Connector %i status: %s", i,
(con->connection == DRM_MODE_CONNECTED) ? "CONNECTED" :
(con->connection == DRM_MODE_DISCONNECTED) ? "DISCONNECTED" :
(con->connection == DRM_MODE_UNKNOWNCONNECTION) ? "UNKNOWN" : "OTHER");
@@ -1356,10 +1357,10 @@ int InitPlatform(void)
platform.modeIndex = 0;
CORE.Window.display.width = platform.connector->modes[0].hdisplay;
CORE.Window.display.height = platform.connector->modes[0].vdisplay;
-
- TRACELOG(LOG_INFO, "DISPLAY: Selected DRM connector mode %s (%ux%u%c@%u) for software rendering",
+
+ TRACELOG(LOG_INFO, "DISPLAY: Selected DRM connector mode %s (%ux%u%c@%u) for software rendering",
platform.connector->modes[0].name,
- platform.connector->modes[0].hdisplay,
+ platform.connector->modes[0].hdisplay,
platform.connector->modes[0].vdisplay,
(platform.connector->modes[0].flags & DRM_MODE_FLAG_INTERLACE) ? 'i' : 'p',
platform.connector->modes[0].vrefresh);
@@ -2262,7 +2263,8 @@ static void PollMouseEvents(void)
}
else CORE.Input.Mouse.currentPosition.x += event.value;
- CORE.Input.Touch.position[0].x = CORE.Input.Mouse.currentPosition.x;
+ // NOTE: For DRM touchscreen, do not simulate touch from mouse movement
+ // CORE.Input.Touch.position[0].x = CORE.Input.Mouse.currentPosition.x;
touchAction = 2; // TOUCH_ACTION_MOVE
}
@@ -2275,7 +2277,8 @@ static void PollMouseEvents(void)
}
else CORE.Input.Mouse.currentPosition.y += event.value;
- CORE.Input.Touch.position[0].y = CORE.Input.Mouse.currentPosition.y;
+ // NOTE: For DRM touchscreen, do not simulate touch from mouse movement
+ // CORE.Input.Touch.position[0].y = CORE.Input.Mouse.currentPosition.y;
touchAction = 2; // TOUCH_ACTION_MOVE
}
diff --git a/src/rcore.c b/src/rcore.c
index f87b68783..350490ad1 100644
--- a/src/rcore.c
+++ b/src/rcore.c
@@ -679,12 +679,15 @@ void InitWindow(int width, int height, const char *title)
// Initialize window data
CORE.Window.screen.width = width;
CORE.Window.screen.height = height;
+ CORE.Window.currentFbo.width = CORE.Window.screen.width;
+ CORE.Window.currentFbo.height = CORE.Window.screen.height;
+
CORE.Window.eventWaiting = false;
- CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default
+ CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default
if ((title != NULL) && (title[0] != 0)) CORE.Window.title = title;
// Initialize global input state
- memset(&CORE.Input, 0, sizeof(CORE.Input)); // Reset CORE.Input structure to 0
+ memset(&CORE.Input, 0, sizeof(CORE.Input)); // Reset CORE.Input structure to 0
CORE.Input.Keyboard.exitKey = KEY_ESCAPE;
CORE.Input.Mouse.scale = (Vector2){ 1.0f, 1.0f };
CORE.Input.Mouse.cursor = MOUSE_CURSOR_ARROW;
@@ -696,7 +699,7 @@ void InitWindow(int width, int height, const char *title)
if (result != 0)
{
- TRACELOG(LOG_WARNING, "SYSTEM: Failed to initialize Platform");
+ TRACELOG(LOG_WARNING, "SYSTEM: Failed to initialize platform");
return;
}
//--------------------------------------------------------------
@@ -2521,7 +2524,7 @@ int MakeDirectory(const char *dirPath)
// Create final directory
if (!DirectoryExists(pathcpy)) MKDIR(pathcpy);
RL_FREE(pathcpy);
-
+
// In case something failed and requested directory
// was not successfully created, return -1
if (!DirectoryExists(dirPath)) return -1;
@@ -3145,7 +3148,7 @@ unsigned int *ComputeSHA256(unsigned char *data, int dataSize)
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) |
diff --git a/src/rlgl.h b/src/rlgl.h
index 9cf8ebefb..e6a1c9432 100644
--- a/src/rlgl.h
+++ b/src/rlgl.h
@@ -785,8 +785,8 @@ RLAPI unsigned int rlLoadShaderCode(const char *vsCode, const char *fsCode);
RLAPI unsigned int rlCompileShader(const char *shaderCode, int type); // Compile custom shader and return shader id (type: RL_VERTEX_SHADER, RL_FRAGMENT_SHADER, RL_COMPUTE_SHADER)
RLAPI unsigned int rlLoadShaderProgram(unsigned int vShaderId, unsigned int fShaderId); // Load custom shader program
RLAPI void rlUnloadShaderProgram(unsigned int id); // Unload shader program
-RLAPI int rlGetLocationUniform(unsigned int shaderId, const char *uniformName); // Get shader location uniform
-RLAPI int rlGetLocationAttrib(unsigned int shaderId, const char *attribName); // Get shader location attribute
+RLAPI int rlGetLocationUniform(unsigned int shaderId, const char *uniformName); // Get shader location uniform, requires shader program id
+RLAPI int rlGetLocationAttrib(unsigned int shaderId, const char *attribName); // Get shader location attribute, requires shader program id
RLAPI void rlSetUniform(int locIndex, const void *value, int uniformType, int count); // Set shader value uniform
RLAPI void rlSetUniformMatrix(int locIndex, Matrix mat); // Set shader value matrix
RLAPI void rlSetUniformMatrices(int locIndex, const Matrix *mat, int count); // Set shader value matrices
@@ -2329,6 +2329,16 @@ void rlglInit(int width, int height)
RLGL.State.currentMatrix = &RLGL.State.modelview;
#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
+#if defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
+ // Initialize software renderer backend
+ int result = swInit(width, height);
+ if (result == 0)
+ {
+ TRACELOG(RL_LOG_ERROR, "RLSW: Software renderer initialization failed!");
+ exit(-1);
+ }
+#endif
+
// Initialize OpenGL default states
//----------------------------------------------------------
// Init state: Depth test
@@ -2345,39 +2355,28 @@ void rlglInit(int width, int height)
glFrontFace(GL_CCW); // Front face are defined counter clockwise (default)
glEnable(GL_CULL_FACE); // Enable backface culling
- // Init state: Cubemap seamless
-#if defined(GRAPHICS_API_OPENGL_33)
- glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); // Seamless cubemaps (not supported on OpenGL ES 2.0)
-#endif
-
#if defined(GRAPHICS_API_OPENGL_11)
// Init state: Color hints (deprecated in OpenGL 3.0+)
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Improve quality of color and texture coordinate interpolation
glShadeModel(GL_SMOOTH); // Smooth shading between vertex (vertex colors interpolation)
#endif
-
-#if defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
- int result = swInit(width, height); // Initialize software renderer backend
- if (result == 0)
- {
- TRACELOG(RL_LOG_ERROR, "RLSW: Software renderer initialization failed!");
- exit(-1);
- }
+#if defined(GRAPHICS_API_OPENGL_33)
+ // Init state: Cubemap seamless
+ glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); // Seamless cubemaps (not supported on OpenGL ES 2.0)
#endif
-
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
// Store screen size into global variables
RLGL.State.framebufferWidth = width;
RLGL.State.framebufferHeight = height;
-
- TRACELOG(RL_LOG_INFO, "RLGL: Default OpenGL state initialized successfully");
- //----------------------------------------------------------
#endif
// Init state: Color/Depth buffers clear
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set clear color (black)
glClearDepth(1.0f); // Set clear depth value (default)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth buffers (depth buffer required for 3D)
+
+ TRACELOG(RL_LOG_INFO, "RLGL: Default OpenGL state initialized successfully");
+ //----------------------------------------------------------
}
// Vertex Buffer Object deinitialization (memory free)
@@ -4238,121 +4237,121 @@ unsigned int rlLoadShaderCode(const char *vsCode, const char *fsCode)
// Compile custom shader and return shader id
unsigned int rlCompileShader(const char *shaderCode, int type)
{
- unsigned int shader = 0;
+ unsigned int shaderId = 0;
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- shader = glCreateShader(type);
- glShaderSource(shader, 1, &shaderCode, NULL);
+ shaderId = glCreateShader(type);
+ glShaderSource(shaderId, 1, &shaderCode, NULL);
GLint success = 0;
- glCompileShader(shader);
- glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
+ glCompileShader(shaderId);
+ glGetShaderiv(shaderId, GL_COMPILE_STATUS, &success);
if (success == GL_FALSE)
{
switch (type)
{
- case GL_VERTEX_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to compile vertex shader code", shader); break;
- case GL_FRAGMENT_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to compile fragment shader code", shader); break;
+ case GL_VERTEX_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to compile vertex shader code", shaderId); break;
+ case GL_FRAGMENT_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to compile fragment shader code", shaderId); break;
//case GL_GEOMETRY_SHADER:
#if defined(GRAPHICS_API_OPENGL_43)
- case GL_COMPUTE_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to compile compute shader code", shader); break;
+ case GL_COMPUTE_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to compile compute shader code", shaderId); break;
#elif defined(GRAPHICS_API_OPENGL_33)
- case GL_COMPUTE_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: Compute shaders not enabled. Define GRAPHICS_API_OPENGL_43", shader); break;
+ case GL_COMPUTE_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: Compute shaders not enabled. Define GRAPHICS_API_OPENGL_43", shaderId); break;
#endif
default: break;
}
int maxLength = 0;
- glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength);
+ glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &maxLength);
if (maxLength > 0)
{
int length = 0;
char *log = (char *)RL_CALLOC(maxLength, sizeof(char));
- glGetShaderInfoLog(shader, maxLength, &length, log);
- TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Compile error: %s", shader, log);
+ glGetShaderInfoLog(shaderId, maxLength, &length, log);
+ TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Compile error: %s", shaderId, log);
RL_FREE(log);
}
// Unload object allocated by glCreateShader(),
// despite failing in the compilation process
- glDeleteShader(shader);
- shader = 0;
+ glDeleteShader(shaderId);
+ shaderId = 0;
}
else
{
switch (type)
{
- case GL_VERTEX_SHADER: TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Vertex shader compiled successfully", shader); break;
- case GL_FRAGMENT_SHADER: TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Fragment shader compiled successfully", shader); break;
+ case GL_VERTEX_SHADER: TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Vertex shader compiled successfully", shaderId); break;
+ case GL_FRAGMENT_SHADER: TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Fragment shader compiled successfully", shaderId); break;
//case GL_GEOMETRY_SHADER:
#if defined(GRAPHICS_API_OPENGL_43)
- case GL_COMPUTE_SHADER: TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Compute shader compiled successfully", shader); break;
+ case GL_COMPUTE_SHADER: TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Compute shader compiled successfully", shaderId); break;
#elif defined(GRAPHICS_API_OPENGL_33)
- case GL_COMPUTE_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: Compute shaders not enabled. Define GRAPHICS_API_OPENGL_43", shader); break;
+ case GL_COMPUTE_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: Compute shaders not enabled. Define GRAPHICS_API_OPENGL_43", shaderId); break;
#endif
default: break;
}
}
#endif
- return shader;
+ return shaderId;
}
// Load custom shader strings and return program id
unsigned int rlLoadShaderProgram(unsigned int vShaderId, unsigned int fShaderId)
{
- unsigned int program = 0;
+ unsigned int programId = 0;
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
GLint success = 0;
- program = glCreateProgram();
+ programId = glCreateProgram();
- glAttachShader(program, vShaderId);
- glAttachShader(program, fShaderId);
+ glAttachShader(programId, vShaderId);
+ glAttachShader(programId, fShaderId);
// NOTE: Default attribute shader locations must be Bound before linking
- glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION, RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION);
- glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD);
- glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL, RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL);
- glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR, RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR);
- glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT, RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT);
- glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2);
- glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_INSTANCE_TX, RL_DEFAULT_SHADER_ATTRIB_NAME_INSTANCE_TX);
+ glBindAttribLocation(programId, RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION, RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION);
+ glBindAttribLocation(programId, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD);
+ glBindAttribLocation(programId, RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL, RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL);
+ glBindAttribLocation(programId, RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR, RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR);
+ glBindAttribLocation(programId, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT, RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT);
+ glBindAttribLocation(programId, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2);
+ glBindAttribLocation(programId, RL_DEFAULT_SHADER_ATTRIB_LOCATION_INSTANCE_TX, RL_DEFAULT_SHADER_ATTRIB_NAME_INSTANCE_TX);
#ifdef RL_SUPPORT_MESH_GPU_SKINNING
- glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS, RL_DEFAULT_SHADER_ATTRIB_NAME_BONEIDS);
- glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS, RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS);
+ glBindAttribLocation(programId, RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS, RL_DEFAULT_SHADER_ATTRIB_NAME_BONEIDS);
+ glBindAttribLocation(programId, RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS, RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS);
#endif
// NOTE: If some attrib name is no found on the shader, it locations becomes -1
- glLinkProgram(program);
+ glLinkProgram(programId);
// NOTE: All uniform variables are intitialised to 0 when a program links
- glGetProgramiv(program, GL_LINK_STATUS, &success);
+ glGetProgramiv(programId, GL_LINK_STATUS, &success);
if (success == GL_FALSE)
{
- TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to link shader program", program);
+ TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to link shader program", programId);
int maxLength = 0;
- glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);
+ glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &maxLength);
if (maxLength > 0)
{
int length = 0;
char *log = (char *)RL_CALLOC(maxLength, sizeof(char));
- glGetProgramInfoLog(program, maxLength, &length, log);
- TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Link error: %s", program, log);
+ glGetProgramInfoLog(programId, maxLength, &length, log);
+ TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Link error: %s", programId, log);
RL_FREE(log);
}
- glDeleteProgram(program);
+ glDeleteProgram(programId);
- program = 0;
+ programId = 0;
}
else
{
@@ -4361,10 +4360,10 @@ unsigned int rlLoadShaderProgram(unsigned int vShaderId, unsigned int fShaderId)
//GLint binarySize = 0;
//glGetProgramiv(id, GL_PROGRAM_BINARY_LENGTH, &binarySize);
- TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Program shader loaded successfully", program);
+ TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Program shader loaded successfully", programId);
}
#endif
- return program;
+ return programId;
}
// Unload shader program
@@ -4378,6 +4377,7 @@ void rlUnloadShaderProgram(unsigned int id)
}
// Get shader location uniform
+// NOTE: First parameter refers to shader program id
int rlGetLocationUniform(unsigned int shaderId, const char *uniformName)
{
int location = -1;
@@ -4391,6 +4391,7 @@ int rlGetLocationUniform(unsigned int shaderId, const char *uniformName)
}
// Get shader location attribute
+// NOTE: First parameter refers to shader program id
int rlGetLocationAttrib(unsigned int shaderId, const char *attribName)
{
int location = -1;
@@ -4516,37 +4517,37 @@ void rlSetShader(unsigned int id, int *locs)
// Load compute shader program
unsigned int rlLoadComputeShaderProgram(unsigned int shaderId)
{
- unsigned int program = 0;
+ unsigned int programId = 0;
#if defined(GRAPHICS_API_OPENGL_43)
GLint success = 0;
- program = glCreateProgram();
- glAttachShader(program, shaderId);
- glLinkProgram(program);
+ programId = glCreateProgram();
+ glAttachShader(programId, shaderId);
+ glLinkProgram(programId);
// NOTE: All uniform variables are intitialised to 0 when a program links
- glGetProgramiv(program, GL_LINK_STATUS, &success);
+ glGetProgramiv(programId, GL_LINK_STATUS, &success);
if (success == GL_FALSE)
{
- TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to link compute shader program", program);
+ TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to link compute shader program", programId);
int maxLength = 0;
- glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);
+ glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &maxLength);
if (maxLength > 0)
{
int length = 0;
char *log = (char *)RL_CALLOC(maxLength, sizeof(char));
- glGetProgramInfoLog(program, maxLength, &length, log);
- TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Link error: %s", program, log);
+ glGetProgramInfoLog(programId, maxLength, &length, log);
+ TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Link error: %s", programId, log);
RL_FREE(log);
}
- glDeleteProgram(program);
+ glDeleteProgram(programId);
- program = 0;
+ programId = 0;
}
else
{
@@ -4555,13 +4556,13 @@ unsigned int rlLoadComputeShaderProgram(unsigned int shaderId)
//GLint binarySize = 0;
//glGetProgramiv(id, GL_PROGRAM_BINARY_LENGTH, &binarySize);
- TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Compute shader program loaded successfully", program);
+ TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Compute shader program loaded successfully", programId);
}
#else
TRACELOG(RL_LOG_WARNING, "SHADER: Compute shaders not enabled. Define GRAPHICS_API_OPENGL_43");
#endif
- return program;
+ return programId;
}
// Dispatch compute shader (equivalent to *draw* for graphics pilepine)
diff --git a/src/rshapes.c b/src/rshapes.c
index 55f7d7fb9..2b5854f86 100644
--- a/src/rshapes.c
+++ b/src/rshapes.c
@@ -1432,6 +1432,7 @@ void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
Rectangle shapeRect = GetShapesTextureRectangle();
rlBegin(RL_QUADS);
+ rlNormal3f(0.0f, 0.0f, 1.0f);
rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height);
@@ -1441,7 +1442,7 @@ void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
rlVertex2f(v2.x, v2.y);
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height);
- rlVertex2f(v2.x, v2.y);
+ rlVertex2f(v3.x, v3.y);
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height);
rlVertex2f(v3.x, v3.y);
diff --git a/src/rtext.c b/src/rtext.c
index 9951dc66d..b4cd560ba 100644
--- a/src/rtext.c
+++ b/src/rtext.c
@@ -1701,9 +1701,9 @@ char *GetTextBetween(const char *text, const char *begin, const char *end)
char *TextReplace(const char *text, const char *search, const char *replacement)
{
char *result = NULL;
-
+
if (!text || !search) return NULL; // Sanity check
-
+
char *insertPoint = NULL; // Next insert point
char *temp = NULL; // Temp pointer
int searchLen = 0; // Search string length of (the string to remove)
@@ -1753,7 +1753,7 @@ char *TextReplaceBetween(const char *text, const char *begin, const char *end, c
char *result = NULL;
if (!text || !begin || !end) return NULL; // Sanity check
-
+
int beginIndex = TextFindIndex(text, begin);
if (beginIndex > -1)
diff --git a/tools/rexm/examples_report.md b/tools/rexm/examples_report.md
index e55610a30..fcc1f8839 100644
--- a/tools/rexm/examples_report.md
+++ b/tools/rexm/examples_report.md
@@ -44,7 +44,7 @@ Example elements validated:
| core_window_flags | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| core_window_letterbox | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| core_window_should_close | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_monitor_change | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_monitor_detector | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| core_custom_logging | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| core_drop_files | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| core_random_values | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
@@ -61,6 +61,9 @@ Example elements validated:
| core_undo_redo | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| core_input_actions | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| core_directory_files | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_highdpi_testbed | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_screen_recording | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_clipboard_text | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shapes_basic_shapes | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shapes_bouncing_ball | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shapes_bullet_hell | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
@@ -87,6 +90,11 @@ Example elements validated:
| shapes_triangle_strip | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shapes_vector_angle | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shapes_pie_chart | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_kaleidoscope | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_clock_of_clocks | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_mouse_trail | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_simple_particles | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_starfield_effect | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| textures_logo_raylib | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| textures_srcrec_dstrec | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| textures_image_drawing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
@@ -152,7 +160,7 @@ Example elements validated:
| models_bone_socket | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| models_tesseract_view | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| models_basic_voxel | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| models_geometry_textures_cube | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| models_rotating_cube | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shaders_ascii_rendering | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shaders_basic_lighting | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shaders_model_shader | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
@@ -196,10 +204,6 @@ Example elements validated:
| easings_testbed | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| 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 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| web_basic_window | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_text_file_loading | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_mandelbrot_set | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
diff --git a/tools/rexm/examples_report_issues.md b/tools/rexm/examples_report_issues.md
index 5178dabdd..5de76a17a 100644
--- a/tools/rexm/examples_report_issues.md
+++ b/tools/rexm/examples_report_issues.md
@@ -20,9 +20,11 @@ Example elements validated:
```
| **EXAMPLE NAME** | [C] | [CAT]| [INFO]|[PNG]|[WPNG]| [RES]| [MK] |[MKWEB]| [VCX]| [SOL]|[RDME]|[JS] | [WOUT]|[WMETA]|
|:---------------------------------|:---:|:----:|:-----:|:---:|:----:|:----:|:----:|:-----:|:----:|:----:|:----:|:---:|:-----:|:-----:|
+| core_highdpi_testbed | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_screen_recording | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| rlgl_standalone | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| rlgl_compute_shader | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| easings_testbed | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| raylib_opengl_interop | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ |
| embedded_files_loading | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| web_basic_window | ✔ | ❌ | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| web_basic_window | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c
index 2dc295f37..d668655c8 100644
--- a/tools/rexm/rexm.c
+++ b/tools/rexm/rexm.c
@@ -69,7 +69,7 @@
#define REXM_MAX_RESOURCE_PATHS 256
// Create local commit with changes on example renaming
-#define RENAME_AUTO_COMMIT_CREATION
+//#define RENAME_AUTO_COMMIT_CREATION
//----------------------------------------------------------------------------------
// Types and Structures Definition
@@ -224,6 +224,7 @@ int main(int argc, char *argv[])
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 showUsage = false; // Flag to show usage help
bool verbose = false; // Flag for verbose log info
// Command-line usage mode: command args processing
@@ -231,12 +232,14 @@ int main(int argc, char *argv[])
if (argc > 1)
{
// Supported commands:
- // help : Provides command-line usage information (default)
// create : Creates an empty example, from internal template
// add : Add existing example, category extracted from name
// rename : Rename an existing example
// remove : Remove an existing example
- // validate : Validate examples collection
+ // build : Build example for Desktop and Web platforms
+ // validate : Validate examples collection, generates report
+ // update : Validate and update examples collection, generates report
+
if (strcmp(argv[1], "create") == 0)
{
// Check for valid upcoming argument
@@ -391,8 +394,8 @@ int main(int argc, char *argv[])
{
// 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
+ {
+ // Category/ALL rebuilt requested
strcpy(exRebuildRequested, argv[2]);
}
else
@@ -410,11 +413,18 @@ int main(int argc, char *argv[])
}
}
}
-
- // Check for verbose log mode request
+
+ // Process command line options arguments
for (int i = 1; i < argc; i++)
{
- if ((strcmp(argv[i], "-v") == 0) || (strcmp(argv[i], "--verbose") == 0)) verbose = true;
+ if ((strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "--help") == 0))
+ {
+ showUsage = true;
+ }
+ else if ((strcmp(argv[i], "-v") == 0) || (strcmp(argv[i], "--verbose") == 0))
+ {
+ verbose = true;
+ }
}
}
@@ -1372,7 +1382,6 @@ int main(int argc, char *argv[])
default: // Help
{
// Supported commands:
- // help : Provides command-line usage information
// create : Creates an empty example, from internal template
// add : Add existing example, category extracted from name
// rename : Rename an existing example
@@ -1394,7 +1403,6 @@ int main(int argc, char *argv[])
printf(" > rexm []\n\n");
printf("COMMANDS:\n\n");
- printf(" help : Provides command-line usage information\n");
printf(" create : Creates an empty example, from internal template\n");
printf(" add : Add existing example, category extracted from name\n");
printf(" Supported categories: core, shapes, textures, text, models\n");
@@ -1403,6 +1411,9 @@ int main(int argc, char *argv[])
printf(" build : Build example for Desktop and Web platforms\n");
printf(" validate : Validate examples collection, generates report\n");
printf(" update : Validate and update examples collection, generates report\n\n");
+ printf("OPTIONS:\n\n");
+ printf(" -h, --help : Show tool version and command line usage help\n");
+ printf(" -v, --verbose : Verbose mode, show additional logs on processes\n");
printf("\nEXAMPLES:\n\n");
printf(" > rexm add shapes_custom_stars\n");
printf(" Add and updates new example provided \n\n");
@@ -2421,7 +2432,7 @@ static void UpdateWebMetadata(const char *exHtmlPath, const char *exFilePath)
static bool TextInList(const char *text, const char **list, int listCount)
{
bool result = false;
-
+
for (int i = 0; i < listCount; i++)
{
if (TextIsEqual(text, list[i])) { result = true; break; }