Merge branch 'raysan5:master' into master

This commit is contained in:
Jason Mao 2026-01-13 23:11:06 -05:00 committed by GitHub
commit 65901389f1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
85 changed files with 6313 additions and 1832 deletions

View File

@ -21,6 +21,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| [claw-raylib](https://github.com/bohonghuang/claw-raylib) | **auto** | [Common Lisp](https://common-lisp.net) | Apache-2.0 | | [claw-raylib](https://github.com/bohonghuang/claw-raylib) | **auto** | [Common Lisp](https://common-lisp.net) | Apache-2.0 |
| [raylib](https://github.com/fosskers/raylib) | 5.5 | [Common Lisp](https://common-lisp.net) | MPL-2.0 | | [raylib](https://github.com/fosskers/raylib) | 5.5 | [Common Lisp](https://common-lisp.net) | MPL-2.0 |
| [chez-raylib](https://github.com/Yunoinsky/chez-raylib) | **auto** | [Chez Scheme](https://cisco.github.io/ChezScheme) | GPLv3 | | [chez-raylib](https://github.com/Yunoinsky/chez-raylib) | **auto** | [Chez Scheme](https://cisco.github.io/ChezScheme) | GPLv3 |
| [chicken-raylib](https://github.com/meowstr/chicken-raylib) | 5.5 | [CHICKEN Scheme](https://wiki.call-cc.org) | MIT |
| [CLIPSraylib](https://github.com/mrryanjohnston/CLIPSraylib) | **auto** | [CLIPS](https://www.clipsrules.net/) | MIT | | [CLIPSraylib](https://github.com/mrryanjohnston/CLIPSraylib) | **auto** | [CLIPS](https://www.clipsrules.net/) | MIT |
| [raylib-cr](https://github.com/sol-vin/raylib-cr) | 4.6-dev (5e1a81) | [Crystal](https://crystal-lang.org) | Apache-2.0 | | [raylib-cr](https://github.com/sol-vin/raylib-cr) | 4.6-dev (5e1a81) | [Crystal](https://crystal-lang.org) | Apache-2.0 |
| [ray-cyber](https://github.com/fubark/ray-cyber) | **5.0** | [Cyber](https://cyberscript.dev) | MIT | | [ray-cyber](https://github.com/fubark/ray-cyber) | **5.0** | [Cyber](https://cyberscript.dev) | MIT |
@ -28,6 +29,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| [bindbc-raylib3](https://github.com/o3o/bindbc-raylib3) | **5.0** | [D](https://dlang.org) | BSL-1.0 | | [bindbc-raylib3](https://github.com/o3o/bindbc-raylib3) | **5.0** | [D](https://dlang.org) | BSL-1.0 |
| [dray](https://github.com/redthing1/dray) | **5.0** | [D](https://dlang.org) | Apache-2.0 | | [dray](https://github.com/redthing1/dray) | **5.0** | [D](https://dlang.org) | Apache-2.0 |
| [raylib-d](https://github.com/schveiguy/raylib-d) | **5.5** | [D](https://dlang.org) | Zlib | | [raylib-d](https://github.com/schveiguy/raylib-d) | **5.5** | [D](https://dlang.org) | Zlib |
| [DenoRaylib550](https://github.com/JJLDonley/DenoRaylib550) | **5.5** | [Deno](https://deno.land) | MIT |
| [rayex](https://github.com/shiryel/rayex) | 3.7 | [elixir](https://elixir-lang.org) | Apache-2.0 | | [rayex](https://github.com/shiryel/rayex) | 3.7 | [elixir](https://elixir-lang.org) | Apache-2.0 |
| [raylib-elle](https://github.com/acquitelol/elle/blob/rewrite/std/raylib.le) | **5.5** | [Elle](https://github.com/acquitelol/elle) | GPL-3.0 | | [raylib-elle](https://github.com/acquitelol/elle/blob/rewrite/std/raylib.le) | **5.5** | [Elle](https://github.com/acquitelol/elle) | GPL-3.0 |
| [raylib-factor](https://github.com/factor/factor/blob/master/extra/raylib/raylib.factor) | 4.5 | [Factor](https://factorcode.org) | BSD | | [raylib-factor](https://github.com/factor/factor/blob/master/extra/raylib/raylib.factor) | 4.5 | [Factor](https://factorcode.org) | BSD |

View File

@ -1,4 +1,4 @@
Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) Copyright (c) 2013-2026 Ramon Santamaria (@raysan5)
This software is provided "as-is", without any express or implied warranty. In no event This software is provided "as-is", without any express or implied warranty. In no event
will the authors be held liable for any damages arising from the use of this software. will the authors be held liable for any damages arising from the use of this software.

View File

@ -140,7 +140,7 @@ contributors
------------ ------------
<a href="https://github.com/raysan5/raylib/graphs/contributors"> <a href="https://github.com/raysan5/raylib/graphs/contributors">
<img src="https://contrib.rocks/image?repo=raysan5/raylib&max=500&columns=20&anon=1" /> <img src="https://contrib.rocks/image?repo=raysan5/raylib&max=800&columns=24&anon=0" />
</a> </a>
license license

View File

@ -15,13 +15,13 @@ _Current version of raylib is complete and functional but there is always room f
**raylib 5.x** **raylib 5.x**
- [ ] `rcore`: Support additional platforms: iOS, consoles? - [ ] `rcore`: Support additional platforms: iOS, consoles?
- [ ] `rcore_web`: Avoid GLFW dependency, functionality can be directly implemented using emscripten SDK - [x] `rcore_web`: Avoid GLFW dependency, functionality can be directly implemented using emscripten SDK
- [ ] `rlgl`: Review GLSL shaders naming conventions for consistency - [ ] `rlgl`: Review GLSL shaders naming conventions for consistency
- [ ] `textures`: Improve compressed textures support, loading and saving - [ ] `textures`: Improve compressed textures support, loading and saving
- [ ] `rmodels`: Improve 3d objects loading, specially animations (obj, gltf) - [ ] `rmodels`: Improve 3d objects loading, specially animations (obj, gltf)
- [ ] `raudio`: Implement miniaudio high-level provided features - [ ] `raudio`: Implement miniaudio high-level provided features
- [ ] `examples`: Review all examples, add more and better code explanations - [x] `examples`: Review all examples, add more and better code explanations
- [ ] Software renderer backend? Maybe using `Image` provided API - [x] Software renderer backend? Maybe using `Image` provided API
**raylib 4.x** **raylib 4.x**
- [x] Split core module into separate platforms? - [x] Split core module into separate platforms?

18
SECURITY.md Normal file
View File

@ -0,0 +1,18 @@
# Security Policy
## Supported Versions
Most considerations of errors and defects can be handled using the project Issues and/or Discussions.
| Version | Supported |
| ------- | ------------------ |
| 6.0.x | :white_check_mark: |
| < 5.5 | :x: |
## Reporting a Vulnerability
Discovered vulnerability can be directly reported using the project Issues and/or Discussions.
_TODO: Tell them where to go, how often they can expect to get an update on a
reported vulnerability, what to expect if the vulnerability is accepted or
declined, etc._

View File

@ -197,7 +197,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
} }
var c_source_files: std.ArrayList([]const u8) = try .initCapacity(b.allocator, 2); var c_source_files: std.ArrayList([]const u8) = try .initCapacity(b.allocator, 2);
c_source_files.appendSliceAssumeCapacity(&.{ "src/rcore.c", "src/utils.c" }); c_source_files.appendSliceAssumeCapacity(&.{ "src/rcore.c" });
if (options.rshapes) { if (options.rshapes) {
try c_source_files.append(b.allocator, "src/rshapes.c"); try c_source_files.append(b.allocator, "src/rshapes.c");
@ -348,7 +348,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
} }
}, },
.freebsd, .openbsd, .netbsd, .dragonfly => { .freebsd, .openbsd, .netbsd, .dragonfly => {
try c_source_files.append(b.allocator, "rglfw.c"); try c_source_files.append(b.allocator, "src/rglfw.c");
raylib.root_module.linkSystemLibrary("GL", .{}); raylib.root_module.linkSystemLibrary("GL", .{});
raylib.root_module.linkSystemLibrary("rt", .{}); raylib.root_module.linkSystemLibrary("rt", .{});
raylib.root_module.linkSystemLibrary("dl", .{}); raylib.root_module.linkSystemLibrary("dl", .{});

View File

@ -30,7 +30,7 @@
# > PLATFORM_ANDROID: # > PLATFORM_ANDROID:
# - Android (ARM, ARM64) # - Android (ARM, ARM64)
# #
# Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) # Copyright (c) 2013-2026 Ramon Santamaria (@raysan5)
# #
# This software is provided "as-is", without any express or implied warranty. In no event # This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software. # will the authors be held liable for any damages arising from the use of this software.
@ -205,15 +205,17 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
endif endif
endif endif
ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID) ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
ifeq ($(PLATFORM_OS),WINDOWS)
MAKE = mingw32-make MAKE = mingw32-make
endif endif
endif
ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW))
ifeq ($(OS),Windows_NT) ifeq ($(PLATFORM_OS),WINDOWS)
MAKE = mingw32-make MAKE = mingw32-make
else else
EMMAKE != type emmake EMMAKE := $(shell command -v emmake)
ifneq (, $(EMMAKE)) ifneq (, $(EMMAKE))
MAKE = emmake make MAKE = $(EMMAKE) make
else else
MAKE = mingw32-make MAKE = mingw32-make
endif endif
@ -542,6 +544,7 @@ CORE = \
core/core_input_mouse_wheel \ core/core_input_mouse_wheel \
core/core_input_multitouch \ core/core_input_multitouch \
core/core_input_virtual_controls \ core/core_input_virtual_controls \
core/core_keyboard_testbed \
core/core_monitor_detector \ core/core_monitor_detector \
core/core_random_sequence \ core/core_random_sequence \
core/core_random_values \ core/core_random_values \
@ -575,6 +578,7 @@ SHAPES = \
shapes/shapes_easings_box \ shapes/shapes_easings_box \
shapes/shapes_easings_rectangles \ shapes/shapes_easings_rectangles \
shapes/shapes_following_eyes \ shapes/shapes_following_eyes \
shapes/shapes_hilbert_curve \
shapes/shapes_kaleidoscope \ shapes/shapes_kaleidoscope \
shapes/shapes_lines_bezier \ shapes/shapes_lines_bezier \
shapes/shapes_lines_drawing \ shapes/shapes_lines_drawing \
@ -605,6 +609,7 @@ TEXTURES = \
textures/textures_bunnymark \ textures/textures_bunnymark \
textures/textures_cellular_automata \ textures/textures_cellular_automata \
textures/textures_fog_of_war \ textures/textures_fog_of_war \
textures/textures_framebuffer_rendering \
textures/textures_gif_player \ textures/textures_gif_player \
textures/textures_image_channel \ textures/textures_image_channel \
textures/textures_image_drawing \ textures/textures_image_drawing \

View File

@ -30,7 +30,7 @@
# > PLATFORM_ANDROID: # > PLATFORM_ANDROID:
# - Android (ARM, ARM64) # - Android (ARM, ARM64)
# #
# Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) # Copyright (c) 2013-2026 Ramon Santamaria (@raysan5)
# #
# This software is provided "as-is", without any express or implied warranty. In no event # This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software. # will the authors be held liable for any damages arising from the use of this software.
@ -208,12 +208,12 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
MAKE = mingw32-make MAKE = mingw32-make
endif endif
ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW))
ifeq ($(OS),Windows_NT) ifeq ($(PLATFORM_OS),WINDOWS)
MAKE = mingw32-make MAKE = mingw32-make
else else
EMMAKE != type emmake EMMAKE := $(shell command -v emmake)
ifneq (, $(EMMAKE)) ifneq (, $(EMMAKE))
MAKE = emmake make MAKE = $(EMMAKE) make
else else
MAKE = mingw32-make MAKE = mingw32-make
endif endif
@ -530,6 +530,7 @@ CORE = \
core/core_input_mouse_wheel \ core/core_input_mouse_wheel \
core/core_input_multitouch \ core/core_input_multitouch \
core/core_input_virtual_controls \ core/core_input_virtual_controls \
core/core_keyboard_testbed \
core/core_monitor_detector \ core/core_monitor_detector \
core/core_random_sequence \ core/core_random_sequence \
core/core_random_values \ core/core_random_values \
@ -563,6 +564,7 @@ SHAPES = \
shapes/shapes_easings_box \ shapes/shapes_easings_box \
shapes/shapes_easings_rectangles \ shapes/shapes_easings_rectangles \
shapes/shapes_following_eyes \ shapes/shapes_following_eyes \
shapes/shapes_hilbert_curve \
shapes/shapes_kaleidoscope \ shapes/shapes_kaleidoscope \
shapes/shapes_lines_bezier \ shapes/shapes_lines_bezier \
shapes/shapes_lines_drawing \ shapes/shapes_lines_drawing \
@ -593,6 +595,7 @@ TEXTURES = \
textures/textures_bunnymark \ textures/textures_bunnymark \
textures/textures_cellular_automata \ textures/textures_cellular_automata \
textures/textures_fog_of_war \ textures/textures_fog_of_war \
textures/textures_framebuffer_rendering \
textures/textures_gif_player \ textures/textures_gif_player \
textures/textures_image_channel \ textures/textures_image_channel \
textures/textures_image_drawing \ textures/textures_image_drawing \
@ -818,6 +821,9 @@ core/core_input_multitouch: core/core_input_multitouch.c
core/core_input_virtual_controls: core/core_input_virtual_controls.c core/core_input_virtual_controls: core/core_input_virtual_controls.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
core/core_keyboard_testbed: core/core_keyboard_testbed.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
core/core_monitor_detector: core/core_monitor_detector.c core/core_monitor_detector: core/core_monitor_detector.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
@ -914,6 +920,9 @@ shapes/shapes_easings_rectangles: shapes/shapes_easings_rectangles.c
shapes/shapes_following_eyes: shapes/shapes_following_eyes.c shapes/shapes_following_eyes: shapes/shapes_following_eyes.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
shapes/shapes_hilbert_curve: shapes/shapes_hilbert_curve.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
shapes/shapes_kaleidoscope: shapes/shapes_kaleidoscope.c shapes/shapes_kaleidoscope: shapes/shapes_kaleidoscope.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
@ -1005,6 +1014,9 @@ textures/textures_cellular_automata: textures/textures_cellular_automata.c
textures/textures_fog_of_war: textures/textures_fog_of_war.c textures/textures_fog_of_war: textures/textures_fog_of_war.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
textures/textures_framebuffer_rendering: textures/textures_framebuffer_rendering.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
textures/textures_gif_player: textures/textures_gif_player.c textures/textures_gif_player: textures/textures_gif_player.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file textures/resources/scarfy_run.gif@resources/scarfy_run.gif --preload-file textures/resources/scarfy_run.gif@resources/scarfy_run.gif
@ -1367,15 +1379,15 @@ shaders/shaders_fog_rendering: shaders/shaders_fog_rendering.c
shaders/shaders_game_of_life: shaders/shaders_game_of_life.c shaders/shaders_game_of_life: shaders/shaders_game_of_life.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file shaders/resources/shaders/glsl100/game_of_life.fs@resources/shaders/glsl100/game_of_life.fs \ --preload-file shaders/resources/shaders/glsl100/game_of_life.fs@resources/shaders/glsl100/game_of_life.fs \
--preload-file shaders/resources/game_of_life/acorn.png@resources/game_of_life/acorn.png \ --preload-file shaders/resources/game_of_life/r_pentomino.png@resources/game_of_life/r_pentomino.png \
--preload-file shaders/resources/game_of_life/breeder.png@resources/game_of_life/breeder.png \
--preload-file shaders/resources/game_of_life/glider.png@resources/game_of_life/glider.png \ --preload-file shaders/resources/game_of_life/glider.png@resources/game_of_life/glider.png \
--preload-file shaders/resources/game_of_life/glider_gun.png@resources/game_of_life/glider_gun.png \ --preload-file shaders/resources/game_of_life/acorn.png@resources/game_of_life/acorn.png \
--preload-file shaders/resources/game_of_life/spaceships.png@resources/game_of_life/spaceships.png \
--preload-file shaders/resources/game_of_life/still_lifes.png@resources/game_of_life/still_lifes.png \
--preload-file shaders/resources/game_of_life/oscillators.png@resources/game_of_life/oscillators.png \ --preload-file shaders/resources/game_of_life/oscillators.png@resources/game_of_life/oscillators.png \
--preload-file shaders/resources/game_of_life/puffer_train.png@resources/game_of_life/puffer_train.png \ --preload-file shaders/resources/game_of_life/puffer_train.png@resources/game_of_life/puffer_train.png \
--preload-file shaders/resources/game_of_life/r_pentomino.png@resources/game_of_life/r_pentomino.png \ --preload-file shaders/resources/game_of_life/glider_gun.png@resources/game_of_life/glider_gun.png \
--preload-file shaders/resources/game_of_life/spaceships.png@resources/game_of_life/spaceships.png \ --preload-file shaders/resources/game_of_life/breeder.png@resources/game_of_life/breeder.png
--preload-file shaders/resources/game_of_life/still_lifes.png@resources/game_of_life/still_lifes.png
shaders/shaders_hot_reloading: shaders/shaders_hot_reloading.c shaders/shaders_hot_reloading: shaders/shaders_hot_reloading.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \

View File

@ -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 [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`) - `zig build [example]` to compile _and run_ a particular example (e.g. `zig build core_basic_window`)
## EXAMPLES COLLECTION [TOTAL: 205] ## EXAMPLES COLLECTION [TOTAL: 208]
### category: core [47] ### category: core [48]
Examples using raylib [core](../src/rcore.c) module platform functionality: window creation, inputs, drawing modes and system functionality. Examples using raylib [core](../src/rcore.c) module platform functionality: window creation, inputs, drawing modes and system functionality.
@ -69,11 +69,12 @@ Examples using raylib [core](../src/rcore.c) module platform functionality: wind
| [core_directory_files](core/core_directory_files.c) | <img src="core/core_directory_files.png" alt="core_directory_files" width="80"> | ⭐☆☆☆ | 5.5 | 5.6 | [Hugo ARNAL](https://github.com/hugoarnal) | | [core_directory_files](core/core_directory_files.c) | <img src="core/core_directory_files.png" alt="core_directory_files" width="80"> | ⭐☆☆☆ | 5.5 | 5.6 | [Hugo ARNAL](https://github.com/hugoarnal) |
| [core_highdpi_testbed](core/core_highdpi_testbed.c) | <img src="core/core_highdpi_testbed.png" alt="core_highdpi_testbed" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) | | [core_highdpi_testbed](core/core_highdpi_testbed.c) | <img src="core/core_highdpi_testbed.png" alt="core_highdpi_testbed" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
| [core_screen_recording](core/core_screen_recording.c) | <img src="core/core_screen_recording.png" alt="core_screen_recording" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) | | [core_screen_recording](core/core_screen_recording.c) | <img src="core/core_screen_recording.png" alt="core_screen_recording" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
| [core_clipboard_text](core/core_clipboard_text.c) | <img src="core/core_clipboard_text.png" alt="core_clipboard_text" width="80"> | ⭐☆☆ | 5.6-dev | 5.6-dev | [Ananth S](https://github.com/Ananth1839) | | [core_clipboard_text](core/core_clipboard_text.c) | <img src="core/core_clipboard_text.png" alt="core_clipboard_text" width="80"> | ⭐☆☆ | 5.6-dev | 5.6-dev | [Ananth S](https://github.com/Ananth1839) |
| [core_text_file_loading](core/core_text_file_loading.c) | <img src="core/core_text_file_loading.png" alt="core_text_file_loading" width="80"> | ⭐☆☆☆ | 5.5 | 5.6 | [Aanjishnu Bhattacharyya](https://github.com/NimComPoo-04) | | [core_text_file_loading](core/core_text_file_loading.c) | <img src="core/core_text_file_loading.png" alt="core_text_file_loading" width="80"> | ⭐☆☆☆ | 5.5 | 5.6 | [Aanjishnu Bhattacharyya](https://github.com/NimComPoo-04) |
| [core_compute_hash](core/core_compute_hash.c) | <img src="core/core_compute_hash.png" alt="core_compute_hash" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) | | [core_compute_hash](core/core_compute_hash.c) | <img src="core/core_compute_hash.png" alt="core_compute_hash" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
| [core_keyboard_testbed](core/core_keyboard_testbed.c) | <img src="core/core_keyboard_testbed.png" alt="core_keyboard_testbed" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Ramon Santamaria](https://github.com/raysan5) |
### category: shapes [38] ### category: shapes [39]
Examples using raylib shapes drawing functionality, provided by raylib [shapes](../src/rshapes.c) module. Examples using raylib shapes drawing functionality, provided by raylib [shapes](../src/rshapes.c) module.
@ -117,8 +118,9 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes](
| [shapes_rlgl_triangle](shapes/shapes_rlgl_triangle.c) | <img src="shapes/shapes_rlgl_triangle.png" alt="shapes_rlgl_triangle" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Robin](https://github.com/RobinsAviary) | | [shapes_rlgl_triangle](shapes/shapes_rlgl_triangle.c) | <img src="shapes/shapes_rlgl_triangle.png" alt="shapes_rlgl_triangle" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Robin](https://github.com/RobinsAviary) |
| [shapes_ball_physics](shapes/shapes_ball_physics.c) | <img src="shapes/shapes_ball_physics.png" alt="shapes_ball_physics" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [David Buzatto](https://github.com/davidbuzatto) | | [shapes_ball_physics](shapes/shapes_ball_physics.c) | <img src="shapes/shapes_ball_physics.png" alt="shapes_ball_physics" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [David Buzatto](https://github.com/davidbuzatto) |
| [shapes_penrose_tile](shapes/shapes_penrose_tile.c) | <img src="shapes/shapes_penrose_tile.png" alt="shapes_penrose_tile" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 5.6-dev | [David Buzatto](https://github.com/davidbuzatto) | | [shapes_penrose_tile](shapes/shapes_penrose_tile.c) | <img src="shapes/shapes_penrose_tile.png" alt="shapes_penrose_tile" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 5.6-dev | [David Buzatto](https://github.com/davidbuzatto) |
| [shapes_hilbert_curve](shapes/shapes_hilbert_curve.c) | <img src="shapes/shapes_hilbert_curve.png" alt="shapes_hilbert_curve" width="80"> | ⭐⭐⭐☆ | 5.6 | 5.6 | [Hamza RAHAL](https://github.com/hmz-rhl) |
### category: textures [29] ### category: textures [30]
Examples using raylib textures functionality, including image/textures loading/generation and drawing, provided by raylib [textures](../src/rtextures.c) module. Examples using raylib textures functionality, including image/textures loading/generation and drawing, provided by raylib [textures](../src/rtextures.c) module.
@ -153,6 +155,7 @@ Examples using raylib textures functionality, including image/textures loading/g
| [textures_textured_curve](textures/textures_textured_curve.c) | <img src="textures/textures_textured_curve.png" alt="textures_textured_curve" width="80"> | ⭐⭐⭐☆ | 4.5 | 4.5 | [Jeffery Myers](https://github.com/JeffM2501) | | [textures_textured_curve](textures/textures_textured_curve.c) | <img src="textures/textures_textured_curve.png" alt="textures_textured_curve" width="80"> | ⭐⭐⭐☆ | 4.5 | 4.5 | [Jeffery Myers](https://github.com/JeffM2501) |
| [textures_sprite_stacking](textures/textures_sprite_stacking.c) | <img src="textures/textures_sprite_stacking.png" alt="textures_sprite_stacking" width="80"> | ⭐⭐☆☆ | 5.6-dev | 6.0 | [Robin](https://github.com/RobinsAviary) | | [textures_sprite_stacking](textures/textures_sprite_stacking.c) | <img src="textures/textures_sprite_stacking.png" alt="textures_sprite_stacking" width="80"> | ⭐⭐☆☆ | 5.6-dev | 6.0 | [Robin](https://github.com/RobinsAviary) |
| [textures_cellular_automata](textures/textures_cellular_automata.c) | <img src="textures/textures_cellular_automata.png" alt="textures_cellular_automata" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) | | [textures_cellular_automata](textures/textures_cellular_automata.c) | <img src="textures/textures_cellular_automata.png" alt="textures_cellular_automata" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) |
| [textures_framebuffer_rendering](textures/textures_framebuffer_rendering.c) | <img src="textures/textures_framebuffer_rendering.png" alt="textures_framebuffer_rendering" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Jack Boakes](https://github.com/jackboakes) |
### category: text [16] ### category: text [16]

View File

@ -113,7 +113,7 @@ int main(void)
DrawText("LEFT-RIGHT for PAN CONTROL", 320, 74, 10, DARKBLUE); DrawText("LEFT-RIGHT for PAN CONTROL", 320, 74, 10, DARKBLUE);
DrawRectangle(300, 100, 200, 12, LIGHTGRAY); DrawRectangle(300, 100, 200, 12, LIGHTGRAY);
DrawRectangleLines(300, 100, 200, 12, GRAY); DrawRectangleLines(300, 100, 200, 12, GRAY);
DrawRectangle(300 + (pan + 1.0)/2.0f*200 - 5, 92, 10, 28, DARKGRAY); DrawRectangle((int)(300 + (pan + 1.0f)/2.0f*200 - 5), 92, 10, 28, DARKGRAY);
DrawRectangle(200, 200, 400, 12, LIGHTGRAY); DrawRectangle(200, 200, 400, 12, LIGHTGRAY);
DrawRectangle(200, 200, (int)(timePlayed*400.0f), 12, MAROON); DrawRectangle(200, 200, (int)(timePlayed*400.0f), 12, MAROON);
@ -125,7 +125,7 @@ int main(void)
DrawText("UP-DOWN for VOLUME CONTROL", 320, 334, 10, DARKGREEN); DrawText("UP-DOWN for VOLUME CONTROL", 320, 334, 10, DARKGREEN);
DrawRectangle(300, 360, 200, 12, LIGHTGRAY); DrawRectangle(300, 360, 200, 12, LIGHTGRAY);
DrawRectangleLines(300, 360, 200, 12, GRAY); DrawRectangleLines(300, 360, 200, 12, GRAY);
DrawRectangle(300 + volume*200 - 5, 352, 10, 28, DARKGRAY); DrawRectangle((int)(300 + volume*200 - 5), 352, 10, 28, DARKGRAY);
EndDrawing(); EndDrawing();
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------

View File

@ -27,12 +27,13 @@ int main(void)
const int screenWidth = 800; const int screenWidth = 800;
const int screenHeight = 450; const int screenHeight = 450;
SetConfigFlags(FLAG_WINDOW_HIGHDPI | FLAG_WINDOW_RESIZABLE); SetConfigFlags(FLAG_WINDOW_RESIZABLE | FLAG_WINDOW_HIGHDPI);
InitWindow(screenWidth, screenHeight, "raylib [core] example - highdpi testbed"); InitWindow(screenWidth, screenHeight, "raylib [core] example - highdpi testbed");
Vector2 scaleDpi = GetWindowScaleDPI(); Vector2 scaleDpi = GetWindowScaleDPI();
Vector2 mousePos = GetMousePosition(); Vector2 mousePos = GetMousePosition();
int currentMonitor = GetCurrentMonitor(); int currentMonitor = GetCurrentMonitor();
Vector2 windowPos = GetWindowPosition();
int gridSpacing = 40; // Grid spacing in pixels int gridSpacing = 40; // Grid spacing in pixels
@ -47,8 +48,10 @@ int main(void)
mousePos = GetMousePosition(); mousePos = GetMousePosition();
currentMonitor = GetCurrentMonitor(); currentMonitor = GetCurrentMonitor();
scaleDpi = GetWindowScaleDPI(); scaleDpi = GetWindowScaleDPI();
windowPos = GetWindowPosition();
if (IsKeyPressed(KEY_SPACE)) ToggleBorderlessWindowed(); if (IsKeyPressed(KEY_SPACE)) ToggleBorderlessWindowed();
if (IsKeyPressed(KEY_F)) ToggleFullscreen();
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Draw // Draw
@ -58,12 +61,12 @@ int main(void)
ClearBackground(RAYWHITE); ClearBackground(RAYWHITE);
// Draw grid // Draw grid
for (int h = 0; h < 20; h++) for (int h = 0; h < GetScreenHeight()/gridSpacing + 1; h++)
{ {
DrawText(TextFormat("%02i", h*gridSpacing), 4, h*gridSpacing - 4, 10, GRAY); DrawText(TextFormat("%02i", h*gridSpacing), 4, h*gridSpacing - 4, 10, GRAY);
DrawLine(24, h*gridSpacing, GetScreenWidth(), h*gridSpacing, LIGHTGRAY); DrawLine(24, h*gridSpacing, GetScreenWidth(), h*gridSpacing, LIGHTGRAY);
} }
for (int v = 0; v < 40; v++) for (int v = 0; v < GetScreenWidth()/gridSpacing + 1; v++)
{ {
DrawText(TextFormat("%02i", v*gridSpacing), v*gridSpacing - 10, 4, 10, GRAY); DrawText(TextFormat("%02i", v*gridSpacing), v*gridSpacing - 10, 4, 10, GRAY);
DrawLine(v*gridSpacing, 20, v*gridSpacing, GetScreenHeight(), LIGHTGRAY); DrawLine(v*gridSpacing, 20, v*gridSpacing, GetScreenHeight(), LIGHTGRAY);
@ -72,9 +75,14 @@ int main(void)
// Draw UI info // Draw UI info
DrawText(TextFormat("CURRENT MONITOR: %i/%i (%ix%i)", currentMonitor + 1, GetMonitorCount(), DrawText(TextFormat("CURRENT MONITOR: %i/%i (%ix%i)", currentMonitor + 1, GetMonitorCount(),
GetMonitorWidth(currentMonitor), GetMonitorHeight(currentMonitor)), 50, 50, 20, DARKGRAY); GetMonitorWidth(currentMonitor), GetMonitorHeight(currentMonitor)), 50, 50, 20, DARKGRAY);
DrawText(TextFormat("SCREEN SIZE: %ix%i", GetScreenWidth(), GetScreenHeight()), 50, 90, 20, DARKGRAY); DrawText(TextFormat("WINDOW POSITION: %ix%i", (int)windowPos.x, (int)windowPos.y), 50, 90, 20, DARKGRAY);
DrawText(TextFormat("RENDER SIZE: %ix%i", GetRenderWidth(), GetRenderHeight()), 50, 130, 20, DARKGRAY); DrawText(TextFormat("SCREEN SIZE: %ix%i", GetScreenWidth(), GetScreenHeight()), 50, 130, 20, DARKGRAY);
DrawText(TextFormat("SCALE FACTOR: %.1fx%.1f", scaleDpi.x, scaleDpi.y), 50, 170, 20, GRAY); DrawText(TextFormat("RENDER SIZE: %ix%i", GetRenderWidth(), GetRenderHeight()), 50, 170, 20, DARKGRAY);
DrawText(TextFormat("SCALE FACTOR: %.1fx%.1f", scaleDpi.x, scaleDpi.y), 50, 210, 20, GRAY);
// Draw reference rectangles, top-left and bottom-right corners
DrawRectangle(0, 0, 30, 60, RED);
DrawRectangle(GetScreenWidth() - 30, GetScreenHeight() - 60, 30, 60, BLUE);
// Draw mouse position // Draw mouse position
DrawCircleV(GetMousePosition(), 20, MAROON); DrawCircleV(GetMousePosition(), 20, MAROON);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -67,7 +67,7 @@ int main(void)
if (IsKeyPressed(KEY_RIGHT)) gamepad++; if (IsKeyPressed(KEY_RIGHT)) gamepad++;
Vector2 mousePosition = GetMousePosition(); Vector2 mousePosition = GetMousePosition();
vibrateButton = (Rectangle){ 10, 70 + 20*GetGamepadAxisCount(gamepad) + 20, 75, 24 }; vibrateButton = (Rectangle){ 10, 70.0f + 20*GetGamepadAxisCount(gamepad) + 20, 75, 24 };
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && CheckCollisionPointRec(mousePosition, vibrateButton)) SetGamepadVibration(gamepad, 1.0, 1.0, 1.0); if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && CheckCollisionPointRec(mousePosition, vibrateButton)) SetGamepadVibration(gamepad, 1.0, 1.0, 1.0);
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -262,7 +262,7 @@ int main(void)
// Draw vibrate button // Draw vibrate button
DrawRectangleRec(vibrateButton, SKYBLUE); DrawRectangleRec(vibrateButton, SKYBLUE);
DrawText("VIBRATE", vibrateButton.x + 14, vibrateButton.y + 1, 10, DARKGRAY); DrawText("VIBRATE", (int)(vibrateButton.x + 14), (int)(vibrateButton.y + 1), 10, DARKGRAY);
if (GetGamepadButtonPressed() != GAMEPAD_BUTTON_UNKNOWN) DrawText(TextFormat("DETECTED BUTTON: %i", GetGamepadButtonPressed()), 10, 430, 10, RED); if (GetGamepadButtonPressed() != GAMEPAD_BUTTON_UNKNOWN) DrawText(TextFormat("DETECTED BUTTON: %i", GetGamepadButtonPressed()), 10, 430, 10, RED);
else DrawText("DETECTED BUTTON: NONE", 10, 430, 10, GRAY); else DrawText("DETECTED BUTTON: NONE", 10, 430, 10, GRAY);

View File

@ -0,0 +1,333 @@
/*******************************************************************************************
*
* raylib [core] example - keyboard testbed
*
* Example complexity rating: [] 2/4
*
* NOTE: raylib defined keys refer to ENG-US Keyboard layout,
* mapping to other layouts is up to the user
*
* Example originally created with raylib 5.6, last time updated with raylib 5.6
*
* 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) 2026 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#define KEY_REC_SPACING 4 // Space in pixels between key rectangles
//------------------------------------------------------------------------------------
// Module Functions Declaration
//------------------------------------------------------------------------------------
static const char *GetKeyText(int key);
static void GuiKeyboardKey(Rectangle bounds, int key);
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [core] example - keyboard testbed");
SetExitKey(KEY_NULL); // Avoid exit on KEY_ESCAPE
// Keyboard line 01
int line01KeyWidths[15] = { 0 };
for (int i = 0; i < 15; i++) line01KeyWidths[i] = 45;
line01KeyWidths[13] = 62; // PRINTSCREEN
int line01Keys[15] = {
KEY_ESCAPE, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5,
KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11,
KEY_F12, KEY_PRINT_SCREEN, KEY_PAUSE
};
// Keyboard line 02
int line02KeyWidths[15] = { 0 };
for (int i = 0; i < 15; i++) line02KeyWidths[i] = 45;
line02KeyWidths[0] = 25; // GRAVE
line02KeyWidths[13] = 82; // BACKSPACE
int line02Keys[15] = {
KEY_GRAVE, KEY_ONE, KEY_TWO, KEY_THREE, KEY_FOUR,
KEY_FIVE, KEY_SIX, KEY_SEVEN, KEY_EIGHT, KEY_NINE,
KEY_ZERO, KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_DELETE };
// Keyboard line 03
int line03KeyWidths[15] = { 0 };
for (int i = 0; i < 15; i++) line03KeyWidths[i] = 45;
line03KeyWidths[0] = 50; // TAB
line03KeyWidths[13] = 57; // BACKSLASH
int line03Keys[15] = {
KEY_TAB, KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y,
KEY_U, KEY_I, KEY_O, KEY_P, KEY_LEFT_BRACKET,
KEY_RIGHT_BRACKET, KEY_BACKSLASH, KEY_INSERT
};
// Keyboard line 04
int line04KeyWidths[14] = { 0 };
for (int i = 0; i < 14; i++) line04KeyWidths[i] = 45;
line04KeyWidths[0] = 68; // CAPS
line04KeyWidths[12] = 88; // ENTER
int line04Keys[14] = {
KEY_CAPS_LOCK, KEY_A, KEY_S, KEY_D, KEY_F, KEY_G,
KEY_H, KEY_J, KEY_K, KEY_L, KEY_SEMICOLON,
KEY_APOSTROPHE, KEY_ENTER, KEY_PAGE_UP
};
// Keyboard line 05
int line05KeyWidths[14] = { 0 };
for (int i = 0; i < 14; i++) line05KeyWidths[i] = 45;
line05KeyWidths[0] = 80; // LSHIFT
line05KeyWidths[11] = 76; // RSHIFT
int line05Keys[14] = {
KEY_LEFT_SHIFT, KEY_Z, KEY_X, KEY_C, KEY_V, KEY_B,
KEY_N, KEY_M, KEY_COMMA, KEY_PERIOD, /*KEY_MINUS*/
KEY_SLASH, KEY_RIGHT_SHIFT, KEY_UP, KEY_PAGE_DOWN
};
// Keyboard line 06
int line06KeyWidths[11] = { 0 };
for (int i = 0; i < 11; i++) line06KeyWidths[i] = 45;
line06KeyWidths[0] = 80; // LCTRL
line06KeyWidths[3] = 208; // SPACE
line06KeyWidths[7] = 60; // RCTRL
int line06Keys[11] = {
KEY_LEFT_CONTROL, KEY_LEFT_SUPER, KEY_LEFT_ALT,
KEY_SPACE, KEY_RIGHT_ALT, 162, KEY_NULL,
KEY_RIGHT_CONTROL, KEY_LEFT, KEY_DOWN, KEY_RIGHT
};
Vector2 keyboardOffset = { 26, 80 };
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
int key = GetKeyPressed(); // Get pressed keycode
if (key > 0) TraceLog(LOG_INFO, "KEYBOARD TESTBED: KEY PRESSED: %d", key);
int ch = GetCharPressed(); // Get pressed char for text input, using OS mapping
if (ch > 0) TraceLog(LOG_INFO, "KEYBOARD TESTBED: CHAR PRESSED: %c (%d)", ch, ch);
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
DrawText("KEYBOARD LAYOUT: ENG-US", 26, 38, 20, LIGHTGRAY);
// Keyboard line 01 - 15 keys
// ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, IMP, CLOSE
for (int i = 0, recOffsetX = 0; i < 15; i++)
{
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y, line01KeyWidths[i], 30 }, line01Keys[i]);
recOffsetX += line01KeyWidths[i] + KEY_REC_SPACING;
}
// Keyboard line 02 - 15 keys
// `, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, -, =, BACKSPACE, DEL
for (int i = 0, recOffsetX = 0; i < 15; i++)
{
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + KEY_REC_SPACING, line02KeyWidths[i], 38 }, line02Keys[i]);
recOffsetX += line02KeyWidths[i] + KEY_REC_SPACING;
}
// Keyboard line 03 - 15 keys
// TAB, Q, W, E, R, T, Y, U, I, O, P, [, ], \, INS
for (int i = 0, recOffsetX = 0; i < 15; i++)
{
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38 + KEY_REC_SPACING*2, line03KeyWidths[i], 38 }, line03Keys[i]);
recOffsetX += line03KeyWidths[i] + KEY_REC_SPACING;
}
// Keyboard line 04 - 14 keys
// MAYUS, A, S, D, F, G, H, J, K, L, ;, ', ENTER, REPAG
for (int i = 0, recOffsetX = 0; i < 14; i++)
{
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38*2 + KEY_REC_SPACING*3, line04KeyWidths[i], 38 }, line04Keys[i]);
recOffsetX += line04KeyWidths[i] + KEY_REC_SPACING;
}
// Keyboard line 05 - 14 keys
// LSHIFT, Z, X, C, V, B, N, M, ,, ., /, RSHIFT, UP, AVPAG
for (int i = 0, recOffsetX = 0; i < 14; i++)
{
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38*3 + KEY_REC_SPACING*4, line05KeyWidths[i], 38 }, line05Keys[i]);
recOffsetX += line05KeyWidths[i] + KEY_REC_SPACING;
}
// Keyboard line 06 - 11 keys
// LCTRL, WIN, LALT, SPACE, ALTGR, \, FN, RCTRL, LEFT, DOWN, RIGHT
for (int i = 0, recOffsetX = 0; i < 11; i++)
{
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38*4 + KEY_REC_SPACING*5, line06KeyWidths[i], 38 }, line06Keys[i]);
recOffsetX += line06KeyWidths[i] + KEY_REC_SPACING;
}
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
//------------------------------------------------------------------------------------
// Module Functions Definition
//------------------------------------------------------------------------------------
// Get keyboard keycode as text (US keyboard)
// NOTE: Mapping for other keyboard layouts can be done here
static const char *GetKeyText(int key)
{
switch (key)
{
case KEY_APOSTROPHE : return "'"; // Key: '
case KEY_COMMA : return ","; // Key: ,
case KEY_MINUS : return "-"; // Key: -
case KEY_PERIOD : return "."; // Key: .
case KEY_SLASH : return "/"; // Key: /
case KEY_ZERO : return "0"; // Key: 0
case KEY_ONE : return "1"; // Key: 1
case KEY_TWO : return "2"; // Key: 2
case KEY_THREE : return "3"; // Key: 3
case KEY_FOUR : return "4"; // Key: 4
case KEY_FIVE : return "5"; // Key: 5
case KEY_SIX : return "6"; // Key: 6
case KEY_SEVEN : return "7"; // Key: 7
case KEY_EIGHT : return "8"; // Key: 8
case KEY_NINE : return "9"; // Key: 9
case KEY_SEMICOLON : return ";"; // Key: ;
case KEY_EQUAL : return "="; // Key: =
case KEY_A : return "A"; // Key: A | a
case KEY_B : return "B"; // Key: B | b
case KEY_C : return "C"; // Key: C | c
case KEY_D : return "D"; // Key: D | d
case KEY_E : return "E"; // Key: E | e
case KEY_F : return "F"; // Key: F | f
case KEY_G : return "G"; // Key: G | g
case KEY_H : return "H"; // Key: H | h
case KEY_I : return "I"; // Key: I | i
case KEY_J : return "J"; // Key: J | j
case KEY_K : return "K"; // Key: K | k
case KEY_L : return "L"; // Key: L | l
case KEY_M : return "M"; // Key: M | m
case KEY_N : return "N"; // Key: N | n
case KEY_O : return "O"; // Key: O | o
case KEY_P : return "P"; // Key: P | p
case KEY_Q : return "Q"; // Key: Q | q
case KEY_R : return "R"; // Key: R | r
case KEY_S : return "S"; // Key: S | s
case KEY_T : return "T"; // Key: T | t
case KEY_U : return "U"; // Key: U | u
case KEY_V : return "V"; // Key: V | v
case KEY_W : return "W"; // Key: W | w
case KEY_X : return "X"; // Key: X | x
case KEY_Y : return "Y"; // Key: Y | y
case KEY_Z : return "Z"; // Key: Z | z
case KEY_LEFT_BRACKET : return "["; // Key: [
case KEY_BACKSLASH : return "\\"; // Key: '\'
case KEY_RIGHT_BRACKET : return "]"; // Key: ]
case KEY_GRAVE : return "`"; // Key: `
case KEY_SPACE : return "SPACE"; // Key: Space
case KEY_ESCAPE : return "ESC"; // Key: Esc
case KEY_ENTER : return "ENTER"; // Key: Enter
case KEY_TAB : return "TAB"; // Key: Tab
case KEY_BACKSPACE : return "BACK"; // Key: Backspace
case KEY_INSERT : return "INS"; // Key: Ins
case KEY_DELETE : return "DEL"; // Key: Del
case KEY_RIGHT : return "RIGHT"; // Key: Cursor right
case KEY_LEFT : return "LEFT"; // Key: Cursor left
case KEY_DOWN : return "DOWN"; // Key: Cursor down
case KEY_UP : return "UP"; // Key: Cursor up
case KEY_PAGE_UP : return "PGUP"; // Key: Page up
case KEY_PAGE_DOWN : return "PGDOWN"; // Key: Page down
case KEY_HOME : return "HOME"; // Key: Home
case KEY_END : return "END"; // Key: End
case KEY_CAPS_LOCK : return "CAPS"; // Key: Caps lock
case KEY_SCROLL_LOCK : return "LOCK"; // Key: Scroll down
case KEY_NUM_LOCK : return "NUMLOCK"; // Key: Num lock
case KEY_PRINT_SCREEN : return "PRINTSCR"; // Key: Print screen
case KEY_PAUSE : return "PAUSE"; // Key: Pause
case KEY_F1 : return "F1"; // Key: F1
case KEY_F2 : return "F2"; // Key: F2
case KEY_F3 : return "F3"; // Key: F3
case KEY_F4 : return "F4"; // Key: F4
case KEY_F5 : return "F5"; // Key: F5
case KEY_F6 : return "F6"; // Key: F6
case KEY_F7 : return "F7"; // Key: F7
case KEY_F8 : return "F8"; // Key: F8
case KEY_F9 : return "F9"; // Key: F9
case KEY_F10 : return "F10"; // Key: F10
case KEY_F11 : return "F11"; // Key: F11
case KEY_F12 : return "F12"; // Key: F12
case KEY_LEFT_SHIFT : return "LSHIFT"; // Key: Shift left
case KEY_LEFT_CONTROL : return "LCTRL"; // Key: Control left
case KEY_LEFT_ALT : return "LALT"; // Key: Alt left
case KEY_LEFT_SUPER : return "WIN"; // Key: Super left
case KEY_RIGHT_SHIFT : return "RSHIFT"; // Key: Shift right
case KEY_RIGHT_CONTROL : return "RCTRL"; // Key: Control right
case KEY_RIGHT_ALT : return "ALTGR"; // Key: Alt right
case KEY_RIGHT_SUPER : return "RSUPER"; // Key: Super right
case KEY_KB_MENU : return "KBMENU"; // Key: KB menu
case KEY_KP_0 : return "KP0"; // Key: Keypad 0
case KEY_KP_1 : return "KP1"; // Key: Keypad 1
case KEY_KP_2 : return "KP2"; // Key: Keypad 2
case KEY_KP_3 : return "KP3"; // Key: Keypad 3
case KEY_KP_4 : return "KP4"; // Key: Keypad 4
case KEY_KP_5 : return "KP5"; // Key: Keypad 5
case KEY_KP_6 : return "KP6"; // Key: Keypad 6
case KEY_KP_7 : return "KP7"; // Key: Keypad 7
case KEY_KP_8 : return "KP8"; // Key: Keypad 8
case KEY_KP_9 : return "KP9"; // Key: Keypad 9
case KEY_KP_DECIMAL : return "KPDEC"; // Key: Keypad .
case KEY_KP_DIVIDE : return "KPDIV"; // Key: Keypad /
case KEY_KP_MULTIPLY : return "KPMUL"; // Key: Keypad *
case KEY_KP_SUBTRACT : return "KPSUB"; // Key: Keypad -
case KEY_KP_ADD : return "KPADD"; // Key: Keypad +
case KEY_KP_ENTER : return "KPENTER"; // Key: Keypad Enter
case KEY_KP_EQUAL : return "KPEQU"; // Key: Keypad =
default: return "";
}
}
// Draw keyboard key
static void GuiKeyboardKey(Rectangle bounds, int key)
{
if (key == KEY_NULL) DrawRectangleLinesEx(bounds, 2.0f, LIGHTGRAY);
else
{
if (IsKeyDown(key))
{
DrawRectangleLinesEx(bounds, 2.0f, MAROON);
DrawText(GetKeyText(key), bounds.x + 4, bounds.y + 4, 10, MAROON);
}
else
{
DrawRectangleLinesEx(bounds, 2.0f, DARKGRAY);
DrawText(GetKeyText(key), bounds.x + 4, bounds.y + 4, 10, DARKGRAY);
}
}
if (CheckCollisionPointRec(GetMousePosition(), bounds))
{
DrawRectangleRec(bounds, Fade(RED, 0.2f));
DrawRectangleLinesEx(bounds, 3.0f, RED);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -112,16 +112,16 @@ int main(void)
if (CheckCollisionPointRec(mousePosition, decreaseResolutionButton) && mousePressed) if (CheckCollisionPointRec(mousePosition, decreaseResolutionButton) && mousePressed)
{ {
resolutionIndex = (resolutionIndex + RESOLUTION_COUNT - 1)%RESOLUTION_COUNT; resolutionIndex = (resolutionIndex + RESOLUTION_COUNT - 1)%RESOLUTION_COUNT;
gameWidth = resolutionList[resolutionIndex].x; gameWidth = (int)resolutionList[resolutionIndex].x;
gameHeight = resolutionList[resolutionIndex].y; gameHeight = (int)resolutionList[resolutionIndex].y;
ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target); ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target);
} }
if (CheckCollisionPointRec(mousePosition, increaseResolutionButton) && mousePressed) if (CheckCollisionPointRec(mousePosition, increaseResolutionButton) && mousePressed)
{ {
resolutionIndex = (resolutionIndex + 1)%RESOLUTION_COUNT; resolutionIndex = (resolutionIndex + 1)%RESOLUTION_COUNT;
gameWidth = resolutionList[resolutionIndex].x; gameWidth = (int)resolutionList[resolutionIndex].x;
gameHeight = resolutionList[resolutionIndex].y; gameHeight = (int)resolutionList[resolutionIndex].y;
ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target); ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target);
} }
@ -145,7 +145,7 @@ int main(void)
// Draw our scene to the render texture // Draw our scene to the render texture
BeginTextureMode(target); BeginTextureMode(target);
ClearBackground(WHITE); ClearBackground(WHITE);
DrawCircle(textureMousePosition.x, textureMousePosition.y, 20.0f, LIME); DrawCircleV(textureMousePosition, 20.0f, LIME);
EndTextureMode(); EndTextureMode();
// Draw render texture to main framebuffer // Draw render texture to main framebuffer
@ -159,7 +159,7 @@ int main(void)
// Draw info box // Draw info box
Rectangle infoRect = (Rectangle){5, 5, 330, 105}; Rectangle infoRect = (Rectangle){5, 5, 330, 105};
DrawRectangleRec(infoRect, Fade(LIGHTGRAY, 0.7f)); DrawRectangleRec(infoRect, Fade(LIGHTGRAY, 0.7f));
DrawRectangleLines(infoRect.x, infoRect.y, infoRect.width, infoRect.height, BLUE); DrawRectangleLinesEx(infoRect, 1, BLUE);
DrawText(TextFormat("Window Resolution: %d x %d", screenWidth, screenHeight), 15, 15, 10, BLACK); DrawText(TextFormat("Window Resolution: %d x %d", screenWidth, screenHeight), 15, 15, 10, BLACK);
DrawText(TextFormat("Game Resolution: %d x %d", gameWidth, gameHeight), 15, 30, 10, BLACK); DrawText(TextFormat("Game Resolution: %d x %d", gameWidth, gameHeight), 15, 30, 10, BLACK);

View File

@ -1,11 +1,13 @@
# #
# raylib examples list used to generate/update collection # raylib examples list with available .c example files
# examples must be provided as: <example_category>;<example_name>;<example_stars>;<raylib_created_version>;<raylib_last_update_version>;<year_created>;<year_reviewed>;"<example_author_name>";<author_github_user> #
# WARNING: List is not ordered by example name but by the display order on web,
# so it can not be automatically generated scanning available .c code files, only updated
# new examples are added at the end of each category; it's up to the user to reorder them as desired
#
# examples data is listed as: <example_category>;<example_name>;<example_stars>;<raylib_created_version>;<raylib_last_update_version>;<year_created>;<year_reviewed>;"<example_author_name>";<author_github_user>
# #
# This list is used as the main reference by [rexm] tool for examples collection validation and management # This list is used as the main reference by [rexm] tool for examples collection validation and management
# New examples must be added to this list and any possible rename must be made on this list first
#
# WARNING: List is not ordered by example name but by the display order on web
# #
core;core_basic_window;★☆☆☆;1.0;1.0;2013;2025;"Ramon Santamaria";@raysan5 core;core_basic_window;★☆☆☆;1.0;1.0;2013;2025;"Ramon Santamaria";@raysan5
core;core_delta_time;★☆☆☆;5.5;5.6-dev;2025;2025;"Robin";@RobinsAviary core;core_delta_time;★☆☆☆;5.5;5.6-dev;2025;2025;"Robin";@RobinsAviary
@ -54,6 +56,7 @@ core;core_screen_recording;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santama
core;core_clipboard_text;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ananth S";@Ananth1839 core;core_clipboard_text;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ananth S";@Ananth1839
core;core_text_file_loading;★☆☆☆;5.5;5.6;0;0;"Aanjishnu Bhattacharyya";@NimComPoo-04 core;core_text_file_loading;★☆☆☆;5.5;5.6;0;0;"Aanjishnu Bhattacharyya";@NimComPoo-04
core;core_compute_hash;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5 core;core_compute_hash;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5
core;core_keyboard_testbed;★★☆☆;5.6;5.6;2026;2026;"Ramon Santamaria";@raysan5
shapes;shapes_basic_shapes;★☆☆☆;1.0;4.2;2014;2025;"Ramon Santamaria";@raysan5 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_bouncing_ball;★☆☆☆;2.5;2.5;2013;2025;"Ramon Santamaria";@raysan5
shapes;shapes_bullet_hell;★☆☆☆;5.6;5.6;2025;2025;"Zero";@zerohorsepower shapes;shapes_bullet_hell;★☆☆☆;5.6;5.6;2025;2025;"Zero";@zerohorsepower
@ -92,6 +95,7 @@ shapes;shapes_rlgl_color_wheel;★★★☆;5.6-dev;5.6-dev;2025;2025;"Robin";@R
shapes;shapes_rlgl_triangle;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Robin";@RobinsAviary shapes;shapes_rlgl_triangle;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Robin";@RobinsAviary
shapes;shapes_ball_physics;★★☆☆;5.6-dev;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto shapes;shapes_ball_physics;★★☆☆;5.6-dev;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto
shapes;shapes_penrose_tile;★★★★;5.5;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto shapes;shapes_penrose_tile;★★★★;5.5;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto
shapes;shapes_hilbert_curve;★★★☆;5.6;5.6;2025;2025;"Hamza RAHAL";@hmz-rhl
textures;textures_logo_raylib;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5 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_srcrec_dstrec;★★★☆;1.3;1.3;2015;2025;"Ramon Santamaria";@raysan5
textures;textures_image_drawing;★★☆☆;1.4;1.4;2016;2025;"Ramon Santamaria";@raysan5 textures;textures_image_drawing;★★☆☆;1.4;1.4;2016;2025;"Ramon Santamaria";@raysan5
@ -121,6 +125,7 @@ textures;textures_screen_buffer;★★☆☆;5.5;5.5;2025;2025;"Agnis Aldiņš";
textures;textures_textured_curve;★★★☆;4.5;4.5;2022;2025;"Jeffery Myers";@JeffM2501 textures;textures_textured_curve;★★★☆;4.5;4.5;2022;2025;"Jeffery Myers";@JeffM2501
textures;textures_sprite_stacking;★★☆☆;5.6-dev;6.0;2025;2025;"Robin";@RobinsAviary textures;textures_sprite_stacking;★★☆☆;5.6-dev;6.0;2025;2025;"Robin";@RobinsAviary
textures;textures_cellular_automata;★★☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant textures;textures_cellular_automata;★★☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
textures;textures_framebuffer_rendering;★★☆☆;5.6;5.6;2026;2026;"Jack Boakes";@jackboakes
text;text_sprite_fonts;★☆☆☆;1.7;3.7;2017;2025;"Ramon Santamaria";@raysan5 text;text_sprite_fonts;★☆☆☆;1.7;3.7;2017;2025;"Ramon Santamaria";@raysan5
text;text_font_spritefont;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5 text;text_font_spritefont;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
text;text_font_filters;★★☆☆;1.3;4.2;2015;2025;"Ramon Santamaria";@raysan5 text;text_font_filters;★★☆☆;1.3;4.2;2015;2025;"Ramon Santamaria";@raysan5

View File

@ -45,7 +45,7 @@ static void FreeMeshBuilder(MeshBuilder *mb);
static Mesh BuildMesh(MeshBuilder *mb); static Mesh BuildMesh(MeshBuilder *mb);
static Mesh GenMeshDecal(Model inputModel, Matrix projection, float decalSize, float decalOffset); static Mesh GenMeshDecal(Model inputModel, Matrix projection, float decalSize, float decalOffset);
static Vector3 ClipSegment(Vector3 v0, Vector3 v1, Vector3 p, float s); static Vector3 ClipSegment(Vector3 v0, Vector3 v1, Vector3 p, float s);
#define FreeDecalMeshData() GenMeshDecal((Model){ .meshCount = -1.0f }, (Matrix){ 0 }, 0.0f, 0.0f) static void FreeDecalMeshData(void) { GenMeshDecal((Model){ .meshCount = -1 }, (Matrix){ 0 }, 0.0f, 0.0f); }
static bool GuiButton(Rectangle rec, const char *label); static bool GuiButton(Rectangle rec, const char *label);
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
@ -198,12 +198,12 @@ int main(void)
EndMode3D(); EndMode3D();
float yPos = 10; float yPos = 10;
float x0 = GetScreenWidth() - 300; float x0 = GetScreenWidth() - 300.0f;
float x1 = x0 + 100; float x1 = x0 + 100;
float x2 = x1 + 100; float x2 = x1 + 100;
DrawText("Vertices", x1, yPos, 10, LIME); DrawText("Vertices", (int)x1, (int)yPos, 10, LIME);
DrawText("Triangles", x2, yPos, 10, LIME); DrawText("Triangles", (int)x2, (int)yPos, 10, LIME);
yPos += 15; yPos += 15;
int vertexCount = 0; int vertexCount = 0;
@ -215,24 +215,24 @@ int main(void)
triangleCount += model.meshes[i].triangleCount; triangleCount += model.meshes[i].triangleCount;
} }
DrawText("Main model", x0, yPos, 10, LIME); DrawText("Main model", (int)x0, (int)yPos, 10, LIME);
DrawText(TextFormat("%d", vertexCount), x1, yPos, 10, LIME); DrawText(TextFormat("%d", vertexCount), (int)x1, (int)yPos, 10, LIME);
DrawText(TextFormat("%d", triangleCount), x2, yPos, 10, LIME); DrawText(TextFormat("%d", triangleCount), (int)x2, (int)yPos, 10, LIME);
yPos += 15; yPos += 15;
for (int i = 0; i < decalCount; i++) for (int i = 0; i < decalCount; i++)
{ {
if (i == 20) if (i == 20)
{ {
DrawText("...", x0, yPos, 10, LIME); DrawText("...", (int)x0, (int)yPos, 10, LIME);
yPos += 15; yPos += 15;
} }
if (i < 20) if (i < 20)
{ {
DrawText(TextFormat("Decal #%d", i+1), x0, yPos, 10, LIME); DrawText(TextFormat("Decal #%d", i+1), (int)x0, (int)yPos, 10, LIME);
DrawText(TextFormat("%d", decalModels[i].meshes[0].vertexCount), x1, yPos, 10, LIME); DrawText(TextFormat("%d", decalModels[i].meshes[0].vertexCount), (int)x1, (int)yPos, 10, LIME);
DrawText(TextFormat("%d", decalModels[i].meshes[0].triangleCount), x2, yPos, 10, LIME); DrawText(TextFormat("%d", decalModels[i].meshes[0].triangleCount), (int)x2, (int)yPos, 10, LIME);
yPos += 15; yPos += 15;
} }
@ -240,18 +240,18 @@ int main(void)
triangleCount += decalModels[i].meshes[0].triangleCount; triangleCount += decalModels[i].meshes[0].triangleCount;
} }
DrawText("TOTAL", x0, yPos, 10, LIME); DrawText("TOTAL", (int)x0, (int)yPos, 10, LIME);
DrawText(TextFormat("%d", vertexCount), x1, yPos, 10, LIME); DrawText(TextFormat("%d", vertexCount), (int)x1, (int)yPos, 10, LIME);
DrawText(TextFormat("%d", triangleCount), x2, yPos, 10, LIME); DrawText(TextFormat("%d", triangleCount), (int)x2, (int)yPos, 10, LIME);
yPos += 15; yPos += 15;
DrawText("Hold RMB to move camera", 10, 430, 10, GRAY); DrawText("Hold RMB to move camera", 10, 430, 10, GRAY);
DrawText("(c) Character model and texture from kenney.nl", screenWidth - 260, screenHeight - 20, 10, GRAY); DrawText("(c) Character model and texture from kenney.nl", screenWidth - 260, screenHeight - 20, 10, GRAY);
// UI elements // UI elements
if (GuiButton((Rectangle){ 10, screenHeight - 100, 100, 60 }, showModel ? "Hide Model" : "Show Model")) showModel = !showModel; if (GuiButton((Rectangle){ 10, screenHeight - 1000.f, 100, 60 }, showModel ? "Hide Model" : "Show Model")) showModel = !showModel;
if (GuiButton((Rectangle){ 10 + 110, screenHeight - 100, 100, 60 }, "Clear Decals")) if (GuiButton((Rectangle){ 10 + 110, screenHeight - 100.0f, 100, 60 }, "Clear Decals"))
{ {
// Clear decals, unload all decal models // Clear decals, unload all decal models
for (int i = 0; i < decalCount; i++) UnloadModel(decalModels[i]); for (int i = 0; i < decalCount; i++) UnloadModel(decalModels[i]);
@ -596,8 +596,8 @@ static bool GuiButton(Rectangle rec, const char *label)
DrawRectangleRec(rec, bgColor); DrawRectangleRec(rec, bgColor);
DrawRectangleLinesEx(rec, 2.0f, DARKGRAY); DrawRectangleLinesEx(rec, 2.0f, DARKGRAY);
float fontSize = 10.0f; int fontSize = 10;
float textWidth = MeasureText(label, fontSize); int textWidth = MeasureText(label, fontSize);
DrawText(label, (int)(rec.x + rec.width*0.5f - textWidth*0.5f), (int)(rec.y + rec.height*0.5f - fontSize*0.5f), fontSize, DARKGRAY); DrawText(label, (int)(rec.x + rec.width*0.5f - textWidth*0.5f), (int)(rec.y + rec.height*0.5f - fontSize*0.5f), fontSize, DARKGRAY);

View File

@ -80,12 +80,17 @@ int main(void)
if (playerCellY < 0) playerCellY = 0; if (playerCellY < 0) playerCellY = 0;
else if (playerCellY >= cubicmap.height) playerCellY = cubicmap.height - 1; else if (playerCellY >= cubicmap.height) playerCellY = cubicmap.height - 1;
// Check map collisions using image data and player position // Check map collisions using image data and player position against surrounding cells only
// TODO: Improvement: Just check player surrounding cells for collision for (int y = playerCellY - 1; y <= playerCellY + 1; y++)
for (int y = 0; y < cubicmap.height; y++)
{ {
for (int x = 0; x < cubicmap.width; x++) // Avoid map accessing out of bounds
if ((y < 0) || (y >= cubicmap.height)) continue;
for (int x = playerCellX - 1; x <= playerCellX + 1; x++)
{ {
// Avoid map accessing out of bounds
if ((x < 0) || (x >= cubicmap.width)) continue;
if ((mapPixels[y*cubicmap.width + x].r == 255) && // Collision: white pixel, only check R channel if ((mapPixels[y*cubicmap.width + x].r == 255) && // Collision: white pixel, only check R channel
(CheckCollisionCircleRec(playerPos, playerRadius, (CheckCollisionCircleRec(playerPos, playerRadius,
(Rectangle){ mapPosition.x - 0.5f + x*1.0f, mapPosition.z - 0.5f + y*1.0f, 1.0f, 1.0f }))) (Rectangle){ mapPosition.x - 0.5f + x*1.0f, mapPosition.z - 0.5f + y*1.0f, 1.0f, 1.0f })))

View File

@ -40,13 +40,13 @@
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// GBuffer data // GBuffer data
typedef struct GBuffer { typedef struct GBuffer {
unsigned int framebuffer; unsigned int framebufferId;
unsigned int positionTexture; unsigned int positionTextureId;
unsigned int normalTexture; unsigned int normalTextureId;
unsigned int albedoSpecTexture; unsigned int albedoSpecTextureId;
unsigned int depthRenderbuffer; unsigned int depthRenderbufferId;
} GBuffer; } GBuffer;
// Deferred mode passes // Deferred mode passes
@ -90,15 +90,10 @@ int main(void)
// Initialize the G-buffer // Initialize the G-buffer
GBuffer gBuffer = { 0 }; GBuffer gBuffer = { 0 };
gBuffer.framebuffer = rlLoadFramebuffer(); gBuffer.framebufferId = rlLoadFramebuffer();
if (gBuffer.framebufferId == 0) TraceLog(LOG_WARNING, "Failed to create framebufferId");
if (!gBuffer.framebuffer) rlEnableFramebuffer(gBuffer.framebufferId);
{
TraceLog(LOG_WARNING, "Failed to create framebuffer");
exit(1);
}
rlEnableFramebuffer(gBuffer.framebuffer);
// NOTE: Vertex positions are stored in a texture for simplicity. A better approach would use a depth texture // NOTE: Vertex positions are stored in a texture for simplicity. A better approach would use a depth texture
// (instead of a detph renderbuffer) to reconstruct world positions in the final render shader via clip-space position, // (instead of a detph renderbuffer) to reconstruct world positions in the final render shader via clip-space position,
@ -107,35 +102,31 @@ int main(void)
// 16-bit precision ensures OpenGL ES 3 compatibility, though it may lack precision for real scenarios // 16-bit precision ensures OpenGL ES 3 compatibility, though it may lack precision for real scenarios
// But as mentioned above, the positions could be reconstructed instead of stored. If not targeting OpenGL ES // But as mentioned above, the positions could be reconstructed instead of stored. If not targeting OpenGL ES
// and you wish to maintain this approach, consider using `RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32` // and you wish to maintain this approach, consider using `RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32`
gBuffer.positionTexture = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16, 1); gBuffer.positionTextureId = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16, 1);
// Similarly, 16-bit precision is used for normals ensures OpenGL ES 3 compatibility // Similarly, 16-bit precision is used for normals ensures OpenGL ES 3 compatibility
// This is generally sufficient, but a 16-bit fixed-point format offer a better uniform precision in all orientations // This is generally sufficient, but a 16-bit fixed-point format offer a better uniform precision in all orientations
gBuffer.normalTexture = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16, 1); gBuffer.normalTextureId = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16, 1);
// Albedo (diffuse color) and specular strength can be combined into one texture // Albedo (diffuse color) and specular strength can be combined into one texture
// The color in RGB, and the specular strength in the alpha channel // The color in RGB, and the specular strength in the alpha channel
gBuffer.albedoSpecTexture = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, 1); gBuffer.albedoSpecTextureId = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, 1);
// Activate the draw buffers for our framebuffer // Activate the draw buffers for our framebufferId
rlActiveDrawBuffers(3); rlActiveDrawBuffers(3);
// Now we attach our textures to the framebuffer // Now we attach our textures to the framebufferId
rlFramebufferAttach(gBuffer.framebuffer, gBuffer.positionTexture, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_TEXTURE2D, 0); rlFramebufferAttach(gBuffer.framebufferId, gBuffer.positionTextureId, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_TEXTURE2D, 0);
rlFramebufferAttach(gBuffer.framebuffer, gBuffer.normalTexture, RL_ATTACHMENT_COLOR_CHANNEL1, RL_ATTACHMENT_TEXTURE2D, 0); rlFramebufferAttach(gBuffer.framebufferId, gBuffer.normalTextureId, RL_ATTACHMENT_COLOR_CHANNEL1, RL_ATTACHMENT_TEXTURE2D, 0);
rlFramebufferAttach(gBuffer.framebuffer, gBuffer.albedoSpecTexture, RL_ATTACHMENT_COLOR_CHANNEL2, RL_ATTACHMENT_TEXTURE2D, 0); rlFramebufferAttach(gBuffer.framebufferId, gBuffer.albedoSpecTextureId, RL_ATTACHMENT_COLOR_CHANNEL2, RL_ATTACHMENT_TEXTURE2D, 0);
// Finally we attach the depth buffer // Finally we attach the depth buffer
gBuffer.depthRenderbuffer = rlLoadTextureDepth(screenWidth, screenHeight, true); gBuffer.depthRenderbufferId = rlLoadTextureDepth(screenWidth, screenHeight, true);
rlFramebufferAttach(gBuffer.framebuffer, gBuffer.depthRenderbuffer, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_RENDERBUFFER, 0); rlFramebufferAttach(gBuffer.framebufferId, gBuffer.depthRenderbufferId, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_RENDERBUFFER, 0);
// Make sure our framebuffer is complete // Make sure our framebufferId is complete
// NOTE: rlFramebufferComplete() automatically unbinds the framebuffer, so we don't have // NOTE: rlFramebufferComplete() automatically unbinds the framebufferId, so we don't have to rlDisableFramebuffer() here
// to rlDisableFramebuffer() here if (!rlFramebufferComplete(gBuffer.framebufferId)) TraceLog(LOG_WARNING, "Framebuffer is not complete");
if (!rlFramebufferComplete(gBuffer.framebuffer))
{
TraceLog(LOG_WARNING, "Framebuffer is not complete");
}
// Now we initialize the sampler2D uniform's in the deferred shader // Now we initialize the sampler2D uniform's in the deferred shader
// We do this by setting the uniform's values to the texture units that // We do this by setting the uniform's values to the texture units that
@ -176,7 +167,7 @@ int main(void)
cubeRotations[i] = (float)(rand()%360); cubeRotations[i] = (float)(rand()%360);
} }
DeferredMode mode = DEFERRED_SHADING; int mode = DEFERRED_SHADING;
rlEnableDepthTest(); rlEnableDepthTest();
@ -215,17 +206,16 @@ int main(void)
BeginDrawing(); BeginDrawing();
// Draw to the geometry buffer by first activating it // Draw to the geometry buffer by first activating it
rlEnableFramebuffer(gBuffer.framebuffer); rlEnableFramebuffer(gBuffer.framebufferId);
rlClearColor(0, 0, 0, 0); rlClearColor(0, 0, 0, 0);
rlClearScreenBuffers(); // Clear color and depth buffer rlClearScreenBuffers(); // Clear color and depth buffer
rlDisableColorBlend(); rlDisableColorBlend();
BeginMode3D(camera); BeginMode3D(camera);
// NOTE: We have to use rlEnableShader here. `BeginShaderMode` or thus `rlSetShader` // NOTE: We have to use rlEnableShader here. `BeginShaderMode` or thus `rlSetShader`
// will not work, as they won't immediately load the shader program // will not work, as they won't immediately load the shader program
rlEnableShader(gbufferShader.id); rlEnableShader(gbufferShader.id);
// When drawing a model here, make sure that the material's shaders // When drawing a model here, make sure that the material's shaders are set to the gbuffer shader!
// are set to the gbuffer shader!
DrawModel(model, Vector3Zero(), 1.0f, WHITE); DrawModel(model, Vector3Zero(), 1.0f, WHITE);
DrawModel(cube, (Vector3) { 0.0, 1.0f, 0.0 }, 1.0f, WHITE); DrawModel(cube, (Vector3) { 0.0, 1.0f, 0.0 }, 1.0f, WHITE);
@ -234,12 +224,12 @@ int main(void)
Vector3 position = cubePositions[i]; Vector3 position = cubePositions[i];
DrawModelEx(cube, position, (Vector3) { 1, 1, 1 }, cubeRotations[i], (Vector3) { CUBE_SCALE, CUBE_SCALE, CUBE_SCALE }, WHITE); DrawModelEx(cube, position, (Vector3) { 1, 1, 1 }, cubeRotations[i], (Vector3) { CUBE_SCALE, CUBE_SCALE, CUBE_SCALE }, WHITE);
} }
rlDisableShader(); rlDisableShader();
EndMode3D(); EndMode3D();
rlEnableColorBlend(); rlEnableColorBlend();
// Go back to the default framebuffer (0) and draw our deferred shading // Go back to the default framebufferId (0) and draw our deferred shading
rlDisableFramebuffer(); rlDisableFramebuffer();
rlClearScreenBuffers(); // Clear color & depth buffer rlClearScreenBuffers(); // Clear color & depth buffer
@ -254,21 +244,21 @@ int main(void)
// We are binding them to locations that we earlier set in sampler2D uniforms `gPosition`, `gNormal`, // We are binding them to locations that we earlier set in sampler2D uniforms `gPosition`, `gNormal`,
// and `gAlbedoSpec` // and `gAlbedoSpec`
rlActiveTextureSlot(texUnitPosition); rlActiveTextureSlot(texUnitPosition);
rlEnableTexture(gBuffer.positionTexture); rlEnableTexture(gBuffer.positionTextureId);
rlActiveTextureSlot(texUnitNormal); rlActiveTextureSlot(texUnitNormal);
rlEnableTexture(gBuffer.normalTexture); rlEnableTexture(gBuffer.normalTextureId);
rlActiveTextureSlot(texUnitAlbedoSpec); rlActiveTextureSlot(texUnitAlbedoSpec);
rlEnableTexture(gBuffer.albedoSpecTexture); rlEnableTexture(gBuffer.albedoSpecTextureId);
// Finally, we draw a fullscreen quad to our default framebuffer // Finally, we draw a fullscreen quad to our default framebufferId
// This will now be shaded using our deferred shader // This will now be shaded using our deferred shader
rlLoadDrawQuad(); rlLoadDrawQuad();
rlDisableShader(); rlDisableShader();
rlEnableColorBlend(); rlEnableColorBlend();
EndMode3D(); EndMode3D();
// As a last step, we now copy over the depth buffer from our g-buffer to the default framebuffer // As a last step, we now copy over the depth buffer from our g-buffer to the default framebufferId
rlBindFramebuffer(RL_READ_FRAMEBUFFER, gBuffer.framebuffer); rlBindFramebuffer(RL_READ_FRAMEBUFFER, gBuffer.framebufferId);
rlBindFramebuffer(RL_DRAW_FRAMEBUFFER, 0); rlBindFramebuffer(RL_DRAW_FRAMEBUFFER, 0);
rlBlitFramebuffer(0, 0, screenWidth, screenHeight, 0, 0, screenWidth, screenHeight, 0x00000100); // GL_DEPTH_BUFFER_BIT rlBlitFramebuffer(0, 0, screenWidth, screenHeight, 0, 0, screenWidth, screenHeight, 0x00000100); // GL_DEPTH_BUFFER_BIT
rlDisableFramebuffer(); rlDisableFramebuffer();
@ -290,7 +280,7 @@ int main(void)
case DEFERRED_POSITION: case DEFERRED_POSITION:
{ {
DrawTextureRec((Texture2D){ DrawTextureRec((Texture2D){
.id = gBuffer.positionTexture, .id = gBuffer.positionTextureId,
.width = screenWidth, .width = screenWidth,
.height = screenHeight, .height = screenHeight,
}, (Rectangle) { 0, 0, (float)screenWidth, (float)-screenHeight }, Vector2Zero(), RAYWHITE); }, (Rectangle) { 0, 0, (float)screenWidth, (float)-screenHeight }, Vector2Zero(), RAYWHITE);
@ -300,7 +290,7 @@ int main(void)
case DEFERRED_NORMAL: case DEFERRED_NORMAL:
{ {
DrawTextureRec((Texture2D){ DrawTextureRec((Texture2D){
.id = gBuffer.normalTexture, .id = gBuffer.normalTextureId,
.width = screenWidth, .width = screenWidth,
.height = screenHeight, .height = screenHeight,
}, (Rectangle) { 0, 0, (float)screenWidth, (float)-screenHeight }, Vector2Zero(), RAYWHITE); }, (Rectangle) { 0, 0, (float)screenWidth, (float)-screenHeight }, Vector2Zero(), RAYWHITE);
@ -310,7 +300,7 @@ int main(void)
case DEFERRED_ALBEDO: case DEFERRED_ALBEDO:
{ {
DrawTextureRec((Texture2D){ DrawTextureRec((Texture2D){
.id = gBuffer.albedoSpecTexture, .id = gBuffer.albedoSpecTextureId,
.width = screenWidth, .width = screenWidth,
.height = screenHeight, .height = screenHeight,
}, (Rectangle) { 0, 0, (float)screenWidth, (float)-screenHeight }, Vector2Zero(), RAYWHITE); }, (Rectangle) { 0, 0, (float)screenWidth, (float)-screenHeight }, Vector2Zero(), RAYWHITE);
@ -331,18 +321,20 @@ int main(void)
// De-Initialization // De-Initialization
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
UnloadModel(model); // Unload the models // Unload the models
UnloadModel(model);
UnloadModel(cube); UnloadModel(cube);
UnloadShader(deferredShader); // Unload shaders // Unload shaders
UnloadShader(deferredShader);
UnloadShader(gbufferShader); UnloadShader(gbufferShader);
// Unload geometry buffer and all attached textures // Unload geometry buffer and all attached textures
rlUnloadFramebuffer(gBuffer.framebuffer); rlUnloadFramebuffer(gBuffer.framebufferId);
rlUnloadTexture(gBuffer.positionTexture); rlUnloadTexture(gBuffer.positionTextureId);
rlUnloadTexture(gBuffer.normalTexture); rlUnloadTexture(gBuffer.normalTextureId);
rlUnloadTexture(gBuffer.albedoSpecTexture); rlUnloadTexture(gBuffer.albedoSpecTextureId);
rlUnloadTexture(gBuffer.depthRenderbuffer); rlUnloadTexture(gBuffer.depthRenderbufferId);
CloseWindow(); // Close window and OpenGL context CloseWindow(); // Close window and OpenGL context
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------

View File

@ -46,12 +46,12 @@ int main(void)
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - ball physics"); InitWindow(screenWidth, screenHeight, "raylib [shapes] example - ball physics");
Ball balls[MAX_BALLS] = {{ Ball balls[MAX_BALLS] = {{
.pos = { GetScreenWidth()/2, GetScreenHeight()/2 }, .pos = { GetScreenWidth()/2.0f, GetScreenHeight()/2.0f },
.vel = { 200, 200 }, .vel = { 200, 200 },
.ppos = { 0 }, .ppos = { 0 },
.radius = 40, .radius = 40,
.friction = 0.99, .friction = 0.99f,
.elasticity = 0.9, .elasticity = 0.9f,
.color = BLUE, .color = BLUE,
.grabbed = false .grabbed = false
}}; }};
@ -110,11 +110,11 @@ int main(void)
{ {
balls[ballCount++] = (Ball){ balls[ballCount++] = (Ball){
.pos = mousePos, .pos = mousePos,
.vel = { GetRandomValue(-300, 300), GetRandomValue(-300, 300) }, .vel = { (float)GetRandomValue(-300, 300), (float)GetRandomValue(-300, 300) },
.ppos = { 0 }, .ppos = { 0 },
.radius = 20 + GetRandomValue(0, 30), .radius = 20.0f + (float)GetRandomValue(0, 30),
.friction = 0.99, .friction = 0.99f,
.elasticity = 0.9, .elasticity = 0.9f,
.color = { GetRandomValue(0, 255), GetRandomValue(0, 255), GetRandomValue(0, 255), 255 }, .color = { GetRandomValue(0, 255), GetRandomValue(0, 255), GetRandomValue(0, 255), 255 },
.grabbed = false .grabbed = false
}; };
@ -126,7 +126,7 @@ int main(void)
{ {
for (int i = 0; i < ballCount; i++) for (int i = 0; i < ballCount; i++)
{ {
if (!balls[i].grabbed) balls[i].vel = (Vector2){ GetRandomValue(-2000, 2000), GetRandomValue(-2000, 2000) }; if (!balls[i].grabbed) balls[i].vel = (Vector2){ (float)GetRandomValue(-2000, 2000), (float)GetRandomValue(-2000, 2000) };
} }
} }

View File

@ -0,0 +1,196 @@
/*******************************************************************************************
*
* raylib [shapes] example - hilbert curve
*
* Example complexity rating: [] 3/4
*
* Example originally created with raylib 5.6, last time updated with raylib 5.6
*
* Example contributed by Hamza RAHAL (@hmz-rhl) 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 Hamza RAHAL (@hmz-rhl)
*
********************************************************************************************/
#include "raylib.h"
#define RAYGUI_IMPLEMENTATION
#include "raygui.h"
#include <stdlib.h> // Required for: calloc(), free()
//------------------------------------------------------------------------------------
// Module Functions Declaration
//------------------------------------------------------------------------------------
static Vector2 *LoadHilbertPath(int order, float size, int *strokeCount);
static void UnloadHilbertPath(Vector2 *hilbertPath);
static Vector2 ComputeHilbertStep(int order, int index);
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - hilbert curve");
int order = 2;
float size = GetScreenHeight();
int strokeCount = 0;
Vector2 *hilbertPath = LoadHilbertPath(order, size, &strokeCount);
int prevOrder = order;
int prevSize = (int)size; // NOTE: Size from slider is float but for comparison we use int
int counter = 0;
float thick = 2.0f;
bool animate = true;
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
//--------------------------------------------------------------------------------------
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// Check if order or size have changed to regenerate
// NOTE: Size from slider is float but for comparison we use int
if ((prevOrder != order) || (prevSize != (int)size))
{
UnloadHilbertPath(hilbertPath);
hilbertPath = LoadHilbertPath(order, size, &strokeCount);
if (animate) counter = 0;
else counter = strokeCount;
prevOrder = order;
prevSize = size;
}
//----------------------------------------------------------------------------------
// Draw
//--------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
if (counter < strokeCount)
{
// Draw Hilbert path animation, one stroke every frame
for (int i = 1; i <= counter; i++)
{
DrawLineEx(hilbertPath[i], hilbertPath[i - 1], thick, ColorFromHSV(((float)i/strokeCount)*360.0f, 1.0f, 1.0f));
}
counter += 1;
}
else
{
// Draw full Hilbert path
for (int i = 1; i < strokeCount; i++)
{
DrawLineEx(hilbertPath[i], hilbertPath[i - 1], thick, ColorFromHSV(((float)i/strokeCount)*360.0f, 1.0f, 1.0f));
}
}
// Draw UI using raygui
GuiCheckBox((Rectangle){ 450, 50, 20, 20 }, "ANIMATE GENERATION ON CHANGE", &animate);
GuiSpinner((Rectangle){ 585, 100, 180, 30 }, "HILBERT CURVE ORDER: ", &order, 2, 8, false);
GuiSlider((Rectangle){ 524, 150, 240, 24 }, "THICKNESS: ", NULL, &thick, 1.0f, 10.0f);
GuiSlider((Rectangle){ 524, 190, 240, 24 }, "TOTAL SIZE: ", NULL, &size, 10.0f, GetScreenHeight()*1.5f);
EndDrawing();
//--------------------------------------------------------------------------
}
//--------------------------------------------------------------------------------------
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadHilbertPath(hilbertPath);
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
//------------------------------------------------------------------------------------
// Module Functions Definition
//------------------------------------------------------------------------------------
// Load the whole Hilbert Path (including each U and their link)
static Vector2 *LoadHilbertPath(int order, float size, int *strokeCount)
{
int N = 1 << order;
float len = size/N;
*strokeCount = N*N;
Vector2 *hilbertPath = (Vector2 *)RL_CALLOC(*strokeCount, sizeof(Vector2));
for (int i = 0; i < *strokeCount; i++)
{
hilbertPath[i] = ComputeHilbertStep(order, i);
hilbertPath[i].x = hilbertPath[i].x*len + len/2.0f;
hilbertPath[i].y = hilbertPath[i].y*len + len/2.0f;
}
return hilbertPath;
}
// Unload Hilbert path data
static void UnloadHilbertPath(Vector2 *hilbertPath)
{
RL_FREE(hilbertPath);
}
// Compute Hilbert path U positions
static Vector2 ComputeHilbertStep(int order, int index)
{
// Hilbert points base pattern
static const Vector2 hilbertPoints[4] = {
[0] = { .x = 0, .y = 0 },
[1] = { .x = 0, .y = 1 },
[2] = { .x = 1, .y = 1 },
[3] = { .x = 1, .y = 0 },
};
int hilbertIndex = index&3;
Vector2 vect = hilbertPoints[hilbertIndex];
float temp = 0.0f;
int len = 0;
for (int j = 1; j < order; j++)
{
index = index >> 2;
hilbertIndex = index&3;
len = 1 << j;
switch (hilbertIndex)
{
case 0:
{
temp = vect.x;
vect.x = vect.y;
vect.y = temp;
} break;
case 2: vect.x += len;
case 1: vect.y += len; break;
case 3:
{
temp = len - 1 - vect.x;
vect.x = 2*len - 1 - vect.y;
vect.y = temp;
} break;
default: break;
}
}
return vect;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -50,9 +50,9 @@ int main(void)
int symmetry = 6; int symmetry = 6;
float angle = 360.0f/(float)symmetry; float angle = 360.0f/(float)symmetry;
float thickness = 3.0f; float thickness = 3.0f;
Rectangle resetButtonRec = { screenWidth - 55, 5, 50, 25 }; Rectangle resetButtonRec = { screenWidth - 55.0f, 5.0f, 50, 25 };
Rectangle backButtonRec = { screenWidth - 55, screenHeight - 30, 25, 25 }; Rectangle backButtonRec = { screenWidth - 55.0f, screenHeight - 30.0f, 25, 25 };
Rectangle nextButtonRec = { screenWidth - 30, screenHeight - 30, 25, 25 }; Rectangle nextButtonRec = { screenWidth - 30.0f, screenHeight - 30.0f, 25, 25 };
Vector2 mousePos = { 0 }; Vector2 mousePos = { 0 };
Vector2 prevMousePos = { 0 }; Vector2 prevMousePos = { 0 };
Vector2 scaleVector = { 1.0f, -1.0f }; Vector2 scaleVector = { 1.0f, -1.0f };

View File

@ -185,12 +185,12 @@ static void BuildProductionStep(PenroseLSystem *ls)
char *newProduction = (char *)RL_MALLOC(sizeof(char)*STR_MAX_SIZE); char *newProduction = (char *)RL_MALLOC(sizeof(char)*STR_MAX_SIZE);
newProduction[0] = '\0'; newProduction[0] = '\0';
int productionLength = strnlen(ls->production, STR_MAX_SIZE); int productionLength = (int)strnlen(ls->production, STR_MAX_SIZE);
for (int i = 0; i < productionLength; i++) for (int i = 0; i < productionLength; i++)
{ {
char step = ls->production[i]; char step = ls->production[i];
int remainingSpace = STR_MAX_SIZE - strnlen(newProduction, STR_MAX_SIZE) - 1; int remainingSpace = STR_MAX_SIZE - (int)strnlen(newProduction, STR_MAX_SIZE) - 1;
switch (step) switch (step)
{ {
case 'W': strncat(newProduction, ls->ruleW, remainingSpace); break; case 'W': strncat(newProduction, ls->ruleW, remainingSpace); break;
@ -201,7 +201,7 @@ static void BuildProductionStep(PenroseLSystem *ls)
{ {
if (step != 'F') if (step != 'F')
{ {
int t = strnlen(newProduction, STR_MAX_SIZE); int t = (int)strnlen(newProduction, STR_MAX_SIZE);
newProduction[t] = step; newProduction[t] = step;
newProduction[t + 1] = '\0'; newProduction[t + 1] = '\0';
} }
@ -218,7 +218,7 @@ static void BuildProductionStep(PenroseLSystem *ls)
// Draw penrose tile lines // Draw penrose tile lines
static void DrawPenroseLSystem(PenroseLSystem *ls) static void DrawPenroseLSystem(PenroseLSystem *ls)
{ {
Vector2 screenCenter = { GetScreenWidth()/2, GetScreenHeight()/2 }; Vector2 screenCenter = { GetScreenWidth()/2.0f, GetScreenHeight()/2.0f };
TurtleState turtle = { TurtleState turtle = {
.origin = { 0 }, .origin = { 0 },
@ -245,7 +245,7 @@ static void DrawPenroseLSystem(PenroseLSystem *ls)
Vector2 startPosScreen = { startPosWorld.x + screenCenter.x, startPosWorld.y + screenCenter.y }; Vector2 startPosScreen = { startPosWorld.x + screenCenter.x, startPosWorld.y + screenCenter.y };
Vector2 endPosScreen = { turtle.origin.x + screenCenter.x, turtle.origin.y + screenCenter.y }; Vector2 endPosScreen = { turtle.origin.x + screenCenter.x, turtle.origin.y + screenCenter.y };
DrawLineEx(startPosScreen, endPosScreen, 2, Fade(BLACK, 0.2)); DrawLineEx(startPosScreen, endPosScreen, 2, Fade(BLACK, 0.2f));
} }
repeats = 1; repeats = 1;

View File

@ -180,12 +180,12 @@ static void DrawTextStyled(Font font, const char *text, Vector2 position, float
if (text[i - 1] == 'c') if (text[i - 1] == 'c')
{ {
colFront = GetColor(colHexValue); colFront = GetColor(colHexValue);
colFront.a *= (float)color.a/255.0f; colFront.a = (unsigned char)(colFront.a * (float)color.a/255.0f);
} }
else if (text[i - 1] == 'b') else if (text[i - 1] == 'b')
{ {
colBack = GetColor(colHexValue); colBack = GetColor(colHexValue);
colBack.a *= (float)color.a/255.0f; colBack.a *= (unsigned char)(colFront.a * (float)color.a / 255.0f);
} }
i += (colHexCount + 1); // Skip color value retrieved and ']' i += (colHexCount + 1); // Skip color value retrieved and ']'

View File

@ -133,7 +133,7 @@ int main(void)
{ {
for (int i = 0; i < particleCount; i++) for (int i = 0; i < particleCount; i++)
{ {
if (!textParticles[i].grabbed) textParticles[i].vel = (Vector2){ GetRandomValue(-2000, 2000), GetRandomValue(-2000, 2000) }; if (!textParticles[i].grabbed) textParticles[i].vel = (Vector2){ (float)GetRandomValue(-2000, 2000), (float)GetRandomValue(-2000, 2000) };
} }
} }
@ -233,9 +233,9 @@ int main(void)
for (int i = 0; i < particleCount; i++) for (int i = 0; i < particleCount; i++)
{ {
TextParticle *tp = &textParticles[i]; TextParticle *tp = &textParticles[i];
DrawRectangle(tp->rect.x-tp->borderWidth, tp->rect.y-tp->borderWidth, tp->rect.width+tp->borderWidth*2, tp->rect.height+tp->borderWidth*2, BLACK); DrawRectangleRec((Rectangle) { tp->rect.x - tp->borderWidth, tp->rect.y - tp->borderWidth, tp->rect.width + tp->borderWidth * 2, tp->rect.height + tp->borderWidth * 2 }, BLACK);
DrawRectangleRec(tp->rect, tp->color); DrawRectangleRec(tp->rect, tp->color);
DrawText(tp->text, tp->rect.x+tp->padding, tp->rect.y+tp->padding, FONT_SIZE, BLACK); DrawText(tp->text, (int)(tp->rect.x+tp->padding), (int)(tp->rect.y+tp->padding), FONT_SIZE, BLACK);
} }
DrawText("grab a text particle by pressing with the mouse and throw it by releasing", 10, 10, 10, DARKGRAY); DrawText("grab a text particle by pressing with the mouse and throw it by releasing", 10, 10, 10, DARKGRAY);
@ -265,8 +265,8 @@ void PrepareFirstTextParticle(const char* text, TextParticle *tps, int *particle
{ {
tps[0] = CreateTextParticle( tps[0] = CreateTextParticle(
text, text,
GetScreenWidth()/2, GetScreenWidth()/2.0f,
GetScreenHeight()/2, GetScreenHeight()/2.0f,
RAYWHITE RAYWHITE
); );
*particleCount = 1; *particleCount = 1;
@ -277,12 +277,12 @@ TextParticle CreateTextParticle(const char *text, float x, float y, Color color)
TextParticle tp = { TextParticle tp = {
.text = "", .text = "",
.rect = { x, y, 30, 30 }, .rect = { x, y, 30, 30 },
.vel = { GetRandomValue(-200, 200), GetRandomValue(-200, 200) }, .vel = { (float)GetRandomValue(-200, 200), (float)GetRandomValue(-200, 200) },
.ppos = { 0 }, .ppos = { 0 },
.padding = 5.0f, .padding = 5.0f,
.borderWidth = 5.0f, .borderWidth = 5.0f,
.friction = 0.99, .friction = 0.99f,
.elasticity = 0.9, .elasticity = 0.9f,
.color = color, .color = color,
.grabbed = false .grabbed = false
}; };

View File

@ -19,8 +19,6 @@
#include "raymath.h" // Required for: Lerp() #include "raymath.h" // Required for: Lerp()
#include <stdio.h>
typedef enum TextAlignment { typedef enum TextAlignment {
TEXT_ALIGN_LEFT = 0, TEXT_ALIGN_LEFT = 0,
TEXT_ALIGN_TOP = 0, TEXT_ALIGN_TOP = 0,

View File

@ -0,0 +1,208 @@
/*******************************************************************************************
*
* raylib [textures] example - framebuffer rendering
*
* Example complexity rating: [] 2/4
*
* Example originally created with raylib 5.6, last time updated with raylib 5.6
*
* Example contributed by Jack Boakes (@jackboakes) 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) 2026 Jack Boakes (@jackboakes)
*
********************************************************************************************/
#include "raylib.h"
#include "raymath.h"
//------------------------------------------------------------------------------------
// Module Functions Declaration
//------------------------------------------------------------------------------------
static void DrawCameraPrism(Camera3D camera, float aspect, Color color);
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
const int splitWidth = screenWidth/2;
InitWindow(screenWidth, screenHeight, "raylib [textures] example - framebuffer rendering");
// Camera to look at the 3D world
Camera3D subjectCamera = { 0 };
subjectCamera.position = (Vector3){ 5.0f, 5.0f, 5.0f };
subjectCamera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
subjectCamera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
subjectCamera.fovy = 45.0f;
subjectCamera.projection = CAMERA_PERSPECTIVE;
// Camera to observe the subject camera and 3D world
Camera3D observerCamera = { 0 };
observerCamera.position = (Vector3){ 10.0f, 10.0f, 10.0f };
observerCamera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
observerCamera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
observerCamera.fovy = 45.0f;
observerCamera.projection = CAMERA_PERSPECTIVE;
// Set up render textures
RenderTexture2D observerTarget = LoadRenderTexture(splitWidth, screenHeight);
Rectangle observerSource = { 0.0f, 0.0f, (float)observerTarget.texture.width, -(float)observerTarget.texture.height };
Rectangle observerDest = { 0.0f, 0.0f, (float)splitWidth, (float)screenHeight };
RenderTexture2D subjectTarget = LoadRenderTexture(splitWidth, screenHeight);
Rectangle subjectSource = { 0.0f, 0.0f, (float)subjectTarget.texture.width, -(float)subjectTarget.texture.height };
Rectangle subjectDest = { (float)splitWidth, 0.0f, (float)splitWidth, (float)screenHeight };
const float textureAspectRatio = (float)subjectTarget.texture.width/(float)subjectTarget.texture.height;
// Rectangles for cropping render texture
const float captureSize = 128.0f;
Rectangle cropSource = { (subjectTarget.texture.width - captureSize)/2.0f, (subjectTarget.texture.height - captureSize)/2.0f, captureSize, -captureSize };
Rectangle cropDest = { splitWidth + 20, 20, captureSize, captureSize};
SetTargetFPS(60);
DisableCursor();
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
UpdateCamera(&observerCamera, CAMERA_FREE);
UpdateCamera(&subjectCamera, CAMERA_ORBITAL);
if (IsKeyPressed(KEY_R)) observerCamera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
// Build LHS observer view texture
BeginTextureMode(observerTarget);
ClearBackground(RAYWHITE);
BeginMode3D(observerCamera);
DrawGrid(10, 1.0f);
DrawCube((Vector3){ 0.0f, 0.0f, 0.0f }, 2.0f, 2.0f, 2.0f, GOLD);
DrawCubeWires((Vector3){ 0.0f, 0.0f, 0.0f }, 2.0f, 2.0f, 2.0f, PINK);
DrawCameraPrism(subjectCamera, textureAspectRatio, GREEN);
EndMode3D();
DrawText("Observer View", 10, observerTarget.texture.height - 30, 20, BLACK);
DrawText("WASD + Mouse to Move", 10, 10, 20, DARKGRAY);
DrawText("Scroll to Zoom", 10, 30, 20, DARKGRAY);
DrawText("R to Reset Observer Target", 10, 50, 20, DARKGRAY);
EndTextureMode();
// Build RHS subject view texture
BeginTextureMode(subjectTarget);
ClearBackground(RAYWHITE);
BeginMode3D(subjectCamera);
DrawCube((Vector3){ 0.0f, 0.0f, 0.0f }, 2.0f, 2.0f, 2.0f, GOLD);
DrawCubeWires((Vector3){ 0.0f, 0.0f, 0.0f }, 2.0f, 2.0f, 2.0f, PINK);
DrawGrid(10, 1.0f);
EndMode3D();
DrawRectangleLines((subjectTarget.texture.width - captureSize)/2, (subjectTarget.texture.height - captureSize)/2, captureSize, captureSize, GREEN);
DrawText("Subject View", 10, subjectTarget.texture.height - 30, 20, BLACK);
EndTextureMode();
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(BLACK);
// Draw observer texture LHS
DrawTexturePro(observerTarget.texture, observerSource, observerDest, (Vector2){0.0f, 0.0f }, 0.0f, WHITE);
// Draw subject texture RHS
DrawTexturePro(subjectTarget.texture, subjectSource, subjectDest, (Vector2){ 0.0f, 0.0f }, 0.0f, WHITE);
// Draw the small crop overlay on top
DrawTexturePro(subjectTarget.texture, cropSource, cropDest, (Vector2){ 0.0f, 0.0f }, 0.0f, WHITE);
DrawRectangleLinesEx(cropDest, 2, BLACK);
// Draw split screen divider line
DrawLine(splitWidth, 0, splitWidth, screenHeight, BLACK);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadRenderTexture(observerTarget);
UnloadRenderTexture(subjectTarget);
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
//----------------------------------------------------------------------------------
// Module Functions Definition
//----------------------------------------------------------------------------------
static void DrawCameraPrism(Camera3D camera, float aspect, Color color)
{
float length = Vector3Distance(camera.position, camera.target);
// Define the 4 corners of the camera's prism plane sliced at the target in Normalized Device Coordinates
Vector3 planeNDC[4] = {
{ -1.0f, -1.0f, 1.0f }, // Bottom Left
{ 1.0f, -1.0f, 1.0f }, // Bottom Right
{ 1.0f, 1.0f, 1.0f }, // Top Right
{ -1.0f, 1.0f, 1.0f } // Top Left
};
// Build the matrices
Matrix view = GetCameraMatrix(camera);
Matrix proj = MatrixPerspective(camera.fovy * DEG2RAD, aspect, 0.05f, length);
// Combine view and projection so we can reverse the full camera transform
Matrix viewProj = MatrixMultiply(view, proj);
// Invert the view-projection matrix to unproject points from NDC space back into world space
Matrix inverseViewProj = MatrixInvert(viewProj);
// Transform the 4 plane corners from NDC into world space
Vector3 corners[4];
for (int i = 0; i < 4; i++)
{
float x = planeNDC[i].x;
float y = planeNDC[i].y;
float z = planeNDC[i].z;
// Multiply NDC position by the inverse view-projection matrix
// This produces a homogeneous (x, y, z, w) position in world space
float vx = inverseViewProj.m0*x + inverseViewProj.m4*y + inverseViewProj.m8*z + inverseViewProj.m12;
float vy = inverseViewProj.m1*x + inverseViewProj.m5*y + inverseViewProj.m9*z + inverseViewProj.m13;
float vz = inverseViewProj.m2*x + inverseViewProj.m6*y + inverseViewProj.m10*z + inverseViewProj.m14;
float vw = inverseViewProj.m3*x + inverseViewProj.m7*y + inverseViewProj.m11*z + inverseViewProj.m15;
corners[i] = (Vector3){ vx/vw, vy/vw, vz/vw };
}
// Draw the far plane sliced at the target
DrawLine3D(corners[0], corners[1], color);
DrawLine3D(corners[1], corners[2], color);
DrawLine3D(corners[2], corners[3], color);
DrawLine3D(corners[3], corners[0], color);
// Draw the prism lines from the far plane to the camera position
for (int i = 0; i < 4; i++)
{
DrawLine3D(camera.position, corners[i], color);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -66,7 +66,7 @@ int main(void)
// Grow flameRoot // Grow flameRoot
for (int x = 2; x < flameWidth; x++) for (int x = 2; x < flameWidth; x++)
{ {
unsigned short flame = flameRootBuffer[x]; unsigned char flame = flameRootBuffer[x];
if (flame == 255) continue; if (flame == 255) continue;
flame += GetRandomValue(0, 2); flame += GetRandomValue(0, 2);
if (flame > 255) flame = 255; if (flame > 255) flame = 255;

View File

@ -190,7 +190,7 @@ static void DrawTexturedCurve(void)
Vector2 normal = Vector2Normalize((Vector2){ -delta.y, delta.x }); Vector2 normal = Vector2Normalize((Vector2){ -delta.y, delta.x });
// The v texture coordinate of the segment (add up the length of all the segments so far) // The v texture coordinate of the segment (add up the length of all the segments so far)
float v = previousV + Vector2Length(delta); float v = previousV + Vector2Length(delta) / (float)(texRoad.height * 2);
// Make sure the start point has a normal // Make sure the start point has a normal
if (!tangentSet) if (!tangentSet)

View File

@ -0,0 +1,569 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug.DLL|ARM64">
<Configuration>Debug.DLL</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug.DLL|Win32">
<Configuration>Debug.DLL</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug.DLL|x64">
<Configuration>Debug.DLL</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release.DLL|ARM64">
<Configuration>Release.DLL</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release.DLL|Win32">
<Configuration>Release.DLL</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release.DLL|x64">
<Configuration>Release.DLL</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{D35D2FDA-B53F-4F70-81CA-24D95812B89C}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>core_keyboard_testbed</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>core_keyboard_testbed</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\core</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>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)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>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)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>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)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>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)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
<Message>Copy Debug DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>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)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
<Message>Copy Debug DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>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)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
<Message>Copy Debug DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>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)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>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)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>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)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>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)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>Copy Release DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>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)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>Copy Release DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>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)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>Copy Release DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\..\examples\core\core_keyboard_testbed.c" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\..\examples\examples.rc" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\raylib\raylib.vcxproj">
<Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,569 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug.DLL|ARM64">
<Configuration>Debug.DLL</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug.DLL|Win32">
<Configuration>Debug.DLL</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug.DLL|x64">
<Configuration>Debug.DLL</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release.DLL|ARM64">
<Configuration>Release.DLL</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release.DLL|Win32">
<Configuration>Release.DLL</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release.DLL|x64">
<Configuration>Release.DLL</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{DC163251-16C3-4B72-B965-ACDBA0F02BD1}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>shapes_hilbert_curve</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>shapes_hilbert_curve</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\shapes</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>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)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>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)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>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)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>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)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
<Message>Copy Debug DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>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)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
<Message>Copy Debug DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>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)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
<Message>Copy Debug DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>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)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>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)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>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)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>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)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>Copy Release DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>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)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>Copy Release DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>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)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>Copy Release DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\..\examples\shapes\shapes_hilbert_curve.c" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\..\examples\examples.rc" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\raylib\raylib.vcxproj">
<Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -292,7 +292,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
@ -309,7 +309,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions>
@ -345,7 +345,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
@ -366,7 +366,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
@ -410,7 +410,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
@ -432,7 +432,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
@ -476,7 +476,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
@ -504,7 +504,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>

View File

@ -292,7 +292,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
@ -309,7 +309,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions>
@ -345,7 +345,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
@ -366,7 +366,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
@ -410,7 +410,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
@ -432,7 +432,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
@ -476,7 +476,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
@ -504,7 +504,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNIGNS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>

View File

@ -0,0 +1,569 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug.DLL|ARM64">
<Configuration>Debug.DLL</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug.DLL|Win32">
<Configuration>Debug.DLL</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug.DLL|x64">
<Configuration>Debug.DLL</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release.DLL|ARM64">
<Configuration>Release.DLL</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release.DLL|Win32">
<Configuration>Release.DLL</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release.DLL|x64">
<Configuration>Release.DLL</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>textures_framebuffer_rendering</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>textures_framebuffer_rendering</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\textures</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>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)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>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)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>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)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>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)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
<Message>Copy Debug DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>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)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
<Message>Copy Debug DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|ARM64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>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)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
<Message>Copy Debug DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>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)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>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)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>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)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>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)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>Copy Release DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>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)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>Copy Release DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|ARM64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>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)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>Copy Release DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\..\examples\textures\textures_framebuffer_rendering.c" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\..\examples\examples.rc" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\raylib\raylib.vcxproj">
<Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -431,6 +431,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_strings_management", "
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_cellular_automata", "examples\textures_cellular_automata.vcxproj", "{0A0FC982-6E31-401F-BA77-3C5E8AB02C68}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_cellular_automata", "examples\textures_cellular_automata.vcxproj", "{0A0FC982-6E31-401F-BA77-3C5E8AB02C68}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_hilbert_curve", "examples\shapes_hilbert_curve.vcxproj", "{DC163251-16C3-4B72-B965-ACDBA0F02BD1}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_keyboard_testbed", "examples\core_keyboard_testbed.vcxproj", "{D35D2FDA-B53F-4F70-81CA-24D95812B89C}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_framebuffer_rendering", "examples\textures_framebuffer_rendering.vcxproj", "{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug.DLL|ARM64 = Debug.DLL|ARM64 Debug.DLL|ARM64 = Debug.DLL|ARM64
@ -5365,6 +5371,78 @@ Global
{0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Release|x64.Build.0 = Release|x64 {0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Release|x64.Build.0 = Release|x64
{0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Release|x86.ActiveCfg = Release|Win32 {0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Release|x86.ActiveCfg = Release|Win32
{0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Release|x86.Build.0 = Release|Win32 {0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Release|x86.Build.0 = Release|Win32
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|ARM64.ActiveCfg = Debug|ARM64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|ARM64.Build.0 = Debug|ARM64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|x64.ActiveCfg = Debug|x64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|x64.Build.0 = Debug|x64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|x86.ActiveCfg = Debug|Win32
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|x86.Build.0 = Debug|Win32
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|x64.Build.0 = Release.DLL|x64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|x86.Build.0 = Release.DLL|Win32
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|ARM64.ActiveCfg = Release|ARM64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|ARM64.Build.0 = Release|ARM64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|x64.ActiveCfg = Release|x64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|x64.Build.0 = Release|x64
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|x86.ActiveCfg = Release|Win32
{DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|x86.Build.0 = Release|Win32
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|ARM64.ActiveCfg = Debug|ARM64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|ARM64.Build.0 = Debug|ARM64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|x64.ActiveCfg = Debug|x64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|x64.Build.0 = Debug|x64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|x86.ActiveCfg = Debug|Win32
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|x86.Build.0 = Debug|Win32
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|x64.Build.0 = Release.DLL|x64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|x86.Build.0 = Release.DLL|Win32
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|ARM64.ActiveCfg = Release|ARM64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|ARM64.Build.0 = Release|ARM64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|x64.ActiveCfg = Release|x64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|x64.Build.0 = Release|x64
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|x86.ActiveCfg = Release|Win32
{D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|x86.Build.0 = Release|Win32
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|ARM64.ActiveCfg = Debug|ARM64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|ARM64.Build.0 = Debug|ARM64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|x64.ActiveCfg = Debug|x64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|x64.Build.0 = Debug|x64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|x86.ActiveCfg = Debug|Win32
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|x86.Build.0 = Debug|Win32
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|x64.Build.0 = Release.DLL|x64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|x86.Build.0 = Release.DLL|Win32
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|ARM64.ActiveCfg = Release|ARM64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|ARM64.Build.0 = Release|ARM64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|x64.ActiveCfg = Release|x64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|x64.Build.0 = Release|x64
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|x86.ActiveCfg = Release|Win32
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|x86.Build.0 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -5532,7 +5610,7 @@ Global
{C54703BF-D68A-480D-BE27-49B62E45D582} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} {C54703BF-D68A-480D-BE27-49B62E45D582} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9}
{9CD8BCAD-F212-4BCC-BA98-899743CE3279} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} {9CD8BCAD-F212-4BCC-BA98-899743CE3279} = {CC132A4D-D081-4C26-BFB9-AB11984054F8}
{0981CA28-E4A5-4DF1-987F-A41D09131EFC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {0981CA28-E4A5-4DF1-987F-A41D09131EFC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
{6B1A933E-71B8-4C1F-9E79-02D98830E671} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
{6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9}
{6777EC3C-077C-42FC-B4AD-B799CE55CCE4} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} {6777EC3C-077C-42FC-B4AD-B799CE55CCE4} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A}
{A61DAD9C-271C-4E95-81AA-DB4CD58564D4} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {A61DAD9C-271C-4E95-81AA-DB4CD58564D4} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
@ -5541,7 +5619,7 @@ Global
{3B27F358-2679-4F38-B297-17B536F580BB} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {3B27F358-2679-4F38-B297-17B536F580BB} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {718FCBD0-591D-448C-B7D5-9F1CA8544E7B} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
{19CA0070-B4B2-4394-90B7-D0C259AA35BA} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {19CA0070-B4B2-4394-90B7-D0C259AA35BA} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
{2CCCD9E4-9058-4291-BD89-39C979F0CA1E} = {278D8859-20B1-428F-8448-064F46E1F021} {2CCCD9E4-9058-4291-BD89-39C979F0CA1E} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE}
{9DB1F875-6E65-4195-B23F-ED8095C0B99C} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} {9DB1F875-6E65-4195-B23F-ED8095C0B99C} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A}
{52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}
{8E132D5A-2C00-48D0-8747-97E41356F26F} = {278D8859-20B1-428F-8448-064F46E1F021} {8E132D5A-2C00-48D0-8747-97E41356F26F} = {278D8859-20B1-428F-8448-064F46E1F021}
@ -5582,6 +5660,9 @@ Global
{7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC} = {278D8859-20B1-428F-8448-064F46E1F021} {7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC} = {278D8859-20B1-428F-8448-064F46E1F021}
{1F4722E7-F78E-413F-A106-D3490211EA57} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} {1F4722E7-F78E-413F-A106-D3490211EA57} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A}
{0A0FC982-6E31-401F-BA77-3C5E8AB02C68} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} {0A0FC982-6E31-401F-BA77-3C5E8AB02C68} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE}
{DC163251-16C3-4B72-B965-ACDBA0F02BD1} = {278D8859-20B1-428F-8448-064F46E1F021}
{D35D2FDA-B53F-4F70-81CA-24D95812B89C} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29} SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29}

View File

@ -582,7 +582,6 @@
<ClCompile Include="..\..\..\src\rshapes.c" /> <ClCompile Include="..\..\..\src\rshapes.c" />
<ClCompile Include="..\..\..\src\rtext.c" /> <ClCompile Include="..\..\..\src\rtext.c" />
<ClCompile Include="..\..\..\src\rtextures.c" /> <ClCompile Include="..\..\..\src\rtextures.c" />
<ClCompile Include="..\..\..\src\utils.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\..\src\external\cgltf.h" /> <ClInclude Include="..\..\..\src\external\cgltf.h" />
@ -602,7 +601,6 @@
<ClInclude Include="..\..\..\src\raylib.h" /> <ClInclude Include="..\..\..\src\raylib.h" />
<ClInclude Include="..\..\..\src\raymath.h" /> <ClInclude Include="..\..\..\src\raymath.h" />
<ClInclude Include="..\..\..\src\rlgl.h" /> <ClInclude Include="..\..\..\src\rlgl.h" />
<ClInclude Include="..\..\..\src\utils.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="..\..\..\src\raylib.dll.rc" /> <ResourceCompile Include="..\..\..\src\raylib.dll.rc" />

View File

@ -22,9 +22,6 @@
<ClCompile Include="..\..\..\src\rtextures.c"> <ClCompile Include="..\..\..\src\rtextures.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\src\utils.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\platforms\rcore_android.c"> <ClCompile Include="..\..\..\src\platforms\rcore_android.c">
<Filter>Source Files\Platform Files</Filter> <Filter>Source Files\Platform Files</Filter>
</ClCompile> </ClCompile>

View File

@ -15,7 +15,7 @@
* This example has been created using raylib 1.0 (www.raylib.com) * This example has been created using raylib 1.0 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* *
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/

View File

@ -36,7 +36,6 @@ set(raylib_sources
rshapes.c rshapes.c
rtext.c rtext.c
rtextures.c rtextures.c
utils.c
) )
# <root>/cmake/GlfwImport.cmake handles the details around the inclusion of glfw # <root>/cmake/GlfwImport.cmake handles the details around the inclusion of glfw

View File

@ -33,7 +33,7 @@
# Many thanks to Milan Nikolic (@gen2brain) for implementing Android platform pipeline. # Many thanks to Milan Nikolic (@gen2brain) for implementing Android platform pipeline.
# Many thanks to Emanuele Petriglia for his contribution on GNU/Linux pipeline. # Many thanks to Emanuele Petriglia for his contribution on GNU/Linux pipeline.
# #
# Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) # Copyright (c) 2013-2026 Ramon Santamaria (@raysan5)
# #
# This software is provided "as-is", without any express or implied warranty. In no event # This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software. # will the authors be held liable for any damages arising from the use of this software.
@ -658,8 +658,7 @@ endif
OBJS = rcore.o \ OBJS = rcore.o \
rshapes.o \ rshapes.o \
rtextures.o \ rtextures.o \
rtext.o \ rtext.o
utils.o
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
ifeq ($(USE_EXTERNAL_GLFW),FALSE) ifeq ($(USE_EXTERNAL_GLFW),FALSE)
@ -758,7 +757,7 @@ endif
rcore.o : platforms/*.c rcore.o : platforms/*.c
# Compile core module # Compile core module
rcore.o : rcore.c raylib.h rlgl.h utils.h raymath.h rcamera.h rgestures.h rcore.o : rcore.c raylib.h rlgl.h raymath.h rcamera.h rgestures.h
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) $(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS)
# Compile rglfw module # Compile rglfw module
@ -770,15 +769,11 @@ rshapes.o : rshapes.c raylib.h rlgl.h
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) $(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS)
# Compile textures module # Compile textures module
rtextures.o : rtextures.c raylib.h rlgl.h utils.h rtextures.o : rtextures.c raylib.h rlgl.h
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) $(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS)
# Compile text module # Compile text module
rtext.o : rtext.c raylib.h utils.h rtext.o : rtext.c raylib.h
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS)
# Compile utils module
utils.o : utils.c utils.h
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) $(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS)
# Compile models module # Compile models module

View File

@ -6,7 +6,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2018-2025 Ahmad Fatoum & Ramon Santamaria (@raysan5) * Copyright (c) 2018-2026 Ahmad Fatoum and Ramon Santamaria (@raysan5)
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -30,17 +30,24 @@
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Module selection - Some modules could be avoided // Module selection - Some modules could be avoided
// Mandatory modules: rcore, rlgl, utils // Mandatory modules: rcore, rlgl
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
#if !defined(EXTERNAL_CONFIG_FLAGS)
#define SUPPORT_MODULE_RSHAPES 1 #define SUPPORT_MODULE_RSHAPES 1
#define SUPPORT_MODULE_RTEXTURES 1 #define SUPPORT_MODULE_RTEXTURES 1
#define SUPPORT_MODULE_RTEXT 1 // WARNING: It requires SUPPORT_MODULE_RTEXTURES to load sprite font textures #define SUPPORT_MODULE_RTEXT 1 // WARNING: It requires SUPPORT_MODULE_RTEXTURES to load sprite font textures
#define SUPPORT_MODULE_RMODELS 1 #define SUPPORT_MODULE_RMODELS 1
#define SUPPORT_MODULE_RAUDIO 1 #define SUPPORT_MODULE_RAUDIO 1
#endif
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Module: rcore - Configuration Flags // Module: rcore - Configuration Flags
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
#if !defined(EXTERNAL_CONFIG_FLAGS)
// Standard file io library (stdio.h) included
#define SUPPORT_STANDARD_FILEIO 1
// Show TRACELOG() output messages
#define SUPPORT_TRACELOG 1
// Camera module is included (rcamera.h) and multiple predefined cameras are available: free, 1st/3rd person, orbital // Camera module is included (rcamera.h) and multiple predefined cameras are available: free, 1st/3rd person, orbital
#define SUPPORT_CAMERA_SYSTEM 1 #define SUPPORT_CAMERA_SYSTEM 1
// Gestures module is included (rgestures.h) to support gestures detection: tap, hold, swipe, drag // Gestures module is included (rgestures.h) to support gestures detection: tap, hold, swipe, drag
@ -69,10 +76,10 @@
// By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timing + PollInputEvents() // By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timing + PollInputEvents()
// Enabling this flag allows manual control of the frame processes, use at your own risk // Enabling this flag allows manual control of the frame processes, use at your own risk
//#define SUPPORT_CUSTOM_FRAME_CONTROL 1 //#define SUPPORT_CUSTOM_FRAME_CONTROL 1
// Support for clipboard image loading // Support for clipboard image loading
// NOTE: Only working on SDL3, GLFW (Windows) and RGFW (Windows) // NOTE: Only working on SDL3, GLFW (Windows) and RGFW (Windows)
#define SUPPORT_CLIPBOARD_IMAGE 1 #define SUPPORT_CLIPBOARD_IMAGE 1
#endif
// NOTE: Clipboard image loading requires support for some image file formats // NOTE: Clipboard image loading requires support for some image file formats
// TODO: Those defines should probably be removed from here, letting the user manage them // TODO: Those defines should probably be removed from here, letting the user manage them
@ -94,8 +101,15 @@
#endif #endif
#endif #endif
#if defined(SUPPORT_TRACELOG)
#define TRACELOG(level, ...) TraceLog(level, __VA_ARGS__)
#else
#define TRACELOG(level, ...) (void)0
#endif
// rcore: Configuration values // rcore: Configuration values
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
#define MAX_TRACELOG_MSG_LENGTH 256 // Max length of one trace-log message
#define MAX_FILEPATH_CAPACITY 8192 // Maximum file paths capacity #define MAX_FILEPATH_CAPACITY 8192 // Maximum file paths capacity
#define MAX_FILEPATH_LENGTH 4096 // Maximum length for filepaths (Linux PATH_MAX default value) #define MAX_FILEPATH_LENGTH 4096 // Maximum length for filepaths (Linux PATH_MAX default value)
@ -105,7 +119,7 @@
#define MAX_GAMEPAD_AXES 8 // Maximum number of axes supported (per gamepad) #define MAX_GAMEPAD_AXES 8 // Maximum number of axes supported (per gamepad)
#define MAX_GAMEPAD_BUTTONS 32 // Maximum number of buttons supported (per gamepad) #define MAX_GAMEPAD_BUTTONS 32 // Maximum number of buttons supported (per gamepad)
#define MAX_GAMEPAD_VIBRATION_TIME 2.0f // Maximum vibration time in seconds #define MAX_GAMEPAD_VIBRATION_TIME 2.0f // Maximum vibration time in seconds
#define MAX_TOUCH_POINTS 8 // Maximum number of touch points supported #define MAX_TOUCH_POINTS 10 // Maximum number of touch points supported
#define MAX_KEY_PRESSED_QUEUE 16 // Maximum number of keys in the key input queue #define MAX_KEY_PRESSED_QUEUE 16 // Maximum number of keys in the key input queue
#define MAX_CHAR_PRESSED_QUEUE 16 // Maximum number of characters in the char input queue #define MAX_CHAR_PRESSED_QUEUE 16 // Maximum number of characters in the char input queue
@ -116,7 +130,7 @@
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Module: rlgl - Configuration values // Module: rlgl - Configuration values
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
#if !defined(EXTERNAL_CONFIG_FLAGS)
// Enable OpenGL Debug Context (only available on OpenGL 4.3) // Enable OpenGL Debug Context (only available on OpenGL 4.3)
//#define RLGL_ENABLE_OPENGL_DEBUG_CONTEXT 1 //#define RLGL_ENABLE_OPENGL_DEBUG_CONTEXT 1
@ -124,6 +138,7 @@
//#define RLGL_SHOW_GL_DETAILS_INFO 1 //#define RLGL_SHOW_GL_DETAILS_INFO 1
#define RL_SUPPORT_MESH_GPU_SKINNING 1 // GPU skinning, comment if your GPU does not support more than 8 VBOs #define RL_SUPPORT_MESH_GPU_SKINNING 1 // GPU skinning, comment if your GPU does not support more than 8 VBOs
#endif
//#define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 4096 // Default internal render batch elements limits //#define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 4096 // Default internal render batch elements limits
#define RL_DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering) #define RL_DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering)
@ -173,9 +188,11 @@
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Module: rshapes - Configuration Flags // Module: rshapes - Configuration Flags
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
#if !defined(EXTERNAL_CONFIG_FLAGS)
// Use QUADS instead of TRIANGLES for drawing when possible // Use QUADS instead of TRIANGLES for drawing when possible
// Some lines-based shapes could still use lines // Some lines-based shapes could still use lines
#define SUPPORT_QUADS_DRAW_MODE 1 #define SUPPORT_QUADS_DRAW_MODE 1
#endif
// rshapes: Configuration values // rshapes: Configuration values
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
@ -184,6 +201,7 @@
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Module: rtextures - Configuration Flags // Module: rtextures - Configuration Flags
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
#if !defined(EXTERNAL_CONFIG_FLAGS)
// Selected desired fileformats to be supported for image data loading // Selected desired fileformats to be supported for image data loading
#define SUPPORT_FILEFORMAT_PNG 1 #define SUPPORT_FILEFORMAT_PNG 1
//#define SUPPORT_FILEFORMAT_BMP 1 //#define SUPPORT_FILEFORMAT_BMP 1
@ -207,10 +225,12 @@
// Support multiple image editing functions to scale, adjust colors, flip, draw on images, crop... // Support multiple image editing functions to scale, adjust colors, flip, draw on images, crop...
// If not defined, still some functions are supported: ImageFormat(), ImageCrop(), ImageToPOT() // If not defined, still some functions are supported: ImageFormat(), ImageCrop(), ImageToPOT()
#define SUPPORT_IMAGE_MANIPULATION 1 #define SUPPORT_IMAGE_MANIPULATION 1
#endif
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Module: rtext - Configuration Flags // Module: rtext - Configuration Flags
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
#if !defined(EXTERNAL_CONFIG_FLAGS)
// Default font is loaded on window initialization to be available for the user to render simple text // Default font is loaded on window initialization to be available for the user to render simple text
// NOTE: If enabled, uses external module functions to load default raylib font // NOTE: If enabled, uses external module functions to load default raylib font
#define SUPPORT_DEFAULT_FONT 1 #define SUPPORT_DEFAULT_FONT 1
@ -230,6 +250,7 @@
// Support conservative font atlas size estimation // Support conservative font atlas size estimation
//#define SUPPORT_FONT_ATLAS_SIZE_CONSERVATIVE 1 //#define SUPPORT_FONT_ATLAS_SIZE_CONSERVATIVE 1
#endif
// rtext: Configuration values // rtext: Configuration values
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
@ -240,6 +261,7 @@
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Module: rmodels - Configuration Flags // Module: rmodels - Configuration Flags
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
#if !defined(EXTERNAL_CONFIG_FLAGS)
// Selected desired model fileformats to be supported for loading // Selected desired model fileformats to be supported for loading
#define SUPPORT_FILEFORMAT_OBJ 1 #define SUPPORT_FILEFORMAT_OBJ 1
#define SUPPORT_FILEFORMAT_MTL 1 #define SUPPORT_FILEFORMAT_MTL 1
@ -250,6 +272,7 @@
// Support procedural mesh generation functions, uses external par_shapes.h library // Support procedural mesh generation functions, uses external par_shapes.h library
// NOTE: Some generated meshes DO NOT include generated texture coordinates // NOTE: Some generated meshes DO NOT include generated texture coordinates
#define SUPPORT_MESH_GENERATION 1 #define SUPPORT_MESH_GENERATION 1
#endif
// rmodels: Configuration values // rmodels: Configuration values
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
@ -264,6 +287,7 @@
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Module: raudio - Configuration Flags // Module: raudio - Configuration Flags
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
#if !defined(EXTERNAL_CONFIG_FLAGS)
// Desired audio fileformats to be supported for loading // Desired audio fileformats to be supported for loading
#define SUPPORT_FILEFORMAT_WAV 1 #define SUPPORT_FILEFORMAT_WAV 1
#define SUPPORT_FILEFORMAT_OGG 1 #define SUPPORT_FILEFORMAT_OGG 1
@ -272,6 +296,7 @@
//#define SUPPORT_FILEFORMAT_FLAC 1 //#define SUPPORT_FILEFORMAT_FLAC 1
#define SUPPORT_FILEFORMAT_XM 1 #define SUPPORT_FILEFORMAT_XM 1
#define SUPPORT_FILEFORMAT_MOD 1 #define SUPPORT_FILEFORMAT_MOD 1
#endif
// raudio: Configuration values // raudio: Configuration values
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
@ -281,18 +306,4 @@
#define MAX_AUDIO_BUFFER_POOL_CHANNELS 16 // Maximum number of audio pool channels #define MAX_AUDIO_BUFFER_POOL_CHANNELS 16 // Maximum number of audio pool channels
//------------------------------------------------------------------------------------
// Module: utils - Configuration Flags
//------------------------------------------------------------------------------------
// Standard file io library (stdio.h) included
#define SUPPORT_STANDARD_FILEIO 1
// Show TRACELOG() output messages
// NOTE: By default LOG_DEBUG traces not shown
#define SUPPORT_TRACELOG 1
//#define SUPPORT_TRACELOG_DEBUG 1
// utils: Configuration values
//------------------------------------------------------------------------------------
#define MAX_TRACELOG_MSG_LENGTH 256 // Max length of one trace-log message
#endif // CONFIG_H #endif // CONFIG_H

22
src/external/RGFW.h vendored
View File

@ -669,7 +669,8 @@ typedef struct RGFW_event {
typedef struct RGFW_window_src { typedef struct RGFW_window_src {
HWND window; /*!< source window */ HWND window; /*!< source window */
HDC hdc; /*!< source HDC */ HDC hdc; /*!< source HDC */
u32 hOffset; /*!< height offset for window */ i32 wOffset; /*!< width offset for window */
i32 hOffset; /*!< height offset for window */
HICON hIconSmall, hIconBig; /*!< source window icons */ HICON hIconSmall, hIconBig; /*!< source window icons */
#if (defined(RGFW_OPENGL)) && !defined(RGFW_OSMESA) && !defined(RGFW_EGL) #if (defined(RGFW_OPENGL)) && !defined(RGFW_OSMESA) && !defined(RGFW_EGL)
HGLRC ctx; /*!< source graphics context */ HGLRC ctx; /*!< source graphics context */
@ -6522,8 +6523,8 @@ LRESULT CALLBACK WndProcW(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
if (win->src.aspectRatio.w != 0 && win->src.aspectRatio.h != 0) { if (win->src.aspectRatio.w != 0 && win->src.aspectRatio.h != 0) {
double aspectRatio = (double)win->src.aspectRatio.w / win->src.aspectRatio.h; double aspectRatio = (double)win->src.aspectRatio.w / win->src.aspectRatio.h;
int width = windowRect.right - windowRect.left; int width = (windowRect.right - windowRect.left) - win->src.wOffset;
int height = windowRect.bottom - windowRect.top; int height = (windowRect.bottom - windowRect.top) - win->src.hOffset;
int newHeight = (int)(width / aspectRatio); int newHeight = (int)(width / aspectRatio);
int newWidth = (int)(height * aspectRatio); int newWidth = (int)(height * aspectRatio);
@ -6537,11 +6538,11 @@ LRESULT CALLBACK WndProcW(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
else windowRect.bottom = windowRect.top + newHeight; else windowRect.bottom = windowRect.top + newHeight;
} }
RGFW_window_resize(win, RGFW_AREA((windowRect.right - windowRect.left), RGFW_window_resize(win, RGFW_AREA((u32)(windowRect.right - windowRect.left) - (u32)win->src.wOffset,
(u32)(windowRect.bottom - windowRect.top) - (u32)win->src.hOffset)); (u32)(windowRect.bottom - windowRect.top) - (u32)win->src.hOffset));
} }
win->r.w = windowRect.right - windowRect.left; win->r.w = (windowRect.right - windowRect.left) - (i32)win->src.wOffset;
win->r.h = (windowRect.bottom - windowRect.top) - (i32)win->src.hOffset; win->r.h = (windowRect.bottom - windowRect.top) - (i32)win->src.hOffset;
RGFW_eventQueuePushEx(e.type = RGFW_windowResized; e._win = win); RGFW_eventQueuePushEx(e.type = RGFW_windowResized; e._win = win);
RGFW_windowResizedCallback(win, win->r); RGFW_windowResizedCallback(win, win->r);
@ -6561,12 +6562,12 @@ LRESULT CALLBACK WndProcW(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
#endif #endif
case WM_GETMINMAXINFO: { case WM_GETMINMAXINFO: {
MINMAXINFO* mmi = (MINMAXINFO*) lParam; MINMAXINFO* mmi = (MINMAXINFO*) lParam;
mmi->ptMinTrackSize.x = (LONG)win->src.minSize.w; mmi->ptMinTrackSize.x = (LONG)(win->src.minSize.w + win->src.wOffset);
mmi->ptMinTrackSize.y = (LONG)(win->src.minSize.h + win->src.hOffset); mmi->ptMinTrackSize.y = (LONG)(win->src.minSize.h + win->src.hOffset);
if (win->src.maxSize.w == 0 && win->src.maxSize.h == 0) if (win->src.maxSize.w == 0 && win->src.maxSize.h == 0)
return DefWindowProcW(hWnd, message, wParam, lParam); return DefWindowProcW(hWnd, message, wParam, lParam);
mmi->ptMaxTrackSize.x = (LONG)win->src.maxSize.w; mmi->ptMaxTrackSize.x = (LONG)(win->src.maxSize.w + win->src.wOffset);
mmi->ptMaxTrackSize.y = (LONG)(win->src.maxSize.h + win->src.hOffset); mmi->ptMaxTrackSize.y = (LONG)(win->src.maxSize.h + win->src.hOffset);
return DefWindowProcW(hWnd, message, wParam, lParam); return DefWindowProcW(hWnd, message, wParam, lParam);
} }
@ -6968,7 +6969,8 @@ RGFW_window* RGFW_createWindowPtr(const char* name, RGFW_rect rect, RGFW_windowF
DestroyWindow(dummyWin); DestroyWindow(dummyWin);
win->src.hOffset = (u32)(windowRect.bottom - windowRect.top) - (u32)(clientRect.bottom - clientRect.top); win->src.hOffset = (u32)(windowRect.bottom - windowRect.top) - (u32)(clientRect.bottom - clientRect.top);
win->src.window = CreateWindowW(Class.lpszClassName, (wchar_t*)wide_name, window_style, win->r.x, win->r.y, win->r.w, win->r.h + (i32)win->src.hOffset, 0, 0, inh, 0); win->src.wOffset = (u32)(windowRect.right - windowRect.left) - (u32)(clientRect.right - clientRect.left);
win->src.window = CreateWindowW(Class.lpszClassName, (wchar_t*)wide_name, window_style, win->r.x, win->r.y, win->r.w + (i32)win->src.wOffset, win->r.h + (i32)win->src.hOffset, 0, 0, inh, 0);
SetPropW(win->src.window, L"RGFW", win); SetPropW(win->src.window, L"RGFW", win);
RGFW_window_resize(win, RGFW_AREA(win->r.w, win->r.h)); /* so WM_GETMINMAXINFO gets called again */ RGFW_window_resize(win, RGFW_AREA(win->r.w, win->r.h)); /* so WM_GETMINMAXINFO gets called again */
@ -7064,7 +7066,7 @@ void RGFW_window_setFullscreen(RGFW_window* win, RGFW_bool fullscreen) {
if (fullscreen == RGFW_FALSE) { if (fullscreen == RGFW_FALSE) {
RGFW_window_setBorder(win, 1); RGFW_window_setBorder(win, 1);
SetWindowPos(win->src.window, HWND_NOTOPMOST, win->_oldRect.x, win->_oldRect.y, win->_oldRect.w, win->_oldRect.h + (i32)win->src.hOffset, SetWindowPos(win->src.window, HWND_NOTOPMOST, win->_oldRect.x, win->_oldRect.y, win->_oldRect.w + (i32)win->src.wOffset, win->_oldRect.h + (i32)win->src.hOffset,
SWP_NOOWNERZORDER | SWP_FRAMECHANGED); SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
win->_flags &= ~(u32)RGFW_windowFullscreen; win->_flags &= ~(u32)RGFW_windowFullscreen;
@ -7898,7 +7900,7 @@ void RGFW_window_resize(RGFW_window* win, RGFW_area a) {
win->r.w = (i32)a.w; win->r.w = (i32)a.w;
win->r.h = (i32)a.h; win->r.h = (i32)a.h;
SetWindowPos(win->src.window, HWND_TOP, 0, 0, win->r.w, win->r.h + (i32)win->src.hOffset, SWP_NOMOVE); SetWindowPos(win->src.window, HWND_TOP, 0, 0, win->r.w + (i32)win->src.wOffset, win->r.h + (i32)win->src.hOffset, SWP_NOMOVE);
} }

View File

@ -62,7 +62,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5)
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -308,7 +308,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
unsigned char alpha = 0; unsigned char alpha = 0;
// NOTE: Data comes as A1R5G5B5, it must be reordered to R5G5B5A1 // NOTE: Data comes as A1R5G5B5, it must be reordered to R5G5B5A1
for (int i = 0; i < image_pixel_size; i++) for (int i = 0; i < data_size/sizeof(unsigned short); i++)
{ {
alpha = ((unsigned short *)image_data)[i] >> 15; alpha = ((unsigned short *)image_data)[i] >> 15;
((unsigned short *)image_data)[i] = ((unsigned short *)image_data)[i] << 1; ((unsigned short *)image_data)[i] = ((unsigned short *)image_data)[i] << 1;
@ -328,7 +328,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
unsigned char alpha = 0; unsigned char alpha = 0;
// NOTE: Data comes as A4R4G4B4, it must be reordered R4G4B4A4 // NOTE: Data comes as A4R4G4B4, it must be reordered R4G4B4A4
for (int i = 0; i < image_pixel_size; i++) for (int i = 0; i < data_size/sizeof(unsigned short); i++)
{ {
alpha = ((unsigned short *)image_data)[i] >> 12; alpha = ((unsigned short *)image_data)[i] >> 12;
((unsigned short *)image_data)[i] = ((unsigned short *)image_data)[i] << 4; ((unsigned short *)image_data)[i] = ((unsigned short *)image_data)[i] << 4;
@ -362,7 +362,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
// NOTE: Data comes as A8R8G8B8, it must be reordered R8G8B8A8 (view next comment) // NOTE: Data comes as A8R8G8B8, it must be reordered R8G8B8A8 (view next comment)
// DirecX understand ARGB as a 32bit DWORD but the actual memory byte alignment is BGRA // DirecX understand ARGB as a 32bit DWORD but the actual memory byte alignment is BGRA
// So, we must realign B8G8R8A8 to R8G8B8A8 // So, we must realign B8G8R8A8 to R8G8B8A8
for (int i = 0; i < image_pixel_size*4; i += 4) for (int i = 0; i < data_size; i += 4)
{ {
blue = ((unsigned char *)image_data)[i]; blue = ((unsigned char *)image_data)[i];
((unsigned char *)image_data)[i] = ((unsigned char *)image_data)[i + 2]; ((unsigned char *)image_data)[i] = ((unsigned char *)image_data)[i + 2];

View File

@ -54,6 +54,12 @@
// 'Ask where to save each file before downloading' - which you can set true/false. // 'Ask where to save each file before downloading' - which you can set true/false.
// If you enable this setting it would always ask you and bring the SaveAsDialog // If you enable this setting it would always ask you and bring the SaveAsDialog
saveAs(blob, localFSname); saveAs(blob, localFSname);
// Alternative implementation to avoid FileSaver.js
//const link = document.createElement("a");
//link.href = URL.createObjectURL(blob);
//link.download = localFSname;
//link.click();
} }
</script> </script>
</head> </head>

View File

@ -13,9 +13,6 @@
* - Improvement 01 * - Improvement 01
* - Improvement 02 * - Improvement 02
* *
* ADDITIONAL NOTES:
* - TRACELOG() function is located in raylib [utils] module
*
* CONFIGURATION: * CONFIGURATION:
* #define RCORE_PLATFORM_CUSTOM_FLAG * #define RCORE_PLATFORM_CUSTOM_FLAG
* Custom flag for rcore on target platform -not used- * Custom flag for rcore on target platform -not used-
@ -27,7 +24,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) and contributors * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) and contributors
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -48,7 +45,11 @@
#include <android_native_app_glue.h> // Required for: android_app struct and activity management #include <android_native_app_glue.h> // Required for: android_app struct and activity management
#include <android/window.h> // Required for: AWINDOW_FLAG_FULLSCREEN definition and others #include <android/window.h> // Required for: AWINDOW_FLAG_FULLSCREEN definition and others
#include <android/log.h> // Required for: Android log system: __android_log_vprint()
#include <android/asset_manager.h> // Required for: AAssetManager
//#include <android/sensor.h> // Required for: Android sensors functions (accelerometer, gyroscope, light...) //#include <android/sensor.h> // Required for: Android sensors functions (accelerometer, gyroscope, light...)
#include <errno.h> // Required for: error types
#include <jni.h> // Required for: JNIEnv and JavaVM [Used in OpenURL() and GetCurrentMonitor()] #include <jni.h> // Required for: JNIEnv and JavaVM [Used in OpenURL() and GetCurrentMonitor()]
#include <EGL/egl.h> // Native platform windowing system interface #include <EGL/egl.h> // Native platform windowing system interface
@ -267,6 +268,19 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd);
static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event); // Process Android inputs static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event); // Process Android inputs
static GamepadButton AndroidTranslateGamepadButton(int button); // Map Android gamepad button to raylib gamepad button static GamepadButton AndroidTranslateGamepadButton(int button); // Map Android gamepad button to raylib gamepad button
static void SetupFramebuffer(int width, int height); // Setup main framebuffer (required by InitPlatform())
static int android_read(void *cookie, char *buf, int size);
static int android_write(void *cookie, const char *buf, int size);
static fpos_t android_seek(void *cookie, fpos_t offset, int whence);
static int android_close(void *cookie);
FILE *android_fopen(const char *fileName, const char *mode); // Replacement for fopen() -> Read-only!
FILE *funopen(const void *cookie, int (*readfn)(void *, char *, int), int (*writefn)(void *, const char *, int),
fpos_t (*seekfn)(void *, fpos_t, int), int (*closefn)(void *));
#define fopen(name, mode) android_fopen(name, mode)
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module Functions Declaration // Module Functions Declaration
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -360,7 +374,7 @@ void SetWindowState(unsigned int flags)
if (!CORE.Window.ready) TRACELOG(LOG_WARNING, "WINDOW: SetWindowState does nothing before window initialization, Use \"SetConfigFlags\" instead"); if (!CORE.Window.ready) TRACELOG(LOG_WARNING, "WINDOW: SetWindowState does nothing before window initialization, Use \"SetConfigFlags\" instead");
// State change: FLAG_WINDOW_ALWAYS_RUN // State change: FLAG_WINDOW_ALWAYS_RUN
if (!FLAG_IS_SET(flags, FLAG_WINDOW_ALWAYS_RUN)) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_ALWAYS_RUN); if (FLAG_IS_SET(flags, FLAG_WINDOW_ALWAYS_RUN)) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_ALWAYS_RUN);
} }
// Clear window configuration state flags // Clear window configuration state flags
@ -817,8 +831,6 @@ int InitPlatform(void)
// Initialize storage system // Initialize storage system
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
InitAssetManager(platform.app->activity->assetManager, platform.app->activity->internalDataPath); // Initialize assets manager
CORE.Storage.basePath = platform.app->activity->internalDataPath; // Define base path for storage CORE.Storage.basePath = platform.app->activity->internalDataPath; // Define base path for storage
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -885,7 +897,6 @@ void ClosePlatform(void)
// NOTE: returns false in case graphic device could not be created // NOTE: returns false in case graphic device could not be created
static int InitGraphicsDevice(void) static int InitGraphicsDevice(void)
{ {
CORE.Window.fullscreen = true;
FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
EGLint samples = 0; EGLint samples = 0;
@ -919,6 +930,7 @@ static int InitGraphicsDevice(void)
// Get an EGL device connection // Get an EGL device connection
platform.device = eglGetDisplay(EGL_DEFAULT_DISPLAY); platform.device = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (platform.device == EGL_NO_DISPLAY) if (platform.device == EGL_NO_DISPLAY)
{ {
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device"); TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
@ -1238,8 +1250,11 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
//int32_t AKeyEvent_getMetaState(event); //int32_t AKeyEvent_getMetaState(event);
// Handle gamepad button presses and releases // Handle gamepad button presses and releases
if (FLAG_IS_SET(source, AINPUT_SOURCE_JOYSTICK) || // NOTE: Skip gamepad handling if this is a keyboard event, as some devices
FLAG_IS_SET(source, AINPUT_SOURCE_GAMEPAD)) // report both AINPUT_SOURCE_KEYBOARD and AINPUT_SOURCE_GAMEPAD flags
if ((FLAG_IS_SET(source, AINPUT_SOURCE_JOYSTICK) ||
FLAG_IS_SET(source, AINPUT_SOURCE_GAMEPAD)) &&
!FLAG_IS_SET(source, AINPUT_SOURCE_KEYBOARD))
{ {
// For now we'll assume a single gamepad which we "detect" on its input event // For now we'll assume a single gamepad which we "detect" on its input event
CORE.Input.Gamepad.ready[0] = true; CORE.Input.Gamepad.ready[0] = true;
@ -1332,30 +1347,17 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
} }
} }
if ((flags == AMOTION_EVENT_ACTION_POINTER_UP) || (flags == AMOTION_EVENT_ACTION_UP) || (flags == AMOTION_EVENT_ACTION_HOVER_EXIT)) #if defined(SUPPORT_GESTURES_SYSTEM)
{ GestureEvent gestureEvent = { 0 };
// One of the touchpoints is released, remove it from touch point arrays
if (flags == AMOTION_EVENT_ACTION_HOVER_EXIT) gestureEvent.pointCount = 0;
{
// If the touchPoint is hover, remove it from hoverPoints // Register touch actions
for (int i = 0; i < MAX_TOUCH_POINTS; i++) if (flags == AMOTION_EVENT_ACTION_DOWN) gestureEvent.touchAction = TOUCH_ACTION_DOWN;
{ else if (flags == AMOTION_EVENT_ACTION_UP) gestureEvent.touchAction = TOUCH_ACTION_UP;
if (touchRaw.hoverPoints[i] == touchRaw.pointId[pointerIndex]) else if (flags == AMOTION_EVENT_ACTION_MOVE) gestureEvent.touchAction = TOUCH_ACTION_MOVE;
{ else if (flags == AMOTION_EVENT_ACTION_CANCEL) gestureEvent.touchAction = TOUCH_ACTION_CANCEL;
touchRaw.hoverPoints[i] = -1;
break;
}
}
}
for (int i = pointerIndex; (i < touchRaw.pointCount - 1) && (i < MAX_TOUCH_POINTS - 1); i++)
{
touchRaw.pointId[i] = touchRaw.pointId[i+1];
touchRaw.position[i] = touchRaw.position[i+1];
}
touchRaw.pointCount--;
}
int pointCount = 0;
for (int i = 0; (i < touchRaw.pointCount) && (i < MAX_TOUCH_POINTS); i++) for (int i = 0; (i < touchRaw.pointCount) && (i < MAX_TOUCH_POINTS); i++)
{ {
// If the touchPoint is hover, Ignore it // If the touchPoint is hover, Ignore it
@ -1371,35 +1373,62 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
} }
if (hover) continue; if (hover) continue;
CORE.Input.Touch.pointId[pointCount] = touchRaw.pointId[i]; gestureEvent.pointId[gestureEvent.pointCount] = touchRaw.pointId[i];
CORE.Input.Touch.position[pointCount] = touchRaw.position[i]; gestureEvent.position[gestureEvent.pointCount] = touchRaw.position[i];
pointCount++; gestureEvent.position[gestureEvent.pointCount].x /= (float)GetScreenWidth();
} gestureEvent.position[gestureEvent.pointCount].y /= (float)GetScreenHeight();
CORE.Input.Touch.pointCount = pointCount; gestureEvent.pointCount++;
#if defined(SUPPORT_GESTURES_SYSTEM)
GestureEvent gestureEvent = { 0 };
gestureEvent.pointCount = CORE.Input.Touch.pointCount;
// Register touch actions
if (flags == AMOTION_EVENT_ACTION_DOWN) gestureEvent.touchAction = TOUCH_ACTION_DOWN;
else if (flags == AMOTION_EVENT_ACTION_UP) gestureEvent.touchAction = TOUCH_ACTION_UP;
else if (flags == AMOTION_EVENT_ACTION_MOVE) gestureEvent.touchAction = TOUCH_ACTION_MOVE;
else if (flags == AMOTION_EVENT_ACTION_CANCEL) gestureEvent.touchAction = TOUCH_ACTION_CANCEL;
for (int i = 0; (i < gestureEvent.pointCount) && (i < MAX_TOUCH_POINTS); i++)
{
gestureEvent.pointId[i] = CORE.Input.Touch.pointId[i];
gestureEvent.position[i] = CORE.Input.Touch.position[i];
gestureEvent.position[i].x /= (float)GetScreenWidth();
gestureEvent.position[i].y /= (float)GetScreenHeight();
} }
// Gesture data is sent to gestures system for processing // Gesture data is sent to gestures system for processing
ProcessGestureEvent(gestureEvent); ProcessGestureEvent(gestureEvent);
#endif #endif
if (flags == AMOTION_EVENT_ACTION_HOVER_EXIT)
{
// Hover exited. So, remove it from hoverPoints
for (int i = 0; i < MAX_TOUCH_POINTS; i++)
{
if (touchRaw.hoverPoints[i] == touchRaw.pointId[pointerIndex])
{
touchRaw.hoverPoints[i] = -1;
break;
}
}
}
if ((flags == AMOTION_EVENT_ACTION_POINTER_UP) || (flags == AMOTION_EVENT_ACTION_UP))
{
// One of the touchpoints is released, remove it from touch point arrays
for (int i = pointerIndex; (i < touchRaw.pointCount - 1) && (i < MAX_TOUCH_POINTS - 1); i++)
{
touchRaw.pointId[i] = touchRaw.pointId[i+1];
touchRaw.position[i] = touchRaw.position[i+1];
}
touchRaw.pointCount--;
}
CORE.Input.Touch.pointCount = 0;
for (int i = 0; (i < touchRaw.pointCount) && (i < MAX_TOUCH_POINTS); i++)
{
// If the touchPoint is hover, Ignore it
bool hover = false;
for (int j = 0; j < MAX_TOUCH_POINTS; j++)
{
// Check if the touchPoint is in hoverPointers
if (touchRaw.hoverPoints[j] == touchRaw.pointId[i])
{
hover = true;
break;
}
}
if (hover) continue;
CORE.Input.Touch.pointId[CORE.Input.Touch.pointCount] = touchRaw.pointId[i];
CORE.Input.Touch.position[CORE.Input.Touch.pointCount] = touchRaw.position[i];
CORE.Input.Touch.pointCount++;
}
// When all touchpoints are tapped and released really quickly, this event is generated // When all touchpoints are tapped and released really quickly, this event is generated
if (flags == AMOTION_EVENT_ACTION_CANCEL) CORE.Input.Touch.pointCount = 0; if (flags == AMOTION_EVENT_ACTION_CANCEL) CORE.Input.Touch.pointCount = 0;
@ -1417,4 +1446,144 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
return 0; return 0;
} }
// Compute framebuffer size relative to screen size and display size
// NOTE: Global variables CORE.Window.render.width/CORE.Window.render.height and CORE.Window.renderOffset.x/CORE.Window.renderOffset.y can be modified
static void SetupFramebuffer(int width, int height)
{
// Calculate CORE.Window.render.width and CORE.Window.render.height, we have the display size (input params) and the desired screen size (global var)
if ((CORE.Window.screen.width > CORE.Window.display.width) || (CORE.Window.screen.height > CORE.Window.display.height))
{
TRACELOG(LOG_WARNING, "DISPLAY: Downscaling required: Screen size (%ix%i) is bigger than display size (%ix%i)", CORE.Window.screen.width, CORE.Window.screen.height, CORE.Window.display.width, CORE.Window.display.height);
// Downscaling to fit display with border-bars
float widthRatio = (float)CORE.Window.display.width/(float)CORE.Window.screen.width;
float heightRatio = (float)CORE.Window.display.height/(float)CORE.Window.screen.height;
if (widthRatio <= heightRatio)
{
CORE.Window.render.width = CORE.Window.display.width;
CORE.Window.render.height = (int)round((float)CORE.Window.screen.height*widthRatio);
CORE.Window.renderOffset.x = 0;
CORE.Window.renderOffset.y = (CORE.Window.display.height - CORE.Window.render.height);
}
else
{
CORE.Window.render.width = (int)round((float)CORE.Window.screen.width*heightRatio);
CORE.Window.render.height = CORE.Window.display.height;
CORE.Window.renderOffset.x = (CORE.Window.display.width - CORE.Window.render.width);
CORE.Window.renderOffset.y = 0;
}
// Screen scaling required
float scaleRatio = (float)CORE.Window.render.width/(float)CORE.Window.screen.width;
CORE.Window.screenScale = MatrixScale(scaleRatio, scaleRatio, 1.0f);
// NOTE: We render to full display resolution!
// We just need to calculate above parameters for downscale matrix and offsets
CORE.Window.render.width = CORE.Window.display.width;
CORE.Window.render.height = CORE.Window.display.height;
TRACELOG(LOG_WARNING, "DISPLAY: Downscale matrix generated, content will be rendered at (%ix%i)", CORE.Window.render.width, CORE.Window.render.height);
}
else if ((CORE.Window.screen.width < CORE.Window.display.width) || (CORE.Window.screen.height < CORE.Window.display.height))
{
// Required screen size is smaller than display size
TRACELOG(LOG_INFO, "DISPLAY: Upscaling required: Screen size (%ix%i) smaller than display size (%ix%i)", CORE.Window.screen.width, CORE.Window.screen.height, CORE.Window.display.width, CORE.Window.display.height);
if ((CORE.Window.screen.width == 0) || (CORE.Window.screen.height == 0))
{
CORE.Window.screen.width = CORE.Window.display.width;
CORE.Window.screen.height = CORE.Window.display.height;
}
// Upscaling to fit display with border-bars
float displayRatio = (float)CORE.Window.display.width/(float)CORE.Window.display.height;
float screenRatio = (float)CORE.Window.screen.width/(float)CORE.Window.screen.height;
if (displayRatio <= screenRatio)
{
CORE.Window.render.width = CORE.Window.screen.width;
CORE.Window.render.height = (int)round((float)CORE.Window.screen.width/displayRatio);
CORE.Window.renderOffset.x = 0;
CORE.Window.renderOffset.y = (CORE.Window.render.height - CORE.Window.screen.height);
}
else
{
CORE.Window.render.width = (int)round((float)CORE.Window.screen.height*displayRatio);
CORE.Window.render.height = CORE.Window.screen.height;
CORE.Window.renderOffset.x = (CORE.Window.render.width - CORE.Window.screen.width);
CORE.Window.renderOffset.y = 0;
}
}
else
{
CORE.Window.render.width = CORE.Window.screen.width;
CORE.Window.render.height = CORE.Window.screen.height;
CORE.Window.renderOffset.x = 0;
CORE.Window.renderOffset.y = 0;
}
}
// Replacement for fopen()
// REF: https://developer.android.com/ndk/reference/group/asset
FILE *android_fopen(const char *fileName, const char *mode)
{
FILE *file = NULL;
if (mode[0] == 'w')
{
// NOTE: fopen() is mapped to android_fopen() that only grants read access to
// assets directory through AAssetManager but we want to also be able to
// write data when required using the standard stdio FILE access functions
// REF: https://stackoverflow.com/questions/11294487/android-writing-saving-files-from-native-code-only
#undef fopen
file = fopen(TextFormat("%s/%s", platform.app->activity->internalDataPath, fileName), mode);
#define fopen(name, mode) android_fopen(name, mode)
}
else
{
// NOTE: AAsset provides access to read-only asset
AAsset *asset = AAssetManager_open(platform.app->activity->assetManager, fileName, AASSET_MODE_UNKNOWN);
if (asset != NULL)
{
// Get pointer to file in the assets
file = funopen(asset, android_read, android_write, android_seek, android_close);
}
else
{
#undef fopen
// Just do a regular open if file is not found in the assets
file = fopen(TextFormat("%s/%s", platform.app->activity->internalDataPath, fileName), mode);
if (file == NULL) file = fopen(fileName, mode);
#define fopen(name, mode) android_fopen(name, mode)
}
}
return file;
}
static int android_read(void *cookie, char *data, int dataSize)
{
return AAsset_read((AAsset *)cookie, data, dataSize);
}
static int android_write(void *cookie, const char *data, int dataSize)
{
TRACELOG(LOG_WARNING, "ANDROID: Failed to provide write access to APK");
return EACCES;
}
static fpos_t android_seek(void *cookie, fpos_t offset, int whence)
{
return AAsset_seek((AAsset *)cookie, offset, whence);
}
static int android_close(void *cookie)
{
AAsset_close((AAsset *)cookie);
return 0;
}
// EOF // EOF

View File

@ -16,9 +16,6 @@
* - Improvement 01 * - Improvement 01
* - Improvement 02 * - Improvement 02
* *
* ADDITIONAL NOTES:
* - TRACELOG() function is located in raylib [utils] module
*
* CONFIGURATION: * CONFIGURATION:
* #define RCORE_PLATFORM_CUSTOM_FLAG * #define RCORE_PLATFORM_CUSTOM_FLAG
* Custom flag for rcore on target platform -not used- * Custom flag for rcore on target platform -not used-
@ -30,7 +27,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) and contributors * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) and contributors
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -176,45 +173,72 @@ bool WindowShouldClose(void)
// Toggle fullscreen mode // Toggle fullscreen mode
void ToggleFullscreen(void) void ToggleFullscreen(void)
{ {
if (!CORE.Window.fullscreen) if (!FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE))
{ {
// Store previous window position (in case we exit fullscreen) // Store previous screen data (in case exiting fullscreen)
CORE.Window.previousPosition = CORE.Window.position; CORE.Window.previousPosition = CORE.Window.position;
CORE.Window.previousScreen = CORE.Window.screen;
// Use current monitor the window is on to get fullscreen required size
int monitorCount = 0; int monitorCount = 0;
int monitorIndex = GetCurrentMonitor(); int monitorIndex = GetCurrentMonitor();
GLFWmonitor **monitors = glfwGetMonitors(&monitorCount); GLFWmonitor **monitors = glfwGetMonitors(&monitorCount);
// Use current monitor, so we correctly get the display the window is on
GLFWmonitor *monitor = (monitorIndex < monitorCount)? monitors[monitorIndex] : NULL; GLFWmonitor *monitor = (monitorIndex < monitorCount)? monitors[monitorIndex] : NULL;
if (monitor == NULL) if (monitor != NULL)
{ {
TRACELOG(LOG_WARNING, "GLFW: Failed to get monitor"); // Get current monitor video mode
const GLFWvidmode *mode = glfwGetVideoMode(monitors[monitorIndex]);
CORE.Window.display.width = mode->width;
CORE.Window.display.height = mode->height;
CORE.Window.fullscreen = false; CORE.Window.position = (Point){ 0, 0 };
FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); CORE.Window.screen = CORE.Window.display;
glfwSetWindowMonitor(platform.handle, NULL, 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE); // Set fullscreen flag to be processed on FramebufferSizeCallback() accordingly
}
else
{
CORE.Window.fullscreen = true;
FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND)
// NOTE: X11 requires undecorating the window before switching to
// fullscreen to avoid issues with framebuffer scaling
glfwSetWindowAttrib(platform.handle, GLFW_DECORATED, GLFW_FALSE);
FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNDECORATED);
#endif
// WARNING: This function launches FramebufferSizeCallback()
glfwSetWindowMonitor(platform.handle, monitor, 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE); glfwSetWindowMonitor(platform.handle, monitor, 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
} }
else TRACELOG(LOG_WARNING, "GLFW: Failed to get monitor");
} }
else else
{ {
CORE.Window.fullscreen = false; // Restore previous window position and size
CORE.Window.position = CORE.Window.previousPosition;
CORE.Window.screen = CORE.Window.previousScreen;
// Set fullscreen flag to be processed on FramebufferSizeCallback() accordingly
// and considered by GetWindowScaleDPI()
FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
glfwSetWindowMonitor(platform.handle, NULL, CORE.Window.previousPosition.x, CORE.Window.previousPosition.y, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE); #if !defined(__APPLE__)
// Make sure to restore render size considering HighDPI scaling
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI))
{
Vector2 scaleDpi = GetWindowScaleDPI();
CORE.Window.screen.width = (unsigned int)(CORE.Window.screen.width * scaleDpi.x);
CORE.Window.screen.height = (unsigned int)(CORE.Window.screen.height * scaleDpi.y);
}
#endif
// we update the window position right away // WARNING: This function launches FramebufferSizeCallback()
CORE.Window.position.x = CORE.Window.previousPosition.x; glfwSetWindowMonitor(platform.handle, NULL, CORE.Window.position.x, CORE.Window.position.y,
CORE.Window.position.y = CORE.Window.previousPosition.y; CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND)
// NOTE: X11 requires restoring the decorated window after switching from
// fullscreen to avoid issues with framebuffer scaling
glfwSetWindowAttrib(platform.handle, GLFW_DECORATED, GLFW_TRUE);
FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNDECORATED);
#endif
} }
// Try to enable GPU V-Sync, so frames are limited to screen refresh rate (60Hz -> 60 FPS) // Try to enable GPU V-Sync, so frames are limited to screen refresh rate (60Hz -> 60 FPS)
@ -226,13 +250,8 @@ void ToggleFullscreen(void)
void ToggleBorderlessWindowed(void) void ToggleBorderlessWindowed(void)
{ {
// Leave fullscreen before attempting to set borderless windowed mode // Leave fullscreen before attempting to set borderless windowed mode
bool wasOnFullscreen = false; // NOTE: Fullscreen already saves the previous position so it does not need to be set again later
if (CORE.Window.fullscreen) if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) ToggleFullscreen();
{
// Fullscreen already saves the previous position so it does not need to be set here again
ToggleFullscreen();
wasOnFullscreen = true;
}
int monitorCount = 0; int monitorCount = 0;
GLFWmonitor **monitors = glfwGetMonitors(&monitorCount); GLFWmonitor **monitors = glfwGetMonitors(&monitorCount);
@ -248,7 +267,7 @@ void ToggleBorderlessWindowed(void)
{ {
// Store screen position and size // Store screen position and size
// NOTE: If it was on fullscreen, screen position was already stored, so skip setting it here // NOTE: If it was on fullscreen, screen position was already stored, so skip setting it here
if (!wasOnFullscreen) CORE.Window.previousPosition = CORE.Window.position; CORE.Window.previousPosition = CORE.Window.position;
CORE.Window.previousScreen = CORE.Window.screen; CORE.Window.previousScreen = CORE.Window.screen;
// Set undecorated flag // Set undecorated flag
@ -256,22 +275,13 @@ void ToggleBorderlessWindowed(void)
FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNDECORATED); FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNDECORATED);
// Get monitor position and size // Get monitor position and size
int monitorPosX = 0; glfwGetMonitorPos(monitors[monitor], &CORE.Window.position.x, &CORE.Window.position.y);
int monitorPosY = 0; CORE.Window.screen.width = mode->width;
glfwGetMonitorPos(monitors[monitor], &monitorPosX, &monitorPosY); CORE.Window.screen.height = mode->height;
const int monitorWidth = mode->width;
const int monitorHeight = mode->height;
// Set screen position and size // Set screen position and size
glfwSetWindowMonitor( glfwSetWindowMonitor(platform.handle, monitors[monitor], CORE.Window.position.x, CORE.Window.position.y,
platform.handle, CORE.Window.screen.width, CORE.Window.screen.height, mode->refreshRate);
monitors[monitor],
monitorPosX,
monitorPosY,
monitorWidth,
monitorHeight,
mode->refreshRate
);
// Refocus window // Refocus window
glfwFocusWindow(platform.handle); glfwFocusWindow(platform.handle);
@ -280,39 +290,32 @@ void ToggleBorderlessWindowed(void)
} }
else else
{ {
// Restore previous screen values
CORE.Window.position = CORE.Window.previousPosition;
CORE.Window.screen = CORE.Window.previousScreen;
// Remove undecorated flag // Remove undecorated flag
glfwSetWindowAttrib(platform.handle, GLFW_DECORATED, GLFW_TRUE); glfwSetWindowAttrib(platform.handle, GLFW_DECORATED, GLFW_TRUE);
FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNDECORATED); FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNDECORATED);
#if !defined(__APPLE__) #if !defined(__APPLE__)
// Make sure to restore size to HighDPI // Make sure to restore size considering HighDPI scaling
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI))
{ {
Vector2 scaleDpi = GetWindowScaleDPI(); Vector2 scaleDpi = GetWindowScaleDPI();
CORE.Window.previousScreen.width *= scaleDpi.x; CORE.Window.screen.width = (unsigned int)(CORE.Window.screen.width * scaleDpi.x);
CORE.Window.previousScreen.height *= scaleDpi.y; CORE.Window.screen.height = (unsigned int)(CORE.Window.screen.height * scaleDpi.y);
} }
#endif #endif
// Return previous screen size and position // Return to previous screen size and position
// NOTE: The order matters here, it must set size first, then set position, otherwise the screen will be positioned incorrectly glfwSetWindowMonitor(platform.handle, NULL, CORE.Window.position.x, CORE.Window.position.y,
glfwSetWindowMonitor( CORE.Window.screen.width, CORE.Window.screen.height, mode->refreshRate);
platform.handle,
NULL,
CORE.Window.previousPosition.x,
CORE.Window.previousPosition.y,
CORE.Window.previousScreen.width,
CORE.Window.previousScreen.height,
mode->refreshRate
);
// Refocus window // Refocus window
glfwFocusWindow(platform.handle); glfwFocusWindow(platform.handle);
FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE);
CORE.Window.position.x = CORE.Window.previousPosition.x;
CORE.Window.position.y = CORE.Window.previousPosition.y;
} }
} }
else TRACELOG(LOG_WARNING, "GLFW: Failed to find video mode for selected monitor"); else TRACELOG(LOG_WARNING, "GLFW: Failed to find video mode for selected monitor");
@ -666,7 +669,7 @@ void SetWindowMonitor(int monitor)
if ((monitor >= 0) && (monitor < monitorCount)) if ((monitor >= 0) && (monitor < monitorCount))
{ {
if (CORE.Window.fullscreen) if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE))
{ {
TRACELOG(LOG_INFO, "GLFW: Selected fullscreen monitor: [%i] %s", monitor, glfwGetMonitorName(monitors[monitor])); TRACELOG(LOG_INFO, "GLFW: Selected fullscreen monitor: [%i] %s", monitor, glfwGetMonitorName(monitors[monitor]));
@ -1013,19 +1016,15 @@ const char *GetMonitorName(int monitor)
// Get window position XY on monitor // Get window position XY on monitor
Vector2 GetWindowPosition(void) Vector2 GetWindowPosition(void)
{ {
int x = 0; return (Vector2){ (float)CORE.Window.position.x, (float)CORE.Window.position.y };
int y = 0;
glfwGetWindowPos(platform.handle, &x, &y);
return (Vector2){ (float)x, (float)y };
} }
// Get window scale DPI factor for current monitor // Get window scale DPI factor for current monitor
Vector2 GetWindowScaleDPI(void) Vector2 GetWindowScaleDPI(void)
{ {
Vector2 scale = { 1.0f, 1.0f }; Vector2 scale = { 1.0f, 1.0f };
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) glfwGetWindowContentScale(platform.handle, &scale.x, &scale.y); if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI) && !FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE))
glfwGetWindowContentScale(platform.handle, &scale.x, &scale.y);
return scale; return scale;
} }
@ -1266,7 +1265,13 @@ void PollInputEvents(void)
// Get current gamepad state // Get current gamepad state
// NOTE: There is no callback available, so we get it manually // NOTE: There is no callback available, so we get it manually
GLFWgamepadstate state = { 0 }; GLFWgamepadstate state = { 0 };
glfwGetGamepadState(i, &state); // This remapps all gamepads so they have their buttons mapped like an xbox controller int result = glfwGetGamepadState(i, &state); // This remaps all gamepads so they have their buttons mapped like an xbox controller
if (result == GLFW_FALSE) // No joystick is connected, no gamepad mapping or an error occurred
{
// Setting axes to expected resting value instead of GLFW 0.0f default when gamepad is not connected
state.axes[GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f;
state.axes[GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f;
}
const unsigned char *buttons = state.buttons; const unsigned char *buttons = state.buttons;
@ -1356,7 +1361,6 @@ void PollInputEvents(void)
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Function wrappers around RL_*alloc macros, used by glfwInitAllocator() inside of InitPlatform() // Function wrappers around RL_*alloc macros, used by glfwInitAllocator() inside of InitPlatform()
// We need to provide these because GLFWallocator expects function pointers with specific signatures // We need to provide these because GLFWallocator expects function pointers with specific signatures
// Similar wrappers exist in utils.c but we cannot reuse them here due to declaration mismatch
// REF: https://www.glfw.org/docs/latest/intro_guide.html#init_allocator // REF: https://www.glfw.org/docs/latest/intro_guide.html#init_allocator
static void *AllocateWrapper(size_t size, void *user) static void *AllocateWrapper(size_t size, void *user)
{ {
@ -1416,8 +1420,6 @@ int InitPlatform(void)
unsigned int requestedWindowFlags = CORE.Window.flags; unsigned int requestedWindowFlags = CORE.Window.flags;
// Check window creation flags // Check window creation flags
if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) CORE.Window.fullscreen = true;
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)) glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // Visible window if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)) glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // Visible window
else glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE); // Window initially hidden else glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE); // Window initially hidden
@ -1530,11 +1532,14 @@ int InitPlatform(void)
// REF: https://github.com/raysan5/raylib/issues/1554 // REF: https://github.com/raysan5/raylib/issues/1554
glfwSetJoystickCallback(NULL); glfwSetJoystickCallback(NULL);
GLFWmonitor *monitor = NULL; if ((CORE.Window.screen.width == 0) || (CORE.Window.screen.height == 0)) FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
if (CORE.Window.fullscreen)
// Init window in fullscreen mode if requested
// NOTE: Keeping original screen size for toggle
if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE))
{ {
// NOTE: Fullscreen applications default to the primary monitor // NOTE: Fullscreen applications default to the primary monitor
monitor = glfwGetPrimaryMonitor(); GLFWmonitor *monitor = glfwGetPrimaryMonitor();
if (!monitor) if (!monitor)
{ {
TRACELOG(LOG_WARNING, "GLFW: Failed to get primary monitor"); TRACELOG(LOG_WARNING, "GLFW: Failed to get primary monitor");
@ -1548,80 +1553,40 @@ int InitPlatform(void)
CORE.Window.display.width = mode->width; CORE.Window.display.width = mode->width;
CORE.Window.display.height = mode->height; CORE.Window.display.height = mode->height;
// Set screen width/height to the display width/height if they are 0 // Check if user requested some screen size
if ((CORE.Window.screen.width == 0) || (CORE.Window.screen.height == 0))
{
// Set some default screen size in case user decides to exit fullscreen mode
CORE.Window.previousScreen.width = 800;
CORE.Window.previousScreen.height = 450;
CORE.Window.previousPosition.x = CORE.Window.display.width/2 - 800/2;
CORE.Window.previousPosition.y = CORE.Window.display.height/2 - 450/2;
// Set screen width/height to the display width/height
if (CORE.Window.screen.width == 0) CORE.Window.screen.width = CORE.Window.display.width; if (CORE.Window.screen.width == 0) CORE.Window.screen.width = CORE.Window.display.width;
if (CORE.Window.screen.height == 0) CORE.Window.screen.height = CORE.Window.display.height; if (CORE.Window.screen.height == 0) CORE.Window.screen.height = CORE.Window.display.height;
// Remember center for switching from fullscreen to window
if ((CORE.Window.screen.height == CORE.Window.display.height) && (CORE.Window.screen.width == CORE.Window.display.width))
{
// If screen width/height equal to the display, we can't calculate the window pos for toggling full-screened/windowed
// Toggling full-screened/windowed with pos(0, 0) can cause problems in some platforms, such as X11
CORE.Window.position.x = CORE.Window.display.width/4;
CORE.Window.position.y = CORE.Window.display.height/4;
} }
else else
{ {
CORE.Window.position.x = CORE.Window.display.width/2 - CORE.Window.screen.width/2; CORE.Window.previousScreen = CORE.Window.screen;
CORE.Window.position.y = CORE.Window.display.height/2 - CORE.Window.screen.height/2; CORE.Window.screen = CORE.Window.display;
} }
if (CORE.Window.position.x < 0) CORE.Window.position.x = 0; platform.handle = glfwCreateWindow(CORE.Window.screen.width, CORE.Window.screen.height, (CORE.Window.title != 0)? CORE.Window.title : " ", monitor, NULL);
if (CORE.Window.position.y < 0) CORE.Window.position.y = 0;
// Obtain recommended CORE.Window.display.width/CORE.Window.display.height from a valid videomode for the monitor
int count = 0;
const GLFWvidmode *modes = glfwGetVideoModes(monitor, &count);
// Get closest video mode to desired CORE.Window.screen.width/CORE.Window.screen.height
for (int i = 0; i < count; i++)
{
if ((unsigned int)modes[i].width >= CORE.Window.screen.width)
{
if ((unsigned int)modes[i].height >= CORE.Window.screen.height)
{
CORE.Window.display.width = modes[i].width;
CORE.Window.display.height = modes[i].height;
break;
}
}
}
TRACELOG(LOG_INFO, "SYSTEM: Closest fullscreen videomode: %i x %i", CORE.Window.display.width, CORE.Window.display.height);
// NOTE: ISSUE: Closest videomode could not match monitor aspect-ratio, for example,
// for a desired screen size of 800x450 (16:9), closest supported videomode is 800x600 (4:3),
// framebuffer is rendered correctly but once displayed on a 16:9 monitor, it gets stretched
// by the sides to fit all monitor space...
// Try to setup the most appropriate fullscreen framebuffer for the requested screenWidth/screenHeight
// It considers device display resolution mode and setups a framebuffer with black bars if required (render size/offset)
// Modified global variables: CORE.Window.screen.width/CORE.Window.screen.height - CORE.Window.render.width/CORE.Window.render.height - CORE.Window.renderOffset.x/CORE.Window.renderOffset.y - CORE.Window.screenScale
// TODO: It is a quite cumbersome solution to display size vs requested size, it should be reviewed or removed...
// HighDPI monitors are properly considered in a following similar function: SetupViewport()
SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);
platform.handle = glfwCreateWindow(CORE.Window.display.width, CORE.Window.display.height, (CORE.Window.title != 0)? CORE.Window.title : " ", monitor, NULL);
if (!platform.handle) if (!platform.handle)
{ {
glfwTerminate(); glfwTerminate();
TRACELOG(LOG_WARNING, "GLFW: Failed to initialize Window"); TRACELOG(LOG_WARNING, "GLFW: Failed to initialize Window");
return -1; return -1;
} }
// NOTE: Full-screen change, not working properly...
//glfwSetWindowMonitor(platform.handle, glfwGetPrimaryMonitor(), 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
} }
else else
{ {
// No-fullscreen window creation
bool requestWindowedFullscreen = (CORE.Window.screen.height == 0) && (CORE.Window.screen.width == 0);
// Default to at least one pixel in size, as creation with a zero dimension is not allowed // Default to at least one pixel in size, as creation with a zero dimension is not allowed
int creationWidth = (CORE.Window.screen.width != 0)? CORE.Window.screen.width : 1; if (CORE.Window.screen.width == 0) CORE.Window.screen.width = 1;
int creationHeight = (CORE.Window.screen.height != 0)? CORE.Window.screen.height : 1; if (CORE.Window.screen.height == 0) CORE.Window.screen.height = 1;
platform.handle = glfwCreateWindow(creationWidth, creationHeight, (CORE.Window.title != 0)? CORE.Window.title : " ", NULL, NULL); platform.handle = glfwCreateWindow(CORE.Window.screen.width, CORE.Window.screen.height, (CORE.Window.title != 0)? CORE.Window.title : " ", NULL, NULL);
if (!platform.handle) if (!platform.handle)
{ {
glfwTerminate(); glfwTerminate();
@ -1630,7 +1595,7 @@ int InitPlatform(void)
} }
// After the window was created, determine the monitor that the window manager assigned // After the window was created, determine the monitor that the window manager assigned
// Derive display sizes, and, if possible, window size in case it was zero at beginning // Derive display sizes and, if possible, window size in case it was zero at beginning
int monitorCount = 0; int monitorCount = 0;
int monitorIndex = GetCurrentMonitor(); int monitorIndex = GetCurrentMonitor();
@ -1638,7 +1603,7 @@ int InitPlatform(void)
if (monitorIndex < monitorCount) if (monitorIndex < monitorCount)
{ {
monitor = monitors[monitorIndex]; GLFWmonitor *monitor = monitors[monitorIndex];
const GLFWvidmode *mode = glfwGetVideoMode(monitor); const GLFWvidmode *mode = glfwGetVideoMode(monitor);
// Default display resolution to that of the current mode // Default display resolution to that of the current mode
@ -1649,7 +1614,7 @@ int InitPlatform(void)
if (CORE.Window.screen.width == 0) CORE.Window.screen.width = CORE.Window.display.width; if (CORE.Window.screen.width == 0) CORE.Window.screen.width = CORE.Window.display.width;
if (CORE.Window.screen.height == 0) CORE.Window.screen.height = CORE.Window.display.height; if (CORE.Window.screen.height == 0) CORE.Window.screen.height = CORE.Window.display.height;
if (requestWindowedFullscreen) glfwSetWindowSize(platform.handle, CORE.Window.screen.width, CORE.Window.screen.height); glfwSetWindowSize(platform.handle, CORE.Window.screen.width, CORE.Window.screen.height);
} }
else else
{ {
@ -1666,11 +1631,11 @@ int InitPlatform(void)
glfwMakeContextCurrent(platform.handle); glfwMakeContextCurrent(platform.handle);
result = glfwGetError(NULL); result = glfwGetError(NULL);
if ((result != GLFW_NO_WINDOW_CONTEXT) && (result != GLFW_PLATFORM_ERROR)) CORE.Window.ready = true; // Checking context activation
// Check context activation if (CORE.Window.ready)
if ((result != GLFW_NO_WINDOW_CONTEXT) && (result != GLFW_PLATFORM_ERROR))
{ {
CORE.Window.ready = true; // Setup additional windows configs and register required window size info
glfwSwapInterval(0); // No V-Sync by default glfwSwapInterval(0); // No V-Sync by default
@ -1691,6 +1656,8 @@ int InitPlatform(void)
{ {
// NOTE: On APPLE platforms system should manage window/input scaling and also framebuffer scaling // NOTE: On APPLE platforms system should manage window/input scaling and also framebuffer scaling
// Framebuffer scaling is activated with: glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_TRUE); // Framebuffer scaling is activated with: glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_TRUE);
// Get current framebuffer size, on high-dpi it could be bigger than screen size
glfwGetFramebufferSize(platform.handle, &fbWidth, &fbHeight); glfwGetFramebufferSize(platform.handle, &fbWidth, &fbHeight);
// Screen scaling matrix is required in case desired screen area is different from display area // Screen scaling matrix is required in case desired screen area is different from display area
@ -1711,37 +1678,34 @@ int InitPlatform(void)
TRACELOG(LOG_INFO, " > Screen size: %i x %i", CORE.Window.screen.width, CORE.Window.screen.height); TRACELOG(LOG_INFO, " > Screen size: %i x %i", CORE.Window.screen.width, CORE.Window.screen.height);
TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height); TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height);
TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y); TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y);
}
else
{
TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphics device");
return -1;
}
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)) MinimizeWindow();
// If graphic device is no properly initialized, we end program
if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return -1; }
else
{
// Try to center window on screen but avoiding window-bar outside of screen // Try to center window on screen but avoiding window-bar outside of screen
int monitorCount = 0;
int monitorIndex = GetCurrentMonitor();
GLFWmonitor **monitors = glfwGetMonitors(&monitorCount);
GLFWmonitor *monitor = monitors[monitorIndex];
int monitorX = 0; int monitorX = 0;
int monitorY = 0; int monitorY = 0;
int monitorWidth = 0; int monitorWidth = 0;
int monitorHeight = 0; int monitorHeight = 0;
glfwGetMonitorWorkarea(monitor, &monitorX, &monitorY, &monitorWidth, &monitorHeight); glfwGetMonitorWorkarea(monitor, &monitorX, &monitorY, &monitorWidth, &monitorHeight);
// Here CORE.Window.render.width/height should be used instead of // TODO: Here CORE.Window.render.width/height should be used instead of
// CORE.Window.screen.width/height to center the window correctly when the high dpi flag is enabled // CORE.Window.screen.width/height to center the window correctly when the high dpi flag is enabled
int posX = monitorX + (monitorWidth - (int)CORE.Window.render.width)/2; CORE.Window.position.x = monitorX + (monitorWidth - (int)CORE.Window.screen.width)/2;
int posY = monitorY + (monitorHeight - (int)CORE.Window.render.height)/2; CORE.Window.position.y = monitorY + (monitorHeight - (int)CORE.Window.screen.height)/2;
if (posX < monitorX) posX = monitorX; //if (CORE.Window.position.x < monitorX) CORE.Window.position.x = monitorX;
if (posY < monitorY) posY = monitorY; //if (CORE.Window.position.y < monitorY) CORE.Window.position.y = monitorY;
SetWindowPosition(posX, posY);
// Update CORE.Window.position here so it is correct from the start SetWindowPosition(CORE.Window.position.x, CORE.Window.position.y);
CORE.Window.position.x = posX;
CORE.Window.position.y = posY; if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)) MinimizeWindow();
}
else
{
TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphics device");
return -1;
} }
// Apply window flags requested previous to initialization // Apply window flags requested previous to initialization
@ -1868,6 +1832,19 @@ static void FramebufferSizeCallback(GLFWwindow *window, int width, int height)
CORE.Window.currentFbo.height = height; CORE.Window.currentFbo.height = height;
CORE.Window.resizedLastFrame = true; CORE.Window.resizedLastFrame = true;
if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE))
{
// On fullscreen mode, strategy is ignoring high-dpi and
// use the all available display size
// Set screen size to render size (physical pixel size)
CORE.Window.screen.width = width;
CORE.Window.screen.height = height;
CORE.Window.screenScale = MatrixScale(1.0f, 1.0f, 1.0f);
SetMouseScale(1.0f, 1.0f);
}
else // Window mode (including borderless window)
{
// Check if render size was actually scaled for high-dpi // Check if render size was actually scaled for high-dpi
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI))
{ {
@ -1875,6 +1852,11 @@ static void FramebufferSizeCallback(GLFWwindow *window, int width, int height)
Vector2 scaleDpi = GetWindowScaleDPI(); Vector2 scaleDpi = GetWindowScaleDPI();
CORE.Window.screen.width = (int)((float)width/scaleDpi.x); CORE.Window.screen.width = (int)((float)width/scaleDpi.x);
CORE.Window.screen.height = (int)((float)height/scaleDpi.y); CORE.Window.screen.height = (int)((float)height/scaleDpi.y);
CORE.Window.screenScale = MatrixScale(scaleDpi.x, scaleDpi.y, 1.0f);
#if !defined(__APPLE__)
// Mouse input scaling for the new screen size
SetMouseScale(1.0f/scaleDpi.x, 1.0f/scaleDpi.y);
#endif
} }
else else
{ {
@ -1882,6 +1864,7 @@ static void FramebufferSizeCallback(GLFWwindow *window, int width, int height)
CORE.Window.screen.width = width; CORE.Window.screen.width = width;
CORE.Window.screen.height = height; CORE.Window.screen.height = height;
} }
}
// WARNING: If using a render texture, it is not scaled to new size // WARNING: If using a render texture, it is not scaled to new size
} }
@ -1890,7 +1873,7 @@ static void FramebufferSizeCallback(GLFWwindow *window, int width, int height)
// WARNING: If FLAG_WINDOW_HIGHDPI is not set, this function is not called // WARNING: If FLAG_WINDOW_HIGHDPI is not set, this function is not called
static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float scaley) static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float scaley)
{ {
TRACELOG(LOG_INFO, "GLFW3: Window content scale changed, scale: [%.2f,%.2f]", scalex, scaley); //TRACELOG(LOG_INFO, "GLFW3: Window content scale changed, scale: [%.2f,%.2f]", scalex, scaley);
float fbWidth = (float)CORE.Window.screen.width*scalex; float fbWidth = (float)CORE.Window.screen.width*scalex;
float fbHeight = (float)CORE.Window.screen.height*scaley; float fbHeight = (float)CORE.Window.screen.height*scaley;
@ -1901,13 +1884,12 @@ static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float s
#if !defined(__APPLE__) #if !defined(__APPLE__)
// Mouse input scaling for the new screen size // Mouse input scaling for the new screen size
SetMouseScale((float)CORE.Window.screen.width/fbWidth, (float)CORE.Window.screen.height/fbHeight); SetMouseScale(1.0f/scalex, 1.0f/scaley);
#endif #endif
CORE.Window.render.width = (int)fbWidth; CORE.Window.render.width = (int)fbWidth;
CORE.Window.render.height = (int)fbHeight; CORE.Window.render.height = (int)fbHeight;
CORE.Window.currentFbo.width = (int)fbWidth; CORE.Window.currentFbo = CORE.Window.render;
CORE.Window.currentFbo.height = (int)fbHeight;
} }
// GLFW3: Window position callback, runs when window position changes // GLFW3: Window position callback, runs when window position changes
@ -1962,7 +1944,7 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths
for (unsigned int i = 0; i < CORE.Window.dropFileCount; i++) for (unsigned int i = 0; i < CORE.Window.dropFileCount; i++)
{ {
CORE.Window.dropFilepaths[i] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); CORE.Window.dropFilepaths[i] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char));
strcpy(CORE.Window.dropFilepaths[i], paths[i]); strncpy(CORE.Window.dropFilepaths[i], paths[i], MAX_FILEPATH_LENGTH - 1);
} }
} }
} }

View File

@ -13,10 +13,7 @@
* - TODO * - TODO
* *
* POSSIBLE IMPROVEMENTS: * POSSIBLE IMPROVEMENTS:
* - TODO * - TBD
*
* ADDITIONAL NOTES:
* - TRACELOG() function is located in raylib [utils] module
* *
* CONFIGURATION: * CONFIGURATION:
* #define RCORE_PLATFORM_RGFW * #define RCORE_PLATFORM_RGFW
@ -29,7 +26,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5), Colleague Riley and contributors * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5), Colleague Riley and contributors
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -290,14 +287,13 @@ bool WindowShouldClose(void)
// Toggle fullscreen mode // Toggle fullscreen mode
void ToggleFullscreen(void) void ToggleFullscreen(void)
{ {
if (!CORE.Window.fullscreen) if (!FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE))
{ {
// Store previous window position (in case we exit fullscreen) // Store previous window position (in case we exit fullscreen)
CORE.Window.previousPosition = CORE.Window.position; CORE.Window.previousPosition = CORE.Window.position;
CORE.Window.previousScreen = CORE.Window.screen; CORE.Window.previousScreen = CORE.Window.screen;
platform.mon = RGFW_window_getMonitor(platform.window); platform.mon = RGFW_window_getMonitor(platform.window);
CORE.Window.fullscreen = true;
FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
RGFW_monitor_scaleToWindow(platform.mon, platform.window); RGFW_monitor_scaleToWindow(platform.mon, platform.window);
@ -305,7 +301,6 @@ void ToggleFullscreen(void)
} }
else else
{ {
CORE.Window.fullscreen = false;
FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
if (platform.mon.mode.area.w) if (platform.mon.mode.area.w)
@ -331,7 +326,9 @@ void ToggleFullscreen(void)
// Toggle borderless windowed mode // Toggle borderless windowed mode
void ToggleBorderlessWindowed(void) void ToggleBorderlessWindowed(void)
{ {
if (CORE.Window.fullscreen) if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) ToggleFullscreen();
if (FLAG_IS_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE))
{ {
CORE.Window.previousPosition = CORE.Window.position; CORE.Window.previousPosition = CORE.Window.position;
CORE.Window.previousScreen = CORE.Window.screen; CORE.Window.previousScreen = CORE.Window.screen;
@ -348,8 +345,6 @@ void ToggleBorderlessWindowed(void)
CORE.Window.position = CORE.Window.previousPosition; CORE.Window.position = CORE.Window.previousPosition;
RGFW_window_resize(platform.window, RGFW_AREA(CORE.Window.previousScreen.width, CORE.Window.previousScreen.height)); RGFW_window_resize(platform.window, RGFW_AREA(CORE.Window.previousScreen.width, CORE.Window.previousScreen.height));
} }
CORE.Window.fullscreen = !CORE.Window.fullscreen;
} }
// Set window state: maximized, if resizable // Set window state: maximized, if resizable
@ -385,7 +380,7 @@ void SetWindowState(unsigned int flags)
} }
if (FLAG_IS_SET(flags, FLAG_FULLSCREEN_MODE)) if (FLAG_IS_SET(flags, FLAG_FULLSCREEN_MODE))
{ {
if (!CORE.Window.fullscreen) ToggleFullscreen(); ToggleFullscreen();
} }
if (FLAG_IS_SET(flags, FLAG_WINDOW_RESIZABLE)) if (FLAG_IS_SET(flags, FLAG_WINDOW_RESIZABLE))
{ {
@ -459,7 +454,7 @@ void ClearWindowState(unsigned int flags)
} }
if (FLAG_IS_SET(flags, FLAG_FULLSCREEN_MODE)) if (FLAG_IS_SET(flags, FLAG_FULLSCREEN_MODE))
{ {
if (CORE.Window.fullscreen) ToggleFullscreen(); ToggleFullscreen();
} }
if (FLAG_IS_SET(flags, FLAG_WINDOW_RESIZABLE)) if (FLAG_IS_SET(flags, FLAG_WINDOW_RESIZABLE))
{ {
@ -510,7 +505,7 @@ void ClearWindowState(unsigned int flags)
} }
if (FLAG_IS_SET(flags, FLAG_BORDERLESS_WINDOWED_MODE)) if (FLAG_IS_SET(flags, FLAG_BORDERLESS_WINDOWED_MODE))
{ {
if (CORE.Window.fullscreen) ToggleBorderlessWindowed(); ToggleBorderlessWindowed();
} }
if (FLAG_IS_SET(flags, FLAG_MSAA_4X_HINT)) if (FLAG_IS_SET(flags, FLAG_MSAA_4X_HINT))
{ {
@ -522,46 +517,15 @@ void ClearWindowState(unsigned int flags)
} }
} }
int RGFW_formatToChannels(int format)
{
switch (format)
{
case PIXELFORMAT_UNCOMPRESSED_GRAYSCALE:
case PIXELFORMAT_UNCOMPRESSED_R16: // 16 bpp (1 channel - half float)
case PIXELFORMAT_UNCOMPRESSED_R32: // 32 bpp (1 channel - float)
return 1;
case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: // 8*2 bpp (2 channels)
case PIXELFORMAT_UNCOMPRESSED_R5G6B5: // 16 bpp
case PIXELFORMAT_UNCOMPRESSED_R8G8B8: // 24 bpp
case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: // 16 bpp (1 bit alpha)
case PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: // 16 bpp (4 bit alpha)
case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: // 32 bpp
return 2;
case PIXELFORMAT_UNCOMPRESSED_R32G32B32: // 32*3 bpp (3 channels - float)
case PIXELFORMAT_UNCOMPRESSED_R16G16B16: // 16*3 bpp (3 channels - half float)
case PIXELFORMAT_COMPRESSED_DXT1_RGB: // 4 bpp (no alpha)
case PIXELFORMAT_COMPRESSED_ETC1_RGB: // 4 bpp
case PIXELFORMAT_COMPRESSED_ETC2_RGB: // 4 bpp
case PIXELFORMAT_COMPRESSED_PVRT_RGB: // 4 bpp
return 3;
case PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: // 32*4 bpp (4 channels - float)
case PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: // 16*4 bpp (4 channels - half float)
case PIXELFORMAT_COMPRESSED_DXT1_RGBA: // 4 bpp (1 bit alpha)
case PIXELFORMAT_COMPRESSED_DXT3_RGBA: // 8 bpp
case PIXELFORMAT_COMPRESSED_DXT5_RGBA: // 8 bpp
case PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA: // 8 bpp
case PIXELFORMAT_COMPRESSED_PVRT_RGBA: // 4 bpp
case PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: // 8 bpp
case PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: // 2 bpp
return 4;
default: return 4;
}
}
// Set icon for window // Set icon for window
void SetWindowIcon(Image image) void SetWindowIcon(Image image)
{ {
RGFW_window_setIcon(platform.window, (u8 *)image.data, RGFW_AREA(image.width, image.height), RGFW_formatToChannels(image.format)); if (image.format != PIXELFORMAT_UNCOMPRESSED_R8G8B8A8)
{
TRACELOG(LOG_WARNING, "RGFW: Window icon image must be in R8G8B8A8 pixel format");
return;
}
RGFW_window_setIcon(platform.window, (u8 *)image.data, RGFW_AREA(image.width, image.height), 4);
} }
// Set icon for window // Set icon for window
@ -578,12 +542,17 @@ void SetWindowIcons(Image *images, int count)
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
if (images[i].format != PIXELFORMAT_UNCOMPRESSED_R8G8B8A8)
{
TRACELOG(LOG_WARNING, "RGFW: Window icon image must be in R8G8B8A8 pixel format");
continue;
}
if ((bigIcon == NULL) || ((images[i].width > bigIcon->width) && (images[i].height > bigIcon->height))) bigIcon = &images[i]; if ((bigIcon == NULL) || ((images[i].width > bigIcon->width) && (images[i].height > bigIcon->height))) bigIcon = &images[i];
if ((smallIcon == NULL) || ((images[i].width < smallIcon->width) && (images[i].height > smallIcon->height))) smallIcon = &images[i]; if ((smallIcon == NULL) || ((images[i].width < smallIcon->width) && (images[i].height > smallIcon->height))) smallIcon = &images[i];
} }
if (smallIcon != NULL) RGFW_window_setIconEx(platform.window, (u8 *)smallIcon->data, RGFW_AREA(smallIcon->width, smallIcon->height), RGFW_formatToChannels(smallIcon->format), RGFW_iconWindow); if (smallIcon != NULL) RGFW_window_setIconEx(platform.window, (u8 *)smallIcon->data, RGFW_AREA(smallIcon->width, smallIcon->height), 4, RGFW_iconWindow);
if (bigIcon != NULL) RGFW_window_setIconEx(platform.window, (u8 *)bigIcon->data, RGFW_AREA(bigIcon->width, bigIcon->height), RGFW_formatToChannels(bigIcon->format), RGFW_iconTaskbar); if (bigIcon != NULL) RGFW_window_setIconEx(platform.window, (u8 *)bigIcon->data, RGFW_AREA(bigIcon->width, bigIcon->height), 4, RGFW_iconTaskbar);
} }
} }
@ -1284,13 +1253,11 @@ int InitPlatform(void)
// Check window creation flags // Check window creation flags
if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE))
{ {
CORE.Window.fullscreen = true;
FLAG_SET(flags, RGFW_windowFullscreen); FLAG_SET(flags, RGFW_windowFullscreen);
} }
if (FLAG_IS_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE)) if (FLAG_IS_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE))
{ {
CORE.Window.fullscreen = true;
FLAG_SET(flags, RGFW_windowedFullscreen); FLAG_SET(flags, RGFW_windowedFullscreen);
} }
@ -1341,10 +1308,6 @@ int InitPlatform(void)
CORE.Window.display.width = CORE.Window.screen.width; CORE.Window.display.width = CORE.Window.screen.width;
CORE.Window.display.height = CORE.Window.screen.height; CORE.Window.display.height = CORE.Window.screen.height;
#endif #endif
// 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 (FLAG_IS_SET(CORE.Window.flags, FLAG_VSYNC_HINT)) RGFW_window_swapInterval(platform.window, 1); if (FLAG_IS_SET(CORE.Window.flags, FLAG_VSYNC_HINT)) RGFW_window_swapInterval(platform.window, 1);
RGFW_window_makeCurrent(platform.window); RGFW_window_makeCurrent(platform.window);

View File

@ -15,9 +15,6 @@
* - Improvement 01 * - Improvement 01
* - Improvement 02 * - Improvement 02
* *
* ADDITIONAL NOTES:
* - TRACELOG() function is located in raylib [utils] module
*
* CONFIGURATION: * CONFIGURATION:
* #define RCORE_PLATFORM_CUSTOM_FLAG * #define RCORE_PLATFORM_CUSTOM_FLAG
* Custom flag for rcore on target platform -not used- * Custom flag for rcore on target platform -not used-
@ -29,7 +26,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) and contributors * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) and contributors
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -472,13 +469,11 @@ void ToggleFullscreen(void)
{ {
SDL_SetWindowFullscreen(platform.window, 0); SDL_SetWindowFullscreen(platform.window, 0);
FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
CORE.Window.fullscreen = false;
} }
else else
{ {
SDL_SetWindowFullscreen(platform.window, SDL_WINDOW_FULLSCREEN); SDL_SetWindowFullscreen(platform.window, SDL_WINDOW_FULLSCREEN);
FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
CORE.Window.fullscreen = true;
} }
} }
else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor"); else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor");
@ -554,7 +549,7 @@ void SetWindowState(unsigned int flags)
#endif #endif
{ {
SDL_SetWindowFullscreen(platform.window, SDL_WINDOW_FULLSCREEN); SDL_SetWindowFullscreen(platform.window, SDL_WINDOW_FULLSCREEN);
CORE.Window.fullscreen = true; FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
} }
else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor"); else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor");
} }
@ -644,7 +639,6 @@ void ClearWindowState(unsigned int flags)
if (FLAG_IS_SET(flags, FLAG_FULLSCREEN_MODE)) if (FLAG_IS_SET(flags, FLAG_FULLSCREEN_MODE))
{ {
SDL_SetWindowFullscreen(platform.window, 0); SDL_SetWindowFullscreen(platform.window, 0);
CORE.Window.fullscreen = false;
} }
if (FLAG_IS_SET(flags, FLAG_WINDOW_RESIZABLE)) if (FLAG_IS_SET(flags, FLAG_WINDOW_RESIZABLE))
{ {
@ -1431,9 +1425,9 @@ void PollInputEvents(void)
// Event memory is now managed by SDL, so you should not free the data in SDL_EVENT_DROP_FILE, // Event memory is now managed by SDL, so you should not free the data in SDL_EVENT_DROP_FILE,
// and if you want to hold onto the text in SDL_EVENT_TEXT_EDITING and SDL_EVENT_TEXT_INPUT events, // and if you want to hold onto the text in SDL_EVENT_TEXT_EDITING and SDL_EVENT_TEXT_INPUT events,
// you should make a copy of it. SDL_TEXTINPUTEVENT_TEXT_SIZE is no longer necessary and has been removed // you should make a copy of it. SDL_TEXTINPUTEVENT_TEXT_SIZE is no longer necessary and has been removed
strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.data); strncpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.data, MAX_FILEPATH_LENGTH - 1);
#else #else
strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file); strncpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file, MAX_FILEPATH_LENGTH - 1);
SDL_free(event.drop.file); SDL_free(event.drop.file);
#endif #endif
@ -1444,9 +1438,9 @@ void PollInputEvents(void)
CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char));
#if defined(USING_VERSION_SDL3) #if defined(USING_VERSION_SDL3)
strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.data); strncpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.data, MAX_FILEPATH_LENGTH - 1);
#else #else
strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file); strncpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file, MAX_FILEPATH_LENGTH - 1);
SDL_free(event.drop.file); SDL_free(event.drop.file);
#endif #endif
@ -1937,11 +1931,7 @@ int InitPlatform(void)
FLAG_SET(flags, SDL_WINDOW_MOUSE_CAPTURE); // Window has mouse captured FLAG_SET(flags, SDL_WINDOW_MOUSE_CAPTURE); // Window has mouse captured
// Check window creation flags // Check window creation flags
if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) FLAG_SET(flags, SDL_WINDOW_FULLSCREEN);
{
CORE.Window.fullscreen = true;
FLAG_SET(flags, SDL_WINDOW_FULLSCREEN);
}
//if (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)) FLAG_SET(flags, SDL_WINDOW_HIDDEN); //if (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)) FLAG_SET(flags, SDL_WINDOW_HIDDEN);
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNDECORATED)) FLAG_SET(flags, SDL_WINDOW_BORDERLESS); if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNDECORATED)) FLAG_SET(flags, SDL_WINDOW_BORDERLESS);

View File

@ -13,9 +13,6 @@
* - Improvement 01 * - Improvement 01
* - Improvement 02 * - Improvement 02
* *
* ADDITIONAL NOTES:
* - TRACELOG() function is located in raylib [utils] module
*
* CONFIGURATION: * CONFIGURATION:
* #define RCORE_PLATFORM_CUSTOM_FLAG * #define RCORE_PLATFORM_CUSTOM_FLAG
* Custom flag for rcore on target platform -not used- * Custom flag for rcore on target platform -not used-
@ -26,7 +23,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) and contributors * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) and contributors
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -1877,14 +1874,24 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara
} break; } break;
case WM_DPICHANGED: case WM_DPICHANGED:
{ {
// Get current dpi scale factor
float scalex = HIWORD(wParam)/96.0f;
float scaley = LOWORD(wParam)/96.0f;
RECT *suggestedRect = (RECT *)lparam; RECT *suggestedRect = (RECT *)lparam;
// Never set the window size to anything other than the suggested rect here // 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 // Doing so can cause a window to stutter between monitors when transitioning between them
int result = (int)SetWindowPos(hwnd, NULL, suggestedRect->left, suggestedRect->top, int result = (int)SetWindowPos(hwnd, NULL,
suggestedRect->right - suggestedRect->left, suggestedRect->bottom - suggestedRect->top, SWP_NOZORDER | SWP_NOACTIVATE); 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()); if (result == 0) TRACELOG(LOG_ERROR, "Failed to set window position [ERROR: %lu]", GetLastError());
// TODO: Update screen data, render size, screen scaling, viewport...
} break; } break;
case WM_SETCURSOR: case WM_SETCURSOR:
{ {
@ -2039,8 +2046,7 @@ static void HandleWindowResize(HWND hwnd, int *width, int *height)
// TODO: Update framebuffer on resize // TODO: Update framebuffer on resize
CORE.Window.currentFbo.width = (int)clientSize.cx; CORE.Window.currentFbo.width = (int)clientSize.cx;
CORE.Window.currentFbo.height = (int)clientSize.cy; CORE.Window.currentFbo.height = (int)clientSize.cy;
//glViewport(0, 0, clientSize.cx, clientSize.cy); //SetupViewport(0, 0, clientSize.cx, clientSize.cy);
//SetupFramebuffer(0, 0);
SetupViewport(clientSize.cx, clientSize.cy); SetupViewport(clientSize.cx, clientSize.cy);
CORE.Window.resizedLastFrame = true; CORE.Window.resizedLastFrame = true;

View File

@ -13,9 +13,6 @@
* - Improvement 01 * - Improvement 01
* - Improvement 02 * - Improvement 02
* *
* ADDITIONAL NOTES:
* - TRACELOG() function is located in raylib [utils] module
*
* CONFIGURATION: * CONFIGURATION:
* #define SUPPORT_SSH_KEYBOARD_RPI (Raspberry Pi only) * #define SUPPORT_SSH_KEYBOARD_RPI (Raspberry Pi only)
* Reconfigure standard input to receive key inputs, works with SSH connection * Reconfigure standard input to receive key inputs, works with SSH connection
@ -29,7 +26,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) and contributors * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) and contributors
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -89,6 +86,10 @@
#define EGL_OPENGL_ES3_BIT 0x40 #define EGL_OPENGL_ES3_BIT 0x40
#endif #endif
#ifndef EGL_PLATFORM_GBM_KHR
#define EGL_PLATFORM_GBM_KHR 0x31D7
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // Defines and Macros
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -135,8 +136,12 @@ typedef struct {
char currentButtonStateEvdev[MAX_MOUSE_BUTTONS]; // Holds the new mouse state for the next polling event to grab char currentButtonStateEvdev[MAX_MOUSE_BUTTONS]; // Holds the new mouse state for the next polling event to grab
bool cursorRelative; // Relative cursor mode bool cursorRelative; // Relative cursor mode
int mouseFd; // File descriptor for the evdev mouse/touch/gestures int mouseFd; // File descriptor for the evdev mouse/touch/gestures
bool mouseIsTouch; // Check if the current mouse device is actually a touchscreen
Rectangle absRange; // Range of values for absolute pointing devices (touchscreens) Rectangle absRange; // Range of values for absolute pointing devices (touchscreens)
int touchSlot; // Hold the touch slot number of the currently being sent multitouch block int touchSlot; // Hold the touch slot number of the currently being sent multitouch block
bool touchActive[MAX_TOUCH_POINTS]; // Track which touch points are currently active
Vector2 touchPosition[MAX_TOUCH_POINTS]; // Track touch positions for each slot
int touchId[MAX_TOUCH_POINTS]; // Track touch IDs for each slot
// Gamepad data // Gamepad data
int gamepadStreamFd[MAX_GAMEPADS]; // Gamepad device file descriptor int gamepadStreamFd[MAX_GAMEPADS]; // Gamepad device file descriptor
@ -265,6 +270,8 @@ static int FindMatchingConnectorMode(const drmModeConnector *connector, const dr
static int FindExactConnectorMode(const drmModeConnector *connector, uint width, uint height, uint fps, bool allowInterlaced); // Search exactly matching DRM connector mode in connector's list static int FindExactConnectorMode(const drmModeConnector *connector, uint width, uint height, uint fps, bool allowInterlaced); // Search exactly matching DRM connector mode in connector's list
static int FindNearestConnectorMode(const drmModeConnector *connector, uint width, uint height, uint fps, bool allowInterlaced); // Search the nearest matching DRM connector mode in connector's list static int FindNearestConnectorMode(const drmModeConnector *connector, uint width, uint height, uint fps, bool allowInterlaced); // Search the nearest matching DRM connector mode in connector's list
static void SetupFramebuffer(int width, int height); // Setup main framebuffer (required by InitPlatform())
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module Functions Declaration // Module Functions Declaration
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -1113,9 +1120,6 @@ void PollInputEvents(void)
// Register previous touch states // Register previous touch states
for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.previousTouchState[i] = CORE.Input.Touch.currentTouchState[i]; for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.previousTouchState[i] = CORE.Input.Touch.currentTouchState[i];
// 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 // Map touch position to mouse position for convenience
// NOTE: For DRM touchscreen devices, this mapping is disabled to avoid false touch detection // NOTE: For DRM touchscreen devices, this mapping is disabled to avoid false touch detection
// CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; // CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition;
@ -1147,7 +1151,6 @@ int InitPlatform(void)
// Initialize graphic device: display/window and graphic context // Initialize graphic device: display/window and graphic context
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
CORE.Window.fullscreen = true;
FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
#if defined(DEFAULT_GRAPHIC_DEVICE_DRM) #if defined(DEFAULT_GRAPHIC_DEVICE_DRM)
@ -1412,9 +1415,27 @@ int InitPlatform(void)
}; };
EGLint numConfigs = 0; EGLint numConfigs = 0;
const char *eglClientExtensions = NULL;
// Get an EGL device connection // Get an EGL device connection
platform.device = eglGetDisplay((EGLNativeDisplayType)platform.gbmDevice); // NOTE: eglGetPlatformDisplay() is preferred over eglGetDisplay() legacy call
platform.device = EGL_NO_DISPLAY;
#if defined(EGL_VERSION_1_5)
platform.device = eglGetPlatformDisplay(EGL_PLATFORM_GBM_KHR, platform.gbmDevice, NULL);
#else
// Check if extension is available for eglGetPlatformDisplayEXT()
// NOTE: Better compatibility with some drivers (e.g. Mali Midgard)
eglClientExtensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
if ((eglClientExtensions != NULL) && (strstr(eglClientExtensions, "EGL_EXT_platform_base") != NULL))
{
PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT");
if (eglGetPlatformDisplayEXT != NULL) platform.device = eglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_KHR, platform.gbmDevice, NULL);
}
// In case extension not found or display could not be retrieved, try useing legacy version
if (platform.device == EGL_NO_DISPLAY) platform.device = eglGetDisplay((EGLNativeDisplayType)platform.gbmDevice);
#endif
if (platform.device == EGL_NO_DISPLAY) if (platform.device == EGL_NO_DISPLAY)
{ {
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device"); TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
@ -1494,8 +1515,21 @@ int InitPlatform(void)
} }
// Create an EGL window surface // Create an EGL window surface
platform.surface = EGL_NO_SURFACE;
if ((eglClientExtensions != NULL) && (strstr(eglClientExtensions, "EGL_EXT_platform_base") != NULL))
{
PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC eglCreatePlatformWindowSurfaceEXT = (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT");
if (eglCreatePlatformWindowSurfaceEXT != NULL) platform.surface = eglCreatePlatformWindowSurfaceEXT(platform.device, platform.config, platform.gbmSurface, NULL);
}
if (platform.surface == EGL_NO_SURFACE)
{
platform.surface = eglCreateWindowSurface(platform.device, platform.config, (EGLNativeWindowType)platform.gbmSurface, NULL); platform.surface = eglCreateWindowSurface(platform.device, platform.config, (EGLNativeWindowType)platform.gbmSurface, NULL);
if (EGL_NO_SURFACE == platform.surface) }
if (platform.surface == EGL_NO_SURFACE)
{ {
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL window surface: 0x%04x", eglGetError()); TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL window surface: 0x%04x", eglGetError());
return -1; return -1;
@ -1564,7 +1598,11 @@ int InitPlatform(void)
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)) MinimizeWindow(); if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)) MinimizeWindow();
// If graphic device is no properly initialized, we end program // If graphic device is no properly initialized, we end program
if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return -1; } if (!CORE.Window.ready)
{
TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device");
return -1;
}
else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor())/2 - CORE.Window.screen.width/2, GetMonitorHeight(GetCurrentMonitor())/2 - CORE.Window.screen.height/2); else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor())/2 - CORE.Window.screen.width/2, GetMonitorHeight(GetCurrentMonitor())/2 - CORE.Window.screen.height/2);
// Set some default window flags // Set some default window flags
@ -1882,8 +1920,15 @@ static void InitEvdevInput(void)
{ {
CORE.Input.Touch.position[i].x = -1; CORE.Input.Touch.position[i].x = -1;
CORE.Input.Touch.position[i].y = -1; CORE.Input.Touch.position[i].y = -1;
platform.touchActive[i] = false;
platform.touchPosition[i].x = -1;
platform.touchPosition[i].y = -1;
platform.touchId[i] = -1;
} }
// Initialize touch slot
platform.touchSlot = 0;
// Reset keyboard key state // Reset keyboard key state
for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) for (int i = 0; i < MAX_KEYBOARD_KEYS; i++)
{ {
@ -2046,9 +2091,32 @@ static void ConfigureEvdevDevice(char *device)
const char *deviceKindStr = "unknown"; const char *deviceKindStr = "unknown";
if (isMouse || isTouch) if (isMouse || isTouch)
{ {
deviceKindStr = "mouse"; bool prioritize = false;
if (platform.mouseFd != -1) close(platform.mouseFd);
// Priority logic: touchscreens override Mice
// 1. No device set yet? Take it
if (platform.mouseFd == -1) prioritize = true;
// 2. Current is mouse, new is touch? Upgrade to touch
else if (isTouch && !platform.mouseIsTouch) prioritize = true;
// 3. Current is touch, new is touch? Use the new one (last one found wins, standard behavior)
else if (isTouch && platform.mouseIsTouch) prioritize = true;
// 4. Current is mouse, new is mouse? Use the new one
else if (!isTouch && !platform.mouseIsTouch) prioritize = true;
// 5. Current is touch, new is mouse? Ignore the mouse, keep the touchscreen
else prioritize = false;
if (prioritize)
{
deviceKindStr = isTouch? "touchscreen" : "mouse";
if (platform.mouseFd != -1)
{
TRACELOG(LOG_INFO, "INPUT: Overwriting previous input device with new %s", deviceKindStr);
close(platform.mouseFd);
}
platform.mouseFd = fd; platform.mouseFd = fd;
platform.mouseIsTouch = isTouch;
if (absAxisCount > 0) if (absAxisCount > 0)
{ {
@ -2058,6 +2126,15 @@ static void ConfigureEvdevDevice(char *device)
platform.absRange.y = absinfo[ABS_Y].info.minimum; platform.absRange.y = absinfo[ABS_Y].info.minimum;
platform.absRange.height = absinfo[ABS_Y].info.maximum - absinfo[ABS_Y].info.minimum; platform.absRange.height = absinfo[ABS_Y].info.maximum - absinfo[ABS_Y].info.minimum;
} }
TRACELOG(LOG_INFO, "INPUT: Initialized input device %s as %s", device, deviceKindStr);
}
else
{
TRACELOG(LOG_INFO, "INPUT: Ignoring device %s (keeping higher priority %s device)", device, platform.mouseIsTouch ? "touchscreen" : "mouse");
close(fd);
return;
}
} }
else if (isGamepad && !isMouse && !isKeyboard && (platform.gamepadCount < MAX_GAMEPADS)) else if (isGamepad && !isMouse && !isKeyboard && (platform.gamepadCount < MAX_GAMEPADS))
{ {
@ -2127,18 +2204,15 @@ static void PollKeyboardEvents(void)
// If the event was a key, we know a working keyboard is connected, so disable the SSH keyboard // If the event was a key, we know a working keyboard is connected, so disable the SSH keyboard
platform.eventKeyboardMode = true; platform.eventKeyboardMode = true;
#endif #endif
// Keyboard keys appear for codes 1 to 255, ignore everthing else // Keyboard keys appear for codes 1 to 255, ignore everthing else
if ((event.code >= 1) && (event.code <= 255)) if ((event.code >= 1) && (event.code <= 255))
{ {
// Lookup the scancode in the keymap to get a keycode // Lookup the scancode in the keymap to get a keycode
keycode = linuxToRaylibMap[event.code]; keycode = linuxToRaylibMap[event.code];
// Make sure we got a valid keycode // Make sure we got a valid keycode
if ((keycode > 0) && (keycode < MAX_KEYBOARD_KEYS)) if ((keycode > 0) && (keycode < MAX_KEYBOARD_KEYS))
{ {
// WARNING: https://www.kernel.org/doc/Documentation/input/input.txt // WARNING: https://www.kernel.org/doc/Documentation/input/input.txt
// Event interface: 'value' is the value the event carries. Either a relative change for EV_REL, // Event interface: 'value' is the value the event carries. Either a relative change for EV_REL,
// absolute new value for EV_ABS (joysticks ...), or 0 for EV_KEY for release, 1 for keypress and 2 for autorepeat // absolute new value for EV_ABS (joysticks ...), or 0 for EV_KEY for release, 1 for keypress and 2 for autorepeat
@ -2187,16 +2261,15 @@ static void PollGamepadEvents(void)
{ {
if (event.code < KEYMAP_SIZE) if (event.code < KEYMAP_SIZE)
{ {
short keycodeRaylib = linuxToRaylibMap[event.code]; short keycode = linuxToRaylibMap[event.code]; // raylib keycode
TRACELOG(LOG_DEBUG, "INPUT: Gamepad %2i: KEY_%s Keycode(linux): %4i Keycode(raylib): %4i", i, (event.value == 0)? "UP" : "DOWN", event.code, keycodeRaylib); TRACELOG(LOG_DEBUG, "INPUT: Gamepad %2i: KEY_%s Keycode(linux): %4i Keycode(raylib): %4i", i, (event.value == 0)? "UP" : "DOWN", event.code, keycode);
if ((keycodeRaylib != 0) && (keycodeRaylib < MAX_GAMEPAD_BUTTONS)) if ((keycode != 0) && (keycode < MAX_GAMEPAD_BUTTONS))
{ {
// 1 - button pressed, 0 - button released // 1 - button pressed, 0 - button released
CORE.Input.Gamepad.currentButtonState[i][keycodeRaylib] = event.value; CORE.Input.Gamepad.currentButtonState[i][keycode] = event.value;
CORE.Input.Gamepad.lastButtonPressed = (event.value == 1)? keycode : GAMEPAD_BUTTON_UNKNOWN;
CORE.Input.Gamepad.lastButtonPressed = (event.value == 1)? keycodeRaylib : GAMEPAD_BUTTON_UNKNOWN;
} }
} }
} }
@ -2230,6 +2303,7 @@ static void PollMouseEvents(void)
struct input_event event = { 0 }; struct input_event event = { 0 };
int touchAction = -1; // 0-TOUCH_ACTION_UP, 1-TOUCH_ACTION_DOWN, 2-TOUCH_ACTION_MOVE int touchAction = -1; // 0-TOUCH_ACTION_UP, 1-TOUCH_ACTION_DOWN, 2-TOUCH_ACTION_MOVE
static bool isMultitouch = false; // Detect if device supports MT events
// Try to read data from the mouse/touch/gesture and only continue if successful // Try to read data from the mouse/touch/gesture and only continue if successful
while (read(fd, &event, sizeof(event)) == (int)sizeof(event)) while (read(fd, &event, sizeof(event)) == (int)sizeof(event))
@ -2275,39 +2349,102 @@ static void PollMouseEvents(void)
if (event.code == ABS_X) if (event.code == ABS_X)
{ {
CORE.Input.Mouse.currentPosition.x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange CORE.Input.Mouse.currentPosition.x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange
CORE.Input.Touch.position[0].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange
touchAction = 2; // TOUCH_ACTION_MOVE // Update single touch position only if it's active and no MT events are being used
if (platform.touchActive[0] && !isMultitouch)
{
platform.touchPosition[0].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width;
if (touchAction == -1) touchAction = 2; // TOUCH_ACTION_MOVE
}
} }
if (event.code == ABS_Y) if (event.code == ABS_Y)
{ {
CORE.Input.Mouse.currentPosition.y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange CORE.Input.Mouse.currentPosition.y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange
CORE.Input.Touch.position[0].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange
touchAction = 2; // TOUCH_ACTION_MOVE // Update single touch position only if it's active and no MT events are being used
if (platform.touchActive[0] && !isMultitouch)
{
platform.touchPosition[0].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height;
if (touchAction == -1) touchAction = 2; // TOUCH_ACTION_MOVE
}
} }
// Multitouch movement // Multitouch movement
if (event.code == ABS_MT_SLOT) platform.touchSlot = event.value; // Remember the slot number for the folowing events if (event.code == ABS_MT_SLOT)
{
platform.touchSlot = event.value;
isMultitouch = true;
}
if (event.code == ABS_MT_POSITION_X) if (event.code == ABS_MT_POSITION_X)
{ {
if (platform.touchSlot < MAX_TOUCH_POINTS) CORE.Input.Touch.position[platform.touchSlot].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange isMultitouch = true;
if (platform.touchSlot < MAX_TOUCH_POINTS)
{
platform.touchPosition[platform.touchSlot].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width;
// If this slot is active, it's a move. If not, we are just updating the buffer for when it becomes active.
// Only set to MOVE if we haven't already detected a DOWN or UP event this frame
if (platform.touchActive[platform.touchSlot] && touchAction == -1) touchAction = 2; // TOUCH_ACTION_MOVE
}
} }
if (event.code == ABS_MT_POSITION_Y) if (event.code == ABS_MT_POSITION_Y)
{ {
if (platform.touchSlot < MAX_TOUCH_POINTS) CORE.Input.Touch.position[platform.touchSlot].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange if (platform.touchSlot < MAX_TOUCH_POINTS)
{
platform.touchPosition[platform.touchSlot].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height;
// If this slot is active, it's a move. If not, we are just updating the buffer for when it becomes active.
// Only set to MOVE if we haven't already detected a DOWN or UP event this frame
if (platform.touchActive[platform.touchSlot] && touchAction == -1) touchAction = 2; // TOUCH_ACTION_MOVE
}
} }
if (event.code == ABS_MT_TRACKING_ID) if (event.code == ABS_MT_TRACKING_ID)
{ {
if ((event.value < 0) && (platform.touchSlot < MAX_TOUCH_POINTS)) if (platform.touchSlot < MAX_TOUCH_POINTS)
{
if (event.value >= 0)
{
platform.touchActive[platform.touchSlot] = true;
platform.touchId[platform.touchSlot] = event.value; // Use Tracking ID for unique IDs
touchAction = 1; // TOUCH_ACTION_DOWN
}
else
{ {
// Touch has ended for this point // Touch has ended for this point
CORE.Input.Touch.position[platform.touchSlot].x = -1; platform.touchActive[platform.touchSlot] = false;
CORE.Input.Touch.position[platform.touchSlot].y = -1; platform.touchPosition[platform.touchSlot].x = -1;
platform.touchPosition[platform.touchSlot].y = -1;
platform.touchId[platform.touchSlot] = -1;
// Force UP action if we haven't already set a DOWN action
// (DOWN takes priority over UP if both happen in one frame, though rare)
if (touchAction != 1) touchAction = 0; // TOUCH_ACTION_UP
}
}
}
// Handle ABS_MT_PRESSURE (0x3a) if available, as some devices use it for lift-off
#ifndef ABS_MT_PRESSURE
#define ABS_MT_PRESSURE 0x3a
#endif
if (event.code == ABS_MT_PRESSURE)
{
if (platform.touchSlot < MAX_TOUCH_POINTS)
{
if (event.value <= 0) // Pressure 0 means lift
{
platform.touchActive[platform.touchSlot] = false;
platform.touchPosition[platform.touchSlot].x = -1;
platform.touchPosition[platform.touchSlot].y = -1;
platform.touchId[platform.touchSlot] = -1;
if (touchAction != 1) touchAction = 0; // TOUCH_ACTION_UP
}
} }
} }
@ -2319,7 +2456,7 @@ static void PollMouseEvents(void)
if (!event.value && previousMouseLeftButtonState) if (!event.value && previousMouseLeftButtonState)
{ {
platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 0; platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 0;
touchAction = 0; // TOUCH_ACTION_UP if (touchAction != 1) touchAction = 0; // TOUCH_ACTION_UP
} }
if (event.value && !previousMouseLeftButtonState) if (event.value && !previousMouseLeftButtonState)
@ -2328,7 +2465,6 @@ static void PollMouseEvents(void)
touchAction = 1; // TOUCH_ACTION_DOWN touchAction = 1; // TOUCH_ACTION_DOWN
} }
} }
} }
// Button parsing // Button parsing
@ -2339,8 +2475,43 @@ static void PollMouseEvents(void)
{ {
platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = event.value; platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = event.value;
if (event.value > 0) touchAction = 1; // TOUCH_ACTION_DOWN if (event.value > 0)
else touchAction = 0; // TOUCH_ACTION_UP {
bool activateSlot0 = false;
if (event.code == BTN_LEFT) activateSlot0 = true; // Mouse click always activates
else if (event.code == BTN_TOUCH)
{
bool anyActive = false;
for (int i = 0; i < MAX_TOUCH_POINTS; i++)
{
if (platform.touchActive[i]) { anyActive = true; break; }
}
if (!anyActive) activateSlot0 = true;
}
if (activateSlot0)
{
platform.touchActive[0] = true;
platform.touchId[0] = 0;
}
touchAction = 1; // TOUCH_ACTION_DOWN
}
else
{
// Only clear touch 0 for actual mouse clicks (BTN_LEFT)
if (event.code == BTN_LEFT)
{
platform.touchActive[0] = false;
platform.touchPosition[0].x = -1;
platform.touchPosition[0].y = -1;
}
else if (event.code == BTN_TOUCH) platform.touchSlot = 0; // Reset slot index to 0
touchAction = 0; // TOUCH_ACTION_UP
}
} }
if (event.code == BTN_RIGHT) platform.currentButtonStateEvdev[MOUSE_BUTTON_RIGHT] = event.value; if (event.code == BTN_RIGHT) platform.currentButtonStateEvdev[MOUSE_BUTTON_RIGHT] = event.value;
@ -2355,24 +2526,40 @@ static void PollMouseEvents(void)
if (!CORE.Input.Mouse.cursorLocked) if (!CORE.Input.Mouse.cursorLocked)
{ {
if (CORE.Input.Mouse.currentPosition.x < 0) CORE.Input.Mouse.currentPosition.x = 0; if (CORE.Input.Mouse.currentPosition.x < 0) CORE.Input.Mouse.currentPosition.x = 0;
if (CORE.Input.Mouse.currentPosition.x > CORE.Window.screen.width/CORE.Input.Mouse.scale.x) CORE.Input.Mouse.currentPosition.x = CORE.Window.screen.width/CORE.Input.Mouse.scale.x; if (CORE.Input.Mouse.currentPosition.x > CORE.Window.screen.width/CORE.Input.Mouse.scale.x)
CORE.Input.Mouse.currentPosition.x = CORE.Window.screen.width/CORE.Input.Mouse.scale.x;
if (CORE.Input.Mouse.currentPosition.y < 0) CORE.Input.Mouse.currentPosition.y = 0; if (CORE.Input.Mouse.currentPosition.y < 0) CORE.Input.Mouse.currentPosition.y = 0;
if (CORE.Input.Mouse.currentPosition.y > CORE.Window.screen.height/CORE.Input.Mouse.scale.y) CORE.Input.Mouse.currentPosition.y = CORE.Window.screen.height/CORE.Input.Mouse.scale.y; if (CORE.Input.Mouse.currentPosition.y > CORE.Window.screen.height/CORE.Input.Mouse.scale.y)
CORE.Input.Mouse.currentPosition.y = CORE.Window.screen.height/CORE.Input.Mouse.scale.y;
} }
// Update touch point count // Repack active touches into CORE.Input.Touch
CORE.Input.Touch.pointCount = 0; int k = 0;
for (int i = 0; i < MAX_TOUCH_POINTS; i++) for (int i = 0; i < MAX_TOUCH_POINTS; i++)
{ {
if (CORE.Input.Touch.position[i].x >= 0) CORE.Input.Touch.pointCount++; if (platform.touchActive[i])
{
CORE.Input.Touch.position[k] = platform.touchPosition[i];
CORE.Input.Touch.pointId[k] = platform.touchId[i];
k++;
}
}
CORE.Input.Touch.pointCount = k;
// Clear remaining slots
for (int i = k; i < MAX_TOUCH_POINTS; i++)
{
CORE.Input.Touch.position[i].x = -1;
CORE.Input.Touch.position[i].y = -1;
CORE.Input.Touch.pointId[i] = -1;
} }
#if defined(SUPPORT_GESTURES_SYSTEM) #if defined(SUPPORT_GESTURES_SYSTEM)
if (touchAction > -1) if (touchAction > -1)
{ {
GestureEvent gestureEvent = { 0 }; GestureEvent gestureEvent = { 0 };
gestureEvent.touchAction = touchAction; gestureEvent.touchAction = touchAction;
gestureEvent.pointCount = CORE.Input.Touch.pointCount; gestureEvent.pointCount = CORE.Input.Touch.pointCount;
@ -2383,7 +2570,6 @@ static void PollMouseEvents(void)
} }
ProcessGestureEvent(gestureEvent); ProcessGestureEvent(gestureEvent);
touchAction = -1; touchAction = -1;
} }
#endif #endif
@ -2479,4 +2665,82 @@ static int FindNearestConnectorMode(const drmModeConnector *connector, uint widt
return nearestIndex; return nearestIndex;
} }
// Compute framebuffer size relative to screen size and display size
// NOTE: Global variables CORE.Window.render.width/CORE.Window.render.height and CORE.Window.renderOffset.x/CORE.Window.renderOffset.y can be modified
static void SetupFramebuffer(int width, int height)
{
// Calculate CORE.Window.render.width and CORE.Window.render.height, we have the display size (input params) and the desired screen size (global var)
if ((CORE.Window.screen.width > CORE.Window.display.width) || (CORE.Window.screen.height > CORE.Window.display.height))
{
TRACELOG(LOG_WARNING, "DISPLAY: Downscaling required: Screen size (%ix%i) is bigger than display size (%ix%i)", CORE.Window.screen.width, CORE.Window.screen.height, CORE.Window.display.width, CORE.Window.display.height);
// Downscaling to fit display with border-bars
float widthRatio = (float)CORE.Window.display.width/(float)CORE.Window.screen.width;
float heightRatio = (float)CORE.Window.display.height/(float)CORE.Window.screen.height;
if (widthRatio <= heightRatio)
{
CORE.Window.render.width = CORE.Window.display.width;
CORE.Window.render.height = (int)round((float)CORE.Window.screen.height*widthRatio);
CORE.Window.renderOffset.x = 0;
CORE.Window.renderOffset.y = (CORE.Window.display.height - CORE.Window.render.height);
}
else
{
CORE.Window.render.width = (int)round((float)CORE.Window.screen.width*heightRatio);
CORE.Window.render.height = CORE.Window.display.height;
CORE.Window.renderOffset.x = (CORE.Window.display.width - CORE.Window.render.width);
CORE.Window.renderOffset.y = 0;
}
// Screen scaling required
float scaleRatio = (float)CORE.Window.render.width/(float)CORE.Window.screen.width;
CORE.Window.screenScale = MatrixScale(scaleRatio, scaleRatio, 1.0f);
// NOTE: We render to full display resolution!
// We just need to calculate above parameters for downscale matrix and offsets
CORE.Window.render.width = CORE.Window.display.width;
CORE.Window.render.height = CORE.Window.display.height;
TRACELOG(LOG_WARNING, "DISPLAY: Downscale matrix generated, content will be rendered at (%ix%i)", CORE.Window.render.width, CORE.Window.render.height);
}
else if ((CORE.Window.screen.width < CORE.Window.display.width) || (CORE.Window.screen.height < CORE.Window.display.height))
{
// Required screen size is smaller than display size
TRACELOG(LOG_INFO, "DISPLAY: Upscaling required: Screen size (%ix%i) smaller than display size (%ix%i)", CORE.Window.screen.width, CORE.Window.screen.height, CORE.Window.display.width, CORE.Window.display.height);
if ((CORE.Window.screen.width == 0) || (CORE.Window.screen.height == 0))
{
CORE.Window.screen.width = CORE.Window.display.width;
CORE.Window.screen.height = CORE.Window.display.height;
}
// Upscaling to fit display with border-bars
float displayRatio = (float)CORE.Window.display.width/(float)CORE.Window.display.height;
float screenRatio = (float)CORE.Window.screen.width/(float)CORE.Window.screen.height;
if (displayRatio <= screenRatio)
{
CORE.Window.render.width = CORE.Window.screen.width;
CORE.Window.render.height = (int)round((float)CORE.Window.screen.width/displayRatio);
CORE.Window.renderOffset.x = 0;
CORE.Window.renderOffset.y = (CORE.Window.render.height - CORE.Window.screen.height);
}
else
{
CORE.Window.render.width = (int)round((float)CORE.Window.screen.height*displayRatio);
CORE.Window.render.height = CORE.Window.screen.height;
CORE.Window.renderOffset.x = (CORE.Window.render.width - CORE.Window.screen.width);
CORE.Window.renderOffset.y = 0;
}
}
else
{
CORE.Window.render.width = CORE.Window.screen.width;
CORE.Window.render.height = CORE.Window.screen.height;
CORE.Window.renderOffset.x = 0;
CORE.Window.renderOffset.y = 0;
}
}
// EOF // EOF

View File

@ -13,9 +13,6 @@
* - Improvement 01 * - Improvement 01
* - Improvement 02 * - Improvement 02
* *
* ADDITIONAL NOTES:
* - TRACELOG() function is located in raylib [utils] module
*
* CONFIGURATION: * CONFIGURATION:
* #define RCORE_PLATFORM_CUSTOM_FLAG * #define RCORE_PLATFORM_CUSTOM_FLAG
* Custom flag for rcore on target platform -not used- * Custom flag for rcore on target platform -not used-
@ -27,7 +24,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2025 Ramon Santamaria (@raysan5) and contributors * Copyright (c) 2025-2026 Ramon Santamaria (@raysan5) and contributors
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.

View File

@ -27,7 +27,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) and contributors * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) and contributors
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -454,7 +454,6 @@ int InitPlatform(void)
// raylib uses OpenGL so, platform should create that kind of connection // raylib uses OpenGL so, platform should create that kind of connection
// Below example illustrates that process using EGL library // Below example illustrates that process using EGL library
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
CORE.Window.fullscreen = true;
FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
if (FLAG_IS_SET(CORE.Window.flags, FLAG_MSAA_4X_HINT)) if (FLAG_IS_SET(CORE.Window.flags, FLAG_MSAA_4X_HINT))

View File

@ -12,9 +12,6 @@
* POSSIBLE IMPROVEMENTS: * POSSIBLE IMPROVEMENTS:
* - Replace glfw3 dependency by direct browser API calls (same as library_glfw3.js) * - Replace glfw3 dependency by direct browser API calls (same as library_glfw3.js)
* *
* ADDITIONAL NOTES:
* - TRACELOG() function is located in raylib [utils] module
*
* CONFIGURATION: * CONFIGURATION:
* #define RCORE_PLATFORM_CUSTOM_FLAG * #define RCORE_PLATFORM_CUSTOM_FLAG
* Custom flag for rcore on target platform -not used- * Custom flag for rcore on target platform -not used-
@ -26,7 +23,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) and contributors * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) and contributors
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -204,7 +201,6 @@ void ToggleFullscreen(void)
EM_ASM(document.exitFullscreen();); EM_ASM(document.exitFullscreen(););
CORE.Window.fullscreen = false;
FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE);
} }
@ -213,14 +209,12 @@ void ToggleFullscreen(void)
if (enterFullscreen) if (enterFullscreen)
{ {
// NOTE: The setTimeouts handle the browser mode change delay // NOTE: The setTimeouts handle the browser mode change delay
EM_ASM EM_ASM(
( setTimeout(function(){
setTimeout(function()
{
Module.requestFullscreen(false, false); Module.requestFullscreen(false, false);
}, 100); }, 100);
); );
CORE.Window.fullscreen = true;
FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
} }
@ -238,7 +232,7 @@ void ToggleFullscreen(void)
*/ */
// EM_ASM(Module.requestFullscreen(false, false);); // EM_ASM(Module.requestFullscreen(false, false););
/* /*
if (!CORE.Window.fullscreen) if (!FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE))
{ {
// Option 1: Request fullscreen for the canvas element // Option 1: Request fullscreen for the canvas element
// This option does not seem to work at all: // This option does not seem to work at all:
@ -274,7 +268,6 @@ void ToggleFullscreen(void)
emscripten_get_canvas_element_size(platform.canvasId, &width, &height); emscripten_get_canvas_element_size(platform.canvasId, &width, &height);
TRACELOG(LOG_WARNING, "Emscripten: Enter fullscreen: Canvas size: %i x %i", width, height); TRACELOG(LOG_WARNING, "Emscripten: Enter fullscreen: Canvas size: %i x %i", width, height);
CORE.Window.fullscreen = true; // Toggle fullscreen flag
FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
} }
else else
@ -286,7 +279,6 @@ void ToggleFullscreen(void)
emscripten_get_canvas_element_size(platform.canvasId, &width, &height); emscripten_get_canvas_element_size(platform.canvasId, &width, &height);
TRACELOG(LOG_WARNING, "Emscripten: Exit fullscreen: Canvas size: %i x %i", width, height); TRACELOG(LOG_WARNING, "Emscripten: Exit fullscreen: Canvas size: %i x %i", width, height);
CORE.Window.fullscreen = false; // Toggle fullscreen flag
FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
} }
*/ */
@ -313,7 +305,6 @@ void ToggleBorderlessWindowed(void)
EM_ASM(document.exitFullscreen();); EM_ASM(document.exitFullscreen(););
CORE.Window.fullscreen = false;
FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE);
} }
@ -545,7 +536,6 @@ void ClearWindowState(unsigned int flags)
if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE) || (canvasStyleWidth > canvasWidth)) EM_ASM(document.exitFullscreen();); if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE) || (canvasStyleWidth > canvasWidth)) EM_ASM(document.exitFullscreen(););
} }
CORE.Window.fullscreen = false;
FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
} }
@ -1111,7 +1101,7 @@ void PollInputEvents(void)
else CORE.Input.Gamepad.currentButtonState[i][button] = 0; else CORE.Input.Gamepad.currentButtonState[i][button] = 0;
} }
//TRACELOGD("INPUT: Gamepad %d, button %d: Digital: %d, Analog: %g", gamepadState.index, j, gamepadState.digitalButton[j], gamepadState.analogButton[j]); //TRACELOG(LOG_DEBUG, "INPUT: Gamepad %d, button %d: Digital: %d, Analog: %g", gamepadState.index, j, gamepadState.digitalButton[j], gamepadState.analogButton[j]);
} }
// Register axis data for every connected gamepad // Register axis data for every connected gamepad
@ -1155,8 +1145,6 @@ int InitPlatform(void)
// glfwWindowHint(GLFW_AUX_BUFFERS, 0); // Number of auxiliar buffers // glfwWindowHint(GLFW_AUX_BUFFERS, 0); // Number of auxiliar buffers
// Check window creation flags // Check window creation flags
if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) CORE.Window.fullscreen = true;
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)) glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // Visible window if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)) glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // Visible window
else glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE); // Window initially hidden else glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE); // Window initially hidden
@ -1260,7 +1248,7 @@ int InitPlatform(void)
// TODO: Consider requesting another type of canvas, not a WebGL one --> Replace GLFW-web by Emscripten? // TODO: Consider requesting another type of canvas, not a WebGL one --> Replace GLFW-web by Emscripten?
platform.pixels = (unsigned int *)RL_CALLOC(CORE.Window.screen.width*CORE.Window.screen.height, sizeof(unsigned int)); platform.pixels = (unsigned int *)RL_CALLOC(CORE.Window.screen.width*CORE.Window.screen.height, sizeof(unsigned int));
#else #else
if (CORE.Window.fullscreen) if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE))
{ {
// remember center for switchinging from fullscreen to window // remember center for switchinging from fullscreen to window
if ((CORE.Window.screen.height == CORE.Window.display.height) && (CORE.Window.screen.width == CORE.Window.display.width)) if ((CORE.Window.screen.height == CORE.Window.display.height) && (CORE.Window.screen.width == CORE.Window.display.width))
@ -1299,18 +1287,6 @@ int InitPlatform(void)
TRACELOG(LOG_WARNING, "SYSTEM: Closest fullscreen videomode: %i x %i", CORE.Window.display.width, CORE.Window.display.height); TRACELOG(LOG_WARNING, "SYSTEM: Closest fullscreen videomode: %i x %i", CORE.Window.display.width, CORE.Window.display.height);
// NOTE: ISSUE: Closest videomode could not match monitor aspect-ratio, for example,
// for a desired screen size of 800x450 (16:9), closest supported videomode is 800x600 (4:3),
// framebuffer is rendered correctly but once displayed on a 16:9 monitor, it gets stretched
// by the sides to fit all monitor space...
// Try to setup the most appropriate fullscreen framebuffer for the requested screenWidth/screenHeight
// It considers device display resolution mode and setups a framebuffer with black bars if required (render size/offset)
// Modified global variables: CORE.Window.screen.width/CORE.Window.screen.height - CORE.Window.render.width/CORE.Window.render.height - CORE.Window.renderOffset.x/CORE.Window.renderOffset.y - CORE.Window.screenScale
// TODO: It is a quite cumbersome solution to display size vs requested size, it should be reviewed or removed...
// HighDPI monitors are properly considered in a following similar function: SetupViewport()
SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);
platform.handle = glfwCreateWindow(CORE.Window.display.width, CORE.Window.display.height, (CORE.Window.title != 0)? CORE.Window.title : " ", glfwGetPrimaryMonitor(), NULL); platform.handle = glfwCreateWindow(CORE.Window.display.width, CORE.Window.display.height, (CORE.Window.title != 0)? CORE.Window.title : " ", glfwGetPrimaryMonitor(), NULL);
// NOTE: Full-screen change, not working properly... // NOTE: Full-screen change, not working properly...
@ -1531,7 +1507,7 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths
for (unsigned int i = 0; i < CORE.Window.dropFileCount; i++) for (unsigned int i = 0; i < CORE.Window.dropFileCount; i++)
{ {
CORE.Window.dropFilepaths[i] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); CORE.Window.dropFilepaths[i] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char));
strcpy(CORE.Window.dropFilepaths[i], paths[i]); strncpy(CORE.Window.dropFilepaths[i], paths[i], MAX_FILEPATH_LENGTH - 1);
} }
} }
} }
@ -1716,12 +1692,12 @@ static EM_BOOL EmscriptenPointerlockCallback(int eventType, const EmscriptenPoin
static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData) static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData)
{ {
/* /*
TRACELOGD("%s: timeStamp: %g, connected: %d, index: %ld, numAxes: %d, numButtons: %d, id: \"%s\", mapping: \"%s\"", TRACELOG(LOG_DEBUG, "%s: timeStamp: %g, connected: %d, index: %ld, numAxes: %d, numButtons: %d, id: \"%s\", mapping: \"%s\"",
eventType != 0? emscripten_event_type_to_string(eventType) : "Gamepad state", eventType != 0? emscripten_event_type_to_string(eventType) : "Gamepad state",
gamepadEvent->timestamp, gamepadEvent->connected, gamepadEvent->index, gamepadEvent->numAxes, gamepadEvent->numButtons, gamepadEvent->id, gamepadEvent->mapping); gamepadEvent->timestamp, gamepadEvent->connected, gamepadEvent->index, gamepadEvent->numAxes, gamepadEvent->numButtons, gamepadEvent->id, gamepadEvent->mapping);
for (int i = 0; i < gamepadEvent->numAxes; i++) TRACELOGD("Axis %d: %g", i, gamepadEvent->axis[i]); for (int i = 0; i < gamepadEvent->numAxes; i++) TRACELOG(LOG_DEBUG, "Axis %d: %g", i, gamepadEvent->axis[i]);
for (int i = 0; i < gamepadEvent->numButtons; i++) TRACELOGD("Button %d: Digital: %d, Analog: %g", i, gamepadEvent->digitalButton[i], gamepadEvent->analogButton[i]); for (int i = 0; i < gamepadEvent->numButtons; i++) TRACELOG(LOG_DEBUG, "Button %d: Digital: %d, Analog: %g", i, gamepadEvent->digitalButton[i], gamepadEvent->analogButton[i]);
*/ */
if (gamepadEvent->connected && (gamepadEvent->index < MAX_GAMEPADS)) if (gamepadEvent->connected && (gamepadEvent->index < MAX_GAMEPADS))
@ -1830,7 +1806,6 @@ static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const Emscripte
const bool wasFullscreen = EM_ASM_INT( { if (document.fullscreenElement) return 1; }, 0); const bool wasFullscreen = EM_ASM_INT( { if (document.fullscreenElement) return 1; }, 0);
if (!wasFullscreen) if (!wasFullscreen)
{ {
CORE.Window.fullscreen = false;
FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE);
} }

File diff suppressed because it is too large Load Diff

View File

@ -50,7 +50,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5)
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -74,12 +74,8 @@
#else #else
#include "raylib.h" // Declares module functions #include "raylib.h" // Declares module functions
// Check if config flags have been externally provided on compilation line
#if !defined(EXTERNAL_CONFIG_FLAGS)
#include "config.h" // Defines module configuration flags #include "config.h" // Defines module configuration flags
#endif #endif
#include "utils.h" // Required for: fopen() Android mapping
#endif
#if defined(SUPPORT_MODULE_RAUDIO) || defined(RAUDIO_STANDALONE) #if defined(SUPPORT_MODULE_RAUDIO) || defined(RAUDIO_STANDALONE)
@ -1134,7 +1130,7 @@ bool ExportWaveAsCode(Wave wave, const char *fileName)
byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n"); byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n");
byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n"); byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n");
byteCount += sprintf(txtData + byteCount, "// //\n"); byteCount += sprintf(txtData + byteCount, "// //\n");
byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2018-2025 Ramon Santamaria (@raysan5) //\n"); byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2018-2026 Ramon Santamaria (@raysan5) //\n");
byteCount += sprintf(txtData + byteCount, "// //\n"); byteCount += sprintf(txtData + byteCount, "// //\n");
byteCount += sprintf(txtData + byteCount, "//////////////////////////////////////////////////////////////////////////////////\n\n"); byteCount += sprintf(txtData + byteCount, "//////////////////////////////////////////////////////////////////////////////////\n\n");
@ -1249,7 +1245,7 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels)
frameCount = (ma_uint32)ma_convert_frames(data, frameCount, formatOut, channels, sampleRate, wave->data, frameCountIn, formatIn, wave->channels, wave->sampleRate); frameCount = (ma_uint32)ma_convert_frames(data, frameCount, formatOut, channels, sampleRate, wave->data, frameCountIn, formatIn, wave->channels, wave->sampleRate);
if (frameCount == 0) if (frameCount == 0)
{ {
RL_FREE(wave->data); RL_FREE(data);
TRACELOG(LOG_WARNING, "WAVE: Failed format conversion"); TRACELOG(LOG_WARNING, "WAVE: Failed format conversion");
return; return;
} }

View File

@ -62,7 +62,7 @@
* raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified, * raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software: * BSD-like license that allows static linking with closed source software:
* *
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5)
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -570,8 +570,7 @@ typedef enum {
} TraceLogLevel; } TraceLogLevel;
// Keyboard keys (US keyboard layout) // Keyboard keys (US keyboard layout)
// NOTE: Use GetKeyPressed() to allow redefining // NOTE: Use GetKeyPressed() to allow redefining required keys for alternative layouts
// required keys for alternative layouts
typedef enum { typedef enum {
KEY_NULL = 0, // Key: NULL, used for no key pressed KEY_NULL = 0, // Key: NULL, used for no key pressed
// Alphanumeric keys // Alphanumeric keys
@ -1099,23 +1098,17 @@ RLAPI void TakeScreenshot(const char *fileName); // Takes a scr
RLAPI void SetConfigFlags(unsigned int flags); // Setup init configuration flags (view FLAGS) RLAPI void SetConfigFlags(unsigned int flags); // Setup init configuration flags (view FLAGS)
RLAPI void OpenURL(const char *url); // Open URL with default system browser (if available) RLAPI void OpenURL(const char *url); // Open URL with default system browser (if available)
// NOTE: Following functions implemented in module [utils] // Logging system
//------------------------------------------------------------------
RLAPI void TraceLog(int logLevel, const char *text, ...); // Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...)
RLAPI void SetTraceLogLevel(int logLevel); // Set the current threshold (minimum) log level RLAPI void SetTraceLogLevel(int logLevel); // Set the current threshold (minimum) log level
RLAPI void TraceLog(int logLevel, const char *text, ...); // Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...)
RLAPI void SetTraceLogCallback(TraceLogCallback callback); // Set custom trace log
// Memory management, using internal allocators
RLAPI void *MemAlloc(unsigned int size); // Internal memory allocator RLAPI void *MemAlloc(unsigned int size); // Internal memory allocator
RLAPI void *MemRealloc(void *ptr, unsigned int size); // Internal memory reallocator RLAPI void *MemRealloc(void *ptr, unsigned int size); // Internal memory reallocator
RLAPI void MemFree(void *ptr); // Internal memory free RLAPI void MemFree(void *ptr); // Internal memory free
// Set custom callbacks // File system management functions
// WARNING: Callbacks setup is intended for advanced users
RLAPI void SetTraceLogCallback(TraceLogCallback callback); // Set custom trace log
RLAPI void SetLoadFileDataCallback(LoadFileDataCallback callback); // Set custom file binary data loader
RLAPI void SetSaveFileDataCallback(SaveFileDataCallback callback); // Set custom file binary data saver
RLAPI void SetLoadFileTextCallback(LoadFileTextCallback callback); // Set custom file text data loader
RLAPI void SetSaveFileTextCallback(SaveFileTextCallback callback); // Set custom file text data saver
// Files management functions
RLAPI unsigned char *LoadFileData(const char *fileName, int *dataSize); // Load file data as byte array (read) RLAPI unsigned char *LoadFileData(const char *fileName, int *dataSize); // Load file data as byte array (read)
RLAPI void UnloadFileData(unsigned char *data); // Unload file data allocated by LoadFileData() RLAPI void UnloadFileData(unsigned char *data); // Unload file data allocated by LoadFileData()
RLAPI bool SaveFileData(const char *fileName, void *data, int dataSize); // Save data to file from byte array (write), returns true on success RLAPI bool SaveFileData(const char *fileName, void *data, int dataSize); // Save data to file from byte array (write), returns true on success
@ -1123,9 +1116,14 @@ RLAPI bool ExportDataAsCode(const unsigned char *data, int dataSize, const char
RLAPI char *LoadFileText(const char *fileName); // Load text data from file (read), returns a '\0' terminated string RLAPI char *LoadFileText(const char *fileName); // Load text data from file (read), returns a '\0' terminated string
RLAPI void UnloadFileText(char *text); // Unload file text data allocated by LoadFileText() RLAPI void UnloadFileText(char *text); // Unload file text data allocated by LoadFileText()
RLAPI bool SaveFileText(const char *fileName, const char *text); // Save text data to file (write), string must be '\0' terminated, returns true on success RLAPI bool SaveFileText(const char *fileName, const char *text); // Save text data to file (write), string must be '\0' terminated, returns true on success
//------------------------------------------------------------------
// File system functions // File access custom callbacks
// WARNING: Callbacks setup is intended for advanced users
RLAPI void SetLoadFileDataCallback(LoadFileDataCallback callback); // Set custom file binary data loader
RLAPI void SetSaveFileDataCallback(SaveFileDataCallback callback); // Set custom file binary data saver
RLAPI void SetLoadFileTextCallback(LoadFileTextCallback callback); // Set custom file text data loader
RLAPI void SetSaveFileTextCallback(SaveFileTextCallback callback); // Set custom file text data saver
RLAPI int FileRename(const char *fileName, const char *fileRename); // Rename file (if exists) RLAPI int FileRename(const char *fileName, const char *fileRename); // Rename file (if exists)
RLAPI int FileRemove(const char *fileName); // Remove file (if exists) RLAPI int FileRemove(const char *fileName); // Remove file (if exists)
RLAPI int FileCopy(const char *srcPath, const char *dstPath); // Copy file from one path to another, dstPath created if it doesn't exist RLAPI int FileCopy(const char *srcPath, const char *dstPath); // Copy file from one path to another, dstPath created if it doesn't exist

View File

@ -19,20 +19,25 @@
* *
* CONFIGURATION: * CONFIGURATION:
* #define RAYMATH_IMPLEMENTATION * #define RAYMATH_IMPLEMENTATION
* Generates the implementation of the library into the included file. * Generates the implementation of the library into the included file
* If not defined, the library is in header only mode and can be included in other headers * If not defined, the library is in header only mode and can be included in other headers
* or source files without problems. But only ONE file should hold the implementation. * or source files without problems. But only ONE file should hold the implementation
* *
* #define RAYMATH_STATIC_INLINE * #define RAYMATH_STATIC_INLINE
* Define static inline functions code, so #include header suffices for use. * Define static inline functions code, so #include header suffices for use
* This may use up lots of memory. * This may use up lots of memory
* *
* #define RAYMATH_DISABLE_CPP_OPERATORS * #define RAYMATH_DISABLE_CPP_OPERATORS
* Disables C++ operator overloads for raymath types. * Disables C++ operator overloads for raymath types.
* *
* #define RAYMATH_USE_SIMD_INTRINSICS
* Try to enable SIMD intrinsics for MatrixMultiply()
* Note that users enabling it must be aware of the target platform where application will
* run to support the selected SIMD intrinsic, for now, only SSE is supported
*
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2015-2025 Ramon Santamaria (@raysan5) * Copyright (c) 2015-2026 Ramon Santamaria (@raysan5)
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -79,7 +84,6 @@
#endif #endif
#endif #endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // Defines and Macros
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -170,6 +174,35 @@ typedef struct float16 {
#include <math.h> // Required for: sinf(), cosf(), tan(), atan2f(), sqrtf(), floor(), fminf(), fmaxf(), fabsf() #include <math.h> // Required for: sinf(), cosf(), tan(), atan2f(), sqrtf(), floor(), fminf(), fmaxf(), fabsf()
#if defined(RAYMATH_USE_SIMD_INTRINSICS)
// SIMD is used on the most costly raymath function MatrixMultiply()
// NOTE: Only SSE intrinsics support implemented
// TODO: Consider support for other SIMD instrinsics:
// - SSEx, AVX, AVX2, FMA, NEON, RVV
/*
#if defined(__SSE4_2__)
#include <nmmintrin.h>
#define RAYMATH_SSE42_ENABLED
#elif defined(__SSE4_1__)
#include <smmintrin.h>
#define RAYMATH_SSE41_ENABLED
#elif defined(__SSSE3__)
#include <tmmintrin.h>
#define RAYMATH_SSSE3_ENABLED
#elif defined(__SSE3__)
#include <pmmintrin.h>
#define RAYMATH_SSE3_ENABLED
#elif defined(__SSE2__) || (defined(_M_AMD64) || defined(_M_X64)) // SSE2 x64
#include <emmintrin.h>
#define RAYMATH_SSE2_ENABLED
#endif
*/
#if defined(__SSE__) || defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP >= 1))
#include <xmmintrin.h>
#define RAYMATH_SSE_ENABLED
#endif
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module Functions Definition - Utils math // Module Functions Definition - Utils math
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -1648,6 +1681,63 @@ RMAPI Matrix MatrixMultiply(Matrix left, Matrix right)
{ {
Matrix result = { 0 }; Matrix result = { 0 };
#if defined(RAYMATH_SSE_ENABLED)
// Load left side and right side
__m128 c0 = _mm_set_ps(right.m12, right.m8, right.m4, right.m0);
__m128 c1 = _mm_set_ps(right.m13, right.m9, right.m5, right.m1);
__m128 c2 = _mm_set_ps(right.m14, right.m10, right.m6, right.m2);
__m128 c3 = _mm_set_ps(right.m15, right.m11, right.m7, right.m3);
// Transpose so c0..c3 become *rows* of the right matrix in semantic order
_MM_TRANSPOSE4_PS(c0, c1, c2, c3);
float tmp[4] = { 0 };
__m128 row;
// Row 0 of result: [m0, m1, m2, m3]
row = _mm_mul_ps(_mm_set1_ps(left.m0), c0);
row = _mm_add_ps(row, _mm_mul_ps(_mm_set1_ps(left.m1), c1));
row = _mm_add_ps(row, _mm_mul_ps(_mm_set1_ps(left.m2), c2));
row = _mm_add_ps(row, _mm_mul_ps(_mm_set1_ps(left.m3), c3));
_mm_storeu_ps(tmp, row);
result.m0 = tmp[0];
result.m1 = tmp[1];
result.m2 = tmp[2];
result.m3 = tmp[3];
// Row 1 of result: [m4, m5, m6, m7]
row = _mm_mul_ps(_mm_set1_ps(left.m4), c0);
row = _mm_add_ps(row, _mm_mul_ps(_mm_set1_ps(left.m5), c1));
row = _mm_add_ps(row, _mm_mul_ps(_mm_set1_ps(left.m6), c2));
row = _mm_add_ps(row, _mm_mul_ps(_mm_set1_ps(left.m7), c3));
_mm_storeu_ps(tmp, row);
result.m4 = tmp[0];
result.m5 = tmp[1];
result.m6 = tmp[2];
result.m7 = tmp[3];
// Row 2 of result: [m8, m9, m10, m11]
row = _mm_mul_ps(_mm_set1_ps(left.m8), c0);
row = _mm_add_ps(row, _mm_mul_ps(_mm_set1_ps(left.m9), c1));
row = _mm_add_ps(row, _mm_mul_ps(_mm_set1_ps(left.m10), c2));
row = _mm_add_ps(row, _mm_mul_ps(_mm_set1_ps(left.m11), c3));
_mm_storeu_ps(tmp, row);
result.m8 = tmp[0];
result.m9 = tmp[1];
result.m10 = tmp[2];
result.m11 = tmp[3];
// Row 3 of result: [m12, m13, m14, m15]
row = _mm_mul_ps(_mm_set1_ps(left.m12), c0);
row = _mm_add_ps(row, _mm_mul_ps(_mm_set1_ps(left.m13), c1));
row = _mm_add_ps(row, _mm_mul_ps(_mm_set1_ps(left.m14), c2));
row = _mm_add_ps(row, _mm_mul_ps(_mm_set1_ps(left.m15), c3));
_mm_storeu_ps(tmp, row);
result.m12 = tmp[0];
result.m13 = tmp[1];
result.m14 = tmp[2];
result.m15 = tmp[3];
#else
result.m0 = left.m0*right.m0 + left.m1*right.m4 + left.m2*right.m8 + left.m3*right.m12; result.m0 = left.m0*right.m0 + left.m1*right.m4 + left.m2*right.m8 + left.m3*right.m12;
result.m1 = left.m0*right.m1 + left.m1*right.m5 + left.m2*right.m9 + left.m3*right.m13; result.m1 = left.m0*right.m1 + left.m1*right.m5 + left.m2*right.m9 + left.m3*right.m13;
result.m2 = left.m0*right.m2 + left.m1*right.m6 + left.m2*right.m10 + left.m3*right.m14; result.m2 = left.m0*right.m2 + left.m1*right.m6 + left.m2*right.m10 + left.m3*right.m14;
@ -1664,6 +1754,7 @@ RMAPI Matrix MatrixMultiply(Matrix left, Matrix right)
result.m13 = left.m12*right.m1 + left.m13*right.m5 + left.m14*right.m9 + left.m15*right.m13; result.m13 = left.m12*right.m1 + left.m13*right.m5 + left.m14*right.m9 + left.m15*right.m13;
result.m14 = left.m12*right.m2 + left.m13*right.m6 + left.m14*right.m10 + left.m15*right.m14; result.m14 = left.m12*right.m2 + left.m13*right.m6 + left.m14*right.m10 + left.m15*right.m14;
result.m15 = left.m12*right.m3 + left.m13*right.m7 + left.m14*right.m11 + left.m15*right.m15; result.m15 = left.m12*right.m3 + left.m13*right.m7 + left.m14*right.m11 + left.m15*right.m15;
#endif
return result; return result;
} }

View File

@ -20,7 +20,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2022-2025 Christoph Wagner (@Crydsch) & Ramon Santamaria (@raysan5) * Copyright (c) 2022-2026 Christoph Wagner (@Crydsch) and Ramon Santamaria (@raysan5)
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -192,6 +192,8 @@ RLAPI Matrix GetCameraProjectionMatrix(Camera *camera, float aspect);
// IsKeyPressed() // IsKeyPressed()
// GetFrameTime() // GetFrameTime()
#include <math.h> // Required for: fabsf()
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // Defines and Macros
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -252,8 +254,11 @@ void CameraMoveForward(Camera *camera, float distance, bool moveInWorldPlane)
if (moveInWorldPlane) if (moveInWorldPlane)
{ {
// Project vector onto world plane // Project vector onto world plane (the plane defined by the up vector)
forward.y = 0; if (fabsf(camera->up.z) > 0.7071f) forward.z = 0;
else if (fabsf(camera->up.x) > 0.7071f) forward.x = 0;
else forward.y = 0;
forward = Vector3Normalize(forward); forward = Vector3Normalize(forward);
} }
@ -285,8 +290,11 @@ void CameraMoveRight(Camera *camera, float distance, bool moveInWorldPlane)
if (moveInWorldPlane) if (moveInWorldPlane)
{ {
// Project vector onto world plane // Project vector onto world plane (the plane defined by the up vector)
right.y = 0; if (fabsf(camera->up.z) > 0.7071f) right.z = 0;
else if (fabsf(camera->up.x) > 0.7071f) right.x = 0;
else right.y = 0;
right = Vector3Normalize(right); right = Vector3Normalize(right);
} }
@ -345,7 +353,7 @@ void CameraYaw(Camera *camera, float angle, bool rotateAroundTarget)
// - lockView prevents camera overrotation (aka "somersaults") // - lockView prevents camera overrotation (aka "somersaults")
// - rotateAroundTarget defines if rotation is around target or around its position // - rotateAroundTarget defines if rotation is around target or around its position
// - rotateUp rotates the up direction as well (typically only usefull in CAMERA_FREE) // - rotateUp rotates the up direction as well (typically only usefull in CAMERA_FREE)
// NOTE: angle must be provided in radians // NOTE: [angle] must be provided in radians
void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp) void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp)
{ {
// Up direction // Up direction
@ -382,7 +390,7 @@ void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTa
// Move position relative to target // Move position relative to target
camera->position = Vector3Subtract(camera->target, targetPosition); camera->position = Vector3Subtract(camera->target, targetPosition);
} }
else // rotate around camera.position else // Rotate around camera.position
{ {
// Move target relative to position // Move target relative to position
camera->target = Vector3Add(camera->position, targetPosition); camera->target = Vector3Add(camera->position, targetPosition);

View File

@ -70,7 +70,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) and contributors * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) and contributors
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -104,16 +104,12 @@
#include "raylib.h" // Declares module functions #include "raylib.h" // Declares module functions
// Check if config flags have been externally provided on compilation line
#if !defined(EXTERNAL_CONFIG_FLAGS)
#include "config.h" // Defines module configuration flags #include "config.h" // Defines module configuration flags
#endif
#include "utils.h" // Required for: TRACELOG() macros #include <stdlib.h> // Required for: srand(), rand(), atexit(), exit()
#include <stdio.h> // Required for: FILE, fopen(), fseek(), ftell(), fread(), fwrite(), fprintf(), vprintf(), fclose(), sprintf() [Used in OpenURL()]
#include <stdlib.h> // Required for: srand(), rand(), atexit() #include <string.h> // Required for: strlen(), strncpy(), strcmp(), strrchr(), memset(), strcat()
#include <stdio.h> // Required for: sprintf() [Used in OpenURL()] #include <stdarg.h> // Required for: va_list, va_start(), va_end() [Used in TraceLog()]
#include <string.h> // Required for: strlen(), strncpy(), strcmp(), strrchr(), memset()
#include <time.h> // Required for: time() [Used in InitTimer()] #include <time.h> // Required for: time() [Used in InitTimer()]
#include <math.h> // Required for: tan() [Used in BeginMode3D()], atan2f() [Used in LoadVrStereoConfig()] #include <math.h> // Required for: tan() [Used in BeginMode3D()], atan2f() [Used in LoadVrStereoConfig()]
@ -205,16 +201,22 @@
#define GETCWD _getcwd // NOTE: MSDN recommends not to use getcwd(), chdir() #define GETCWD _getcwd // NOTE: MSDN recommends not to use getcwd(), chdir()
#define CHDIR _chdir #define CHDIR _chdir
#define MKDIR(dir) _mkdir(dir) #define MKDIR(dir) _mkdir(dir)
#define ACCESS(fn) _access(fn, 0)
#else #else
#include <unistd.h> // Required for: getch(), chdir(), mkdir(), access() #include <unistd.h> // Required for: getch(), chdir(), mkdir(), access()
#define GETCWD getcwd #define GETCWD getcwd
#define CHDIR chdir #define CHDIR chdir
#define MKDIR(dir) mkdir(dir, 0777) #define MKDIR(dir) mkdir(dir, 0777)
#define ACCESS(fn) access(fn, F_OK)
#endif #endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // Defines and Macros
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
#ifndef MAX_TRACELOG_MSG_LENGTH
#define MAX_TRACELOG_MSG_LENGTH 256 // Max length of one trace-log message
#endif
#ifndef MAX_FILEPATH_CAPACITY #ifndef MAX_FILEPATH_CAPACITY
#define MAX_FILEPATH_CAPACITY 8192 // Maximum capacity for filepath #define MAX_FILEPATH_CAPACITY 8192 // Maximum capacity for filepath
#endif #endif
@ -273,7 +275,7 @@
#define FLAG_SET(n, f) ((n) |= (f)) #define FLAG_SET(n, f) ((n) |= (f))
#define FLAG_CLEAR(n, f) ((n) &= ~(f)) #define FLAG_CLEAR(n, f) ((n) &= ~(f))
#define FLAG_TOGGLE(n, f) ((n) ^= (f)) #define FLAG_TOGGLE(n, f) ((n) ^= (f))
#define FLAG_IS_SET(n, f) (((n) & (f)) > 0) #define FLAG_IS_SET(n, f) (((n) & (f)) == (f))
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Types and Structures Definition // Types and Structures Definition
@ -287,20 +289,19 @@ typedef struct CoreData {
const char *title; // Window text title const pointer const char *title; // Window text title const pointer
unsigned int flags; // Configuration flags (bit based), keeps window state unsigned int flags; // Configuration flags (bit based), keeps window state
bool ready; // Check if window has been initialized successfully bool ready; // Check if window has been initialized successfully
bool fullscreen; // Check if fullscreen mode is enabled
bool shouldClose; // Check if window set for closing bool shouldClose; // Check if window set for closing
bool resizedLastFrame; // Check if window has been resized last frame bool resizedLastFrame; // Check if window has been resized last frame
bool eventWaiting; // Wait for events before ending frame bool eventWaiting; // Wait for events before ending frame
bool usingFbo; // Using FBO (RenderTexture) for rendering instead of default framebuffer bool usingFbo; // Using FBO (RenderTexture) for rendering instead of default framebuffer
Point position; // Window position (required on fullscreen toggle)
Point previousPosition; // Window previous position (required on borderless windowed toggle)
Size display; // Display width and height (monitor, device-screen, LCD, ...) Size display; // Display width and height (monitor, device-screen, LCD, ...)
Size screen; // Screen width and height (used render area) Size screen; // Screen current width and height
Size previousScreen; // Screen previous width and height (required on borderless windowed toggle) Point position; // Window current position
Size currentFbo; // Current render width and height (depends on active fbo) Size previousScreen; // Screen previous width and height (required on fullscreen/borderless-windowed toggle)
Size render; // Framebuffer width and height (render area, including black bars if required) Point previousPosition; // Window previous position (required on fullscreeen/borderless-windowed toggle)
Point renderOffset; // Offset from render area (must be divided by 2) Size render; // Screen framebuffer width and height
Point renderOffset; // Screen framebuffer render offset (Not required anymore?)
Size currentFbo; // Current framebuffer render width and height (depends on active render texture)
Size screenMin; // Screen minimum width and height (for resizable window) Size screenMin; // Screen minimum width and height (for resizable window)
Size screenMax; // Screen maximum width and height (for resizable window) Size screenMax; // Screen maximum width and height (for resizable window)
Matrix screenScale; // Matrix to scale screen (framebuffer rendering) Matrix screenScale; // Matrix to scale screen (framebuffer rendering)
@ -352,6 +353,7 @@ typedef struct CoreData {
int pointCount; // Number of touch points active int pointCount; // Number of touch points active
int pointId[MAX_TOUCH_POINTS]; // Point identifiers int pointId[MAX_TOUCH_POINTS]; // Point identifiers
Vector2 position[MAX_TOUCH_POINTS]; // Touch position on screen Vector2 position[MAX_TOUCH_POINTS]; // Touch position on screen
Vector2 previousPosition[MAX_TOUCH_POINTS]; // Previous touch position on screen
char currentTouchState[MAX_TOUCH_POINTS]; // Registers current touch state char currentTouchState[MAX_TOUCH_POINTS]; // Registers current touch state
char previousTouchState[MAX_TOUCH_POINTS]; // Registers previous touch state char previousTouchState[MAX_TOUCH_POINTS]; // Registers previous touch state
@ -387,6 +389,14 @@ RLAPI const char *raylib_version = RAYLIB_VERSION; // raylib version exported s
CoreData CORE = { 0 }; // Global CORE state context CoreData CORE = { 0 }; // Global CORE state context
static int logTypeLevel = LOG_INFO; // Minimum log type level
static TraceLogCallback traceLog = NULL; // TraceLog callback function pointer
static LoadFileDataCallback loadFileData = NULL; // LoadFileData callback function pointer
static SaveFileDataCallback saveFileData = NULL; // SaveFileText callback function pointer
static LoadFileTextCallback loadFileText = NULL; // LoadFileText callback function pointer
static SaveFileTextCallback saveFileText = NULL; // SaveFileText callback function pointer
#if defined(SUPPORT_SCREEN_CAPTURE) #if defined(SUPPORT_SCREEN_CAPTURE)
static int screenshotCounter = 0; // Screenshots counter static int screenshotCounter = 0; // Screenshots counter
#endif #endif
@ -493,7 +503,6 @@ extern int InitPlatform(void); // Initialize platform (graphics, inputs
extern void ClosePlatform(void); // Close platform extern void ClosePlatform(void); // Close platform
static void InitTimer(void); // Initialize timer, hi-resolution if available (required by InitPlatform()) static void InitTimer(void); // Initialize timer, hi-resolution if available (required by InitPlatform())
static void SetupFramebuffer(int width, int height); // Setup main framebuffer (required by InitPlatform())
static void SetupViewport(int width, int height); // Set viewport for a provided width and height static void SetupViewport(int width, int height); // Set viewport for a provided width and height
static void ScanDirectoryFiles(const char *basePath, FilePathList *list, const char *filter); // Scan all files and directories in a base path static void ScanDirectoryFiles(const char *basePath, FilePathList *list, const char *filter); // Scan all files and directories in a base path
@ -762,31 +771,31 @@ bool IsWindowReady(void)
// Check if window is currently fullscreen // Check if window is currently fullscreen
bool IsWindowFullscreen(void) bool IsWindowFullscreen(void)
{ {
return CORE.Window.fullscreen; return FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE);
} }
// Check if window is currently hidden // Check if window is currently hidden
bool IsWindowHidden(void) bool IsWindowHidden(void)
{ {
return (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)); return FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN);
} }
// Check if window has been minimized // Check if window has been minimized
bool IsWindowMinimized(void) bool IsWindowMinimized(void)
{ {
return (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)); return FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED);
} }
// Check if window has been maximized // Check if window has been maximized
bool IsWindowMaximized(void) bool IsWindowMaximized(void)
{ {
return (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED)); return FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED);
} }
// Check if window has the focus // Check if window has the focus
bool IsWindowFocused(void) bool IsWindowFocused(void)
{ {
return (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED)); return !FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED);
} }
// Check if window has been resizedLastFrame // Check if window has been resizedLastFrame
@ -798,7 +807,7 @@ bool IsWindowResized(void)
// Check if one specific window flag is enabled // Check if one specific window flag is enabled
bool IsWindowState(unsigned int flag) bool IsWindowState(unsigned int flag)
{ {
return (FLAG_IS_SET(CORE.Window.flags, flag)); return FLAG_IS_SET(CORE.Window.flags, flag);
} }
// Get current screen width // Get current screen width
@ -1100,7 +1109,7 @@ void BeginScissorMode(int x, int y, int width, int height)
rlScissor((int)(x*scale.x), (int)(GetScreenHeight()*scale.y - (((y + height)*scale.y))), (int)(width*scale.x), (int)(height*scale.y)); rlScissor((int)(x*scale.x), (int)(GetScreenHeight()*scale.y - (((y + height)*scale.y))), (int)(width*scale.x), (int)(height*scale.y));
} }
#else #else
if (!CORE.Window.usingFbo && (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI))) if (!CORE.Window.usingFbo && FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI))
{ {
Vector2 scale = GetWindowScaleDPI(); Vector2 scale = GetWindowScaleDPI();
rlScissor((int)(x*scale.x), (int)(CORE.Window.currentFbo.height - (y + height)*scale.y), (int)(width*scale.x), (int)(height*scale.y)); rlScissor((int)(x*scale.x), (int)(CORE.Window.currentFbo.height - (y + height)*scale.y), (int)(width*scale.x), (int)(height*scale.y));
@ -1856,9 +1865,389 @@ void SetConfigFlags(unsigned int flags)
FLAG_SET(CORE.Window.flags, flags); FLAG_SET(CORE.Window.flags, flags);
} }
// void OpenURL(const char *url); // Defined per platform
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module Functions Definition: File system // Module Functions Definition: Logging system
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Set the current threshold (minimum) log level
void SetTraceLogLevel(int logType) { logTypeLevel = logType; }
// Show trace log messages (LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_DEBUG)
void TraceLog(int logType, const char *text, ...)
{
#if defined(SUPPORT_TRACELOG)
// Message has level below current threshold, don't emit
if ((logType < logTypeLevel) || (text == NULL)) return;
va_list args;
va_start(args, text);
if (traceLog)
{
traceLog(logType, text, args);
va_end(args);
return;
}
#if defined(PLATFORM_ANDROID)
switch (logType)
{
case LOG_TRACE: __android_log_vprint(ANDROID_LOG_VERBOSE, "raylib", text, args); break;
case LOG_DEBUG: __android_log_vprint(ANDROID_LOG_DEBUG, "raylib", text, args); break;
case LOG_INFO: __android_log_vprint(ANDROID_LOG_INFO, "raylib", text, args); break;
case LOG_WARNING: __android_log_vprint(ANDROID_LOG_WARN, "raylib", text, args); break;
case LOG_ERROR: __android_log_vprint(ANDROID_LOG_ERROR, "raylib", text, args); break;
case LOG_FATAL: __android_log_vprint(ANDROID_LOG_FATAL, "raylib", text, args); break;
default: break;
}
#else
char buffer[MAX_TRACELOG_MSG_LENGTH] = { 0 };
switch (logType)
{
case LOG_TRACE: strncpy(buffer, "TRACE: ", 8); break;
case LOG_DEBUG: strncpy(buffer, "DEBUG: ", 8); break;
case LOG_INFO: strncpy(buffer, "INFO: ", 7); break;
case LOG_WARNING: strncpy(buffer, "WARNING: ", 10); break;
case LOG_ERROR: strncpy(buffer, "ERROR: ", 8); break;
case LOG_FATAL: strncpy(buffer, "FATAL: ", 8); break;
default: break;
}
unsigned int textLength = (unsigned int)strlen(text);
memcpy(buffer + strlen(buffer), text, (textLength < (MAX_TRACELOG_MSG_LENGTH - 12))? textLength : (MAX_TRACELOG_MSG_LENGTH - 12));
strcat(buffer, "\n");
vprintf(buffer, args);
fflush(stdout);
#endif
va_end(args);
if (logType == LOG_FATAL) exit(EXIT_FAILURE); // If fatal logging, exit program
#endif // SUPPORT_TRACELOG
}
// Set custom trace log
void SetTraceLogCallback(TraceLogCallback callback)
{
traceLog = callback;
}
//----------------------------------------------------------------------------------
// Module Functions Definition: Memory management
//----------------------------------------------------------------------------------
// Internal memory allocator
// NOTE: Initializes to zero by default
void *MemAlloc(unsigned int size)
{
void *ptr = RL_CALLOC(size, 1);
return ptr;
}
// Internal memory reallocator
void *MemRealloc(void *ptr, unsigned int size)
{
void *ret = RL_REALLOC(ptr, size);
return ret;
}
// Internal memory free
void MemFree(void *ptr)
{
RL_FREE(ptr);
}
//----------------------------------------------------------------------------------
// Module Functions Definition: File System management
//----------------------------------------------------------------------------------
// Load data from file into a buffer
unsigned char *LoadFileData(const char *fileName, int *dataSize)
{
unsigned char *data = NULL;
*dataSize = 0;
if (fileName != NULL)
{
if (loadFileData)
{
data = loadFileData(fileName, dataSize);
return data;
}
#if defined(SUPPORT_STANDARD_FILEIO)
FILE *file = fopen(fileName, "rb");
if (file != NULL)
{
// WARNING: On binary streams SEEK_END could not be found,
// using fseek() and ftell() could not work in some (rare) cases
fseek(file, 0, SEEK_END);
int size = ftell(file); // WARNING: ftell() returns 'long int', maximum size returned is INT_MAX (2147483647 bytes)
fseek(file, 0, SEEK_SET);
if (size > 0)
{
data = (unsigned char *)RL_CALLOC(size, sizeof(unsigned char));
if (data != NULL)
{
// NOTE: fread() returns number of read elements instead of bytes, so we read [1 byte, size elements]
size_t count = fread(data, sizeof(unsigned char), size, file);
// WARNING: fread() returns a size_t value, usually 'unsigned int' (32bit compilation) and 'unsigned long long' (64bit compilation)
// dataSize is unified along raylib as a 'int' type, so, for file-sizes > INT_MAX (2147483647 bytes) we have a limitation
if (count > 2147483647)
{
TRACELOG(LOG_WARNING, "FILEIO: [%s] File is bigger than 2147483647 bytes, avoid using LoadFileData()", fileName);
RL_FREE(data);
data = NULL;
}
else
{
*dataSize = (int)count;
if ((*dataSize) != size) TRACELOG(LOG_WARNING, "FILEIO: [%s] File partially loaded (%i bytes out of %i)", fileName, dataSize, count);
else TRACELOG(LOG_INFO, "FILEIO: [%s] File loaded successfully", fileName);
}
}
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to allocated memory for file reading", fileName);
}
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to read file", fileName);
fclose(file);
}
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open file", fileName);
#else
TRACELOG(LOG_WARNING, "FILEIO: Standard file io not supported, use custom file callback");
#endif
}
else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid");
return data;
}
// Unload file data allocated by LoadFileData()
void UnloadFileData(unsigned char *data)
{
RL_FREE(data);
}
// Save data to file from buffer
bool SaveFileData(const char *fileName, void *data, int dataSize)
{
bool success = false;
if (fileName != NULL)
{
if (saveFileData)
{
return saveFileData(fileName, data, dataSize);
}
#if defined(SUPPORT_STANDARD_FILEIO)
FILE *file = fopen(fileName, "wb");
if (file != NULL)
{
// WARNING: fwrite() returns a size_t value, usually 'unsigned int' (32bit compilation) and 'unsigned long long' (64bit compilation)
// and expects a size_t input value but as dataSize is limited to INT_MAX (2147483647 bytes), there shouldn't be a problem
int count = (int)fwrite(data, sizeof(unsigned char), dataSize, file);
if (count == 0) TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to write file", fileName);
else if (count != dataSize) TRACELOG(LOG_WARNING, "FILEIO: [%s] File partially written", fileName);
else TRACELOG(LOG_INFO, "FILEIO: [%s] File saved successfully", fileName);
int result = fclose(file);
if (result == 0) success = true;
}
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open file", fileName);
#else
TRACELOG(LOG_WARNING, "FILEIO: Standard file io not supported, use custom file callback");
#endif
}
else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid");
return success;
}
// Export data to code (.h), returns true on success
bool ExportDataAsCode(const unsigned char *data, int dataSize, const char *fileName)
{
bool success = false;
#ifndef TEXT_BYTES_PER_LINE
#define TEXT_BYTES_PER_LINE 20
#endif
// NOTE: Text data buffer size is estimated considering raw data size in bytes
// and requiring 6 char bytes for every byte: "0x00, "
char *txtData = (char *)RL_CALLOC(dataSize*6 + 2000, sizeof(char));
int byteCount = 0;
byteCount += sprintf(txtData + byteCount, "////////////////////////////////////////////////////////////////////////////////////////\n");
byteCount += sprintf(txtData + byteCount, "// //\n");
byteCount += sprintf(txtData + byteCount, "// DataAsCode exporter v1.0 - Raw data exported as an array of bytes //\n");
byteCount += sprintf(txtData + byteCount, "// //\n");
byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n");
byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n");
byteCount += sprintf(txtData + byteCount, "// //\n");
byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2022-2026 Ramon Santamaria (@raysan5) //\n");
byteCount += sprintf(txtData + byteCount, "// //\n");
byteCount += sprintf(txtData + byteCount, "////////////////////////////////////////////////////////////////////////////////////////\n\n");
// Get file name from path
char varFileName[256] = { 0 };
strncpy(varFileName, GetFileNameWithoutExt(fileName), 256 - 1);
for (int i = 0; varFileName[i] != '\0'; i++)
{
// Convert variable name to uppercase
if ((varFileName[i] >= 'a') && (varFileName[i] <= 'z')) { varFileName[i] = varFileName[i] - 32; }
// Replace non valid character for C identifier with '_'
else if (varFileName[i] == '.' || varFileName[i] == '-' || varFileName[i] == '?' || varFileName[i] == '!' || varFileName[i] == '+') { varFileName[i] = '_'; }
}
byteCount += sprintf(txtData + byteCount, "#define %s_DATA_SIZE %i\n\n", varFileName, dataSize);
byteCount += sprintf(txtData + byteCount, "static unsigned char %s_DATA[%s_DATA_SIZE] = { ", varFileName, varFileName);
for (int i = 0; i < (dataSize - 1); i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "0x%x,\n" : "0x%x, "), data[i]);
byteCount += sprintf(txtData + byteCount, "0x%x };\n", data[dataSize - 1]);
// NOTE: Text data size exported is determined by '\0' (NULL) character
success = SaveFileText(fileName, txtData);
RL_FREE(txtData);
if (success != 0) TRACELOG(LOG_INFO, "FILEIO: [%s] Data as code exported successfully", fileName);
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to export data as code", fileName);
return success;
}
// Load text data from file, returns a '\0' terminated string
// NOTE: text chars array should be freed manually
char *LoadFileText(const char *fileName)
{
char *text = NULL;
if (fileName != NULL)
{
if (loadFileText)
{
text = loadFileText(fileName);
return text;
}
#if defined(SUPPORT_STANDARD_FILEIO)
FILE *file = fopen(fileName, "rt");
if (file != NULL)
{
// WARNING: When reading a file as 'text' file,
// text mode causes carriage return-linefeed translation...
// ...but using fseek() should return correct byte-offset
fseek(file, 0, SEEK_END);
unsigned int size = (unsigned int)ftell(file);
fseek(file, 0, SEEK_SET);
if (size > 0)
{
text = (char *)RL_CALLOC(size + 1, sizeof(char));
if (text != NULL)
{
unsigned int count = (unsigned int)fread(text, sizeof(char), size, file);
// WARNING: \r\n is converted to \n on reading, so,
// read bytes count gets reduced by the number of lines
if (count < size) text = (char *)RL_REALLOC(text, count + 1);
// Zero-terminate the string
text[count] = '\0';
TRACELOG(LOG_INFO, "FILEIO: [%s] Text file loaded successfully", fileName);
}
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to allocated memory for file reading", fileName);
}
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to read text file", fileName);
fclose(file);
}
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open text file", fileName);
#else
TRACELOG(LOG_WARNING, "FILEIO: Standard file io not supported, use custom file callback");
#endif
}
else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid");
return text;
}
// Unload file text data allocated by LoadFileText()
void UnloadFileText(char *text)
{
RL_FREE(text);
}
// Save text data to file (write), string must be '\0' terminated
bool SaveFileText(const char *fileName, const char *text)
{
bool success = false;
if (fileName != NULL)
{
if (saveFileText)
{
return saveFileText(fileName, text);
}
#if defined(SUPPORT_STANDARD_FILEIO)
FILE *file = fopen(fileName, "wt");
if (file != NULL)
{
int count = fprintf(file, "%s", text);
if (count < 0) TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to write text file", fileName);
else TRACELOG(LOG_INFO, "FILEIO: [%s] Text file saved successfully", fileName);
int result = fclose(file);
if (result == 0) success = true;
}
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open text file", fileName);
#else
TRACELOG(LOG_WARNING, "FILEIO: Standard file io not supported, use custom file callback");
#endif
}
else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid");
return success;
}
// File access custom callbacks
// WARNING: Callbacks setup is intended for advanced users
// Set custom file binary data loader
void SetLoadFileDataCallback(LoadFileDataCallback callback)
{
loadFileData = callback;
}
// Set custom file binary data saver
void SetSaveFileDataCallback(SaveFileDataCallback callback)
{
saveFileData = callback;
}
// Set custom file text data loader
void SetLoadFileTextCallback(LoadFileTextCallback callback)
{
loadFileText = callback;
}
// Set custom file text data saver
void SetSaveFileTextCallback(SaveFileTextCallback callback)
{
saveFileText = callback;
}
// Rename file (if exists) // Rename file (if exists)
// NOTE: Only rename file name required, not full path // NOTE: Only rename file name required, not full path
@ -1974,11 +2363,7 @@ bool FileExists(const char *fileName)
{ {
bool result = false; bool result = false;
#if defined(_WIN32) if (ACCESS(fileName) != -1) result = true;
if (_access(fileName, 0) != -1) result = true;
#else
if (access(fileName, F_OK) != -1) result = true;
#endif
// NOTE: Alternatively, stat() can be used instead of access() // NOTE: Alternatively, stat() can be used instead of access()
//#include <sys/stat.h> //#include <sys/stat.h>
@ -3233,14 +3618,23 @@ bool ExportAutomationEventList(AutomationEventList list, const char *fileName)
#if defined(SUPPORT_AUTOMATION_EVENTS) #if defined(SUPPORT_AUTOMATION_EVENTS)
// Export events as binary file // Export events as binary file
// TODO: Save to memory buffer and SaveFileData() // NOTE: Code not used, only for reference if required in the future
/* /*
unsigned char fileId[4] = "rAE "; if (list.count > 0)
FILE *raeFile = fopen(fileName, "wb"); {
fwrite(fileId, sizeof(unsigned char), 4, raeFile); int binarySize = 4 + sizeof(int) + sizeof(AutomationEvent)*list.count;
fwrite(&eventCount, sizeof(int), 1, raeFile); unsigned char *binBuffer = (unsigned char *)RL_CALLOC(binarySize, 1);
fwrite(events, sizeof(AutomationEvent), eventCount, raeFile); int offset = 0;
fclose(raeFile); memcpy(binBuffer + offset, "rAE ", 4);
offset += 4;
memcpy(binBuffer + offset, &list.count, sizeof(int));
offset += sizeof(int);
memcpy(binBuffer + offset, list.events, sizeof(AutomationEvent)*list.count);
offset += sizeof(AutomationEvent)*list.count;
success = SaveFileData(TextFormat("%s.rae",fileName), binBuffer, binarySize);
RL_FREE(binBuffer);
}
*/ */
// Export events as text // Export events as text
@ -3257,7 +3651,7 @@ bool ExportAutomationEventList(AutomationEventList list, const char *fileName)
byteCount += sprintf(txtData + byteCount, "# more info and bugs-report: github.com/raysan5/raylib\n"); byteCount += sprintf(txtData + byteCount, "# more info and bugs-report: github.com/raysan5/raylib\n");
byteCount += sprintf(txtData + byteCount, "# feedback and support: ray[at]raylib.com\n"); byteCount += sprintf(txtData + byteCount, "# feedback and support: ray[at]raylib.com\n");
byteCount += sprintf(txtData + byteCount, "#\n"); byteCount += sprintf(txtData + byteCount, "#\n");
byteCount += sprintf(txtData + byteCount, "# Copyright (c) 2023-2025 Ramon Santamaria (@raysan5)\n"); byteCount += sprintf(txtData + byteCount, "# Copyright (c) 2023-2026 Ramon Santamaria (@raysan5)\n");
byteCount += sprintf(txtData + byteCount, "#\n\n"); byteCount += sprintf(txtData + byteCount, "#\n\n");
// Add events data // Add events data
@ -3828,84 +4222,6 @@ void SetupViewport(int width, int height)
rlLoadIdentity(); // Reset current matrix (modelview) rlLoadIdentity(); // Reset current matrix (modelview)
} }
// Compute framebuffer size relative to screen size and display size
// NOTE: Global variables CORE.Window.render.width/CORE.Window.render.height and CORE.Window.renderOffset.x/CORE.Window.renderOffset.y can be modified
void SetupFramebuffer(int width, int height)
{
// Calculate CORE.Window.render.width and CORE.Window.render.height, we have the display size (input params) and the desired screen size (global var)
if ((CORE.Window.screen.width > CORE.Window.display.width) || (CORE.Window.screen.height > CORE.Window.display.height))
{
TRACELOG(LOG_WARNING, "DISPLAY: Downscaling required: Screen size (%ix%i) is bigger than display size (%ix%i)", CORE.Window.screen.width, CORE.Window.screen.height, CORE.Window.display.width, CORE.Window.display.height);
// Downscaling to fit display with border-bars
float widthRatio = (float)CORE.Window.display.width/(float)CORE.Window.screen.width;
float heightRatio = (float)CORE.Window.display.height/(float)CORE.Window.screen.height;
if (widthRatio <= heightRatio)
{
CORE.Window.render.width = CORE.Window.display.width;
CORE.Window.render.height = (int)round((float)CORE.Window.screen.height*widthRatio);
CORE.Window.renderOffset.x = 0;
CORE.Window.renderOffset.y = (CORE.Window.display.height - CORE.Window.render.height);
}
else
{
CORE.Window.render.width = (int)round((float)CORE.Window.screen.width*heightRatio);
CORE.Window.render.height = CORE.Window.display.height;
CORE.Window.renderOffset.x = (CORE.Window.display.width - CORE.Window.render.width);
CORE.Window.renderOffset.y = 0;
}
// Screen scaling required
float scaleRatio = (float)CORE.Window.render.width/(float)CORE.Window.screen.width;
CORE.Window.screenScale = MatrixScale(scaleRatio, scaleRatio, 1.0f);
// NOTE: We render to full display resolution!
// We just need to calculate above parameters for downscale matrix and offsets
CORE.Window.render.width = CORE.Window.display.width;
CORE.Window.render.height = CORE.Window.display.height;
TRACELOG(LOG_WARNING, "DISPLAY: Downscale matrix generated, content will be rendered at (%ix%i)", CORE.Window.render.width, CORE.Window.render.height);
}
else if ((CORE.Window.screen.width < CORE.Window.display.width) || (CORE.Window.screen.height < CORE.Window.display.height))
{
// Required screen size is smaller than display size
TRACELOG(LOG_INFO, "DISPLAY: Upscaling required: Screen size (%ix%i) smaller than display size (%ix%i)", CORE.Window.screen.width, CORE.Window.screen.height, CORE.Window.display.width, CORE.Window.display.height);
if ((CORE.Window.screen.width == 0) || (CORE.Window.screen.height == 0))
{
CORE.Window.screen.width = CORE.Window.display.width;
CORE.Window.screen.height = CORE.Window.display.height;
}
// Upscaling to fit display with border-bars
float displayRatio = (float)CORE.Window.display.width/(float)CORE.Window.display.height;
float screenRatio = (float)CORE.Window.screen.width/(float)CORE.Window.screen.height;
if (displayRatio <= screenRatio)
{
CORE.Window.render.width = CORE.Window.screen.width;
CORE.Window.render.height = (int)round((float)CORE.Window.screen.width/displayRatio);
CORE.Window.renderOffset.x = 0;
CORE.Window.renderOffset.y = (CORE.Window.render.height - CORE.Window.screen.height);
}
else
{
CORE.Window.render.width = (int)round((float)CORE.Window.screen.height*displayRatio);
CORE.Window.render.height = CORE.Window.screen.height;
CORE.Window.renderOffset.x = (CORE.Window.render.width - CORE.Window.screen.width);
CORE.Window.renderOffset.y = 0;
}
}
else
{
CORE.Window.render.width = CORE.Window.screen.width;
CORE.Window.render.height = CORE.Window.screen.height;
CORE.Window.renderOffset.x = 0;
CORE.Window.renderOffset.y = 0;
}
}
// Scan all files and directories in a base path // Scan all files and directories in a base path
// WARNING: files.paths[] must be previously allocated and // WARNING: files.paths[] must be previously allocated and
// contain enough space to store all required paths // contain enough space to store all required paths
@ -4187,21 +4503,19 @@ static void RecordAutomationEvent(void)
if (currentEventList->count == currentEventList->capacity) return; // Security check if (currentEventList->count == currentEventList->capacity) return; // Security check
// Event type: INPUT_TOUCH_POSITION // Event type: INPUT_TOUCH_POSITION
// TODO: It requires the id! if (((int)CORE.Input.Touch.position[id].x != (int)CORE.Input.Touch.previousPosition[id].x) ||
/* ((int)CORE.Input.Touch.position[id].y != (int)CORE.Input.Touch.previousPosition[id].y))
if (((int)CORE.Input.Touch.currentPosition[id].x != (int)CORE.Input.Touch.previousPosition[id].x) ||
((int)CORE.Input.Touch.currentPosition[id].y != (int)CORE.Input.Touch.previousPosition[id].y))
{ {
currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter; currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter;
currentEventList->events[currentEventList->count].type = INPUT_TOUCH_POSITION; currentEventList->events[currentEventList->count].type = INPUT_TOUCH_POSITION;
currentEventList->events[currentEventList->count].params[0] = id; currentEventList->events[currentEventList->count].params[0] = id;
currentEventList->events[currentEventList->count].params[1] = (int)CORE.Input.Touch.currentPosition[id].x; currentEventList->events[currentEventList->count].params[1] = (int)CORE.Input.Touch.position[id].x;
currentEventList->events[currentEventList->count].params[2] = (int)CORE.Input.Touch.currentPosition[id].y; currentEventList->events[currentEventList->count].params[2] = (int)CORE.Input.Touch.position[id].y;
TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_TOUCH_POSITION | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]); TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_TOUCH_POSITION | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]);
currentEventList->count++; currentEventList->count++;
} }
*/
if (currentEventList->count == currentEventList->capacity) return; // Security check if (currentEventList->count == currentEventList->capacity) return; // Security check
} }

View File

@ -21,7 +21,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2014-2025 Ramon Santamaria (@raysan5) * Copyright (c) 2014-2026 Ramon Santamaria (@raysan5)
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.

View File

@ -7,7 +7,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2017-2025 Ramon Santamaria (@raysan5) * Copyright (c) 2017-2026 Ramon Santamaria (@raysan5)
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.

View File

@ -37,10 +37,6 @@
* If not defined, the library is in header only mode and can be included in other headers * If not defined, the library is in header only mode and can be included in other headers
* or source files without problems. But only ONE file should hold the implementation * or source files without problems. But only ONE file should hold the implementation
* *
* #define RLGL_RENDER_TEXTURES_HINT
* Enable framebuffer objects (fbo) support (enabled by default)
* Some GPUs could not support them despite the OpenGL version
*
* #define RLGL_SHOW_GL_DETAILS_INFO * #define RLGL_SHOW_GL_DETAILS_INFO
* Show OpenGL extensions and capabilities detailed logs on init * Show OpenGL extensions and capabilities detailed logs on init
* *
@ -89,7 +85,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2014-2025 Ramon Santamaria (@raysan5) * Copyright (c) 2014-2026 Ramon Santamaria (@raysan5)
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -132,7 +128,6 @@
// Support TRACELOG macros // Support TRACELOG macros
#ifndef TRACELOG #ifndef TRACELOG
#define TRACELOG(level, ...) (void)0 #define TRACELOG(level, ...) (void)0
#define TRACELOGD(...) (void)0
#endif #endif
// Allow custom memory allocators // Allow custom memory allocators
@ -197,10 +192,6 @@
#define GRAPHICS_API_OPENGL_ES2 #define GRAPHICS_API_OPENGL_ES2
#endif #endif
// Support framebuffer objects by default
// NOTE: Some driver implementation do not support it, despite they should
#define RLGL_RENDER_TEXTURES_HINT
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // Defines and Macros
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -1864,7 +1855,7 @@ void rlDisableShader(void)
// Enable rendering to texture (fbo) // Enable rendering to texture (fbo)
void rlEnableFramebuffer(unsigned int id) void rlEnableFramebuffer(unsigned int id)
{ {
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2))
glBindFramebuffer(GL_FRAMEBUFFER, id); glBindFramebuffer(GL_FRAMEBUFFER, id);
#endif #endif
} }
@ -1873,7 +1864,7 @@ void rlEnableFramebuffer(unsigned int id)
unsigned int rlGetActiveFramebuffer(void) unsigned int rlGetActiveFramebuffer(void)
{ {
GLint fboId = 0; GLint fboId = 0;
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES3)) && defined(RLGL_RENDER_TEXTURES_HINT) #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES3))
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &fboId); glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &fboId);
#endif #endif
return fboId; return fboId;
@ -1882,7 +1873,7 @@ unsigned int rlGetActiveFramebuffer(void)
// Disable rendering to texture // Disable rendering to texture
void rlDisableFramebuffer(void) void rlDisableFramebuffer(void)
{ {
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2))
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
#endif #endif
} }
@ -1890,7 +1881,7 @@ void rlDisableFramebuffer(void)
// Blit active framebuffer to main framebuffer // Blit active framebuffer to main framebuffer
void rlBlitFramebuffer(int srcX, int srcY, int srcWidth, int srcHeight, int dstX, int dstY, int dstWidth, int dstHeight, int bufferMask) void rlBlitFramebuffer(int srcX, int srcY, int srcWidth, int srcHeight, int dstX, int dstY, int dstWidth, int dstHeight, int bufferMask)
{ {
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES3)) && defined(RLGL_RENDER_TEXTURES_HINT) #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES3))
glBlitFramebuffer(srcX, srcY, srcWidth, srcHeight, dstX, dstY, dstWidth, dstHeight, bufferMask, GL_NEAREST); glBlitFramebuffer(srcX, srcY, srcWidth, srcHeight, dstX, dstY, dstWidth, dstHeight, bufferMask, GL_NEAREST);
#endif #endif
} }
@ -1898,7 +1889,7 @@ void rlBlitFramebuffer(int srcX, int srcY, int srcWidth, int srcHeight, int dstX
// Bind framebuffer object (fbo) // Bind framebuffer object (fbo)
void rlBindFramebuffer(unsigned int target, unsigned int framebuffer) void rlBindFramebuffer(unsigned int target, unsigned int framebuffer)
{ {
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2))
glBindFramebuffer(target, framebuffer); glBindFramebuffer(target, framebuffer);
#endif #endif
} }
@ -1907,7 +1898,7 @@ void rlBindFramebuffer(unsigned int target, unsigned int framebuffer)
// NOTE: One color buffer is always active by default // NOTE: One color buffer is always active by default
void rlActiveDrawBuffers(int count) void rlActiveDrawBuffers(int count)
{ {
#if ((defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES3)) && defined(RLGL_RENDER_TEXTURES_HINT)) #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES3))
// NOTE: Maximum number of draw buffers supported is implementation dependant, // NOTE: Maximum number of draw buffers supported is implementation dependant,
// it can be queried with glGet*() but it must be at least 8 // it can be queried with glGet*() but it must be at least 8
//GLint maxDrawBuffers = 0; //GLint maxDrawBuffers = 0;
@ -3324,7 +3315,7 @@ unsigned int rlLoadTexture(const void *data, int width, int height, int format,
unsigned int glInternalFormat, glFormat, glType; unsigned int glInternalFormat, glFormat, glType;
rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType); rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType);
TRACELOGD("TEXTURE: Load mipmap level %i (%i x %i), size: %i, offset: %i", i, mipWidth, mipHeight, mipSize, mipOffset); TRACELOG(RL_LOG_DEBUG, "TEXTURE: Load mipmap level %i (%i x %i), size: %i, offset: %i", i, mipWidth, mipHeight, mipSize, mipOffset);
if (glInternalFormat != 0) if (glInternalFormat != 0)
{ {
@ -3827,7 +3818,7 @@ unsigned int rlLoadFramebuffer(void)
unsigned int fboId = 0; unsigned int fboId = 0;
if (!isGpuReady) { TRACELOG(RL_LOG_WARNING, "GL: GPU is not ready to load data, trying to load before InitWindow()?"); return fboId; } if (!isGpuReady) { TRACELOG(RL_LOG_WARNING, "GL: GPU is not ready to load data, trying to load before InitWindow()?"); return fboId; }
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2))
glGenFramebuffers(1, &fboId); // Create the framebuffer object glGenFramebuffers(1, &fboId); // Create the framebuffer object
glBindFramebuffer(GL_FRAMEBUFFER, 0); // Unbind any framebuffer glBindFramebuffer(GL_FRAMEBUFFER, 0); // Unbind any framebuffer
#endif #endif
@ -3839,7 +3830,7 @@ unsigned int rlLoadFramebuffer(void)
// NOTE: Attach type: 0-Color, 1-Depth renderbuffer, 2-Depth texture // NOTE: Attach type: 0-Color, 1-Depth renderbuffer, 2-Depth texture
void rlFramebufferAttach(unsigned int fboId, unsigned int texId, int attachType, int texType, int mipLevel) void rlFramebufferAttach(unsigned int fboId, unsigned int texId, int attachType, int texType, int mipLevel)
{ {
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2))
glBindFramebuffer(GL_FRAMEBUFFER, fboId); glBindFramebuffer(GL_FRAMEBUFFER, fboId);
switch (attachType) switch (attachType)
@ -3879,7 +3870,7 @@ bool rlFramebufferComplete(unsigned int id)
{ {
bool result = false; bool result = false;
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2))
glBindFramebuffer(GL_FRAMEBUFFER, id); glBindFramebuffer(GL_FRAMEBUFFER, id);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
@ -3910,7 +3901,7 @@ bool rlFramebufferComplete(unsigned int id)
// NOTE: All attached textures/cubemaps/renderbuffers are also deleted // NOTE: All attached textures/cubemaps/renderbuffers are also deleted
void rlUnloadFramebuffer(unsigned int id) void rlUnloadFramebuffer(unsigned int id)
{ {
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2))
// Query depth attachment to automatically delete texture/renderbuffer // Query depth attachment to automatically delete texture/renderbuffer
int depthType = 0, depthId = 0; int depthType = 0, depthId = 0;
glBindFramebuffer(GL_FRAMEBUFFER, id); // Bind framebuffer to query depth texture type glBindFramebuffer(GL_FRAMEBUFFER, id); // Bind framebuffer to query depth texture type
@ -4246,7 +4237,7 @@ unsigned int rlLoadShaderCode(const char *vsCode, const char *fsCode)
glGetActiveUniform(id, i, sizeof(name) - 1, &namelen, &num, &type, name); glGetActiveUniform(id, i, sizeof(name) - 1, &namelen, &num, &type, name);
name[namelen] = 0; name[namelen] = 0;
TRACELOGD("SHADER: [ID %i] Active uniform (%s) set at location: %i", id, name, glGetUniformLocation(id, name)); TRACELOG(RL_LOG_DEBUG, "SHADER: [ID %i] Active uniform (%s) set at location: %i", id, name, glGetUniformLocation(id, name));
} }
} }
*/ */

View File

@ -21,7 +21,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5)
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -42,14 +42,10 @@
#include "raylib.h" // Declares module functions #include "raylib.h" // Declares module functions
// Check if config flags have been externally provided on compilation line
#if !defined(EXTERNAL_CONFIG_FLAGS)
#include "config.h" // Defines module configuration flags #include "config.h" // Defines module configuration flags
#endif
#if defined(SUPPORT_MODULE_RMODELS) #if defined(SUPPORT_MODULE_RMODELS)
#include "utils.h" // Required for: TRACELOG(), LoadFileData(), LoadFileText(), SaveFileText()
#include "rlgl.h" // OpenGL abstraction layer to OpenGL 1.1, 2.1, 3.3+ or ES2 #include "rlgl.h" // OpenGL abstraction layer to OpenGL 1.1, 2.1, 3.3+ or ES2
#include "raymath.h" // Required for: Vector3, Quaternion and Matrix functionality #include "raymath.h" // Required for: Vector3, Quaternion and Matrix functionality
@ -1762,12 +1758,15 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i
instancesVboId = rlLoadVertexBuffer(instanceTransforms, instances*sizeof(float16), false); instancesVboId = rlLoadVertexBuffer(instanceTransforms, instances*sizeof(float16), false);
// Instances transformation matrices are sent to shader attribute location: SHADER_LOC_VERTEX_INSTANCE_TX // Instances transformation matrices are sent to shader attribute location: SHADER_LOC_VERTEX_INSTANCE_TX
if (material.shader.locs[SHADER_LOC_VERTEX_INSTANCE_TX] != -1)
{
for (unsigned int i = 0; i < 4; i++) for (unsigned int i = 0; i < 4; i++)
{ {
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_INSTANCE_TX] + i); rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_INSTANCE_TX] + i);
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_INSTANCE_TX] + i, 4, RL_FLOAT, 0, sizeof(Matrix), i*sizeof(Vector4)); rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_INSTANCE_TX] + i, 4, RL_FLOAT, 0, sizeof(Matrix), i*sizeof(Vector4));
rlSetVertexAttributeDivisor(material.shader.locs[SHADER_LOC_VERTEX_INSTANCE_TX] + i, 1); rlSetVertexAttributeDivisor(material.shader.locs[SHADER_LOC_VERTEX_INSTANCE_TX] + i, 1);
} }
}
rlDisableVertexBuffer(); rlDisableVertexBuffer();
rlDisableVertexArray(); rlDisableVertexArray();
@ -1987,7 +1986,7 @@ bool ExportMesh(Mesh mesh, const char *fileName)
byteCount += sprintf(txtData + byteCount, "# // more info and bugs-report: github.com/raysan5/raylib //\n"); byteCount += sprintf(txtData + byteCount, "# // more info and bugs-report: github.com/raysan5/raylib //\n");
byteCount += sprintf(txtData + byteCount, "# // feedback and support: ray[at]raylib.com //\n"); byteCount += sprintf(txtData + byteCount, "# // feedback and support: ray[at]raylib.com //\n");
byteCount += sprintf(txtData + byteCount, "# // //\n"); byteCount += sprintf(txtData + byteCount, "# // //\n");
byteCount += sprintf(txtData + byteCount, "# // Copyright (c) 2018-2025 Ramon Santamaria (@raysan5) //\n"); byteCount += sprintf(txtData + byteCount, "# // Copyright (c) 2018-2026 Ramon Santamaria (@raysan5) //\n");
byteCount += sprintf(txtData + byteCount, "# // //\n"); byteCount += sprintf(txtData + byteCount, "# // //\n");
byteCount += sprintf(txtData + byteCount, "# //////////////////////////////////////////////////////////////////////////////////\n\n"); byteCount += sprintf(txtData + byteCount, "# //////////////////////////////////////////////////////////////////////////////////\n\n");
byteCount += sprintf(txtData + byteCount, "# Vertex Count: %i\n", mesh.vertexCount); byteCount += sprintf(txtData + byteCount, "# Vertex Count: %i\n", mesh.vertexCount);
@ -6353,7 +6352,7 @@ static bool GetPoseAtTimeGLTF(cgltf_interpolation_type interpolationType, cgltf_
return true; return true;
} }
#define GLTF_ANIMDELAY 17 // Animation frames delay, (~1000 ms/60 FPS = 16.666666* ms) #define GLTF_FRAMERATE 60.0f // glTF animation framerate (frames per second)
static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCount) static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCount)
{ {
@ -6473,13 +6472,13 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo
if (animData.name != NULL) strncpy(animations[i].name, animData.name, sizeof(animations[i].name) - 1); if (animData.name != NULL) strncpy(animations[i].name, animData.name, sizeof(animations[i].name) - 1);
animations[i].frameCount = (int)(animDuration*1000.0f/GLTF_ANIMDELAY) + 1; animations[i].frameCount = (int)(animDuration*GLTF_FRAMERATE) + 1;
animations[i].framePoses = (Transform **)RL_MALLOC(animations[i].frameCount*sizeof(Transform *)); animations[i].framePoses = (Transform **)RL_MALLOC(animations[i].frameCount*sizeof(Transform *));
for (int j = 0; j < animations[i].frameCount; j++) for (int j = 0; j < animations[i].frameCount; j++)
{ {
animations[i].framePoses[j] = (Transform *)RL_MALLOC(animations[i].boneCount*sizeof(Transform)); animations[i].framePoses[j] = (Transform *)RL_MALLOC(animations[i].boneCount*sizeof(Transform));
float time = ((float) j*GLTF_ANIMDELAY)/1000.0f; float time = (float)j / GLTF_FRAMERATE;
for (int k = 0; k < animations[i].boneCount; k++) for (int k = 0; k < animations[i].boneCount; k++)
{ {
@ -7042,8 +7041,8 @@ static ModelAnimation *LoadModelAnimationsM3D(const char *fileName, int *animCou
else TRACELOG(LOG_INFO, "MODEL: [%s] M3D data loaded successfully: %i animations, %i bones, %i skins", fileName, else TRACELOG(LOG_INFO, "MODEL: [%s] M3D data loaded successfully: %i animations, %i bones, %i skins", fileName,
m3d->numaction, m3d->numbone, m3d->numskin); m3d->numaction, m3d->numbone, m3d->numskin);
// No animation or bone+skin? // No animation or bones, exit out. skins are not required because some people use one animation for N models
if (!m3d->numaction || !m3d->numbone || !m3d->numskin) if (!m3d->numaction || !m3d->numbone)
{ {
m3d_free(m3d); m3d_free(m3d);
UnloadFileData(fileData); UnloadFileData(fileData);

View File

@ -25,7 +25,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5)
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -46,10 +46,7 @@
#include "raylib.h" // Declares module functions #include "raylib.h" // Declares module functions
// Check if config flags have been externally provided on compilation line
#if !defined(EXTERNAL_CONFIG_FLAGS)
#include "config.h" // Defines module configuration flags #include "config.h" // Defines module configuration flags
#endif
#if defined(SUPPORT_MODULE_RSHAPES) #if defined(SUPPORT_MODULE_RSHAPES)

View File

@ -34,7 +34,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5)
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -55,14 +55,10 @@
#include "raylib.h" // Declares module functions #include "raylib.h" // Declares module functions
// Check if config flags have been externally provided on compilation line
#if !defined(EXTERNAL_CONFIG_FLAGS)
#include "config.h" // Defines module configuration flags #include "config.h" // Defines module configuration flags
#endif
#if defined(SUPPORT_MODULE_RTEXT) #if defined(SUPPORT_MODULE_RTEXT)
#include "utils.h" // Required for: LoadFile*()
#include "rlgl.h" // OpenGL abstraction layer to OpenGL 1.1, 2.1, 3.3+ or ES2 -> Only DrawTextPro() #include "rlgl.h" // OpenGL abstraction layer to OpenGL 1.1, 2.1, 3.3+ or ES2 -> Only DrawTextPro()
#include <stdlib.h> // Required for: malloc(), free() #include <stdlib.h> // Required for: malloc(), free()
@ -744,13 +740,17 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz
glyphs[k].advanceX = (int)((float)glyphs[k].advanceX*scaleFactor); glyphs[k].advanceX = (int)((float)glyphs[k].advanceX*scaleFactor);
Image imSpace = { Image imSpace = {
.data = RL_CALLOC(glyphs[k].advanceX*fontSize, 2), .data = NULL,
.width = glyphs[k].advanceX, .width = glyphs[k].advanceX,
.height = fontSize, .height = fontSize,
.mipmaps = 1, .mipmaps = 1,
.format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE .format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE
}; };
// Only allocate space image if required
if (glyphs[k].advanceX > 0) imSpace.data = RL_CALLOC(glyphs[k].advanceX*fontSize, 1);
else glyphs[k].advanceX = 0;
glyphs[k].image = imSpace; glyphs[k].image = imSpace;
} }
@ -853,7 +853,8 @@ Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyp
} }
#endif #endif
atlas.data = (unsigned char *)RL_CALLOC(1, atlas.width*atlas.height); // Create a bitmap to store characters (8 bpp) int atlasDataSize = atlas.width*atlas.height; // Save total size for bounds checking
atlas.data = (unsigned char *)RL_CALLOC(atlasDataSize, 1); // Create a bitmap to store characters (8 bpp)
atlas.format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE; atlas.format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE;
atlas.mipmaps = 1; atlas.mipmaps = 1;
@ -898,7 +899,15 @@ Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyp
{ {
for (int x = 0; x < glyphs[i].image.width; x++) for (int x = 0; x < glyphs[i].image.width; x++)
{ {
((unsigned char *)atlas.data)[(offsetY + y)*atlas.width + (offsetX + x)] = ((unsigned char *)glyphs[i].image.data)[y*glyphs[i].image.width + x]; int destX = offsetX + x;
int destY = offsetY + y;
// Security: check both lower and upper bounds
if ((destX >= 0) && (destX < atlas.width) && (destY >= 0) && (destY < atlas.height))
{
((unsigned char *)atlas.data)[destY*atlas.width + destX] =
((unsigned char *)glyphs[i].image.data)[y*glyphs[i].image.width + x];
}
} }
} }
@ -946,7 +955,15 @@ Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyp
{ {
for (int x = 0; x < glyphs[i].image.width; x++) for (int x = 0; x < glyphs[i].image.width; x++)
{ {
((unsigned char *)atlas.data)[(rects[i].y + padding + y)*atlas.width + (rects[i].x + padding + x)] = ((unsigned char *)glyphs[i].image.data)[y*glyphs[i].image.width + x]; int destX = rects[i].x + padding + x;
int destY = rects[i].y + padding + y;
// Security fix: check both lower and upper bounds
if (destX >= 0 && destX < atlas.width && destY >= 0 && destY < atlas.height)
{
((unsigned char *)atlas.data)[destY * atlas.width + destX] =
((unsigned char *)glyphs[i].image.data)[y * glyphs[i].image.width + x];
}
} }
} }
} }
@ -960,8 +977,10 @@ Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyp
#if defined(SUPPORT_FONT_ATLAS_WHITE_REC) #if defined(SUPPORT_FONT_ATLAS_WHITE_REC)
// Add a 3x3 white rectangle at the bottom-right corner of the generated atlas, // Add a 3x3 white rectangle at the bottom-right corner of the generated atlas,
// useful to use as the white texture to draw shapes with raylib, using this rectangle // useful to use as the white texture to draw shapes with raylib
// shapes and text can be backed into a single draw call: SetShapesTexture() // Security: ensure the atlas is large enough to hold a 3x3 rectangle
if ((atlas.width >= 3) && (atlas.height >= 3))
{
for (int i = 0, k = atlas.width*atlas.height - 1; i < 3; i++) for (int i = 0, k = atlas.width*atlas.height - 1; i < 3; i++)
{ {
((unsigned char *)atlas.data)[k - 0] = 255; ((unsigned char *)atlas.data)[k - 0] = 255;
@ -969,6 +988,7 @@ Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyp
((unsigned char *)atlas.data)[k - 2] = 255; ((unsigned char *)atlas.data)[k - 2] = 255;
k -= atlas.width; k -= atlas.width;
} }
}
#endif #endif
// Convert image data from GRAYSCALE to GRAY_ALPHA // Convert image data from GRAYSCALE to GRAY_ALPHA
@ -1011,7 +1031,7 @@ void UnloadFont(Font font)
UnloadTexture(font.texture); UnloadTexture(font.texture);
RL_FREE(font.recs); RL_FREE(font.recs);
TRACELOGD("FONT: Unloaded font data from RAM and VRAM"); TRACELOG(LOG_DEBUG, "FONT: Unloaded font data from RAM and VRAM");
} }
} }
@ -1042,7 +1062,7 @@ bool ExportFontAsCode(Font font, const char *fileName)
byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n"); byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n");
byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n"); byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n");
byteCount += sprintf(txtData + byteCount, "// //\n"); byteCount += sprintf(txtData + byteCount, "// //\n");
byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2018-2025 Ramon Santamaria (@raysan5) //\n"); byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2018-2026 Ramon Santamaria (@raysan5) //\n");
byteCount += sprintf(txtData + byteCount, "// //\n"); byteCount += sprintf(txtData + byteCount, "// //\n");
byteCount += sprintf(txtData + byteCount, "// ---------------------------------------------------------------------------------- //\n"); byteCount += sprintf(txtData + byteCount, "// ---------------------------------------------------------------------------------- //\n");
byteCount += sprintf(txtData + byteCount, "// //\n"); byteCount += sprintf(txtData + byteCount, "// //\n");
@ -1597,14 +1617,13 @@ float TextToFloat(const char *text)
#if defined(SUPPORT_TEXT_MANIPULATION) #if defined(SUPPORT_TEXT_MANIPULATION)
// Copy one string to another, returns bytes copied // Copy one string to another, returns bytes copied
// NOTE: Alternative implementation to strcpy(dst, src) from C standard library
int TextCopy(char *dst, const char *src) int TextCopy(char *dst, const char *src)
{ {
int bytes = 0; int bytes = 0;
if ((src != NULL) && (dst != NULL)) if ((src != NULL) && (dst != NULL))
{ {
// NOTE: Alternative: use strcpy(dst, src)
while (*src != '\0') while (*src != '\0')
{ {
*dst = *src; *dst = *src;
@ -1717,11 +1736,13 @@ char *TextReplace(const char *text, const char *search, const char *replacement)
{ {
char *insertPoint = NULL; // Next insert point char *insertPoint = NULL; // Next insert point
char *temp = NULL; // Temp pointer char *temp = NULL; // Temp pointer
int textLen = 0; // Text string length
int searchLen = 0; // Search string length of (the string to remove) int searchLen = 0; // Search string length of (the string to remove)
int replaceLen = 0; // Replacement length (the string to replace by) int replaceLen = 0; // Replacement length (the string to replace by)
int lastReplacePos = 0; // Distance between next search and end of last replace int lastReplacePos = 0; // Distance between next search and end of last replace
int count = 0; // Number of replacements int count = 0; // Number of replacements
textLen = TextLength(text);
searchLen = TextLength(search); searchLen = TextLength(search);
if (searchLen == 0) return NULL; // Empty search causes infinite loop during count if (searchLen == 0) return NULL; // Empty search causes infinite loop during count
@ -1732,7 +1753,8 @@ char *TextReplace(const char *text, const char *search, const char *replacement)
for (count = 0; (temp = strstr(insertPoint, search)); count++) insertPoint = temp + searchLen; for (count = 0; (temp = strstr(insertPoint, search)); count++) insertPoint = temp + searchLen;
// Allocate returning string and point temp to it // Allocate returning string and point temp to it
temp = result = (char *)RL_MALLOC(TextLength(text) + (replaceLen - searchLen)*count + 1); int tempLen = textLen + (replaceLen - searchLen)*count + 1;
temp = result = (char *)RL_MALLOC(tempLen);
if (!result) return NULL; // Memory could not be allocated if (!result) return NULL; // Memory could not be allocated
@ -1744,13 +1766,23 @@ char *TextReplace(const char *text, const char *search, const char *replacement)
{ {
insertPoint = (char *)strstr(text, search); insertPoint = (char *)strstr(text, search);
lastReplacePos = (int)(insertPoint - text); lastReplacePos = (int)(insertPoint - text);
// TODO: Review logic to avoid strcpy()
// OK - Those lines work
temp = strncpy(temp, text, lastReplacePos) + lastReplacePos; temp = strncpy(temp, text, lastReplacePos) + lastReplacePos;
temp = strcpy(temp, replacement) + replaceLen; temp = strcpy(temp, replacement) + replaceLen;
// WRONG - But not those ones
//temp = strncpy(temp, text, tempLen - 1) + lastReplacePos;
//tempLen -= lastReplacePos;
//temp = strncpy(temp, replacement, tempLen - 1) + replaceLen;
//tempLen -= replaceLen;
text += lastReplacePos + searchLen; // Move to next "end of replace" text += lastReplacePos + searchLen; // Move to next "end of replace"
} }
// Copy remaind text part after replacement to result (pointed by moving temp) // Copy remaind text part after replacement to result (pointed by moving temp)
strcpy(temp, text); strcpy(temp, text); // OK
//strncpy(temp, text, tempLen - 1); // WRONG
} }
return result; return result;
@ -2090,7 +2122,7 @@ int *LoadCodepoints(const char *text, int *count)
int textLength = TextLength(text); int textLength = TextLength(text);
// Allocate a big enough buffer to store as many codepoints as text bytes // Allocate a big enough buffer to store as many codepoints as text bytes
int *codepoints = (int *)RL_CALLOC(textLength, sizeof(int)); codepoints = (int *)RL_CALLOC(textLength, sizeof(int));
int codepointSize = 0; int codepointSize = 0;
for (int i = 0; i < textLength; codepointCount++) for (int i = 0; i < textLength; codepointCount++)

View File

@ -42,7 +42,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) * Copyright (c) 2013-2026 Ramon Santamaria (@raysan5)
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -63,14 +63,10 @@
#include "raylib.h" // Declares module functions #include "raylib.h" // Declares module functions
// Check if config flags have been externally provided on compilation line
#if !defined(EXTERNAL_CONFIG_FLAGS)
#include "config.h" // Defines module configuration flags #include "config.h" // Defines module configuration flags
#endif
#if defined(SUPPORT_MODULE_RTEXTURES) #if defined(SUPPORT_MODULE_RTEXTURES)
#include "utils.h" // Required for: TRACELOG()
#include "rlgl.h" // OpenGL abstraction layer to multiple versions #include "rlgl.h" // OpenGL abstraction layer to multiple versions
#include <stdlib.h> // Required for: malloc(), calloc(), free() #include <stdlib.h> // Required for: malloc(), calloc(), free()
@ -765,7 +761,7 @@ bool ExportImageAsCode(Image image, const char *fileName)
byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n"); byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n");
byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n"); byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n");
byteCount += sprintf(txtData + byteCount, "// //\n"); byteCount += sprintf(txtData + byteCount, "// //\n");
byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2018-2025 Ramon Santamaria (@raysan5) //\n"); byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2018-2026 Ramon Santamaria (@raysan5) //\n");
byteCount += sprintf(txtData + byteCount, "// //\n"); byteCount += sprintf(txtData + byteCount, "// //\n");
byteCount += sprintf(txtData + byteCount, "////////////////////////////////////////////////////////////////////////////////////////\n\n"); byteCount += sprintf(txtData + byteCount, "////////////////////////////////////////////////////////////////////////////////////////\n\n");
@ -2395,7 +2391,7 @@ void ImageMipmaps(Image *image)
if (mipWidth < 1) mipWidth = 1; if (mipWidth < 1) mipWidth = 1;
if (mipHeight < 1) mipHeight = 1; if (mipHeight < 1) mipHeight = 1;
TRACELOGD("IMAGE: Next mipmap level: %i x %i - current size %i", mipWidth, mipHeight, mipSize); TRACELOG(LOG_DEBUG, "IMAGE: Next mipmap level: %i x %i - current size %i", mipWidth, mipHeight, mipSize);
mipCount++; mipCount++;
mipSize += GetPixelDataSize(mipWidth, mipHeight, image->format); // Add mipmap size (in bytes) mipSize += GetPixelDataSize(mipWidth, mipHeight, image->format); // Add mipmap size (in bytes)
@ -2432,7 +2428,7 @@ void ImageMipmaps(Image *image)
if (i < image->mipmaps) continue; if (i < image->mipmaps) continue;
TRACELOGD("IMAGE: Generating mipmap level: %i (%i x %i) - size: %i - offset: 0x%x", i, mipWidth, mipHeight, mipSize, nextmip); TRACELOG(LOG_DEBUG, "IMAGE: Generating mipmap level: %i (%i x %i) - size: %i - offset: 0x%x", i, mipWidth, mipHeight, mipSize, nextmip);
ImageResize(&imCopy, mipWidth, mipHeight); // Uses internally Mitchell cubic downscale filter ImageResize(&imCopy, mipWidth, mipHeight); // Uses internally Mitchell cubic downscale filter
memcpy(nextmip, imCopy.data, mipSize); memcpy(nextmip, imCopy.data, mipSize);
} }

View File

@ -179,7 +179,7 @@ jwE50AGjLCVuS8Yt4H7OgZLKK5EKOsLviEWJSL/+0uMi7gLUSBseYwqEbXvSHCec1CJvZPyHCmYQffaB
<span id='controls'> <span id='controls'>
<span><input type="button" value="📜 SOURCE CODE" onclick="location.href='https://github.com/raysan5/raylib';"/></span> <span><input type="button" value="📜 SOURCE CODE" onclick="location.href='https://github.com/raysan5/raylib';"/></span>
<span><input type="button" value="🖵 FULLSCREEN" onclick="Module.requestFullscreen(false, false)"></span> <span><input type="button" value="🖵 FULLSCREEN" onclick="Module.canvas.requestFullscreen(false, false)"></span>
<span><input type="button" id="btn-audio" value="🔇 MUTE" onclick="toggleAudio()"></span> <span><input type="button" id="btn-audio" value="🔇 MUTE" onclick="toggleAudio()"></span>
</span> </span>

View File

@ -1,509 +0,0 @@
/**********************************************************************************************
*
* raylib.utils - Some common utility functions
*
* CONFIGURATION:
* #define SUPPORT_TRACELOG
* Show TraceLog() output messages
* NOTE: By default LOG_DEBUG traces not shown
*
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2014-2025 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose, including commercial
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not claim that you
* wrote the original software. If you use this software in a product, an acknowledgment
* in the product documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
* as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#include "raylib.h" // WARNING: Required for: LogType enum
// Check if config flags have been externally provided on compilation line
#if !defined(EXTERNAL_CONFIG_FLAGS)
#include "config.h" // Defines module configuration flags
#endif
#include "utils.h"
#if defined(PLATFORM_ANDROID)
#include <errno.h> // Required for: Android error types
#include <android/log.h> // Required for: Android log system: __android_log_vprint()
#include <android/asset_manager.h> // Required for: Android assets manager: AAsset, AAssetManager_open()...
#endif
#include <stdlib.h> // Required for: exit()
#include <stdio.h> // Required for: FILE, fopen(), fseek(), ftell(), fread(), fwrite(), fprintf(), vprintf(), fclose()
#include <stdarg.h> // Required for: va_list, va_start(), va_end()
#include <string.h> // Required for: strcpy(), strcat()
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
#ifndef MAX_TRACELOG_MSG_LENGTH
#define MAX_TRACELOG_MSG_LENGTH 256 // Max length of one trace-log message
#endif
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
static int logTypeLevel = LOG_INFO; // Minimum log type level
static TraceLogCallback traceLog = NULL; // TraceLog callback function pointer
static LoadFileDataCallback loadFileData = NULL; // LoadFileData callback function pointer
static SaveFileDataCallback saveFileData = NULL; // SaveFileText callback function pointer
static LoadFileTextCallback loadFileText = NULL; // LoadFileText callback function pointer
static SaveFileTextCallback saveFileText = NULL; // SaveFileText callback function pointer
//----------------------------------------------------------------------------------
// Functions to set internal callbacks
//----------------------------------------------------------------------------------
void SetTraceLogCallback(TraceLogCallback callback) { traceLog = callback; } // Set custom trace log
void SetLoadFileDataCallback(LoadFileDataCallback callback) { loadFileData = callback; } // Set custom file data loader
void SetSaveFileDataCallback(SaveFileDataCallback callback) { saveFileData = callback; } // Set custom file data saver
void SetLoadFileTextCallback(LoadFileTextCallback callback) { loadFileText = callback; } // Set custom file text loader
void SetSaveFileTextCallback(SaveFileTextCallback callback) { saveFileText = callback; } // Set custom file text saver
#if defined(PLATFORM_ANDROID)
static AAssetManager *assetManager = NULL; // Android assets manager pointer
static const char *internalDataPath = NULL; // Android internal data path
#endif
//----------------------------------------------------------------------------------
// Module Internal Functions Declaration
//----------------------------------------------------------------------------------
#if defined(PLATFORM_ANDROID)
FILE *funopen(const void *cookie, int (*readfn)(void *, char *, int), int (*writefn)(void *, const char *, int),
fpos_t (*seekfn)(void *, fpos_t, int), int (*closefn)(void *));
static int android_read(void *cookie, char *buf, int size);
static int android_write(void *cookie, const char *buf, int size);
static fpos_t android_seek(void *cookie, fpos_t offset, int whence);
static int android_close(void *cookie);
#endif
//----------------------------------------------------------------------------------
// Module Functions Definition
//----------------------------------------------------------------------------------
// Set the current threshold (minimum) log level
void SetTraceLogLevel(int logType) { logTypeLevel = logType; }
// Show trace log messages (LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_DEBUG)
void TraceLog(int logType, const char *text, ...)
{
#if defined(SUPPORT_TRACELOG)
// Message has level below current threshold, don't emit
if ((logType < logTypeLevel) || (text == NULL)) return;
va_list args;
va_start(args, text);
if (traceLog)
{
traceLog(logType, text, args);
va_end(args);
return;
}
#if defined(PLATFORM_ANDROID)
switch (logType)
{
case LOG_TRACE: __android_log_vprint(ANDROID_LOG_VERBOSE, "raylib", text, args); break;
case LOG_DEBUG: __android_log_vprint(ANDROID_LOG_DEBUG, "raylib", text, args); break;
case LOG_INFO: __android_log_vprint(ANDROID_LOG_INFO, "raylib", text, args); break;
case LOG_WARNING: __android_log_vprint(ANDROID_LOG_WARN, "raylib", text, args); break;
case LOG_ERROR: __android_log_vprint(ANDROID_LOG_ERROR, "raylib", text, args); break;
case LOG_FATAL: __android_log_vprint(ANDROID_LOG_FATAL, "raylib", text, args); break;
default: break;
}
#else
char buffer[MAX_TRACELOG_MSG_LENGTH] = { 0 };
switch (logType)
{
case LOG_TRACE: strcpy(buffer, "TRACE: "); break;
case LOG_DEBUG: strcpy(buffer, "DEBUG: "); break;
case LOG_INFO: strcpy(buffer, "INFO: "); break;
case LOG_WARNING: strcpy(buffer, "WARNING: "); break;
case LOG_ERROR: strcpy(buffer, "ERROR: "); break;
case LOG_FATAL: strcpy(buffer, "FATAL: "); break;
default: break;
}
unsigned int textLength = (unsigned int)strlen(text);
memcpy(buffer + strlen(buffer), text, (textLength < (MAX_TRACELOG_MSG_LENGTH - 12))? textLength : (MAX_TRACELOG_MSG_LENGTH - 12));
strcat(buffer, "\n");
vprintf(buffer, args);
fflush(stdout);
#endif
va_end(args);
if (logType == LOG_FATAL) exit(EXIT_FAILURE); // If fatal logging, exit program
#endif // SUPPORT_TRACELOG
}
// Internal memory allocator
// NOTE: Initializes to zero by default
void *MemAlloc(unsigned int size)
{
void *ptr = RL_CALLOC(size, 1);
return ptr;
}
// Internal memory reallocator
void *MemRealloc(void *ptr, unsigned int size)
{
void *ret = RL_REALLOC(ptr, size);
return ret;
}
// Internal memory free
void MemFree(void *ptr)
{
RL_FREE(ptr);
}
// Load data from file into a buffer
unsigned char *LoadFileData(const char *fileName, int *dataSize)
{
unsigned char *data = NULL;
*dataSize = 0;
if (fileName != NULL)
{
if (loadFileData)
{
data = loadFileData(fileName, dataSize);
return data;
}
#if defined(SUPPORT_STANDARD_FILEIO)
FILE *file = fopen(fileName, "rb");
if (file != NULL)
{
// WARNING: On binary streams SEEK_END could not be found,
// using fseek() and ftell() could not work in some (rare) cases
fseek(file, 0, SEEK_END);
int size = ftell(file); // WARNING: ftell() returns 'long int', maximum size returned is INT_MAX (2147483647 bytes)
fseek(file, 0, SEEK_SET);
if (size > 0)
{
data = (unsigned char *)RL_CALLOC(size, sizeof(unsigned char));
if (data != NULL)
{
// NOTE: fread() returns number of read elements instead of bytes, so we read [1 byte, size elements]
size_t count = fread(data, sizeof(unsigned char), size, file);
// WARNING: fread() returns a size_t value, usually 'unsigned int' (32bit compilation) and 'unsigned long long' (64bit compilation)
// dataSize is unified along raylib as a 'int' type, so, for file-sizes > INT_MAX (2147483647 bytes) we have a limitation
if (count > 2147483647)
{
TRACELOG(LOG_WARNING, "FILEIO: [%s] File is bigger than 2147483647 bytes, avoid using LoadFileData()", fileName);
RL_FREE(data);
data = NULL;
}
else
{
*dataSize = (int)count;
if ((*dataSize) != size) TRACELOG(LOG_WARNING, "FILEIO: [%s] File partially loaded (%i bytes out of %i)", fileName, dataSize, count);
else TRACELOG(LOG_INFO, "FILEIO: [%s] File loaded successfully", fileName);
}
}
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to allocated memory for file reading", fileName);
}
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to read file", fileName);
fclose(file);
}
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open file", fileName);
#else
TRACELOG(LOG_WARNING, "FILEIO: Standard file io not supported, use custom file callback");
#endif
}
else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid");
return data;
}
// Unload file data allocated by LoadFileData()
void UnloadFileData(unsigned char *data)
{
RL_FREE(data);
}
// Save data to file from buffer
bool SaveFileData(const char *fileName, void *data, int dataSize)
{
bool success = false;
if (fileName != NULL)
{
if (saveFileData)
{
return saveFileData(fileName, data, dataSize);
}
#if defined(SUPPORT_STANDARD_FILEIO)
FILE *file = fopen(fileName, "wb");
if (file != NULL)
{
// WARNING: fwrite() returns a size_t value, usually 'unsigned int' (32bit compilation) and 'unsigned long long' (64bit compilation)
// and expects a size_t input value but as dataSize is limited to INT_MAX (2147483647 bytes), there shouldn't be a problem
int count = (int)fwrite(data, sizeof(unsigned char), dataSize, file);
if (count == 0) TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to write file", fileName);
else if (count != dataSize) TRACELOG(LOG_WARNING, "FILEIO: [%s] File partially written", fileName);
else TRACELOG(LOG_INFO, "FILEIO: [%s] File saved successfully", fileName);
int result = fclose(file);
if (result == 0) success = true;
}
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open file", fileName);
#else
TRACELOG(LOG_WARNING, "FILEIO: Standard file io not supported, use custom file callback");
#endif
}
else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid");
return success;
}
// Export data to code (.h), returns true on success
bool ExportDataAsCode(const unsigned char *data, int dataSize, const char *fileName)
{
bool success = false;
#ifndef TEXT_BYTES_PER_LINE
#define TEXT_BYTES_PER_LINE 20
#endif
// NOTE: Text data buffer size is estimated considering raw data size in bytes
// and requiring 6 char bytes for every byte: "0x00, "
char *txtData = (char *)RL_CALLOC(dataSize*6 + 2000, sizeof(char));
int byteCount = 0;
byteCount += sprintf(txtData + byteCount, "////////////////////////////////////////////////////////////////////////////////////////\n");
byteCount += sprintf(txtData + byteCount, "// //\n");
byteCount += sprintf(txtData + byteCount, "// DataAsCode exporter v1.0 - Raw data exported as an array of bytes //\n");
byteCount += sprintf(txtData + byteCount, "// //\n");
byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n");
byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n");
byteCount += sprintf(txtData + byteCount, "// //\n");
byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2022-2025 Ramon Santamaria (@raysan5) //\n");
byteCount += sprintf(txtData + byteCount, "// //\n");
byteCount += sprintf(txtData + byteCount, "////////////////////////////////////////////////////////////////////////////////////////\n\n");
// Get file name from path
char varFileName[256] = { 0 };
strncpy(varFileName, GetFileNameWithoutExt(fileName), 256 - 1);
for (int i = 0; varFileName[i] != '\0'; i++)
{
// Convert variable name to uppercase
if ((varFileName[i] >= 'a') && (varFileName[i] <= 'z')) { varFileName[i] = varFileName[i] - 32; }
// Replace non valid character for C identifier with '_'
else if (varFileName[i] == '.' || varFileName[i] == '-' || varFileName[i] == '?' || varFileName[i] == '!' || varFileName[i] == '+') { varFileName[i] = '_'; }
}
byteCount += sprintf(txtData + byteCount, "#define %s_DATA_SIZE %i\n\n", varFileName, dataSize);
byteCount += sprintf(txtData + byteCount, "static unsigned char %s_DATA[%s_DATA_SIZE] = { ", varFileName, varFileName);
for (int i = 0; i < (dataSize - 1); i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "0x%x,\n" : "0x%x, "), data[i]);
byteCount += sprintf(txtData + byteCount, "0x%x };\n", data[dataSize - 1]);
// NOTE: Text data size exported is determined by '\0' (NULL) character
success = SaveFileText(fileName, txtData);
RL_FREE(txtData);
if (success != 0) TRACELOG(LOG_INFO, "FILEIO: [%s] Data as code exported successfully", fileName);
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to export data as code", fileName);
return success;
}
// Load text data from file, returns a '\0' terminated string
// NOTE: text chars array should be freed manually
char *LoadFileText(const char *fileName)
{
char *text = NULL;
if (fileName != NULL)
{
if (loadFileText)
{
text = loadFileText(fileName);
return text;
}
#if defined(SUPPORT_STANDARD_FILEIO)
FILE *file = fopen(fileName, "rt");
if (file != NULL)
{
// WARNING: When reading a file as 'text' file,
// text mode causes carriage return-linefeed translation...
// ...but using fseek() should return correct byte-offset
fseek(file, 0, SEEK_END);
unsigned int size = (unsigned int)ftell(file);
fseek(file, 0, SEEK_SET);
if (size > 0)
{
text = (char *)RL_CALLOC(size + 1, sizeof(char));
if (text != NULL)
{
unsigned int count = (unsigned int)fread(text, sizeof(char), size, file);
// WARNING: \r\n is converted to \n on reading, so,
// read bytes count gets reduced by the number of lines
if (count < size) text = (char *)RL_REALLOC(text, count + 1);
// Zero-terminate the string
text[count] = '\0';
TRACELOG(LOG_INFO, "FILEIO: [%s] Text file loaded successfully", fileName);
}
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to allocated memory for file reading", fileName);
}
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to read text file", fileName);
fclose(file);
}
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open text file", fileName);
#else
TRACELOG(LOG_WARNING, "FILEIO: Standard file io not supported, use custom file callback");
#endif
}
else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid");
return text;
}
// Unload file text data allocated by LoadFileText()
void UnloadFileText(char *text)
{
RL_FREE(text);
}
// Save text data to file (write), string must be '\0' terminated
bool SaveFileText(const char *fileName, const char *text)
{
bool success = false;
if (fileName != NULL)
{
if (saveFileText)
{
return saveFileText(fileName, text);
}
#if defined(SUPPORT_STANDARD_FILEIO)
FILE *file = fopen(fileName, "wt");
if (file != NULL)
{
int count = fprintf(file, "%s", text);
if (count < 0) TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to write text file", fileName);
else TRACELOG(LOG_INFO, "FILEIO: [%s] Text file saved successfully", fileName);
int result = fclose(file);
if (result == 0) success = true;
}
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open text file", fileName);
#else
TRACELOG(LOG_WARNING, "FILEIO: Standard file io not supported, use custom file callback");
#endif
}
else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid");
return success;
}
#if defined(PLATFORM_ANDROID)
// Initialize asset manager from android app
void InitAssetManager(AAssetManager *manager, const char *dataPath)
{
assetManager = manager;
internalDataPath = dataPath;
}
// Replacement for fopen()
// REF: https://developer.android.com/ndk/reference/group/asset
FILE *android_fopen(const char *fileName, const char *mode)
{
if (mode[0] == 'w')
{
// NOTE: fopen() is mapped to android_fopen() that only grants read access to
// assets directory through AAssetManager but we want to also be able to
// write data when required using the standard stdio FILE access functions
// REF: https://stackoverflow.com/questions/11294487/android-writing-saving-files-from-native-code-only
#undef fopen
return fopen(TextFormat("%s/%s", internalDataPath, fileName), mode);
#define fopen(name, mode) android_fopen(name, mode)
}
else
{
// NOTE: AAsset provides access to read-only asset
AAsset *asset = AAssetManager_open(assetManager, fileName, AASSET_MODE_UNKNOWN);
if (asset != NULL)
{
// Get pointer to file in the assets
return funopen(asset, android_read, android_write, android_seek, android_close);
}
else
{
#undef fopen
// Just do a regular open if file is not found in the assets
return fopen(TextFormat("%s/%s", internalDataPath, fileName), mode);
#define fopen(name, mode) android_fopen(name, mode)
}
}
}
#endif // PLATFORM_ANDROID
//----------------------------------------------------------------------------------
// Module Internal Functions Definition
//----------------------------------------------------------------------------------
#if defined(PLATFORM_ANDROID)
static int android_read(void *cookie, char *data, int dataSize)
{
return AAsset_read((AAsset *)cookie, data, dataSize);
}
static int android_write(void *cookie, const char *data, int dataSize)
{
TRACELOG(LOG_WARNING, "ANDROID: Failed to provide write access to APK");
return EACCES;
}
static fpos_t android_seek(void *cookie, fpos_t offset, int whence)
{
return AAsset_seek((AAsset *)cookie, offset, whence);
}
static int android_close(void *cookie)
{
AAsset_close((AAsset *)cookie);
return 0;
}
#endif // PLATFORM_ANDROID

View File

@ -1,81 +0,0 @@
/**********************************************************************************************
*
* raylib.utils - Some common utility functions
*
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2014-2025 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose, including commercial
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not claim that you
* wrote the original software. If you use this software in a product, an acknowledgment
* in the product documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
* as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#ifndef UTILS_H
#define UTILS_H
#if defined(PLATFORM_ANDROID)
#include <stdio.h> // Required for: FILE
#include <android/asset_manager.h> // Required for: AAssetManager
#endif
#if defined(SUPPORT_TRACELOG)
#define TRACELOG(level, ...) TraceLog(level, __VA_ARGS__)
#if defined(SUPPORT_TRACELOG_DEBUG)
#define TRACELOGD(...) TraceLog(LOG_DEBUG, __VA_ARGS__)
#else
#define TRACELOGD(...) (void)0
#endif
#else
#define TRACELOG(level, ...) (void)0
#define TRACELOGD(...) (void)0
#endif
//----------------------------------------------------------------------------------
// Some basic Defines
//----------------------------------------------------------------------------------
#if defined(PLATFORM_ANDROID)
#define fopen(name, mode) android_fopen(name, mode)
#endif
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
//...
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
// Nop...
//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
#if defined(__cplusplus)
extern "C" { // Prevents name mangling of functions
#endif
#if defined(PLATFORM_ANDROID)
void InitAssetManager(AAssetManager *manager, const char *dataPath); // Initialize asset manager from android app
FILE *android_fopen(const char *fileName, const char *mode); // Replacement for fopen() -> Read-only!
#endif
#if defined(__cplusplus)
}
#endif
#endif // UTILS_H

View File

@ -102,4 +102,4 @@ char *TextReplaceBetween(const char *text, const char *begin, const char *end, c
`rexm` is an **open source** project, licensed under an unmodified [zlib/libpng license](LICENSE) `rexm` is an **open source** project, licensed under an unmodified [zlib/libpng license](LICENSE)
*Copyright (c) 2025 Ramon Santamaria ([@raysan5](https://github.com/raysan5))* *Copyright (c) 2025-2026 Ramon Santamaria ([@raysan5](https://github.com/raysan5))*

View File

@ -312,7 +312,6 @@
<ClCompile Include="$(RaylibSrcPath)\rshapes.c" /> <ClCompile Include="$(RaylibSrcPath)\rshapes.c" />
<ClCompile Include="$(RaylibSrcPath)\rtext.c" /> <ClCompile Include="$(RaylibSrcPath)\rtext.c" />
<ClCompile Include="$(RaylibSrcPath)\rtextures.c" /> <ClCompile Include="$(RaylibSrcPath)\rtextures.c" />
<ClCompile Include="$(RaylibSrcPath)\utils.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="$(RaylibSrcPath)\config.h" /> <ClInclude Include="$(RaylibSrcPath)\config.h" />
@ -320,7 +319,6 @@
<ClInclude Include="$(RaylibSrcPath)\raylib.h" /> <ClInclude Include="$(RaylibSrcPath)\raylib.h" />
<ClInclude Include="$(RaylibSrcPath)\raymath.h" /> <ClInclude Include="$(RaylibSrcPath)\raymath.h" />
<ClInclude Include="$(RaylibSrcPath)\rlgl.h" /> <ClInclude Include="$(RaylibSrcPath)\rlgl.h" />
<ClInclude Include="$(RaylibSrcPath)\utils.h" />
<ClInclude Include="$(RaylibSrcPath)\rcamera.h" /> <ClInclude Include="$(RaylibSrcPath)\rcamera.h" />
<ClInclude Include="$(RaylibSrcPath)\external\glad.h" /> <ClInclude Include="$(RaylibSrcPath)\external\glad.h" />
<ClInclude Include="$(RaylibSrcPath)\external\jar_mod.h" /> <ClInclude Include="$(RaylibSrcPath)\external\jar_mod.h" />

View File

@ -8,7 +8,6 @@
<ClCompile Include="$(RaylibSrcPath)\rshapes.c" /> <ClCompile Include="$(RaylibSrcPath)\rshapes.c" />
<ClCompile Include="$(RaylibSrcPath)\rtext.c" /> <ClCompile Include="$(RaylibSrcPath)\rtext.c" />
<ClCompile Include="$(RaylibSrcPath)\rtextures.c" /> <ClCompile Include="$(RaylibSrcPath)\rtextures.c" />
<ClCompile Include="$(RaylibSrcPath)\utils.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="$(RaylibSrcPath)\config.h" /> <ClInclude Include="$(RaylibSrcPath)\config.h" />
@ -16,7 +15,6 @@
<ClInclude Include="$(RaylibSrcPath)\raylib.h" /> <ClInclude Include="$(RaylibSrcPath)\raylib.h" />
<ClInclude Include="$(RaylibSrcPath)\raymath.h" /> <ClInclude Include="$(RaylibSrcPath)\raymath.h" />
<ClInclude Include="$(RaylibSrcPath)\rlgl.h" /> <ClInclude Include="$(RaylibSrcPath)\rlgl.h" />
<ClInclude Include="$(RaylibSrcPath)\utils.h" />
<ClInclude Include="$(RaylibSrcPath)\rcamera.h" /> <ClInclude Include="$(RaylibSrcPath)\rcamera.h" />
<ClInclude Include="$(RaylibSrcPath)\external\cgltf.h"> <ClInclude Include="$(RaylibSrcPath)\external\cgltf.h">
<Filter>external</Filter> <Filter>external</Filter>

View File

@ -21,10 +21,9 @@ Example elements validated:
| **EXAMPLE NAME** | [C] | [CAT]| [INFO]|[PNG]|[WPNG]| [RES]| [MK] |[MKWEB]| [VCX]| [SOL]|[RDME]|[JS] | [WOUT]|[WMETA]| | **EXAMPLE NAME** | [C] | [CAT]| [INFO]|[PNG]|[WPNG]| [RES]| [MK] |[MKWEB]| [VCX]| [SOL]|[RDME]|[JS] | [WOUT]|[WMETA]|
|:---------------------------------|:---:|:----:|:-----:|:---:|:----:|:----:|:----:|:-----:|:----:|:----:|:----:|:---:|:-----:|:-----:| |:---------------------------------|:---:|:----:|:-----:|:---:|:----:|:----:|:----:|:-----:|:----:|:----:|:----:|:---:|:-----:|:-----:|
| core_highdpi_testbed | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_highdpi_testbed | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shaders_game_of_life | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | | rlgl_standalone | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| rlgl_standalone | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | | rlgl_compute_shader | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| rlgl_compute_shader | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | | easings_testbed | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| easings_testbed | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | raylib_opengl_interop | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ |
| raylib_opengl_interop | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ❌ | ✔ | ❌ | ✔ | ✔ | | embedded_files_loading | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| embedded_files_loading | ✔ | ❌ | ❌ | ✔ | ✔ | ❌ | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | | web_basic_window | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| web_basic_window | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |

View File

@ -56,7 +56,7 @@ Example elements validated:
| core_smooth_pixelperfect | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_smooth_pixelperfect | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| core_random_sequence | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_random_sequence | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| core_automation_events | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_automation_events | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| core_high_dpi | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_highdpi_demo | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| core_render_texture | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_render_texture | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| core_undo_redo | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_undo_redo | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| core_viewport_scaling | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_viewport_scaling | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
@ -67,6 +67,7 @@ Example elements validated:
| core_clipboard_text | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_clipboard_text | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| core_text_file_loading | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_text_file_loading | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| core_compute_hash | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_compute_hash | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| core_keyboard_testbed | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shapes_basic_shapes | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_basic_shapes | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shapes_bouncing_ball | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_bouncing_ball | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shapes_bullet_hell | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_bullet_hell | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
@ -105,6 +106,7 @@ Example elements validated:
| shapes_rlgl_triangle | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_rlgl_triangle | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shapes_ball_physics | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_ball_physics | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shapes_penrose_tile | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_penrose_tile | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shapes_hilbert_curve | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| textures_logo_raylib | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_logo_raylib | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| textures_srcrec_dstrec | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_srcrec_dstrec | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| textures_image_drawing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_image_drawing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
@ -134,6 +136,7 @@ Example elements validated:
| textures_textured_curve | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_textured_curve | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| textures_sprite_stacking | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_sprite_stacking | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| textures_cellular_automata | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_cellular_automata | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| textures_framebuffer_rendering | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| text_sprite_fonts | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_sprite_fonts | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| text_font_spritefont | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_font_spritefont | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| text_font_filters | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_font_filters | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
@ -209,7 +212,7 @@ Example elements validated:
| shaders_lightmap_rendering | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_lightmap_rendering | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shaders_rounded_rectangle | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_rounded_rectangle | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shaders_depth_rendering | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_depth_rendering | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| shaders_game_of_life | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | | shaders_game_of_life | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| audio_module_playing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | audio_module_playing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| audio_music_stream | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | audio_music_stream | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| audio_raw_stream | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | audio_raw_stream | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
@ -219,9 +222,9 @@ Example elements validated:
| audio_sound_multi | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | audio_sound_multi | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| audio_sound_positioning | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | audio_sound_positioning | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| audio_spectrum_visualizer | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | audio_spectrum_visualizer | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| rlgl_standalone | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | | rlgl_standalone | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| rlgl_compute_shader | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | | rlgl_compute_shader | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| easings_testbed | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | easings_testbed | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| raylib_opengl_interop | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ❌ | ✔ | ❌ | ✔ | ✔ | | raylib_opengl_interop | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ |
| embedded_files_loading | ✔ | ❌ | ❌ | ✔ | ✔ | ❌ | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | | embedded_files_loading | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| web_basic_window | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | web_basic_window | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |

View File

@ -30,7 +30,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2025 Ramon Santamaria (@raysan5) * Copyright (c) 2025-2026 Ramon Santamaria (@raysan5)
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -207,8 +207,8 @@ static void UpdateSourceMetadata(const char *exSrcPath, const rlExampleInfo *inf
// Update generated Web example .html file metadata // Update generated Web example .html file metadata
static void UpdateWebMetadata(const char *exHtmlPath, const char *exFilePath); static void UpdateWebMetadata(const char *exHtmlPath, const char *exFilePath);
// Check if text string is a list of strings // Check if text string is in a list of strings and get index, -1 if not found
static bool TextInList(const char *text, const char **list, int listCount); static int GetTextListIndex(const char *text, const char **list, int listCount);
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Program main entry point // Program main entry point
@ -570,7 +570,7 @@ int main(int argc, char *argv[])
// ----------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------
// Add example to the collection list, if not already there // Add example to the collection list, if not already there
// NOTE: Required format: shapes;shapes_basic_shapes;★☆☆☆;1.0;4.2;2014;2025;"Ray";@raysan5 // NOTE: Required format: shapes;shapes_basic_shapes;★☆☆☆;1.0;4.2;2014;2026;"Ray";@raysan5
//------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------
char *exCollectionList = LoadFileText(exCollectionFilePath); char *exCollectionList = LoadFileText(exCollectionFilePath);
if (TextFindIndex(exCollectionList, exName) == -1) // Example not found if (TextFindIndex(exCollectionList, exName) == -1) // Example not found
@ -660,7 +660,8 @@ int main(int argc, char *argv[])
// we must store provided file paths because pointers will be overwriten // we must store provided file paths because pointers will be overwriten
// TODO: It seems projects are added to solution BUT not to required solution folder, // TODO: It seems projects are added to solution BUT not to required solution folder,
// that process still requires to be done manually // that process still requires to be done manually
LOG("INFO: [%s] Adding project to raylib solution (.sln)\n", TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exName)); LOG("INFO: [%s] Adding project to raylib solution (.sln)\n",
TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exName));
AddVSProjectToSolution(exVSProjectSolutionFile, AddVSProjectToSolution(exVSProjectSolutionFile,
TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exName), exCategory); TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exName), exCategory);
//------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------
@ -1003,6 +1004,9 @@ int main(int argc, char *argv[])
VALID_INVALID_CATEGORY VALID_INVALID_CATEGORY
*/ */
// Validate and update examples collection list
// NOTE: New .c examples found are added at the end of its category
//---------------------------------------------------------------------------------------------------
// Scan available example .c files and add to collection missing ones // Scan available example .c files and add to collection missing ones
// NOTE: Source of truth is what we have in the examples directories (on validation/update) // NOTE: Source of truth is what we have in the examples directories (on validation/update)
LOG("INFO: Scanning available example (.c) files to be added to collection...\n"); LOG("INFO: Scanning available example (.c) files to be added to collection...\n");
@ -1010,14 +1014,66 @@ int main(int argc, char *argv[])
// Load examples collection list file (raylib/examples/examples_list.txt) // Load examples collection list file (raylib/examples/examples_list.txt)
char *exList = LoadFileText(exCollectionFilePath); char *exList = LoadFileText(exCollectionFilePath);
int exListLen = (int)strlen(exList);
char *exListUpdated = (char *)RL_CALLOC(REXM_MAX_BUFFER_SIZE, 1); char *exListUpdated = (char *)RL_CALLOC(REXM_MAX_BUFFER_SIZE, 1);
bool listUpdated = false; bool listUpdated = false;
int exListLen = (int)strlen(exList); // Add new examples to the collection list if not found
strcpy(exListUpdated, exList); // WARNING: Added to the end of category, order defines place on raylib webpage
for (unsigned int i = 0; i < clist.count; i++)
{
// NOTE: Skipping "examples_template" from checks
if (!TextIsEqual(GetFileNameWithoutExt(clist.paths[i]), "examples_template") &&
(TextFindIndex(exList, GetFileNameWithoutExt(clist.paths[i])) == -1))
{
// Get new example data
rlExampleInfo *exInfo = LoadExampleInfo(clist.paths[i]);
// Copy examples list into an update list // Get example category, -1 if not found in list
// NOTE: Checking and removing duplicate entries int catIndex = GetTextListIndex(exInfo->category, exCategories, REXM_MAX_EXAMPLE_CATEGORIES);
if (catIndex > -1)
{
int nextCatIndex = catIndex + 1;
if (nextCatIndex > (REXM_MAX_EXAMPLE_CATEGORIES - 1)) nextCatIndex = -1; // EOF
// Find position to add new example on list, just before the following category
// Category order: core, shapes, textures, text, models, shaders, audio, [others]
int exListNextCatIndex = -1;
if (nextCatIndex != -1) exListNextCatIndex = TextFindIndex(exList, exCategories[nextCatIndex]);
else exListNextCatIndex = exListLen; // EOF
strncpy(exListUpdated, exList, exListNextCatIndex);
// Get example difficulty stars
char starsText[16] = { 0 };
for (int s = 0; s < 4; s++)
{
// NOTE: Every UTF-8 star are 3 bytes
if (s < exInfo->stars) strcpy(starsText + 3*s, "");
else strcpy(starsText + 3*s, "");
}
// Add new example to the list
int exListNewExLen = sprintf(exListUpdated + exListNextCatIndex,
TextFormat("%s;%s;%s;%s;%s;%i;%i;\"%s\";@%s\n",
exInfo->category, exInfo->name, starsText, exInfo->verCreated,
exInfo->verUpdated, exInfo->yearCreated, exInfo->yearReviewed,
exInfo->author, exInfo->authorGitHub));
// Add the following examples to the end of collection list
strncpy(exListUpdated + exListNextCatIndex + exListNewExLen, exList + exListNextCatIndex, exListLen - exListNextCatIndex);
listUpdated = true;
}
UnloadExampleInfo(exInfo);
}
}
/*
// Check and remove duplicate example entries
int lineCount = 0; int lineCount = 0;
char **exListLines = LoadTextLines(exList, &lineCount); char **exListLines = LoadTextLines(exList, &lineCount);
int exListUpdatedOffset = 0; int exListUpdatedOffset = 0;
@ -1031,46 +1087,7 @@ int main(int argc, char *argv[])
} }
UnloadTextLines(exListLines, lineCount); UnloadTextLines(exListLines, lineCount);
*/
for (unsigned int i = 0; i < clist.count; i++)
{
// NOTE: Skipping "examples_template" from checks
if (!TextIsEqual(GetFileNameWithoutExt(clist.paths[i]), "examples_template") &&
(TextFindIndex(exList, GetFileNameWithoutExt(clist.paths[i])) == -1))
{
// TODO: Examples to be added in the list should be added at the end of their categories,
// not at the end of the file...
// Add example to the examples collection list
// WARNING: Added to the end of the list, order must be set by users and
// defines placement on raylib webpage
rlExampleInfo *exInfo = LoadExampleInfo(clist.paths[i]);
// Validate example category
// TODO: Should [others] category be considered?
if (TextInList(exInfo->category, exCategories, REXM_MAX_EXAMPLE_CATEGORIES))// && !TextIsEqual(exInfo->category, "others"))
{
// Get example difficulty stars
char starsText[16] = { 0 };
for (int s = 0; s < 4; s++)
{
// NOTE: Every UTF-8 star are 3 bytes
if (s < exInfo->stars) strcpy(starsText + 3*s, "");
else strcpy(starsText + 3*s, "");
}
exListLen += sprintf(exListUpdated + exListLen,
TextFormat("%s;%s;%s;%s;%s;%i;%i;\"%s\";@%s\n",
exInfo->category, exInfo->name, starsText, exInfo->verCreated,
exInfo->verUpdated, exInfo->yearCreated, exInfo->yearReviewed,
exInfo->author, exInfo->authorGitHub));
listUpdated = true;
}
UnloadExampleInfo(exInfo);
}
}
if (listUpdated) SaveFileText(exCollectionFilePath, exListUpdated); if (listUpdated) SaveFileText(exCollectionFilePath, exListUpdated);
@ -1078,6 +1095,7 @@ int main(int argc, char *argv[])
RL_FREE(exListUpdated); RL_FREE(exListUpdated);
UnloadDirectoryFiles(clist); UnloadDirectoryFiles(clist);
//---------------------------------------------------------------------------------------------------
// Check all examples in collection [examples_list.txt] -> Source of truth! // Check all examples in collection [examples_list.txt] -> Source of truth!
LOG("INFO: Validating examples in collection...\n"); LOG("INFO: Validating examples in collection...\n");
@ -1226,6 +1244,18 @@ int main(int argc, char *argv[])
// Actions to fix/review anything possible from validation results // Actions to fix/review anything possible from validation results
//------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------
// Update files: Makefile, Makefile.Web, README.md, examples.js
// Solves: VALID_NOT_IN_MAKEFILE, VALID_NOT_IN_MAKEFILE_WEB, VALID_NOT_IN_README, VALID_NOT_IN_JS
// WARNING: Makefile.Web needs to be updated before trying to rebuild web example!
UpdateRequiredFiles();
for (int i = 0; i < exCollectionCount; i++)
{
exCollection[i].status &= ~VALID_NOT_IN_MAKEFILE;
exCollection[i].status &= ~VALID_NOT_IN_MAKEFILE_WEB;
exCollection[i].status &= ~VALID_NOT_IN_README;
exCollection[i].status &= ~VALID_NOT_IN_JS;
}
// Check examples "status" information // Check examples "status" information
for (int i = 0; i < exCollectionCount; i++) for (int i = 0; i < exCollectionCount; i++)
{ {
@ -1325,17 +1355,6 @@ int main(int argc, char *argv[])
} }
} }
} }
// Update files: Makefile, Makefile.Web, README.md, examples.js
// Solves: VALID_NOT_IN_MAKEFILE, VALID_NOT_IN_MAKEFILE_WEB, VALID_NOT_IN_README, VALID_NOT_IN_JS
UpdateRequiredFiles();
for (int i = 0; i < exCollectionCount; i++)
{
exCollection[i].status &= ~VALID_NOT_IN_MAKEFILE;
exCollection[i].status &= ~VALID_NOT_IN_MAKEFILE_WEB;
exCollection[i].status &= ~VALID_NOT_IN_README;
exCollection[i].status &= ~VALID_NOT_IN_JS;
}
//------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------
} }
@ -1591,11 +1610,16 @@ int main(int argc, char *argv[])
FileRemove(TextFormat("%s/%s/%s.original.c", exBasePath, exCategory, exName)); FileRemove(TextFormat("%s/%s/%s.original.c", exBasePath, exCategory, exName));
// STEP 3: Run example on browser // STEP 3: Run example on browser
if (FileExists(TextFormat("%s/%s/%s.html", exBasePath, exCategory, exName)) &&
FileExists(TextFormat("%s/%s/%s.wasm", exBasePath, exCategory, exName)) &&
FileExists(TextFormat("%s/%s/%s.js", exBasePath, exCategory, exName)))
{
// WARNING: Example download is asynchronous so reading fails on next step // WARNING: Example download is asynchronous so reading fails on next step
// when looking for a file that could not have been downloaded yet // when looking for a file that could not have been downloaded yet
ChangeDirectory(TextFormat("%s", exBasePath)); ChangeDirectory(TextFormat("%s", exBasePath));
if (i == 0) system("start python -m http.server 8080"); // Init localhost just once if (i == 0) system("start python -m http.server 8080"); // Init localhost just once
system(TextFormat("start explorer \"http:\\localhost:8080/%s/%s.html", exCategory, exName)); system(TextFormat("start explorer \"http:\\localhost:8080/%s/%s.html", exCategory, exName));
}
// NOTE: Example .log is automatically downloaded into system Downloads directory on browser-example exectution // NOTE: Example .log is automatically downloaded into system Downloads directory on browser-example exectution
@ -1858,7 +1882,7 @@ int main(int argc, char *argv[])
printf("// rexm [raylib examples manager] - A simple command-line tool to manage raylib examples //\n"); printf("// rexm [raylib examples manager] - A simple command-line tool to manage raylib examples //\n");
printf("// powered by raylib v5.6-dev //\n"); printf("// powered by raylib v5.6-dev //\n");
printf("// //\n"); printf("// //\n");
printf("// Copyright (c) 2025 Ramon Santamaria (@raysan5) //\n"); printf("// Copyright (c) 2025-2026 Ramon Santamaria (@raysan5) //\n");
printf("// //\n"); printf("// //\n");
printf("////////////////////////////////////////////////////////////////////////////////////////////\n\n"); printf("////////////////////////////////////////////////////////////////////////////////////////////\n\n");
@ -2417,7 +2441,7 @@ static void UnloadExampleInfo(rlExampleInfo *exInfo)
} }
// raylib example line info parser // raylib example line info parser
// Parses following line format: core;core_basic_window;★☆☆☆;1.0;1.0;2013;2025;"Ray";@raysan5 // Parses following line format: core;core_basic_window;★☆☆☆;1.0;1.0;2013;2026;"Ray";@raysan5
static int ParseExampleInfoLine(const char *line, rlExampleInfo *entry) static int ParseExampleInfoLine(const char *line, rlExampleInfo *entry)
{ {
#define MAX_EXAMPLE_INFO_LINE_LEN 512 #define MAX_EXAMPLE_INFO_LINE_LEN 512
@ -2429,7 +2453,10 @@ static int ParseExampleInfoLine(const char *line, rlExampleInfo *entry)
int tokenCount = 0; int tokenCount = 0;
char **tokens = TextSplit(line, ';', &tokenCount); char **tokens = TextSplit(line, ';', &tokenCount);
if (tokenCount != 9) LOG("REXM: WARNING: Example collection line contains invalid number of tokens: %i\n", tokenCount); if (tokenCount != 9)
{
LOG("REXM: WARNING: Example collection line contains invalid number of tokens: %i\n", tokenCount);
}
// Get category and name // Get category and name
strcpy(entry->category, tokens[0]); strcpy(entry->category, tokens[0]);
@ -2587,7 +2614,7 @@ static int AddVSProjectToSolution(const char *slnFile, const char *projFile, con
int result = 0; int result = 0;
// WARNING: Function uses extensively TextFormat(), // WARNING: Function uses extensively TextFormat(),
// *projFile ptr will be overwriten after a while // *projFile ptr could be overwriten after a while -> Use copied string
// Generate unique UUID // Generate unique UUID
const char *uuid = GenerateUUIDv4(); const char *uuid = GenerateUUIDv4();
@ -2671,14 +2698,22 @@ static int AddVSProjectToSolution(const char *slnFile, const char *projFile, con
// Add project folder line // Add project folder line
// NOTE: Folder uuid depends on category // NOTE: Folder uuid depends on category
if (strcmp(category, "core") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}\n", uuid)); if (strcmp(category, "core") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex,
else if (strcmp(category, "shapes") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s} = {278D8859-20B1-428F-8448-064F46E1F021}\n", uuid)); TextFormat("\t\t{%s} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}\n", uuid));
else if (strcmp(category, "textures") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE}\n", uuid)); else if (strcmp(category, "shapes") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex,
else if (strcmp(category, "text") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A}\n", uuid)); TextFormat("\t\t{%s} = {278D8859-20B1-428F-8448-064F46E1F021}\n", uuid));
else if (strcmp(category, "models") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}\n", uuid)); else if (strcmp(category, "textures") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex,
else if (strcmp(category, "shaders") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9}\n", uuid)); TextFormat("\t\t{%s} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE}\n", uuid));
else if (strcmp(category, "audio") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s} = {CC132A4D-D081-4C26-BFB9-AB11984054F8}\n", uuid)); else if (strcmp(category, "text") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex,
else if (strcmp(category, "other") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s} = {E9D708A5-9C1F-4B84-A795-C5F191801762}\n", uuid)); TextFormat("\t\t{%s} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A}\n", uuid));
else if (strcmp(category, "models") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex,
TextFormat("\t\t{%s} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}\n", uuid));
else if (strcmp(category, "shaders") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex,
TextFormat("\t\t{%s} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9}\n", uuid));
else if (strcmp(category, "audio") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex,
TextFormat("\t\t{%s} = {CC132A4D-D081-4C26-BFB9-AB11984054F8}\n", uuid));
else if (strcmp(category, "other") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex,
TextFormat("\t\t{%s} = {E9D708A5-9C1F-4B84-A795-C5F191801762}\n", uuid));
else LOG("WARNING: Provided category is not valid: %s\n", category); else LOG("WARNING: Provided category is not valid: %s\n", category);
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
@ -2817,7 +2852,7 @@ static void UpdateSourceMetadata(const char *exSrcPath, const rlExampleInfo *inf
if (exTextUpdated[2] != NULL) exTextUpdatedPtr = exTextUpdated[2]; if (exTextUpdated[2] != NULL) exTextUpdatedPtr = exTextUpdated[2];
// Update copyright message // Update copyright message
// String: "* Copyright (c) 2019-2025 Contributor Name (@github_user) and Ramon Santamaria (@raysan5)" // String: "* Copyright (c) 2019-2026 Contributor Name (@github_user) and Ramon Santamaria (@raysan5)"
if (info->yearCreated == info->yearReviewed) if (info->yearCreated == info->yearReviewed)
{ {
exTextUpdated[3] = TextReplaceBetween(exTextUpdatedPtr, "Copyright (c) ", ")", exTextUpdated[3] = TextReplaceBetween(exTextUpdatedPtr, "Copyright (c) ", ")",
@ -2871,8 +2906,8 @@ static void UpdateWebMetadata(const char *exHtmlPath, const char *exFilePath)
// Get example name: replace underscore by spaces // Get example name: replace underscore by spaces
strncpy(exName, GetFileNameWithoutExt(exHtmlPathCopy), 64 - 1); strncpy(exName, GetFileNameWithoutExt(exHtmlPathCopy), 64 - 1);
strncpy(exTitle, exName, 64 - 1); strcpy(exTitle, exName);
for (int i = 0; (i < 256) && (exTitle[i] != '\0'); i++) { if (exTitle[i] == '_') exTitle[i] = ' '; } for (int i = 0; (i < 64) && (exTitle[i] != '\0'); i++) { if (exTitle[i] == '_') exTitle[i] = ' '; }
// Get example category from exName: copy until first underscore // Get example category from exName: copy until first underscore
for (int i = 0; (exName[i] != '_'); i++) exCategory[i] = exName[i]; for (int i = 0; (exName[i] != '_'); i++) exCategory[i] = exName[i];
@ -2912,13 +2947,13 @@ static void UpdateWebMetadata(const char *exHtmlPath, const char *exFilePath)
} }
// Check if text string is a list of strings // Check if text string is a list of strings
static bool TextInList(const char *text, const char **list, int listCount) static int GetTextListIndex(const char *text, const char **list, int listCount)
{ {
bool result = false; int result = -1;
for (int i = 0; i < listCount; i++) for (int i = 0; i < listCount; i++)
{ {
if (TextIsEqual(text, list[i])) { result = true; break; } if (TextIsEqual(text, list[i])) { result = i; break; }
} }
return result; return result;

View File

@ -1,4 +1,4 @@
Copyright (c) 2021-2025 Ramon Santamaria (@raysan5) Copyright (c) 2021-2026 Ramon Santamaria (@raysan5)
This software is provided "as-is", without any express or implied warranty. In no event This software is provided "as-is", without any express or implied warranty. In no event
will the authors be held liable for any damages arising from the use of this software. will the authors be held liable for any damages arising from the use of this software.

View File

@ -19,7 +19,7 @@ Check `rlparser.c` for details about those structs.
// // // //
// more info and bugs-report: github.com/raysan5/raylib/tools/rlparser // // more info and bugs-report: github.com/raysan5/raylib/tools/rlparser //
// // // //
// Copyright (c) 2021-2025 Ramon Santamaria (@raysan5) // // Copyright (c) 2021-2026 Ramon Santamaria (@raysan5) //
// // // //
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////

View File

@ -4191,6 +4191,17 @@
} }
] ]
}, },
{
"name": "SetTraceLogLevel",
"description": "Set the current threshold (minimum) log level",
"returnType": "void",
"params": [
{
"type": "int",
"name": "logLevel"
}
]
},
{ {
"name": "TraceLog", "name": "TraceLog",
"description": "Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...)", "description": "Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...)",
@ -4211,13 +4222,13 @@
] ]
}, },
{ {
"name": "SetTraceLogLevel", "name": "SetTraceLogCallback",
"description": "Set the current threshold (minimum) log level", "description": "Set custom trace log",
"returnType": "void", "returnType": "void",
"params": [ "params": [
{ {
"type": "int", "type": "TraceLogCallback",
"name": "logLevel" "name": "callback"
} }
] ]
}, },
@ -4258,61 +4269,6 @@
} }
] ]
}, },
{
"name": "SetTraceLogCallback",
"description": "Set custom trace log",
"returnType": "void",
"params": [
{
"type": "TraceLogCallback",
"name": "callback"
}
]
},
{
"name": "SetLoadFileDataCallback",
"description": "Set custom file binary data loader",
"returnType": "void",
"params": [
{
"type": "LoadFileDataCallback",
"name": "callback"
}
]
},
{
"name": "SetSaveFileDataCallback",
"description": "Set custom file binary data saver",
"returnType": "void",
"params": [
{
"type": "SaveFileDataCallback",
"name": "callback"
}
]
},
{
"name": "SetLoadFileTextCallback",
"description": "Set custom file text data loader",
"returnType": "void",
"params": [
{
"type": "LoadFileTextCallback",
"name": "callback"
}
]
},
{
"name": "SetSaveFileTextCallback",
"description": "Set custom file text data saver",
"returnType": "void",
"params": [
{
"type": "SaveFileTextCallback",
"name": "callback"
}
]
},
{ {
"name": "LoadFileData", "name": "LoadFileData",
"description": "Load file data as byte array (read)", "description": "Load file data as byte array (read)",
@ -4414,6 +4370,50 @@
} }
] ]
}, },
{
"name": "SetLoadFileDataCallback",
"description": "Set custom file binary data loader",
"returnType": "void",
"params": [
{
"type": "LoadFileDataCallback",
"name": "callback"
}
]
},
{
"name": "SetSaveFileDataCallback",
"description": "Set custom file binary data saver",
"returnType": "void",
"params": [
{
"type": "SaveFileDataCallback",
"name": "callback"
}
]
},
{
"name": "SetLoadFileTextCallback",
"description": "Set custom file text data loader",
"returnType": "void",
"params": [
{
"type": "LoadFileTextCallback",
"name": "callback"
}
]
},
{
"name": "SetSaveFileTextCallback",
"description": "Set custom file text data saver",
"returnType": "void",
"params": [
{
"type": "SaveFileTextCallback",
"name": "callback"
}
]
},
{ {
"name": "FileRename", "name": "FileRename",
"description": "Rename file (if exists)", "description": "Rename file (if exists)",

View File

@ -3864,6 +3864,14 @@ return {
{type = "const char *", name = "url"} {type = "const char *", name = "url"}
} }
}, },
{
name = "SetTraceLogLevel",
description = "Set the current threshold (minimum) log level",
returnType = "void",
params = {
{type = "int", name = "logLevel"}
}
},
{ {
name = "TraceLog", name = "TraceLog",
description = "Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...)", description = "Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...)",
@ -3875,11 +3883,11 @@ return {
} }
}, },
{ {
name = "SetTraceLogLevel", name = "SetTraceLogCallback",
description = "Set the current threshold (minimum) log level", description = "Set custom trace log",
returnType = "void", returnType = "void",
params = { params = {
{type = "int", name = "logLevel"} {type = "TraceLogCallback", name = "callback"}
} }
}, },
{ {
@ -3907,46 +3915,6 @@ return {
{type = "void *", name = "ptr"} {type = "void *", name = "ptr"}
} }
}, },
{
name = "SetTraceLogCallback",
description = "Set custom trace log",
returnType = "void",
params = {
{type = "TraceLogCallback", name = "callback"}
}
},
{
name = "SetLoadFileDataCallback",
description = "Set custom file binary data loader",
returnType = "void",
params = {
{type = "LoadFileDataCallback", name = "callback"}
}
},
{
name = "SetSaveFileDataCallback",
description = "Set custom file binary data saver",
returnType = "void",
params = {
{type = "SaveFileDataCallback", name = "callback"}
}
},
{
name = "SetLoadFileTextCallback",
description = "Set custom file text data loader",
returnType = "void",
params = {
{type = "LoadFileTextCallback", name = "callback"}
}
},
{
name = "SetSaveFileTextCallback",
description = "Set custom file text data saver",
returnType = "void",
params = {
{type = "SaveFileTextCallback", name = "callback"}
}
},
{ {
name = "LoadFileData", name = "LoadFileData",
description = "Load file data as byte array (read)", description = "Load file data as byte array (read)",
@ -4009,6 +3977,38 @@ return {
{type = "const char *", name = "text"} {type = "const char *", name = "text"}
} }
}, },
{
name = "SetLoadFileDataCallback",
description = "Set custom file binary data loader",
returnType = "void",
params = {
{type = "LoadFileDataCallback", name = "callback"}
}
},
{
name = "SetSaveFileDataCallback",
description = "Set custom file binary data saver",
returnType = "void",
params = {
{type = "SaveFileDataCallback", name = "callback"}
}
},
{
name = "SetLoadFileTextCallback",
description = "Set custom file text data loader",
returnType = "void",
params = {
{type = "LoadFileTextCallback", name = "callback"}
}
},
{
name = "SetSaveFileTextCallback",
description = "Set custom file text data saver",
returnType = "void",
params = {
{type = "SaveFileTextCallback", name = "callback"}
}
},
{ {
name = "FileRename", name = "FileRename",
description = "Rename file (if exists)", description = "Rename file (if exists)",

View File

@ -1563,100 +1563,100 @@ Function 106: OpenURL() (1 input parameters)
Return type: void Return type: void
Description: Open URL with default system browser (if available) Description: Open URL with default system browser (if available)
Param[1]: url (type: const char *) Param[1]: url (type: const char *)
Function 107: TraceLog() (3 input parameters) Function 107: SetTraceLogLevel() (1 input parameters)
Name: SetTraceLogLevel
Return type: void
Description: Set the current threshold (minimum) log level
Param[1]: logLevel (type: int)
Function 108: TraceLog() (3 input parameters)
Name: TraceLog Name: TraceLog
Return type: void Return type: void
Description: Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...) Description: Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...)
Param[1]: logLevel (type: int) Param[1]: logLevel (type: int)
Param[2]: text (type: const char *) Param[2]: text (type: const char *)
Param[3]: args (type: ...) Param[3]: args (type: ...)
Function 108: SetTraceLogLevel() (1 input parameters) Function 109: SetTraceLogCallback() (1 input parameters)
Name: SetTraceLogLevel Name: SetTraceLogCallback
Return type: void Return type: void
Description: Set the current threshold (minimum) log level Description: Set custom trace log
Param[1]: logLevel (type: int) Param[1]: callback (type: TraceLogCallback)
Function 109: MemAlloc() (1 input parameters) Function 110: MemAlloc() (1 input parameters)
Name: MemAlloc Name: MemAlloc
Return type: void * Return type: void *
Description: Internal memory allocator Description: Internal memory allocator
Param[1]: size (type: unsigned int) Param[1]: size (type: unsigned int)
Function 110: MemRealloc() (2 input parameters) Function 111: MemRealloc() (2 input parameters)
Name: MemRealloc Name: MemRealloc
Return type: void * Return type: void *
Description: Internal memory reallocator Description: Internal memory reallocator
Param[1]: ptr (type: void *) Param[1]: ptr (type: void *)
Param[2]: size (type: unsigned int) Param[2]: size (type: unsigned int)
Function 111: MemFree() (1 input parameters) Function 112: MemFree() (1 input parameters)
Name: MemFree Name: MemFree
Return type: void Return type: void
Description: Internal memory free Description: Internal memory free
Param[1]: ptr (type: void *) Param[1]: ptr (type: void *)
Function 112: SetTraceLogCallback() (1 input parameters) Function 113: LoadFileData() (2 input parameters)
Name: SetTraceLogCallback
Return type: void
Description: Set custom trace log
Param[1]: callback (type: TraceLogCallback)
Function 113: SetLoadFileDataCallback() (1 input parameters)
Name: SetLoadFileDataCallback
Return type: void
Description: Set custom file binary data loader
Param[1]: callback (type: LoadFileDataCallback)
Function 114: SetSaveFileDataCallback() (1 input parameters)
Name: SetSaveFileDataCallback
Return type: void
Description: Set custom file binary data saver
Param[1]: callback (type: SaveFileDataCallback)
Function 115: SetLoadFileTextCallback() (1 input parameters)
Name: SetLoadFileTextCallback
Return type: void
Description: Set custom file text data loader
Param[1]: callback (type: LoadFileTextCallback)
Function 116: SetSaveFileTextCallback() (1 input parameters)
Name: SetSaveFileTextCallback
Return type: void
Description: Set custom file text data saver
Param[1]: callback (type: SaveFileTextCallback)
Function 117: LoadFileData() (2 input parameters)
Name: LoadFileData Name: LoadFileData
Return type: unsigned char * Return type: unsigned char *
Description: Load file data as byte array (read) Description: Load file data as byte array (read)
Param[1]: fileName (type: const char *) Param[1]: fileName (type: const char *)
Param[2]: dataSize (type: int *) Param[2]: dataSize (type: int *)
Function 118: UnloadFileData() (1 input parameters) Function 114: UnloadFileData() (1 input parameters)
Name: UnloadFileData Name: UnloadFileData
Return type: void Return type: void
Description: Unload file data allocated by LoadFileData() Description: Unload file data allocated by LoadFileData()
Param[1]: data (type: unsigned char *) Param[1]: data (type: unsigned char *)
Function 119: SaveFileData() (3 input parameters) Function 115: SaveFileData() (3 input parameters)
Name: SaveFileData Name: SaveFileData
Return type: bool Return type: bool
Description: Save data to file from byte array (write), returns true on success Description: Save data to file from byte array (write), returns true on success
Param[1]: fileName (type: const char *) Param[1]: fileName (type: const char *)
Param[2]: data (type: void *) Param[2]: data (type: void *)
Param[3]: dataSize (type: int) Param[3]: dataSize (type: int)
Function 120: ExportDataAsCode() (3 input parameters) Function 116: ExportDataAsCode() (3 input parameters)
Name: ExportDataAsCode Name: ExportDataAsCode
Return type: bool Return type: bool
Description: Export data to code (.h), returns true on success Description: Export data to code (.h), returns true on success
Param[1]: data (type: const unsigned char *) Param[1]: data (type: const unsigned char *)
Param[2]: dataSize (type: int) Param[2]: dataSize (type: int)
Param[3]: fileName (type: const char *) Param[3]: fileName (type: const char *)
Function 121: LoadFileText() (1 input parameters) Function 117: LoadFileText() (1 input parameters)
Name: LoadFileText Name: LoadFileText
Return type: char * Return type: char *
Description: Load text data from file (read), returns a '\0' terminated string Description: Load text data from file (read), returns a '\0' terminated string
Param[1]: fileName (type: const char *) Param[1]: fileName (type: const char *)
Function 122: UnloadFileText() (1 input parameters) Function 118: UnloadFileText() (1 input parameters)
Name: UnloadFileText Name: UnloadFileText
Return type: void Return type: void
Description: Unload file text data allocated by LoadFileText() Description: Unload file text data allocated by LoadFileText()
Param[1]: text (type: char *) Param[1]: text (type: char *)
Function 123: SaveFileText() (2 input parameters) Function 119: SaveFileText() (2 input parameters)
Name: SaveFileText Name: SaveFileText
Return type: bool Return type: bool
Description: Save text data to file (write), string must be '\0' terminated, returns true on success Description: Save text data to file (write), string must be '\0' terminated, returns true on success
Param[1]: fileName (type: const char *) Param[1]: fileName (type: const char *)
Param[2]: text (type: const char *) Param[2]: text (type: const char *)
Function 120: SetLoadFileDataCallback() (1 input parameters)
Name: SetLoadFileDataCallback
Return type: void
Description: Set custom file binary data loader
Param[1]: callback (type: LoadFileDataCallback)
Function 121: SetSaveFileDataCallback() (1 input parameters)
Name: SetSaveFileDataCallback
Return type: void
Description: Set custom file binary data saver
Param[1]: callback (type: SaveFileDataCallback)
Function 122: SetLoadFileTextCallback() (1 input parameters)
Name: SetLoadFileTextCallback
Return type: void
Description: Set custom file text data loader
Param[1]: callback (type: LoadFileTextCallback)
Function 123: SetSaveFileTextCallback() (1 input parameters)
Name: SetSaveFileTextCallback
Return type: void
Description: Set custom file text data saver
Param[1]: callback (type: SaveFileTextCallback)
Function 124: FileRename() (2 input parameters) Function 124: FileRename() (2 input parameters)
Name: FileRename Name: FileRename
Return type: int Return type: int

View File

@ -988,13 +988,16 @@
<Function name="OpenURL" retType="void" paramCount="1" desc="Open URL with default system browser (if available)"> <Function name="OpenURL" retType="void" paramCount="1" desc="Open URL with default system browser (if available)">
<Param type="const char *" name="url" desc="" /> <Param type="const char *" name="url" desc="" />
</Function> </Function>
<Function name="SetTraceLogLevel" retType="void" paramCount="1" desc="Set the current threshold (minimum) log level">
<Param type="int" name="logLevel" desc="" />
</Function>
<Function name="TraceLog" retType="void" paramCount="3" desc="Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...)"> <Function name="TraceLog" retType="void" paramCount="3" desc="Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...)">
<Param type="int" name="logLevel" desc="" /> <Param type="int" name="logLevel" desc="" />
<Param type="const char *" name="text" desc="" /> <Param type="const char *" name="text" desc="" />
<Param type="..." name="args" desc="" /> <Param type="..." name="args" desc="" />
</Function> </Function>
<Function name="SetTraceLogLevel" retType="void" paramCount="1" desc="Set the current threshold (minimum) log level"> <Function name="SetTraceLogCallback" retType="void" paramCount="1" desc="Set custom trace log">
<Param type="int" name="logLevel" desc="" /> <Param type="TraceLogCallback" name="callback" desc="" />
</Function> </Function>
<Function name="MemAlloc" retType="void *" paramCount="1" desc="Internal memory allocator"> <Function name="MemAlloc" retType="void *" paramCount="1" desc="Internal memory allocator">
<Param type="unsigned int" name="size" desc="" /> <Param type="unsigned int" name="size" desc="" />
@ -1006,21 +1009,6 @@
<Function name="MemFree" retType="void" paramCount="1" desc="Internal memory free"> <Function name="MemFree" retType="void" paramCount="1" desc="Internal memory free">
<Param type="void *" name="ptr" desc="" /> <Param type="void *" name="ptr" desc="" />
</Function> </Function>
<Function name="SetTraceLogCallback" retType="void" paramCount="1" desc="Set custom trace log">
<Param type="TraceLogCallback" name="callback" desc="" />
</Function>
<Function name="SetLoadFileDataCallback" retType="void" paramCount="1" desc="Set custom file binary data loader">
<Param type="LoadFileDataCallback" name="callback" desc="" />
</Function>
<Function name="SetSaveFileDataCallback" retType="void" paramCount="1" desc="Set custom file binary data saver">
<Param type="SaveFileDataCallback" name="callback" desc="" />
</Function>
<Function name="SetLoadFileTextCallback" retType="void" paramCount="1" desc="Set custom file text data loader">
<Param type="LoadFileTextCallback" name="callback" desc="" />
</Function>
<Function name="SetSaveFileTextCallback" retType="void" paramCount="1" desc="Set custom file text data saver">
<Param type="SaveFileTextCallback" name="callback" desc="" />
</Function>
<Function name="LoadFileData" retType="unsigned char *" paramCount="2" desc="Load file data as byte array (read)"> <Function name="LoadFileData" retType="unsigned char *" paramCount="2" desc="Load file data as byte array (read)">
<Param type="const char *" name="fileName" desc="" /> <Param type="const char *" name="fileName" desc="" />
<Param type="int *" name="dataSize" desc="" /> <Param type="int *" name="dataSize" desc="" />
@ -1048,6 +1036,18 @@
<Param type="const char *" name="fileName" desc="" /> <Param type="const char *" name="fileName" desc="" />
<Param type="const char *" name="text" desc="" /> <Param type="const char *" name="text" desc="" />
</Function> </Function>
<Function name="SetLoadFileDataCallback" retType="void" paramCount="1" desc="Set custom file binary data loader">
<Param type="LoadFileDataCallback" name="callback" desc="" />
</Function>
<Function name="SetSaveFileDataCallback" retType="void" paramCount="1" desc="Set custom file binary data saver">
<Param type="SaveFileDataCallback" name="callback" desc="" />
</Function>
<Function name="SetLoadFileTextCallback" retType="void" paramCount="1" desc="Set custom file text data loader">
<Param type="LoadFileTextCallback" name="callback" desc="" />
</Function>
<Function name="SetSaveFileTextCallback" retType="void" paramCount="1" desc="Set custom file text data saver">
<Param type="SaveFileTextCallback" name="callback" desc="" />
</Function>
<Function name="FileRename" retType="int" paramCount="2" desc="Rename file (if exists)"> <Function name="FileRename" retType="int" paramCount="2" desc="Rename file (if exists)">
<Param type="const char *" name="fileName" desc="" /> <Param type="const char *" name="fileName" desc="" />
<Param type="const char *" name="fileRename" desc="" /> <Param type="const char *" name="fileRename" desc="" />

View File

@ -52,7 +52,7 @@
raylib-parser is licensed under an unmodified zlib/libpng license, which is an OSI-certified, raylib-parser is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
BSD-like license that allows static linking with closed source software: BSD-like license that allows static linking with closed source software:
Copyright (c) 2021-2025 Ramon Santamaria (@raysan5) Copyright (c) 2021-2026 Ramon Santamaria (@raysan5)
**********************************************************************************************/ **********************************************************************************************/
@ -1084,7 +1084,7 @@ static void ShowCommandLineInfo(void)
printf("// //\n"); printf("// //\n");
printf("// more info and bugs-report: github.com/raysan5/raylib/tools/rlparser //\n"); printf("// more info and bugs-report: github.com/raysan5/raylib/tools/rlparser //\n");
printf("// //\n"); printf("// //\n");
printf("// Copyright (c) 2021-2025 Ramon Santamaria (@raysan5) //\n"); printf("// Copyright (c) 2021-2026 Ramon Santamaria (@raysan5) //\n");
printf("// //\n"); printf("// //\n");
printf("//////////////////////////////////////////////////////////////////////////////////\n\n"); printf("//////////////////////////////////////////////////////////////////////////////////\n\n");