diff --git a/.github/workflows/update_examples.yml b/.github/workflows/update_examples.yml index 7feba7d89..c4ada2bd1 100644 --- a/.github/workflows/update_examples.yml +++ b/.github/workflows/update_examples.yml @@ -29,8 +29,9 @@ jobs: shell: bash - name: Build and run rexm tool (requires GNU Makefile) - # "rexm update" validates and updates all required examples in raylib and even raylib.com repos, - # note that it calls examples/Makefile.Web internally, so it requires [make] tool available + # "rexm validate" validates examples collection, looking for inconsistencies, it does not rebuild examples + # "rexm update" validates and updates all examples with inconsistencies, pushing fixes to raylib and raylib.com repos + # note that rexm calls examples/Makefile.Web internally, so it requires [make] tool available run: | sudo apt-get update && sudo apt-get install -y libopengl0 libglu1-mesa libx11-dev libxrandr-dev libxcursor-dev libxi-dev libxinerama-dev libgl1-mesa-dev libglu1-mesa-dev cd "${{ github.workspace }}/src" @@ -47,7 +48,7 @@ jobs: export REXM_EXAMPLES_COLLECTION_FILE_PATH="${{ github.workspace }}/examples/examples_list.txt" export REXM_EXAMPLES_VS2022_SLN_FILE="${{ github.workspace }}/projects/VS2022/raylib.sln" export EMSDK_PATH="${{ github.workspace }}/emsdk-cache/emsdk-main" - ./rexm update + ./rexm validate shell: bash - name: Commit changes to raylib repo (DISABLED) diff --git a/.gitignore b/.gitignore index e5f6faf4d..f7b2cccf6 100644 --- a/.gitignore +++ b/.gitignore @@ -58,6 +58,10 @@ packages/ *.h.pch ./*.obj +# Ignore SDL libs for testing +src/external/SDL2 +src/external/SDL3 + # Emscripten emsdk diff --git a/BINDINGS.md b/BINDINGS.md index 07f590d7d..ee7da46f4 100644 --- a/BINDINGS.md +++ b/BINDINGS.md @@ -76,6 +76,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers | [raylib-rs](https://github.com/raylib-rs/raylib-rs) | **5.5** | [Rust](https://www.rust-lang.org) | Zlib | | [raylib-ruby](https://github.com/wilsonsilva/raylib-ruby) | 4.5 | [Ruby](https://www.ruby-lang.org) | Zlib | | [Relib](https://github.com/RedCubeDev-ByteSpace/Relib) | 3.5 | [ReCT](https://github.com/RedCubeDev-ByteSpace/ReCT) | **???** | +| [ringraylib5](https://github.com/ring-lang/ring/tree/master/extensions/ringraylib5) | **5.0** | [Ring](https://ring-lang.github.io/) | **???** | | [racket-raylib](https://github.com/eutro/racket-raylib) | **5.5** | [Racket](https://racket-lang.org) | MIT/Apache-2.0 | | [raylib-swift](https://github.com/STREGAsGate/Raylib) | 4.0 | [Swift](https://swift.org) | MIT | | [raylib-scopes](https://github.com/salotz/raylib-scopes) | auto | [Scopes](http://scopes.rocks) | MIT | diff --git a/build.zig b/build.zig index 031a6824d..239b10f9e 100644 --- a/build.zig +++ b/build.zig @@ -106,9 +106,9 @@ const config_h_flags = outer: { if (std.mem.startsWith(u8, line, "//")) continue; if (std.mem.startsWith(u8, line, "#if")) continue; - var flag = std.mem.trimLeft(u8, line, " \t"); // Trim whitespace + var flag = std.mem.trimStart(u8, line, " \t"); // Trim whitespace flag = flag["#define ".len - 1 ..]; // Remove #define - flag = std.mem.trimLeft(u8, flag, " \t"); // Trim whitespace + flag = std.mem.trimStart(u8, flag, " \t"); // Trim whitespace flag = flag[0 .. std.mem.indexOf(u8, flag, " ") orelse continue]; // Flag is only one word, so capture till space flag = "-D" ++ flag; // Prepend with -D @@ -155,9 +155,9 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std. ); } - // Sets a flag indiciating the use of a custom `config.h` - try raylib_flags_arr.append(b.allocator, "-DEXTERNAL_CONFIG_FLAGS"); if (options.config.len > 0) { + // Sets a flag indicating the use of a custom `config.h` + try raylib_flags_arr.append(b.allocator, "-DEXTERNAL_CONFIG_FLAGS"); // Splits a space-separated list of config flags into multiple flags // // Note: This means certain flags like `-x c++` won't be processed properly. @@ -187,13 +187,13 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std. try raylib_flags_arr.append(b.allocator, flag); } } else { - // Set default config if no custome config got set + // Set default config if no custom config got set try raylib_flags_arr.appendSlice(b.allocator, &config_h_flags); } // No GLFW required on PLATFORM_DRM if (options.platform != .drm) { - raylib.addIncludePath(b.path("src/external/glfw/include")); + raylib.root_module.addIncludePath(b.path("src/external/glfw/include")); } var c_source_files: std.ArrayList([]const u8) = try .initCapacity(b.allocator, 2); @@ -224,7 +224,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std. raylib.root_module.addCMacro(options.opengl_version.toCMacroStr(), ""); } - raylib.addIncludePath(b.path("src/platforms")); + raylib.root_module.addIncludePath(b.path("src/platforms")); switch (target.result.os.tag) { .windows => { switch (options.platform) { @@ -438,7 +438,7 @@ pub const Options = struct { pub fn getOptions(b: *std.Build) Options { return .{ - .platform = b.option(PlatformBackend, "platform", "Choose the platform backedn for desktop target") orelse defaults.platform, + .platform = b.option(PlatformBackend, "platform", "Choose the platform backend for desktop target") orelse defaults.platform, .raudio = b.option(bool, "raudio", "Compile with audio support") orelse defaults.raudio, .rmodels = b.option(bool, "rmodels", "Compile with models support") orelse defaults.rmodels, .rtext = b.option(bool, "rtext", "Compile with text support") orelse defaults.rtext, diff --git a/examples/Makefile b/examples/Makefile index 48cfba97a..bc2afbb3c 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -531,7 +531,7 @@ CORE = \ core/core_delta_time \ core/core_directory_files \ core/core_drop_files \ - core/core_high_dpi \ + core/core_highdpi_demo \ core/core_highdpi_testbed \ core/core_input_actions \ core/core_input_gamepad \ @@ -583,6 +583,7 @@ SHAPES = \ shapes/shapes_math_angle_rotation \ shapes/shapes_math_sine_cosine \ shapes/shapes_mouse_trail \ + shapes/shapes_penrose_tile \ shapes/shapes_pie_chart \ shapes/shapes_rectangle_advanced \ shapes/shapes_rectangle_scaling \ @@ -602,6 +603,7 @@ TEXTURES = \ textures/textures_background_scrolling \ textures/textures_blend_modes \ textures/textures_bunnymark \ + textures/textures_cellular_automata \ textures/textures_fog_of_war \ textures/textures_gif_player \ textures/textures_image_channel \ @@ -640,6 +642,7 @@ TEXT = \ text/text_input_box \ text/text_rectangle_bounds \ text/text_sprite_fonts \ + text/text_strings_management \ text/text_unicode_emojis \ text/text_unicode_ranges \ text/text_words_alignment \ @@ -685,6 +688,7 @@ SHADERS = \ shaders/shaders_depth_writing \ shaders/shaders_eratosthenes_sieve \ shaders/shaders_fog_rendering \ + shaders/shaders_game_of_life \ shaders/shaders_hot_reloading \ shaders/shaders_hybrid_rendering \ shaders/shaders_julia_set \ diff --git a/examples/Makefile.Android b/examples/Makefile.Android index c00da171e..cf4ad1257 100644 --- a/examples/Makefile.Android +++ b/examples/Makefile.Android @@ -130,7 +130,7 @@ ifeq ($(ANDROID_ARCH),ARM) CFLAGS = -std=c99 -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 endif ifeq ($(ANDROID_ARCH),ARM64) - CFLAGS = -std=c99 -target aarch64 -mfix-cortex-a53-835769 + CFLAGS = -std=c99 -mfix-cortex-a53-835769 endif # Compilation functions attributes options CFLAGS += -ffunction-sections -funwind-tables -fstack-protector-strong -fPIC diff --git a/examples/Makefile.Web b/examples/Makefile.Web index 522b50fe0..f36113f15 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -519,7 +519,7 @@ CORE = \ core/core_delta_time \ core/core_directory_files \ core/core_drop_files \ - core/core_high_dpi \ + core/core_highdpi_demo \ core/core_highdpi_testbed \ core/core_input_actions \ core/core_input_gamepad \ @@ -571,6 +571,7 @@ SHAPES = \ shapes/shapes_math_angle_rotation \ shapes/shapes_math_sine_cosine \ shapes/shapes_mouse_trail \ + shapes/shapes_penrose_tile \ shapes/shapes_pie_chart \ shapes/shapes_rectangle_advanced \ shapes/shapes_rectangle_scaling \ @@ -590,6 +591,7 @@ TEXTURES = \ textures/textures_background_scrolling \ textures/textures_blend_modes \ textures/textures_bunnymark \ + textures/textures_cellular_automata \ textures/textures_fog_of_war \ textures/textures_gif_player \ textures/textures_image_channel \ @@ -628,6 +630,7 @@ TEXT = \ text/text_input_box \ text/text_rectangle_bounds \ text/text_sprite_fonts \ + text/text_strings_management \ text/text_unicode_emojis \ text/text_unicode_ranges \ text/text_words_alignment \ @@ -673,6 +676,7 @@ SHADERS = \ shaders/shaders_depth_writing \ shaders/shaders_eratosthenes_sieve \ shaders/shaders_fog_rendering \ + shaders/shaders_game_of_life \ shaders/shaders_hot_reloading \ shaders/shaders_hybrid_rendering \ shaders/shaders_julia_set \ @@ -779,7 +783,7 @@ core/core_directory_files: core/core_directory_files.c core/core_drop_files: core/core_drop_files.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -core/core_high_dpi: core/core_high_dpi.c +core/core_highdpi_demo: core/core_highdpi_demo.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) core/core_highdpi_testbed: core/core_highdpi_testbed.c @@ -934,6 +938,9 @@ shapes/shapes_math_sine_cosine: shapes/shapes_math_sine_cosine.c shapes/shapes_mouse_trail: shapes/shapes_mouse_trail.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) +shapes/shapes_penrose_tile: shapes/shapes_penrose_tile.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + shapes/shapes_pie_chart: shapes/shapes_pie_chart.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) @@ -992,6 +999,9 @@ textures/textures_bunnymark: textures/textures_bunnymark.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file textures/resources/raybunny.png@resources/raybunny.png +textures/textures_cellular_automata: textures/textures_cellular_automata.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + textures/textures_fog_of_war: textures/textures_fog_of_war.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) @@ -1143,6 +1153,9 @@ text/text_sprite_fonts: text/text_sprite_fonts.c --preload-file text/resources/sprite_fonts/alpha_beta.png@resources/sprite_fonts/alpha_beta.png \ --preload-file text/resources/sprite_fonts/jupiter_crash.png@resources/sprite_fonts/jupiter_crash.png +text/text_strings_management: text/text_strings_management.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + text/text_unicode_emojis: text/text_unicode_emojis.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file text/resources/dejavu.fnt@resources/dejavu.fnt \ @@ -1351,6 +1364,19 @@ shaders/shaders_fog_rendering: shaders/shaders_fog_rendering.c --preload-file shaders/resources/shaders/glsl100/lighting.vs@resources/shaders/glsl100/lighting.vs \ --preload-file shaders/resources/shaders/glsl100/fog.fs@resources/shaders/glsl100/fog.fs +shaders/shaders_game_of_life: shaders/shaders_game_of_life.c + $(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/game_of_life/acorn.png@resources/game_of_life/acorn.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_gun.png@resources/game_of_life/glider_gun.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/r_pentomino.png@resources/game_of_life/r_pentomino.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 + shaders/shaders_hot_reloading: shaders/shaders_hot_reloading.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file shaders/resources/shaders/glsl100/reload.fs@resources/shaders/glsl100/reload.fs diff --git a/examples/README.md b/examples/README.md index 148caffe0..367bfa0ab 100644 --- a/examples/README.md +++ b/examples/README.md @@ -17,7 +17,7 @@ You may find it easier to use than other toolchains, especially when it comes to - `zig build [module]` to compile all examples for a module (e.g. `zig build core`) - `zig build [example]` to compile _and run_ a particular example (e.g. `zig build core_basic_window`) -## EXAMPLES COLLECTION [TOTAL: 201] +## EXAMPLES COLLECTION [TOTAL: 205] ### category: core [47] @@ -61,7 +61,7 @@ Examples using raylib [core](../src/rcore.c) module platform functionality: wind | [core_smooth_pixelperfect](core/core_smooth_pixelperfect.c) | core_smooth_pixelperfect | ⭐⭐⭐☆ | 3.7 | 4.0 | [Giancamillo Alessandroni](https://github.com/NotManyIdeasDev) | | [core_random_sequence](core/core_random_sequence.c) | core_random_sequence | ⭐☆☆☆ | 5.0 | 5.0 | [Dalton Overmyer](https://github.com/REDl3east) | | [core_automation_events](core/core_automation_events.c) | core_automation_events | ⭐⭐⭐☆ | 5.0 | 5.0 | [Ramon Santamaria](https://github.com/raysan5) | -| [core_high_dpi](core/core_high_dpi.c) | core_high_dpi | ⭐⭐☆☆ | 5.0 | 5.5 | [Jonathan Marler](https://github.com/marler8997) | +| [core_highdpi_demo](core/core_highdpi_demo.c) | core_highdpi_demo | ⭐⭐☆☆ | 5.0 | 5.5 | [Jonathan Marler](https://github.com/marler8997) | | [core_render_texture](core/core_render_texture.c) | core_render_texture | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) | | [core_undo_redo](core/core_undo_redo.c) | core_undo_redo | ⭐⭐⭐☆ | 5.5 | 5.6 | [Ramon Santamaria](https://github.com/raysan5) | | [core_viewport_scaling](core/core_viewport_scaling.c) | core_viewport_scaling | ⭐⭐☆☆ | 5.5 | 5.5 | [Agnis Aldiņš](https://github.com/nezvers) | @@ -73,7 +73,7 @@ Examples using raylib [core](../src/rcore.c) module platform functionality: wind | [core_text_file_loading](core/core_text_file_loading.c) | core_text_file_loading | ⭐☆☆☆ | 5.5 | 5.6 | [Aanjishnu Bhattacharyya](https://github.com/NimComPoo-04) | | [core_compute_hash](core/core_compute_hash.c) | core_compute_hash | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) | -### category: shapes [37] +### category: shapes [38] Examples using raylib shapes drawing functionality, provided by raylib [shapes](../src/rshapes.c) module. @@ -116,8 +116,9 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes]( | [shapes_rlgl_color_wheel](shapes/shapes_rlgl_color_wheel.c) | shapes_rlgl_color_wheel | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [Robin](https://github.com/RobinsAviary) | | [shapes_rlgl_triangle](shapes/shapes_rlgl_triangle.c) | shapes_rlgl_triangle | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Robin](https://github.com/RobinsAviary) | | [shapes_ball_physics](shapes/shapes_ball_physics.c) | shapes_ball_physics | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [David Buzatto](https://github.com/davidbuzatto) | +| [shapes_penrose_tile](shapes/shapes_penrose_tile.c) | shapes_penrose_tile | ⭐⭐⭐⭐️ | 5.5 | 5.6-dev | [David Buzatto](https://github.com/davidbuzatto) | -### category: textures [28] +### category: textures [29] Examples using raylib textures functionality, including image/textures loading/generation and drawing, provided by raylib [textures](../src/rtextures.c) module. @@ -151,8 +152,9 @@ Examples using raylib textures functionality, including image/textures loading/g | [textures_screen_buffer](textures/textures_screen_buffer.c) | textures_screen_buffer | ⭐⭐☆☆ | 5.5 | 5.5 | [Agnis Aldiņš](https://github.com/nezvers) | | [textures_textured_curve](textures/textures_textured_curve.c) | textures_textured_curve | ⭐⭐⭐☆ | 4.5 | 4.5 | [Jeffery Myers](https://github.com/JeffM2501) | | [textures_sprite_stacking](textures/textures_sprite_stacking.c) | textures_sprite_stacking | ⭐⭐☆☆ | 5.6-dev | 6.0 | [Robin](https://github.com/RobinsAviary) | +| [textures_cellular_automata](textures/textures_cellular_automata.c) | textures_cellular_automata | ⭐⭐☆☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) | -### category: text [15] +### category: text [16] Examples using raylib text functionality, including sprite fonts loading/generation and text drawing, provided by raylib [text](../src/rtext.c) module. @@ -173,6 +175,7 @@ Examples using raylib text functionality, including sprite fonts loading/generat | [text_codepoints_loading](text/text_codepoints_loading.c) | text_codepoints_loading | ⭐⭐⭐☆ | 4.2 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) | | [text_inline_styling](text/text_inline_styling.c) | text_inline_styling | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [Wagner Barongello](https://github.com/SultansOfCode) | | [text_words_alignment](text/text_words_alignment.c) | text_words_alignment | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) | +| [text_strings_management](text/text_strings_management.c) | text_strings_management | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [David Buzatto](https://github.com/davidbuzatto) | ### category: models [27] @@ -208,7 +211,7 @@ Examples using raylib models functionality, including models loading/generation | [models_decals](models/models_decals.c) | models_decals | ⭐⭐⭐⭐️ | 5.6-dev | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) | | [models_directional_billboard](models/models_directional_billboard.c) | models_directional_billboard | ⭐⭐☆☆ | 5.6-dev | 5.6 | [Robin](https://github.com/RobinsAviary) | -### category: shaders [32] +### category: shaders [33] Examples using raylib shaders functionality, including shaders loading, parameters configuration and drawing using them (model shaders and postprocessing shaders). This functionality is directly provided by raylib [rlgl](../src/rlgl.c) module. @@ -246,6 +249,7 @@ Examples using raylib shaders functionality, including shaders loading, paramete | [shaders_lightmap_rendering](shaders/shaders_lightmap_rendering.c) | shaders_lightmap_rendering | ⭐⭐⭐☆ | 4.5 | 4.5 | [Jussi Viitala](https://github.com/nullstare) | | [shaders_rounded_rectangle](shaders/shaders_rounded_rectangle.c) | shaders_rounded_rectangle | ⭐⭐⭐☆ | 5.5 | 5.5 | [Anstro Pleuton](https://github.com/anstropleuton) | | [shaders_depth_rendering](shaders/shaders_depth_rendering.c) | shaders_depth_rendering | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [Luís Almeida](https://github.com/luis605) | +| [shaders_game_of_life](shaders/shaders_game_of_life.c) | shaders_game_of_life | ⭐⭐⭐☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) | ### category: audio [9] diff --git a/examples/core/core_2d_camera.c b/examples/core/core_2d_camera.c index b752a9640..7e5a14a70 100644 --- a/examples/core/core_2d_camera.c +++ b/examples/core/core_2d_camera.c @@ -125,8 +125,8 @@ int main(void) DrawRectangle( 10, 10, 250, 113, Fade(SKYBLUE, 0.5f)); DrawRectangleLines( 10, 10, 250, 113, BLUE); - DrawText("Free 2d camera controls:", 20, 20, 10, BLACK); - DrawText("- Right/Left to move Offset", 40, 40, 10, DARKGRAY); + DrawText("Free 2D camera controls:", 20, 20, 10, BLACK); + DrawText("- Right/Left to move player", 40, 40, 10, DARKGRAY); DrawText("- Mouse Wheel to Zoom in-out", 40, 60, 10, DARKGRAY); DrawText("- A / S to Rotate", 40, 80, 10, DARKGRAY); DrawText("- R to reset Zoom and Rotation", 40, 100, 10, DARKGRAY); diff --git a/examples/core/core_2d_camera.png b/examples/core/core_2d_camera.png index d2f9e634f..a0fdabb49 100644 Binary files a/examples/core/core_2d_camera.png and b/examples/core/core_2d_camera.png differ diff --git a/examples/core/core_clipboard_text.c b/examples/core/core_clipboard_text.c index 2f8e5712b..59de6509c 100644 --- a/examples/core/core_clipboard_text.c +++ b/examples/core/core_clipboard_text.c @@ -2,6 +2,8 @@ * * raylib [core] example - clipboard text * +* Example complexity rating: [★★☆☆] 2/4 +* * Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev * * Example contributed by Ananth S (@Ananth1839) and reviewed by Ramon Santamaria (@raysan5) diff --git a/examples/core/core_high_dpi.c b/examples/core/core_highdpi_demo.c similarity index 98% rename from examples/core/core_high_dpi.c rename to examples/core/core_highdpi_demo.c index 312f0c3e2..b1f706d98 100644 --- a/examples/core/core_high_dpi.c +++ b/examples/core/core_highdpi_demo.c @@ -1,6 +1,6 @@ /******************************************************************************************* * -* raylib [core] example - high dpi +* raylib [core] example - highdpi demo * * Example complexity rating: [★★☆☆] 2/4 * @@ -33,7 +33,7 @@ int main(void) const int screenHeight = 450; SetConfigFlags(FLAG_WINDOW_HIGHDPI | FLAG_WINDOW_RESIZABLE); - InitWindow(screenWidth, screenHeight, "raylib [core] example - high dpi"); + InitWindow(screenWidth, screenHeight, "raylib [core] example - highdpi demo"); SetWindowMinSize(450, 450); int logicalGridDescY = 120; diff --git a/examples/core/core_high_dpi.png b/examples/core/core_highdpi_demo.png similarity index 100% rename from examples/core/core_high_dpi.png rename to examples/core/core_highdpi_demo.png diff --git a/examples/core/core_highdpi_testbed.c b/examples/core/core_highdpi_testbed.c index a341d081c..6a036bbfc 100644 --- a/examples/core/core_highdpi_testbed.c +++ b/examples/core/core_highdpi_testbed.c @@ -30,6 +30,10 @@ int main(void) SetConfigFlags(FLAG_WINDOW_HIGHDPI | FLAG_WINDOW_RESIZABLE); InitWindow(screenWidth, screenHeight, "raylib [core] example - highdpi testbed"); + Vector2 scaleDpi = GetWindowScaleDPI(); + Vector2 mousePos = GetMousePosition(); + int currentMonitor = GetCurrentMonitor(); + int gridSpacing = 40; // Grid spacing in pixels SetTargetFPS(60); @@ -40,7 +44,11 @@ int main(void) { // Update //---------------------------------------------------------------------------------- - // TODO: Update variables / Implement example logic at this point + mousePos = GetMousePosition(); + currentMonitor = GetCurrentMonitor(); + scaleDpi = GetWindowScaleDPI(); + + if (IsKeyPressed(KEY_SPACE)) ToggleBorderlessWindowed(); //---------------------------------------------------------------------------------- // Draw @@ -50,11 +58,30 @@ int main(void) ClearBackground(RAYWHITE); // Draw grid - for (int h = 0; h < 20; h++) DrawLine(0, h*gridSpacing, GetRenderWidth(), h*gridSpacing, LIGHTGRAY); - for (int v = 0; v < 40; v++) DrawLine(v*gridSpacing, 0, v*gridSpacing, GetScreenHeight(), LIGHTGRAY); + for (int h = 0; h < 20; h++) + { + DrawText(TextFormat("%02i", h*gridSpacing), 4, h*gridSpacing - 4, 10, GRAY); + DrawLine(24, h*gridSpacing, GetScreenWidth(), h*gridSpacing, LIGHTGRAY); + } + for (int v = 0; v < 40; v++) + { + DrawText(TextFormat("%02i", v*gridSpacing), v*gridSpacing - 10, 4, 10, GRAY); + DrawLine(v*gridSpacing, 20, v*gridSpacing, GetScreenHeight(), LIGHTGRAY); + } // Draw UI info - DrawText(TextFormat("SCREEN SIZE: %ix%i", GetScreenWidth(), GetScreenHeight()), 10, 10, 20, BLACK); + DrawText(TextFormat("CURRENT MONITOR: %i/%i (%ix%i)", currentMonitor + 1, GetMonitorCount(), + GetMonitorWidth(currentMonitor), GetMonitorHeight(currentMonitor)), 50, 50, 20, DARKGRAY); + DrawText(TextFormat("SCREEN SIZE: %ix%i", GetScreenWidth(), GetScreenHeight()), 50, 90, 20, DARKGRAY); + DrawText(TextFormat("RENDER SIZE: %ix%i", GetRenderWidth(), GetRenderHeight()), 50, 130, 20, DARKGRAY); + DrawText(TextFormat("SCALE FACTOR: %.1fx%.1f", scaleDpi.x, scaleDpi.y), 50, 170, 20, GRAY); + + // Draw mouse position + DrawCircleV(GetMousePosition(), 20, MAROON); + DrawRectangle(mousePos.x - 25, mousePos.y, 50, 2, BLACK); + DrawRectangle(mousePos.x, mousePos.y - 25, 2, 50, BLACK); + DrawText(TextFormat("[%i,%i]", GetMouseX(), GetMouseY()), mousePos.x - 44, + (mousePos.y > GetScreenHeight() - 60)? mousePos.y - 46 : mousePos.y + 30, 20, BLACK); EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/examples/examples_list.txt b/examples/examples_list.txt index 2373fcc9b..3310cf2d2 100644 --- a/examples/examples_list.txt +++ b/examples/examples_list.txt @@ -43,7 +43,7 @@ core;core_custom_frame_control;★★★★;4.0;4.0;2021;2025;"Ramon Santamaria" core;core_smooth_pixelperfect;★★★☆;3.7;4.0;2021;2025;"Giancamillo Alessandroni";@NotManyIdeasDev core;core_random_sequence;★☆☆☆;5.0;5.0;2023;2025;"Dalton Overmyer";@REDl3east core;core_automation_events;★★★☆;5.0;5.0;2023;2025;"Ramon Santamaria";@raysan5 -core;core_high_dpi;★★☆☆;5.0;5.5;2025;2025;"Jonathan Marler";@marler8997 +core;core_highdpi_demo;★★☆☆;5.0;5.5;2025;2025;"Jonathan Marler";@marler8997 core;core_render_texture;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5 core;core_undo_redo;★★★☆;5.5;5.6;2025;2025;"Ramon Santamaria";@raysan5 core;core_viewport_scaling;★★☆☆;5.5;5.5;2025;2025;"Agnis Aldiņš";@nezvers @@ -51,7 +51,7 @@ core;core_input_actions;★★☆☆;5.5;5.6;2025;2025;"Jett";@JettMonstersGoBoo core;core_directory_files;★☆☆☆;5.5;5.6;2025;2025;"Hugo ARNAL";@hugoarnal core;core_highdpi_testbed;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5 core;core_screen_recording;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5 -core;core_clipboard_text;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"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_compute_hash;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5 shapes;shapes_basic_shapes;★☆☆☆;1.0;4.2;2014;2025;"Ramon Santamaria";@raysan5 @@ -91,6 +91,7 @@ shapes;shapes_math_angle_rotation;★☆☆☆;5.6-dev;5.6;2025;2025;"Kris";@kri shapes;shapes_rlgl_color_wheel;★★★☆;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_penrose_tile;★★★★;5.5;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto textures;textures_logo_raylib;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5 textures;textures_srcrec_dstrec;★★★☆;1.3;1.3;2015;2025;"Ramon Santamaria";@raysan5 textures;textures_image_drawing;★★☆☆;1.4;1.4;2016;2025;"Ramon Santamaria";@raysan5 @@ -119,6 +120,7 @@ textures;textures_image_rotate;★★☆☆;1.0;1.0;2014;2025;"Ramon Santamaria" textures;textures_screen_buffer;★★☆☆;5.5;5.5;2025;2025;"Agnis Aldiņš";@nezvers 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_cellular_automata;★★☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant 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_filters;★★☆☆;1.3;4.2;2015;2025;"Ramon Santamaria";@raysan5 @@ -134,6 +136,7 @@ text;text_3d_drawing;★★★★;3.5;4.0;2021;2025;"Vlad Adrian";@demizdor text;text_codepoints_loading;★★★☆;4.2;4.2;2022;2025;"Ramon Santamaria";@raysan5 text;text_inline_styling;★★★☆;5.6-dev;5.6-dev;2025;2025;"Wagner Barongello";@SultansOfCode text;text_words_alignment;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates +text;text_strings_management;★★★☆;5.6-dev;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto models;models_animation_playing;★★☆☆;2.5;3.5;2019;2025;"Culacant";@culacant models;models_billboard_rendering;★★★☆;1.3;3.5;2015;2025;"Ramon Santamaria";@raysan5 models;models_box_collisions;★☆☆☆;1.3;3.5;2015;2025;"Ramon Santamaria";@raysan5 @@ -193,6 +196,7 @@ shaders;shaders_basic_pbr;★★★★;5.0;5.5;2023;2025;"Afan OLOVCIC";@_DevDad shaders;shaders_lightmap_rendering;★★★☆;4.5;4.5;2019;2025;"Jussi Viitala";@nullstare shaders;shaders_rounded_rectangle;★★★☆;5.5;5.5;2025;2025;"Anstro Pleuton";@anstropleuton shaders;shaders_depth_rendering;★★★☆;5.6-dev;5.6-dev;2025;2025;"Luís Almeida";@luis605 +shaders;shaders_game_of_life;★★★☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant audio;audio_module_playing;★☆☆☆;1.5;3.5;2016;2025;"Ramon Santamaria";@raysan5 audio;audio_music_stream;★☆☆☆;1.3;4.2;2015;2025;"Ramon Santamaria";@raysan5 audio;audio_raw_stream;★★★☆;1.6;4.2;2015;2025;"Ramon Santamaria";@raysan5 diff --git a/examples/shaders/resources/game_of_life/acorn.png b/examples/shaders/resources/game_of_life/acorn.png new file mode 100644 index 000000000..58ea0b4d1 Binary files /dev/null and b/examples/shaders/resources/game_of_life/acorn.png differ diff --git a/examples/shaders/resources/game_of_life/breeder.png b/examples/shaders/resources/game_of_life/breeder.png new file mode 100644 index 000000000..88aa073d3 Binary files /dev/null and b/examples/shaders/resources/game_of_life/breeder.png differ diff --git a/examples/shaders/resources/game_of_life/glider.png b/examples/shaders/resources/game_of_life/glider.png new file mode 100644 index 000000000..921adb8ed Binary files /dev/null and b/examples/shaders/resources/game_of_life/glider.png differ diff --git a/examples/shaders/resources/game_of_life/glider_gun.png b/examples/shaders/resources/game_of_life/glider_gun.png new file mode 100644 index 000000000..29b65d3de Binary files /dev/null and b/examples/shaders/resources/game_of_life/glider_gun.png differ diff --git a/examples/shaders/resources/game_of_life/oscillators.png b/examples/shaders/resources/game_of_life/oscillators.png new file mode 100644 index 000000000..badd6a92d Binary files /dev/null and b/examples/shaders/resources/game_of_life/oscillators.png differ diff --git a/examples/shaders/resources/game_of_life/puffer_train.png b/examples/shaders/resources/game_of_life/puffer_train.png new file mode 100644 index 000000000..8d77219b0 Binary files /dev/null and b/examples/shaders/resources/game_of_life/puffer_train.png differ diff --git a/examples/shaders/resources/game_of_life/r_pentomino.png b/examples/shaders/resources/game_of_life/r_pentomino.png new file mode 100644 index 000000000..1707f3c12 Binary files /dev/null and b/examples/shaders/resources/game_of_life/r_pentomino.png differ diff --git a/examples/shaders/resources/game_of_life/spaceships.png b/examples/shaders/resources/game_of_life/spaceships.png new file mode 100644 index 000000000..867f6fea3 Binary files /dev/null and b/examples/shaders/resources/game_of_life/spaceships.png differ diff --git a/examples/shaders/resources/game_of_life/still_lifes.png b/examples/shaders/resources/game_of_life/still_lifes.png new file mode 100644 index 000000000..ac184ac49 Binary files /dev/null and b/examples/shaders/resources/game_of_life/still_lifes.png differ diff --git a/examples/shaders/resources/shaders/glsl100/game_of_life.fs b/examples/shaders/resources/shaders/glsl100/game_of_life.fs new file mode 100644 index 000000000..70c12ac2c --- /dev/null +++ b/examples/shaders/resources/shaders/glsl100/game_of_life.fs @@ -0,0 +1,44 @@ +#version 100 + +precision highp float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// Input size in pixels of the textures +uniform vec2 resolution; + +void main() +{ + // Size of one pixel in texture coordinates (from 0.0 to 1.0) + float x = 1.0/resolution.x; + float y = 1.0/resolution.y; + + // Status of the current cell (1 = alive, 0 = dead) + int origValue = (texture2D(texture0, fragTexCoord).r < 0.1)? 1 : 0; + + // Sum of alive neighbors + int sumValue = (texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Top-left + sumValue += (texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y )).r < 0.1)? 1 : 0; // Top + sumValue += (texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Top-right + + sumValue += (texture2D(texture0, vec2(fragTexCoord.x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Left + sumValue += (texture2D(texture0, vec2(fragTexCoord.x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Right + + sumValue += (texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Bottom-left + sumValue += (texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y )).r < 0.1)? 1 : 0; // Bottom + sumValue += (texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Bottom-right + + // Game of life rules: + // Current cell remains alive when 2 or 3 neighbors are alive, dies otherwise + // Current cell goes from dead to alive when exactly 3 neighbors are alive + if ((origValue == 1 && sumValue == 2) || sumValue == 3) + gl_FragColor = vec4(0.0, 0.0, 0.0, 255.0); // Alive: draw the pixel black + else + gl_FragColor = fragColor; // Dead: draw the pixel with the background color, RAYWHITE +} diff --git a/examples/shaders/resources/shaders/glsl120/game_of_life.fs b/examples/shaders/resources/shaders/glsl120/game_of_life.fs new file mode 100644 index 000000000..611f961bc --- /dev/null +++ b/examples/shaders/resources/shaders/glsl120/game_of_life.fs @@ -0,0 +1,42 @@ +#version 120 + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// Input size in pixels of the textures +uniform vec2 resolution; + +void main() +{ + // Size of one pixel in texture coordinates (from 0.0 to 1.0) + float x = 1.0/resolution.x; + float y = 1.0/resolution.y; + + // Status of the current cell (1 = alive, 0 = dead) + int origValue = (texture2D(texture0, fragTexCoord).r < 0.1)? 1 : 0; + + // Sum of alive neighbors + int sumValue = (texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Top-left + sumValue += (texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y )).r < 0.1)? 1 : 0; // Top + sumValue += (texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Top-right + + sumValue += (texture2D(texture0, vec2(fragTexCoord.x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Left + sumValue += (texture2D(texture0, vec2(fragTexCoord.x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Right + + sumValue += (texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Bottom-left + sumValue += (texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y )).r < 0.1)? 1 : 0; // Bottom + sumValue += (texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Bottom-right + + // Game of life rules: + // Current cell remains alive when 2 or 3 neighbors are alive, dies otherwise + // Current cell goes from dead to alive when exactly 3 neighbors are alive + if (((origValue == 1) && (sumValue == 2)) || sumValue == 3) + gl_FragColor = vec4(0.0, 0.0, 0.0, 255.0); // Alive: draw the pixel black + else + gl_FragColor = fragColor; // Dead: draw the pixel with the background color, RAYWHITE +} diff --git a/examples/shaders/resources/shaders/glsl330/game_of_life.fs b/examples/shaders/resources/shaders/glsl330/game_of_life.fs new file mode 100644 index 000000000..cc80861d6 --- /dev/null +++ b/examples/shaders/resources/shaders/glsl330/game_of_life.fs @@ -0,0 +1,45 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// Output fragment color +out vec4 finalColor; + +// Input size in pixels of the textures +uniform vec2 resolution; + +void main() +{ + // Size of one pixel in texture coordinates (from 0.0 to 1.0) + float x = 1.0/resolution.x; + float y = 1.0/resolution.y; + + // Status of the current cell (1 = alive, 0 = dead) + int origValue = (texture(texture0, fragTexCoord).r < 0.1)? 1 : 0; + + // Sum of alive neighbors + int sumValue = (texture(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Top-left + sumValue += (texture(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y )).r < 0.1)? 1 : 0; // Top + sumValue += (texture(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Top-right + + sumValue += (texture(texture0, vec2(fragTexCoord.x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Left + sumValue += (texture(texture0, vec2(fragTexCoord.x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Right + + sumValue += (texture(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Bottom-left + sumValue += (texture(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y )).r < 0.1)? 1 : 0; // Bottom + sumValue += (texture(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Bottom-right + + // Game of life rules: + // Current cell remains alive when 2 or 3 neighbors are alive, dies otherwise + // Current cell goes from dead to alive when exactly 3 neighbors are alive + if (((origValue == 1) && (sumValue == 2)) || sumValue == 3) + finalColor = vec4(0.0, 0.0, 0.0, 255.0); // Alive: draw the pixel black + else + finalColor = fragColor; // Dead: draw the pixel with the background color, RAYWHITE +} diff --git a/examples/shaders/shaders_game_of_life.c b/examples/shaders/shaders_game_of_life.c new file mode 100644 index 000000000..9b9242a0d --- /dev/null +++ b/examples/shaders/shaders_game_of_life.c @@ -0,0 +1,353 @@ +/******************************************************************************************* +* +* raylib [shaders] example - game of life +* +* Example complexity rating: [★★★☆] 3/4 +* +* NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support, +* OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version +* +* Example originally created with raylib 5.6, last time updated with raylib 5.6 +* +* Example contributed by Jordi Santonja (@JordSant) 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 Jordi Santonja (@JordSant) +* +********************************************************************************************/ + +#include "raylib.h" + +#define RAYGUI_IMPLEMENTATION +#include "raygui.h" // Required for GUI controls + +#if defined(PLATFORM_DESKTOP) + #define GLSL_VERSION 330 +#else // PLATFORM_ANDROID, PLATFORM_WEB + #define GLSL_VERSION 100 +#endif + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +// Interaction mode +typedef enum { + MODE_RUN = 0, + MODE_PAUSE, + MODE_DRAW, +} InteractionMode; + +// Struct to store example preset patterns +typedef struct { + char *name; + Vector2 position; +} PresetPattern; + +//---------------------------------------------------------------------------------- +// Functions declaration +//---------------------------------------------------------------------------------- +void FreeImageToDraw(Image **imageToDraw); + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [shaders] example - game of life"); + + const int menuWidth = 100; + const int windowWidth = screenWidth - menuWidth; + const int windowHeight = screenHeight; + + const int worldWidth = 2048; + const int worldHeight = 2048; + + const int randomTiles = 8; // Random preset: divide the world to compute random points in each tile + + const Rectangle worldRectSource = { 0, 0, (float)worldWidth, (float)-worldHeight }; + const Rectangle worldRectDest = { 0, 0, (float)worldWidth, (float)worldHeight }; + const Rectangle textureOnScreen = { 0, 0, (float)windowWidth, (float)windowHeight }; + + const PresetPattern presetPatterns[] = { + { "Glider", { 0.5f, 0.5f } }, { "R-pentomino", { 0.5f, 0.5f } }, { "Acorn", { 0.5f,0.5f } }, + { "Spaceships", { 0.1f, 0.5f } }, { "Still lifes", { 0.5f, 0.5f } }, { "Oscillators", { 0.5f, 0.5f } }, + { "Puffer train", { 0.1f, 0.5f } }, { "Glider Gun", { 0.2f, 0.2f } }, { "Breeder", { 0.1f, 0.5f } }, + { "Random", { 0.5f, 0.5f } } + }; + + const int numberOfPresets = sizeof(presetPatterns)/sizeof(presetPatterns[0]); + + int zoom = 1; + float offsetX = (worldWidth - windowWidth)/2.0f; // Centered on window + float offsetY = (worldHeight - windowHeight)/2.0f; // Centered on window + int framesPerStep = 1; + int frame = 0; + + int preset = -1; // No button pressed for preset + int mode = MODE_RUN; // Starting mode: running + bool buttonZoomIn = false; // Button states: false not pressed + bool buttonZomOut = false; + bool buttonFaster = false; + bool buttonSlower = false; + + // Load shader + Shader shdrGameOfLife = LoadShader(0, TextFormat("resources/shaders/glsl%i/game_of_life.fs", GLSL_VERSION)); + + // Set shader uniform size of the world + int resolutionLoc = GetShaderLocation(shdrGameOfLife, "resolution"); + const float resolution[2] = { (float)worldWidth, (float)worldHeight }; + SetShaderValue(shdrGameOfLife, resolutionLoc, resolution, SHADER_UNIFORM_VEC2); + + // Define two textures: the current world and the previous world + RenderTexture2D world1 = LoadRenderTexture(worldWidth, worldHeight); + RenderTexture2D world2 = LoadRenderTexture(worldWidth, worldHeight); + BeginTextureMode(world2); + ClearBackground(RAYWHITE); + EndTextureMode(); + + Image startPattern = LoadImage("resources/game_of_life/r_pentomino.png"); + UpdateTextureRec(world2.texture, (Rectangle){ worldWidth/2.0f, worldHeight/2.0f, (float)(startPattern.width), (float)(startPattern.height) }, startPattern.data); + UnloadImage(startPattern); + + // Pointers to the two textures, to be swapped + RenderTexture2D *currentWorld = &world2; + RenderTexture2D *previousWorld = &world1; + + // Image to be used in DRAW mode, to be changed with mouse input + Image *imageToDraw = NULL; + + SetTargetFPS(60); // Set at 60 frames-per-second + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + frame++; + + // Change zoom: both by buttons or by mouse wheel + float mouseWheelMove = GetMouseWheelMove(); + if (buttonZoomIn || (buttonZomOut && (zoom > 1)) || (mouseWheelMove != 0.0f)) + { + FreeImageToDraw(&imageToDraw); // Zoom change: free the image to draw to be recreated again + + const float centerX = offsetX + (windowWidth/2.0f)/zoom; + const float centerY = offsetY + (windowHeight/2.0f)/zoom; + if (buttonZoomIn || (mouseWheelMove > 0.0f)) zoom *= 2; + if ((buttonZomOut || (mouseWheelMove < 0.0f)) && (zoom > 1)) zoom /= 2; + offsetX = centerX - (windowWidth/2.0f)/zoom; + offsetY = centerY - (windowHeight/2.0f)/zoom; + } + + // Change speed: number of frames per step + if (buttonFaster && framesPerStep > 1) framesPerStep--; + if (buttonSlower) framesPerStep++; + + // Mouse management + if ((mode == MODE_RUN) || (mode == MODE_PAUSE)) + { + FreeImageToDraw(&imageToDraw); // Free the image to draw: no longer needed in these modes + + // Pan with mouse left button + static Vector2 previousMousePosition = { 0.0f, 0.0f }; + const Vector2 mousePosition = GetMousePosition(); + if (IsMouseButtonDown(MOUSE_BUTTON_LEFT) && (mousePosition.x < windowWidth)) + { + offsetX -= (mousePosition.x - previousMousePosition.x)/zoom; + offsetY -= (mousePosition.y - previousMousePosition.y)/zoom; + } + previousMousePosition = mousePosition; + } + else // MODE_DRAW + { + const float offsetDecimalX = offsetX - floorf(offsetX); + const float offsetDecimalY = offsetY - floorf(offsetY); + int sizeInWorldX = (int)(ceilf((float)(windowWidth + offsetDecimalX*zoom)/zoom)); + int sizeInWorldY = (int)(ceilf((float)(windowHeight + offsetDecimalY*zoom)/zoom)); + if (offsetX + sizeInWorldX >= worldWidth) sizeInWorldX = worldWidth - (int)floorf(offsetX); + if (offsetY + sizeInWorldY >= worldHeight) sizeInWorldY = worldHeight - (int)floorf(offsetY); + + // Create image to draw if not created yet + if (imageToDraw == NULL) + { + RenderTexture2D worldOnScreen = LoadRenderTexture(sizeInWorldX, sizeInWorldY); + BeginTextureMode(worldOnScreen); + DrawTexturePro(currentWorld->texture, (Rectangle) { floorf(offsetX), floorf(offsetY), (float)(sizeInWorldX), -(float)(sizeInWorldY) }, + (Rectangle) { 0, 0, (float)(sizeInWorldX), (float)(sizeInWorldY) }, (Vector2) { 0, 0 }, 0.0f, WHITE); + EndTextureMode(); + imageToDraw = (Image*)RL_MALLOC(sizeof(Image)); + *imageToDraw = LoadImageFromTexture(worldOnScreen.texture); + + UnloadRenderTexture(worldOnScreen); + } + + const Vector2 mousePosition = GetMousePosition(); + static int firstColor = -1; + if (IsMouseButtonDown(MOUSE_BUTTON_LEFT) && (mousePosition.x < windowWidth)) + { + int mouseX = (int)(mousePosition.x + offsetDecimalX*zoom)/zoom; + int mouseY = (int)(mousePosition.y + offsetDecimalY*zoom)/zoom; + if (mouseX >= sizeInWorldX) mouseX = sizeInWorldX - 1; + if (mouseY >= sizeInWorldY) mouseY = sizeInWorldY - 1; + if (firstColor == -1) firstColor = (GetImageColor(*imageToDraw, mouseX, mouseY).r < 5)? 0 : 1; + const int prevColor = (GetImageColor(*imageToDraw, mouseX, mouseY).r < 5)? 0 : 1; + + ImageDrawPixel(imageToDraw, mouseX, mouseY, (firstColor) ? BLACK : RAYWHITE); + + if (prevColor != firstColor) UpdateTextureRec(currentWorld->texture, (Rectangle){ floorf(offsetX), floorf(offsetY), (float)(sizeInWorldX), (float)(sizeInWorldY) }, imageToDraw->data); + } + else firstColor = -1; + } + + // Load selected preset + if (preset >= 0) + { + Image pattern; + if (preset < numberOfPresets - 1) // Preset with pattern image lo load + { + switch (preset) + { + case 0: pattern = LoadImage("resources/game_of_life/glider.png"); break; + case 1: pattern = LoadImage("resources/game_of_life/r_pentomino.png"); break; + case 2: pattern = LoadImage("resources/game_of_life/acorn.png"); break; + case 3: pattern = LoadImage("resources/game_of_life/spaceships.png"); break; + case 4: pattern = LoadImage("resources/game_of_life/still_lifes.png"); break; + case 5: pattern = LoadImage("resources/game_of_life/oscillators.png"); break; + case 6: pattern = LoadImage("resources/game_of_life/puffer_train.png"); break; + case 7: pattern = LoadImage("resources/game_of_life/glider_gun.png"); break; + case 8: pattern = LoadImage("resources/game_of_life/breeder.png"); break; + } + BeginTextureMode(*currentWorld); + ClearBackground(RAYWHITE); + EndTextureMode(); + + UpdateTextureRec(currentWorld->texture, (Rectangle){ worldWidth*presetPatterns[preset].position.x - pattern.width/2.0f, + worldHeight*presetPatterns[preset].position.y - pattern.height/2.0f, + (float)(pattern.width), (float)(pattern.height) }, pattern.data); + } + else // Last preset: Random values + { + pattern = GenImageColor(worldWidth/randomTiles, worldHeight/randomTiles, RAYWHITE); + for (int i = 0; i < randomTiles; i++) + { + for (int j = 0; j < randomTiles; j++) + { + ImageClearBackground(&pattern, RAYWHITE); + for (int x = 0; x < pattern.width; x++) + { + for (int y = 0; y < pattern.height; y++) + { + if (GetRandomValue(0, 100) < 15) ImageDrawPixel(&pattern, x, y, BLACK); + } + } + UpdateTextureRec(currentWorld->texture, + (Rectangle){ (float)(pattern.width*i), (float)(pattern.height*j), + (float)(pattern.width), (float)(pattern.height) }, pattern.data); + } + } + } + + UnloadImage(pattern); + + mode = MODE_PAUSE; + offsetX = worldWidth*presetPatterns[preset].position.x - windowWidth/zoom/2.0f; + offsetY = worldHeight*presetPatterns[preset].position.y - windowHeight/zoom/2.0f; + } + + // Check window draw inside world limits + if (offsetX < 0) offsetX = 0; + if (offsetY < 0) offsetY = 0; + if (offsetX > worldWidth - (float)(windowWidth)/zoom) offsetX = worldWidth - (float)(windowWidth)/zoom; + if (offsetY > worldHeight - (float)(windowHeight)/zoom) offsetY = worldHeight - (float)(windowHeight)/zoom; + + // Rectangles for drawing texture portion to screen + const Rectangle textureSourceToScreen = { offsetX, offsetY, (float)windowWidth/zoom, (float)windowHeight/zoom }; + //---------------------------------------------------------------------------------- + + // Draw to texture + //---------------------------------------------------------------------------------- + if ((mode == MODE_RUN) && ((frame%framesPerStep) == 0)) + { + // Swap worlds + RenderTexture2D *tempWorld = currentWorld; + currentWorld = previousWorld; + previousWorld = tempWorld; + + // Draw to texture + BeginTextureMode(*currentWorld); + BeginShaderMode(shdrGameOfLife); + DrawTexturePro(previousWorld->texture, worldRectSource, worldRectDest, (Vector2){ 0, 0 }, 0.0f, RAYWHITE); + EndShaderMode(); + EndTextureMode(); + } + //---------------------------------------------------------------------------------- + + // Draw to screen + //---------------------------------------------------------------------------------- + BeginDrawing(); + + DrawTexturePro(currentWorld->texture, textureSourceToScreen, textureOnScreen, (Vector2){ 0, 0 }, 0.0f, WHITE); + + DrawLine(windowWidth, 0, windowWidth, screenHeight, (Color){ 218, 218, 218, 255 }); + DrawRectangle(windowWidth, 0, screenWidth - windowWidth, screenHeight, (Color){ 232, 232, 232, 255 }); + + DrawText("Conway's", 704, 4, 20, DARKBLUE); + DrawText(" game of", 704, 19, 20, DARKBLUE); + DrawText(" life", 708, 34, 20, DARKBLUE); + DrawText("in raylib", 757, 42, 6, BLACK); + + DrawText("Presets", 710, 58, 8, GRAY); + preset = -1; + for (int i = 0; i < numberOfPresets; i++) + if (GuiButton((Rectangle){ 710.0f, 70.0f + 18*i, 80.0f, 16.0f }, presetPatterns[i].name)) preset = i; + + GuiToggleGroup((Rectangle){ 710, 258, 80, 16 }, "Run\nPause\nDraw", &mode); + + DrawText(TextFormat("Zoom: %ix", zoom), 710, 316, 8, GRAY); + buttonZoomIn = GuiButton((Rectangle){ 710, 328, 80, 16 }, "Zoom in"); + buttonZomOut = GuiButton((Rectangle){ 710, 346, 80, 16 }, "Zoom out"); + + DrawText(TextFormat("Speed: %i frame%s", framesPerStep, (framesPerStep > 1)? "s" : ""), 710, 370, 8, GRAY); + buttonFaster = GuiButton((Rectangle){ 710, 382, 80, 16 }, "Faster"); + buttonSlower = GuiButton((Rectangle){ 710, 400, 80, 16 }, "Slower"); + + DrawFPS(712, 426); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadShader(shdrGameOfLife); + UnloadRenderTexture(world1); + UnloadRenderTexture(world2); + + FreeImageToDraw(&imageToDraw); + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} + +//---------------------------------------------------------------------------------- +// Functions definition +//---------------------------------------------------------------------------------- +void FreeImageToDraw(Image **imageToDraw) +{ + if (*imageToDraw != NULL) + { + UnloadImage(**imageToDraw); + RL_FREE(*imageToDraw); + *imageToDraw = NULL; + } +} diff --git a/examples/shaders/shaders_game_of_life.png b/examples/shaders/shaders_game_of_life.png new file mode 100644 index 000000000..8ebc2c12e Binary files /dev/null and b/examples/shaders/shaders_game_of_life.png differ diff --git a/examples/shapes/shapes_penrose_tile.c b/examples/shapes/shapes_penrose_tile.c index 354ebb457..304dca3cc 100644 --- a/examples/shapes/shapes_penrose_tile.c +++ b/examples/shapes/shapes_penrose_tile.c @@ -4,7 +4,7 @@ * * Example complexity rating: [★★★★] 4/4 * -* Example originally created with raylib 5.5 +* Example originally created with raylib 5.5, last time updated with raylib 5.6-dev * Based on: https://processing.org/examples/penrosetile.html * * Example contributed by David Buzatto (@davidbuzatto) and reviewed by Ramon Santamaria (@raysan5) diff --git a/examples/text/text_strings_management.c b/examples/text/text_strings_management.c index d6b4aeb57..d2e349279 100644 --- a/examples/text/text_strings_management.c +++ b/examples/text/text_strings_management.c @@ -60,7 +60,7 @@ int main(void) const int screenWidth = 800; const int screenHeight = 450; - InitWindow(screenWidth, screenHeight, "raylib [shapes] example - strings management"); + InitWindow(screenWidth, screenHeight, "raylib [text] example - strings management"); TextParticle textParticles[MAX_TEXT_PARTICLES] = { 0 }; int particleCount = 0; @@ -316,7 +316,7 @@ void SliceTextParticle(TextParticle *tp, int particlePos, int sliceLength, TextP void SliceTextParticleByChar(TextParticle *tp, char charToSlice, TextParticle *tps, int *particleCount) { int tokenCount = 0; - const char **tokens = TextSplit(tp->text, charToSlice, &tokenCount); + char **tokens = TextSplit(tp->text, charToSlice, &tokenCount); if (tokenCount > 1) { diff --git a/examples/text/text_words_alignment.c b/examples/text/text_words_alignment.c index 6cfd2a85c..a558d5b11 100644 --- a/examples/text/text_words_alignment.c +++ b/examples/text/text_words_alignment.c @@ -19,6 +19,8 @@ #include "raymath.h" // Required for: Lerp() +#include + typedef enum TextAlignment { TEXT_ALIGN_LEFT = 0, TEXT_ALIGN_TOP = 0, @@ -58,7 +60,7 @@ int main(void) // And of course the font... Font font = GetFontDefault(); - // Intialize the alignment variables + // Initialize the alignment variables TextAlignment hAlign = TEXT_ALIGN_CENTRE; TextAlignment vAlign = TEXT_ALIGN_MIDDLE; @@ -72,8 +74,7 @@ int main(void) //---------------------------------------------------------------------------------- if (IsKeyPressed(KEY_LEFT)) { - hAlign = hAlign - 1; - if (hAlign < 0) hAlign = 0; + if (hAlign > 0) hAlign = hAlign - 1; } if (IsKeyPressed(KEY_RIGHT)) @@ -84,8 +85,7 @@ int main(void) if (IsKeyPressed(KEY_UP)) { - vAlign = vAlign - 1; - if (vAlign < 0) vAlign = 0; + if (vAlign > 0) vAlign = vAlign - 1; } if (IsKeyPressed(KEY_DOWN)) @@ -95,7 +95,8 @@ int main(void) } // One word per second - wordIndex = (int)GetTime()%wordCount; + if (wordCount > 0) wordIndex = (int)GetTime()%wordCount; + else wordIndex = 0; //---------------------------------------------------------------------------------- // Draw @@ -132,4 +133,4 @@ int main(void) //-------------------------------------------------------------------------------------- return 0; -} \ No newline at end of file +} diff --git a/examples/textures/textures_cellular_automata.c b/examples/textures/textures_cellular_automata.c new file mode 100644 index 000000000..affeeda93 --- /dev/null +++ b/examples/textures/textures_cellular_automata.c @@ -0,0 +1,212 @@ +/******************************************************************************************* +* +* raylib [textures] example - cellular automata +* +* Example complexity rating: [★★☆☆] 2/4 +* +* Example originally created with raylib 5.6, last time updated with raylib 5.6 +* +* Example contributed by Jordi Santonja (@JordSant) 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 Jordi Santonja (@JordSant) +* +********************************************************************************************/ + +#include "raylib.h" + +// Initialization constants +//-------------------------------------------------------------------------------------- +const int screenWidth = 800; +const int screenHeight = 450; +const int imageWidth = 800; +const int imageHeight = 800/2; + +// Rule button sizes and positions +const int drawRuleStartX = 585; +const int drawRuleStartY = 10; +const int drawRuleSpacing = 15; +const int drawRuleGroupSpacing = 50; +const int drawRuleSize = 14; +const int drawRuleInnerSize = 10; + +// Preset button sizes +const int presetsSizeX = 42; +const int presetsSizeY = 22; + +const int linesUpdatedPerFrame = 4; + +//---------------------------------------------------------------------------------- +// Functions +//---------------------------------------------------------------------------------- +void ComputeLine(Image *image, int line, int rule) +{ + // Compute next line pixels. Boundaries are not computed, always 0 + for (int i = 1; i < imageWidth - 1; i++) + { + // Get, from the previous line, the 3 pixels states as a binary value + const int prevValue = ((GetImageColor(*image, i - 1, line - 1).r < 5)? 4 : 0) + // Left pixel + ((GetImageColor(*image, i, line - 1).r < 5)? 2 : 0) + // Center pixel + ((GetImageColor(*image, i + 1, line - 1).r < 5)? 1 : 0); // Right pixel + // Get next value from rule bitmask + const bool currValue = (rule & (1 << prevValue)); + // Update pixel color + ImageDrawPixel(image, i, line, (currValue)? BLACK : RAYWHITE); + } +} + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + InitWindow(screenWidth, screenHeight, "raylib [textures] example - cellular automata"); + + // Image that contains the cellular automaton + Image image = GenImageColor(imageWidth, imageHeight, RAYWHITE); + // The top central pixel set as black + ImageDrawPixel(&image, imageWidth/2, 0, BLACK); + + Texture2D texture = LoadTextureFromImage(image); + + // Some interesting rules + const int presetValues[] = { 18, 30, 60, 86, 102, 124, 126, 150, 182, 225 }; + const int presetsCount = sizeof(presetValues)/sizeof(presetValues[0]); + + // Variables + int rule = 30; // Starting rule + int line = 1; // Line to compute, starting from line 1. One point in line 0 is already set + + SetTargetFPS(60); + //--------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + // Handle mouse + const Vector2 mouse = GetMousePosition(); + int mouseInCell = -1; // -1: outside any button; 0-7: rule cells; 8+: preset cells + + // Check mouse on rule cells + for (int i = 0; i < 8; i++) + { + const int cellX = drawRuleStartX - drawRuleGroupSpacing*i + drawRuleSpacing; + const int cellY = drawRuleStartY + drawRuleSpacing; + if ((mouse.x >= cellX) && (mouse.x <= cellX + drawRuleSize) && + (mouse.y >= cellY) && (mouse.y <= cellY + drawRuleSize)) + { + mouseInCell = i; // 0-7: rule cells + break; + } + } + + // Check mouse on preset cells + if (mouseInCell < 0) + { + for (int i = 0; i < presetsCount; i++) + { + const int cellX = 4 + (presetsSizeX + 2)*(i/2); + const int cellY = 2 + (presetsSizeY + 2)*(i%2); + if ((mouse.x >= cellX) && (mouse.x <= cellX + presetsSizeX) && + (mouse.y >= cellY) && (mouse.y <= cellY + presetsSizeY)) + { + mouseInCell = i + 8; // 8+: preset cells + break; + } + } + } + + if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && (mouseInCell >= 0)) + { + // Rule changed both by selecting a preset or toggling a bit + if (mouseInCell < 8) + rule ^= (1 << mouseInCell); + else + rule = presetValues[mouseInCell - 8]; + + // Reset image + ImageClearBackground(&image, RAYWHITE); + ImageDrawPixel(&image, imageWidth/2, 0, BLACK); + line = 1; + } + + // Compute next lines + //---------------------------------------------------------------------------------- + if (line < imageHeight) + { + for (int i = 0; (i < linesUpdatedPerFrame) && (line + i < imageHeight); i++) + ComputeLine(&image, line + i, rule); + line += linesUpdatedPerFrame; + + UpdateTexture(texture, image.data); + } + + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + ClearBackground(RAYWHITE); + + // Draw cellular automaton texture + DrawTexture(texture, 0, screenHeight - imageHeight, WHITE); + + // Draw preset values + for (int i = 0; i < presetsCount; i++) + { + DrawText(TextFormat("%i", presetValues[i]), 8 + (presetsSizeX + 2)*(i/2), 4 + (presetsSizeY + 2)*(i%2), 20, GRAY); + DrawRectangleLines(4 + (presetsSizeX + 2)*(i/2), 2 + (presetsSizeY + 2)*(i%2), presetsSizeX, presetsSizeY, BLUE); + + // If the mouse is on this preset, highlight it + if (mouseInCell == i + 8) + DrawRectangleLinesEx((Rectangle) { 2 + (presetsSizeX + 2.0f)*(i/2), + (presetsSizeY + 2.0f)*(i%2), + presetsSizeX + 4.0f, presetsSizeY + 4.0f }, 3, RED); + } + + // Draw rule bits + for (int i = 0; i < 8; i++) + { + // The three input bits + for (int j = 0; j < 3; j++) + { + DrawRectangleLines(drawRuleStartX - drawRuleGroupSpacing*i + drawRuleSpacing*j, drawRuleStartY, drawRuleSize, drawRuleSize, GRAY); + if (i & (4 >> j)) + DrawRectangle(drawRuleStartX + 2 - drawRuleGroupSpacing*i + drawRuleSpacing*j, drawRuleStartY + 2, drawRuleInnerSize, drawRuleInnerSize, BLACK); + } + + // The output bit + DrawRectangleLines(drawRuleStartX - drawRuleGroupSpacing*i + drawRuleSpacing, drawRuleStartY + drawRuleSpacing, drawRuleSize, drawRuleSize, BLUE); + if (rule & (1 << i)) + DrawRectangle(drawRuleStartX + 2 - drawRuleGroupSpacing*i + drawRuleSpacing, drawRuleStartY + 2 + drawRuleSpacing, drawRuleInnerSize, drawRuleInnerSize, BLACK); + + // If the mouse is on this rule bit, highlight it + if (mouseInCell == i) + DrawRectangleLinesEx((Rectangle){ drawRuleStartX - drawRuleGroupSpacing*i + drawRuleSpacing - 2.0f, + drawRuleStartY + drawRuleSpacing - 2.0f, + drawRuleSize + 4.0f, drawRuleSize + 4.0f }, 3, RED); + } + + DrawText(TextFormat("RULE: %i", rule), drawRuleStartX + drawRuleSpacing*4, drawRuleStartY + 1, 30, GRAY); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadImage(image); + UnloadTexture(texture); + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} + diff --git a/examples/textures/textures_cellular_automata.png b/examples/textures/textures_cellular_automata.png new file mode 100644 index 000000000..2d88041d2 Binary files /dev/null and b/examples/textures/textures_cellular_automata.png differ diff --git a/projects/4coder/Makefile.Android b/projects/4coder/Makefile.Android index 29d437b1b..9e6773651 100644 --- a/projects/4coder/Makefile.Android +++ b/projects/4coder/Makefile.Android @@ -96,7 +96,7 @@ ifeq ($(ANDROID_ARCH),ARM) CFLAGS = -std=c99 -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 endif ifeq ($(ANDROID_ARCH),ARM64) - CFLAGS = -std=c99 -target aarch64 -mfix-cortex-a53-835769 + CFLAGS = -std=c99 -mfix-cortex-a53-835769 endif # Compilation functions attributes options CFLAGS += -ffunction-sections -funwind-tables -fstack-protector-strong -fPIC diff --git a/projects/VS2022/examples/core_high_dpi.vcxproj b/projects/VS2022/examples/core_highdpi_demo.vcxproj similarity index 97% rename from projects/VS2022/examples/core_high_dpi.vcxproj rename to projects/VS2022/examples/core_highdpi_demo.vcxproj index 11e1b41c0..8a7cdce40 100644 --- a/projects/VS2022/examples/core_high_dpi.vcxproj +++ b/projects/VS2022/examples/core_highdpi_demo.vcxproj @@ -1,569 +1,569 @@ - - - - - Debug.DLL - ARM64 - - - Debug.DLL - Win32 - - - Debug.DLL - x64 - - - Debug - ARM64 - - - Debug - Win32 - - - Debug - x64 - - - Release.DLL - ARM64 - - - Release.DLL - Win32 - - - Release.DLL - x64 - - - Release - ARM64 - - - Release - Win32 - - - Release - x64 - - - - {BCB71111-8505-4B35-8CEF-EC6115DC9D4D} - Win32Proj - core_high_dpi - 10.0 - core_high_dpi - - - - Application - true - $(DefaultPlatformToolset) - Unicode - - - Application - true - $(DefaultPlatformToolset) - Unicode - - - Application - true - $(DefaultPlatformToolset) - Unicode - - - Application - true - $(DefaultPlatformToolset) - Unicode - - - Application - true - $(DefaultPlatformToolset) - Unicode - - - Application - true - $(DefaultPlatformToolset) - Unicode - - - Application - false - $(DefaultPlatformToolset) - true - Unicode - - - Application - false - $(DefaultPlatformToolset) - true - Unicode - - - Application - false - $(DefaultPlatformToolset) - true - Unicode - - - Application - false - $(DefaultPlatformToolset) - true - Unicode - - - Application - false - $(DefaultPlatformToolset) - true - Unicode - - - Application - false - $(DefaultPlatformToolset) - true - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ - $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ - - - true - $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ - $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ - - - true - $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ - $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ - - - true - $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ - $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ - - - true - $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ - $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ - - - true - $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ - $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ - - - false - $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ - $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ - - - false - $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ - $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ - - - false - $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ - $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ - - - false - $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ - $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ - - - false - $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ - $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ - - - false - $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ - $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ - - - $(SolutionDir)..\..\examples\core - WindowsLocalDebugger - - - $(SolutionDir)..\..\examples\core - WindowsLocalDebugger - - - $(SolutionDir)..\..\examples\core - WindowsLocalDebugger - - - $(SolutionDir)..\..\examples\core - WindowsLocalDebugger - - - $(SolutionDir)..\..\examples\core - WindowsLocalDebugger - - - $(SolutionDir)..\..\examples\core - WindowsLocalDebugger - - - $(SolutionDir)..\..\examples\core - WindowsLocalDebugger - - - $(SolutionDir)..\..\examples\core - WindowsLocalDebugger - - - $(SolutionDir)..\..\examples\core - WindowsLocalDebugger - - - $(SolutionDir)..\..\examples\core - WindowsLocalDebugger - - - $(SolutionDir)..\..\examples\core - WindowsLocalDebugger - - - $(SolutionDir)..\..\examples\core - WindowsLocalDebugger - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) - CompileAsC - $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) - - - Console - true - $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ - raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) - CompileAsC - $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) - /FS %(AdditionalOptions) - - - Console - true - $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ - raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) - CompileAsC - $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) - /FS %(AdditionalOptions) - - - Console - true - $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ - raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) - CompileAsC - $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) - - - Console - true - $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ - raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - - - xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" - Copy Debug DLL to output directory - - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) - CompileAsC - $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) - - - Console - true - $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ - raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - - - xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" - Copy Debug DLL to output directory - - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) - CompileAsC - $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) - - - Console - true - $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ - raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - - - xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" - Copy Debug DLL to output directory - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP - $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) - CompileAsC - true - - - Console - true - true - true - raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP - $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) - CompileAsC - true - - - Console - true - true - true - raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP - $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) - CompileAsC - true - - - Console - true - true - true - raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP - $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) - CompileAsC - true - - - Console - true - true - true - raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ - - - xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" - - - Copy Release DLL to output directory - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP - $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) - CompileAsC - true - - - Console - true - true - true - raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ - - - xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" - - - Copy Release DLL to output directory - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP - $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) - CompileAsC - true - - - Console - true - true - true - raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ - - - xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" - - - Copy Release DLL to output directory - - - - - - - - - - - {e89d61ac-55de-4482-afd4-df7242ebc859} - - - - - - + + + + + Debug.DLL + ARM64 + + + Debug.DLL + Win32 + + + Debug.DLL + x64 + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + Release.DLL + ARM64 + + + Release.DLL + Win32 + + + Release.DLL + x64 + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + {BCB71111-8505-4B35-8CEF-EC6115DC9D4D} + Win32Proj + core_highdpi_demo + 10.0 + core_highdpi_demo + + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + + + + + + + {e89d61ac-55de-4482-afd4-df7242ebc859} + + + + + + diff --git a/projects/VS2022/examples/shaders_game_of_life.vcxproj b/projects/VS2022/examples/shaders_game_of_life.vcxproj new file mode 100644 index 000000000..0ede87cda --- /dev/null +++ b/projects/VS2022/examples/shaders_game_of_life.vcxproj @@ -0,0 +1,569 @@ + + + + + Debug.DLL + ARM64 + + + Debug.DLL + Win32 + + + Debug.DLL + x64 + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + Release.DLL + ARM64 + + + Release.DLL + Win32 + + + Release.DLL + x64 + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + {071E64F3-1396-4A97-97CA-98CAC059B168} + Win32Proj + shaders_game_of_life + 10.0 + shaders_game_of_life + + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + + + + + + + {e89d61ac-55de-4482-afd4-df7242ebc859} + + + + + + \ No newline at end of file diff --git a/projects/VS2022/examples/shapes_ball_physics.vcxproj b/projects/VS2022/examples/shapes_ball_physics.vcxproj index 47bec68f2..9b7e98658 100644 --- a/projects/VS2022/examples/shapes_ball_physics.vcxproj +++ b/projects/VS2022/examples/shapes_ball_physics.vcxproj @@ -51,7 +51,7 @@ - {6B1A933E-71B8-4C1F-9E79-02D98830E671} + {0653AFAF-5578-4C02-AF29-0C873E7634AE} Win32Proj shapes_ball_physics 10.0 diff --git a/projects/VS2022/examples/shapes_penrose_tile.vcxproj b/projects/VS2022/examples/shapes_penrose_tile.vcxproj new file mode 100644 index 000000000..bde99f8c1 --- /dev/null +++ b/projects/VS2022/examples/shapes_penrose_tile.vcxproj @@ -0,0 +1,569 @@ + + + + + Debug.DLL + ARM64 + + + Debug.DLL + Win32 + + + Debug.DLL + x64 + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + Release.DLL + ARM64 + + + Release.DLL + Win32 + + + Release.DLL + x64 + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + {7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC} + Win32Proj + shapes_penrose_tile + 10.0 + shapes_penrose_tile + + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + + + + + + + {e89d61ac-55de-4482-afd4-df7242ebc859} + + + + + + \ No newline at end of file diff --git a/projects/VS2022/examples/text_strings_management.vcxproj b/projects/VS2022/examples/text_strings_management.vcxproj new file mode 100644 index 000000000..41b9b3ac0 --- /dev/null +++ b/projects/VS2022/examples/text_strings_management.vcxproj @@ -0,0 +1,569 @@ + + + + + Debug.DLL + ARM64 + + + Debug.DLL + Win32 + + + Debug.DLL + x64 + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + Release.DLL + ARM64 + + + Release.DLL + Win32 + + + Release.DLL + x64 + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + {1F4722E7-F78E-413F-A106-D3490211EA57} + Win32Proj + text_strings_management + 10.0 + text_strings_management + + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + $(SolutionDir)..\..\examples\text + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\text + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\text + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\text + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\text + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\text + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\text + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\text + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\text + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\text + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\text + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\text + WindowsLocalDebugger + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + + + + + + + {e89d61ac-55de-4482-afd4-df7242ebc859} + + + + + + \ No newline at end of file diff --git a/projects/VS2022/examples/textures_cellular_automata.vcxproj b/projects/VS2022/examples/textures_cellular_automata.vcxproj new file mode 100644 index 000000000..f8b434a6d --- /dev/null +++ b/projects/VS2022/examples/textures_cellular_automata.vcxproj @@ -0,0 +1,569 @@ + + + + + Debug.DLL + ARM64 + + + Debug.DLL + Win32 + + + Debug.DLL + x64 + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + Release.DLL + ARM64 + + + Release.DLL + Win32 + + + Release.DLL + x64 + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + {0A0FC982-6E31-401F-BA77-3C5E8AB02C68} + Win32Proj + textures_cellular_automata + 10.0 + textures_cellular_automata + + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + + + + + + + {e89d61ac-55de-4482-afd4-df7242ebc859} + + + + + + \ No newline at end of file diff --git a/projects/VS2022/raylib.sln b/projects/VS2022/raylib.sln index b541b10fe..50fef1cf5 100644 --- a/projects/VS2022/raylib.sln +++ b/projects/VS2022/raylib.sln @@ -57,7 +57,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_custom_logging", "exam EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_drop_files", "examples\core_drop_files.vcxproj", "{0199E349-0701-40BC-8A7F-06A54FFA3E7C}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_high_dpi", "examples\core_high_dpi.vcxproj", "{BCB71111-8505-4B35-8CEF-EC6115DC9D4D}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_highdpi_demo", "examples\core_highdpi_demo.vcxproj", "{BCB71111-8505-4B35-8CEF-EC6115DC9D4D}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_input_gamepad", "examples\core_input_gamepad.vcxproj", "{8F19E3DA-8929-4000-87B5-3CA6929636CC}" EndProject @@ -421,7 +421,15 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_rlgl_triangle", "exa EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_sprite_stacking", "examples\textures_sprite_stacking.vcxproj", "{FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_ball_physics", "examples\shapes_ball_physics.vcxproj", "{6B1A933E-71B8-4C1F-9E79-02D98830E671}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_ball_physics", "examples\shapes_ball_physics.vcxproj", "{0653AFAF-5578-4C02-AF29-0C873E7634AE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_game_of_life", "examples\shaders_game_of_life.vcxproj", "{071E64F3-1396-4A97-97CA-98CAC059B168}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_penrose_tile", "examples\shapes_penrose_tile.vcxproj", "{7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_strings_management", "examples\text_strings_management.vcxproj", "{1F4722E7-F78E-413F-A106-D3490211EA57}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_cellular_automata", "examples\textures_cellular_automata.vcxproj", "{0A0FC982-6E31-401F-BA77-3C5E8AB02C68}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -5237,30 +5245,126 @@ Global {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Release|x64.Build.0 = Release|x64 {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Release|x86.ActiveCfg = Release|Win32 {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Release|x86.Build.0 = Release|Win32 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|ARM64.Build.0 = Debug|ARM64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x64.ActiveCfg = Debug|x64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x64.Build.0 = Debug|x64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x86.ActiveCfg = Debug|Win32 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x86.Build.0 = Debug|Win32 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|ARM64.ActiveCfg = Release|ARM64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|ARM64.Build.0 = Release|ARM64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x64.ActiveCfg = Release|x64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x64.Build.0 = Release|x64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x86.ActiveCfg = Release|Win32 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x86.Build.0 = Release|Win32 + {0653AFAF-5578-4C02-AF29-0C873E7634AE}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {0653AFAF-5578-4C02-AF29-0C873E7634AE}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {0653AFAF-5578-4C02-AF29-0C873E7634AE}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {0653AFAF-5578-4C02-AF29-0C873E7634AE}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {0653AFAF-5578-4C02-AF29-0C873E7634AE}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {0653AFAF-5578-4C02-AF29-0C873E7634AE}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {0653AFAF-5578-4C02-AF29-0C873E7634AE}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {0653AFAF-5578-4C02-AF29-0C873E7634AE}.Debug|ARM64.Build.0 = Debug|ARM64 + {0653AFAF-5578-4C02-AF29-0C873E7634AE}.Debug|x64.ActiveCfg = Debug|x64 + {0653AFAF-5578-4C02-AF29-0C873E7634AE}.Debug|x64.Build.0 = Debug|x64 + {0653AFAF-5578-4C02-AF29-0C873E7634AE}.Debug|x86.ActiveCfg = Debug|Win32 + {0653AFAF-5578-4C02-AF29-0C873E7634AE}.Debug|x86.Build.0 = Debug|Win32 + {0653AFAF-5578-4C02-AF29-0C873E7634AE}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {0653AFAF-5578-4C02-AF29-0C873E7634AE}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {0653AFAF-5578-4C02-AF29-0C873E7634AE}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {0653AFAF-5578-4C02-AF29-0C873E7634AE}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {0653AFAF-5578-4C02-AF29-0C873E7634AE}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {0653AFAF-5578-4C02-AF29-0C873E7634AE}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {0653AFAF-5578-4C02-AF29-0C873E7634AE}.Release|ARM64.ActiveCfg = Release|ARM64 + {0653AFAF-5578-4C02-AF29-0C873E7634AE}.Release|ARM64.Build.0 = Release|ARM64 + {0653AFAF-5578-4C02-AF29-0C873E7634AE}.Release|x64.ActiveCfg = Release|x64 + {0653AFAF-5578-4C02-AF29-0C873E7634AE}.Release|x64.Build.0 = Release|x64 + {0653AFAF-5578-4C02-AF29-0C873E7634AE}.Release|x86.ActiveCfg = Release|Win32 + {0653AFAF-5578-4C02-AF29-0C873E7634AE}.Release|x86.Build.0 = Release|Win32 + {071E64F3-1396-4A97-97CA-98CAC059B168}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {071E64F3-1396-4A97-97CA-98CAC059B168}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {071E64F3-1396-4A97-97CA-98CAC059B168}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {071E64F3-1396-4A97-97CA-98CAC059B168}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {071E64F3-1396-4A97-97CA-98CAC059B168}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {071E64F3-1396-4A97-97CA-98CAC059B168}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {071E64F3-1396-4A97-97CA-98CAC059B168}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {071E64F3-1396-4A97-97CA-98CAC059B168}.Debug|ARM64.Build.0 = Debug|ARM64 + {071E64F3-1396-4A97-97CA-98CAC059B168}.Debug|x64.ActiveCfg = Debug|x64 + {071E64F3-1396-4A97-97CA-98CAC059B168}.Debug|x64.Build.0 = Debug|x64 + {071E64F3-1396-4A97-97CA-98CAC059B168}.Debug|x86.ActiveCfg = Debug|Win32 + {071E64F3-1396-4A97-97CA-98CAC059B168}.Debug|x86.Build.0 = Debug|Win32 + {071E64F3-1396-4A97-97CA-98CAC059B168}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {071E64F3-1396-4A97-97CA-98CAC059B168}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {071E64F3-1396-4A97-97CA-98CAC059B168}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {071E64F3-1396-4A97-97CA-98CAC059B168}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {071E64F3-1396-4A97-97CA-98CAC059B168}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {071E64F3-1396-4A97-97CA-98CAC059B168}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {071E64F3-1396-4A97-97CA-98CAC059B168}.Release|ARM64.ActiveCfg = Release|ARM64 + {071E64F3-1396-4A97-97CA-98CAC059B168}.Release|ARM64.Build.0 = Release|ARM64 + {071E64F3-1396-4A97-97CA-98CAC059B168}.Release|x64.ActiveCfg = Release|x64 + {071E64F3-1396-4A97-97CA-98CAC059B168}.Release|x64.Build.0 = Release|x64 + {071E64F3-1396-4A97-97CA-98CAC059B168}.Release|x86.ActiveCfg = Release|Win32 + {071E64F3-1396-4A97-97CA-98CAC059B168}.Release|x86.Build.0 = Release|Win32 + {7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC}.Debug|ARM64.Build.0 = Debug|ARM64 + {7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC}.Debug|x64.ActiveCfg = Debug|x64 + {7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC}.Debug|x64.Build.0 = Debug|x64 + {7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC}.Debug|x86.ActiveCfg = Debug|Win32 + {7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC}.Debug|x86.Build.0 = Debug|Win32 + {7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC}.Release|ARM64.ActiveCfg = Release|ARM64 + {7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC}.Release|ARM64.Build.0 = Release|ARM64 + {7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC}.Release|x64.ActiveCfg = Release|x64 + {7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC}.Release|x64.Build.0 = Release|x64 + {7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC}.Release|x86.ActiveCfg = Release|Win32 + {7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC}.Release|x86.Build.0 = Release|Win32 + {1F4722E7-F78E-413F-A106-D3490211EA57}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {1F4722E7-F78E-413F-A106-D3490211EA57}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {1F4722E7-F78E-413F-A106-D3490211EA57}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {1F4722E7-F78E-413F-A106-D3490211EA57}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {1F4722E7-F78E-413F-A106-D3490211EA57}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {1F4722E7-F78E-413F-A106-D3490211EA57}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {1F4722E7-F78E-413F-A106-D3490211EA57}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {1F4722E7-F78E-413F-A106-D3490211EA57}.Debug|ARM64.Build.0 = Debug|ARM64 + {1F4722E7-F78E-413F-A106-D3490211EA57}.Debug|x64.ActiveCfg = Debug|x64 + {1F4722E7-F78E-413F-A106-D3490211EA57}.Debug|x64.Build.0 = Debug|x64 + {1F4722E7-F78E-413F-A106-D3490211EA57}.Debug|x86.ActiveCfg = Debug|Win32 + {1F4722E7-F78E-413F-A106-D3490211EA57}.Debug|x86.Build.0 = Debug|Win32 + {1F4722E7-F78E-413F-A106-D3490211EA57}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {1F4722E7-F78E-413F-A106-D3490211EA57}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {1F4722E7-F78E-413F-A106-D3490211EA57}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {1F4722E7-F78E-413F-A106-D3490211EA57}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {1F4722E7-F78E-413F-A106-D3490211EA57}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {1F4722E7-F78E-413F-A106-D3490211EA57}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {1F4722E7-F78E-413F-A106-D3490211EA57}.Release|ARM64.ActiveCfg = Release|ARM64 + {1F4722E7-F78E-413F-A106-D3490211EA57}.Release|ARM64.Build.0 = Release|ARM64 + {1F4722E7-F78E-413F-A106-D3490211EA57}.Release|x64.ActiveCfg = Release|x64 + {1F4722E7-F78E-413F-A106-D3490211EA57}.Release|x64.Build.0 = Release|x64 + {1F4722E7-F78E-413F-A106-D3490211EA57}.Release|x86.ActiveCfg = Release|Win32 + {1F4722E7-F78E-413F-A106-D3490211EA57}.Release|x86.Build.0 = Release|Win32 + {0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Debug|ARM64.Build.0 = Debug|ARM64 + {0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Debug|x64.ActiveCfg = Debug|x64 + {0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Debug|x64.Build.0 = Debug|x64 + {0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Debug|x86.ActiveCfg = Debug|Win32 + {0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Debug|x86.Build.0 = Debug|Win32 + {0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Release|ARM64.ActiveCfg = Release|ARM64 + {0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Release|ARM64.Build.0 = Release|ARM64 + {0A0FC982-6E31-401F-BA77-3C5E8AB02C68}.Release|x64.ActiveCfg = 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.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -5428,7 +5532,7 @@ Global {C54703BF-D68A-480D-BE27-49B62E45D582} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} {9CD8BCAD-F212-4BCC-BA98-899743CE3279} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} {0981CA28-E4A5-4DF1-987F-A41D09131EFC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} + {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {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} {A61DAD9C-271C-4E95-81AA-DB4CD58564D4} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} @@ -5437,9 +5541,9 @@ Global {3B27F358-2679-4F38-B297-17B536F580BB} = {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} - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} - {9DB1F875-6E65-4195-B23F-ED8095C0B99C} = {278D8859-20B1-428F-8448-064F46E1F021} - {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F} = {278D8859-20B1-428F-8448-064F46E1F021} + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E} = {278D8859-20B1-428F-8448-064F46E1F021} + {9DB1F875-6E65-4195-B23F-ED8095C0B99C} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} + {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} {8E132D5A-2C00-48D0-8747-97E41356F26F} = {278D8859-20B1-428F-8448-064F46E1F021} {A4662163-83E7-4309-8CAA-B0BF13655FE6} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} {5F4B766F-DD52-4B53-B6C3-BC7611E17F20} = {278D8859-20B1-428F-8448-064F46E1F021} @@ -5455,7 +5559,7 @@ Global {124935CC-73BB-489E-92E8-4F922A85DB5D} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F} = {278D8859-20B1-428F-8448-064F46E1F021} {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2} = {278D8859-20B1-428F-8448-064F46E1F021} - {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91} = {278D8859-20B1-428F-8448-064F46E1F021} {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {9DE2FC01-A839-4F89-8319-9071D4C54821} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {2F578155-D51F-4C03-AB7F-5C5122CA46CC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} @@ -5473,7 +5577,11 @@ Global {32FE2658-1D70-442E-8672-0AC5C6F0BD7B} = {278D8859-20B1-428F-8448-064F46E1F021} {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F} = {278D8859-20B1-428F-8448-064F46E1F021} {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {278D8859-20B1-428F-8448-064F46E1F021} + {0653AFAF-5578-4C02-AF29-0C873E7634AE} = {278D8859-20B1-428F-8448-064F46E1F021} + {071E64F3-1396-4A97-97CA-98CAC059B168} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {7883D076-CA8F-4FF7-8B5D-0DFF41CEF8FC} = {278D8859-20B1-428F-8448-064F46E1F021} + {1F4722E7-F78E-413F-A106-D3490211EA57} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} + {0A0FC982-6E31-401F-BA77-3C5E8AB02C68} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29} diff --git a/projects/VSCode/Makefile.Android b/projects/VSCode/Makefile.Android index 7e41ea52f..279790d2a 100644 --- a/projects/VSCode/Makefile.Android +++ b/projects/VSCode/Makefile.Android @@ -96,7 +96,7 @@ ifeq ($(ANDROID_ARCH),ARM) CFLAGS = -std=c99 -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 endif ifeq ($(ANDROID_ARCH),ARM64) - CFLAGS = -std=c99 -target aarch64 -mfix-cortex-a53-835769 + CFLAGS = -std=c99 -mfix-cortex-a53-835769 endif # Compilation functions attributes options CFLAGS += -ffunction-sections -funwind-tables -fstack-protector-strong -fPIC diff --git a/src/Makefile b/src/Makefile index 41867da1c..bc84abece 100644 --- a/src/Makefile +++ b/src/Makefile @@ -406,7 +406,7 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID) CFLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 endif ifeq ($(ANDROID_ARCH),arm64) - CFLAGS += -target aarch64 -mfix-cortex-a53-835769 + CFLAGS += -mfix-cortex-a53-835769 endif ifeq ($(ANDROID_ARCH),x86) CFLAGS += -march=i686 diff --git a/src/external/rl_gputex.h b/src/external/rl_gputex.h index 29500f3cf..78d618db5 100644 --- a/src/external/rl_gputex.h +++ b/src/external/rl_gputex.h @@ -308,7 +308,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_ unsigned char alpha = 0; // 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; ((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; // 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; ((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) // DirecX understand ARGB as a 32bit DWORD but the actual memory byte alignment is BGRA // 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]; ((unsigned char *)image_data)[i] = ((unsigned char *)image_data)[i + 2]; diff --git a/src/external/rlsw.h b/src/external/rlsw.h index 025216e39..80fb02c4f 100644 --- a/src/external/rlsw.h +++ b/src/external/rlsw.h @@ -2217,7 +2217,7 @@ static inline bool sw_triangle_face_culling(void) const float *h2 = RLSW.vertexBuffer[2].homogeneous; // Compute a value proportional to the signed area in the projected 2D plane, - // calculated directly using homogeneous coordinates BEFORE division by w. + // calculated directly using homogeneous coordinates BEFORE division by w // This is the determinant of the matrix formed by the (x, y, w) components // of the vertices, which correctly captures the winding order in homogeneous // space and its relationship to the projected 2D winding order, even with @@ -2235,13 +2235,13 @@ static inline bool sw_triangle_face_culling(void) // Discard the triangle if its winding order (determined by the sign // of the homogeneous area/determinant) matches the culled direction // A positive hSgnArea typically corresponds to a counter-clockwise - // winding in the projected space when all w > 0. + // winding in the projected space when all w > 0 // This test is robust for points with w > 0 or w < 0, correctly // capturing the change in orientation when crossing the w=0 plane // The culling logic remains the same based on the signed area/determinant // A value of 0 for hSgnArea means the points are collinear in (x, y, w) - // space, which corresponds to a degenerate triangle projection. + // space, which corresponds to a degenerate triangle projection // Such triangles are typically not culled by this test (0 < 0 is false, 0 > 0 is false) // and should be handled by the clipper if necessary return (RLSW.cullFace == SW_FRONT)? (hSgnArea < 0) : (hSgnArea > 0); // Cull if winding is "clockwise" : "counter-clockwise" @@ -2602,7 +2602,7 @@ static inline bool sw_quad_face_culling(void) // space, which corresponds to a degenerate triangle projection // Such quads might also be degenerate or non-planar. They are typically // not culled by this test (0 < 0 is false, 0 > 0 is false) - // and should be handled by the clipper if necessary. + // and should be handled by the clipper if necessary return (RLSW.cullFace == SW_FRONT)? (hSgnArea < 0.0f) : (hSgnArea > 0.0f); // Cull if winding is "clockwise" : "counter-clockwise" } diff --git a/src/platforms/rcore_android.c b/src/platforms/rcore_android.c index 88b3b4bba..20a85a6a4 100644 --- a/src/platforms/rcore_android.c +++ b/src/platforms/rcore_android.c @@ -84,7 +84,6 @@ typedef struct { // Global Variables Definition //---------------------------------------------------------------------------------- extern CoreData CORE; // Global CORE state context -extern bool isGpuReady; // Flag to note GPU has been initialized successfully static PlatformData platform = { 0 }; // Platform specific data //---------------------------------------------------------------------------------- @@ -358,13 +357,17 @@ void RestoreWindow(void) // Set window configuration state using flags void SetWindowState(unsigned int flags) { - TRACELOG(LOG_WARNING, "SetWindowState() not available on target platform"); + if (!CORE.Window.ready) TRACELOG(LOG_WARNING, "WINDOW: SetWindowState does nothing before window initialization, Use \"SetConfigFlags\" instead"); + + // State change: 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 void ClearWindowState(unsigned int flags) { - TRACELOG(LOG_WARNING, "ClearWindowState() not available on target platform"); + // State change: FLAG_WINDOW_ALWAYS_RUN + if (FLAG_IS_SET(flags, FLAG_WINDOW_ALWAYS_RUN)) FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_ALWAYS_RUN); } // Set icon for window @@ -602,7 +605,7 @@ void DisableCursor(void) // Swap back buffer with front buffer (screen drawing) void SwapScreenBuffer(void) { - eglSwapBuffers(platform.device, platform.surface); + if (platform.surface != EGL_NO_SURFACE) eglSwapBuffers(platform.device, platform.surface); } //---------------------------------------------------------------------------------- @@ -741,8 +744,8 @@ void PollInputEvents(void) int pollEvents = 0; // Poll Events (registered events) until we reach TIMEOUT which indicates there are no events left to poll - // NOTE: Activity is paused if not enabled (platform.appEnabled) - while ((pollResult = ALooper_pollOnce(platform.appEnabled? 0 : -1, NULL, &pollEvents, ((void **)&platform.source)) > ALOOPER_POLL_TIMEOUT)) + // NOTE: Activity is paused if not enabled (platform.appEnabled) and always run flag is not set (FLAG_WINDOW_ALWAYS_RUN) + while ((pollResult = ALooper_pollOnce((platform.appEnabled || FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_ALWAYS_RUN))? 0 : -1, NULL, &pollEvents, ((void **)&platform.source)) > ALOOPER_POLL_TIMEOUT)) { // Process this event if (platform.source != NULL) platform.source->process(platform.app, platform.source); @@ -1042,7 +1045,6 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd) // Initialize OpenGL context (states and resources) // NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height); - isGpuReady = true; // Setup default viewport // NOTE: It updated CORE.Window.render.width and CORE.Window.render.height @@ -1164,8 +1166,8 @@ static GamepadButton AndroidTranslateGamepadButton(int button) static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) { // If additional inputs are required check: - // Ref: https://developer.android.com/ndk/reference/group/input - // Ref: https://developer.android.com/training/game-controllers/controller-input + // REF: https://developer.android.com/ndk/reference/group/input + // REF: https://developer.android.com/training/game-controllers/controller-input int type = AInputEvent_getType(event); int source = AInputEvent_getSource(event); diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index 211e0f701..efa146fd0 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -134,12 +134,13 @@ static void ErrorCallback(int error, const char *description); // Window callbacks events static void WindowSizeCallback(GLFWwindow *window, int width, int height); // GLFW3 WindowSize Callback, runs when window is resized -static void WindowPosCallback(GLFWwindow* window, int x, int y); // GLFW3 WindowPos Callback, runs when window is moved +static void FramebufferSizeCallback(GLFWwindow *window, int width, int height); // GLFW3 FramebufferSize Callback, runs when window is resized +static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float scaley); // GLFW3 Window Content Scale Callback, runs when window changes scale +static void WindowPosCallback(GLFWwindow *window, int x, int y); // GLFW3 WindowPos Callback, runs when window is moved static void WindowIconifyCallback(GLFWwindow *window, int iconified); // GLFW3 WindowIconify Callback, runs when window is minimized/restored -static void WindowMaximizeCallback(GLFWwindow* window, int maximized); // GLFW3 Window Maximize Callback, runs when window is maximized +static void WindowMaximizeCallback(GLFWwindow *window, int maximized); // GLFW3 Window Maximize Callback, runs when window is maximized static void WindowFocusCallback(GLFWwindow *window, int focused); // GLFW3 WindowFocus Callback, runs when window get/lose focus static void WindowDropCallback(GLFWwindow *window, int count, const char **paths); // GLFW3 Window Drop Callback, runs when drop files into window -static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float scaley); // GLFW3 Window Content Scale Callback, runs when window changes scale // Input callbacks events static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods); // GLFW3 Keyboard Callback, runs on key pressed @@ -155,8 +156,6 @@ static void *AllocateWrapper(size_t size, void *user); static void *ReallocateWrapper(void *block, size_t size, void *user); // GLFW3 GLFWreallocatefun, wrapps around RL_REALLOC macro static void DeallocateWrapper(void *block, void *user); // GLFW3 GLFWdeallocatefun, wraps around RL_FREE macro -static void SetDimensionsFromMonitor(GLFWmonitor *monitor); // Set screen dimensions from monitor/display dimensions - //---------------------------------------------------------------------------------- // Module Functions Declaration //---------------------------------------------------------------------------------- @@ -205,7 +204,6 @@ void ToggleFullscreen(void) glfwSetWindowMonitor(platform.handle, monitor, 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE); } - } else { @@ -231,22 +229,22 @@ void ToggleBorderlessWindowed(void) bool wasOnFullscreen = false; if (CORE.Window.fullscreen) { - // fullscreen already saves the previous position so it does not need to be set here again + // Fullscreen already saves the previous position so it does not need to be set here again ToggleFullscreen(); wasOnFullscreen = true; } - const int monitor = GetCurrentMonitor(); - int monitorCount; + int monitorCount = 0; GLFWmonitor **monitors = glfwGetMonitors(&monitorCount); + const int monitor = GetCurrentMonitor(); if ((monitor >= 0) && (monitor < monitorCount)) { const GLFWvidmode *mode = glfwGetVideoMode(monitors[monitor]); - if (mode) + if (mode != NULL) { - if (!IsWindowState(FLAG_BORDERLESS_WINDOWED_MODE)) + if (!FLAG_IS_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE)) { // Store screen position and size // NOTE: If it was on fullscreen, screen position was already stored, so skip setting it here @@ -286,6 +284,16 @@ void ToggleBorderlessWindowed(void) glfwSetWindowAttrib(platform.handle, GLFW_DECORATED, GLFW_TRUE); FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNDECORATED); + #if !defined(__APPLE__) + // Make sure to restore size to HighDPI + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) + { + Vector2 scaleDpi = GetWindowScaleDPI(); + CORE.Window.previousScreen.width *= scaleDpi.x; + CORE.Window.previousScreen.height *= scaleDpi.y; + } + #endif + // Return 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( @@ -475,13 +483,13 @@ void ClearWindowState(unsigned int flags) // NOTE: This must be handled before FLAG_FULLSCREEN_MODE because ToggleBorderlessWindowed() needs to get some fullscreen values if fullscreen is running if ((FLAG_IS_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE)) && (FLAG_IS_SET(flags, FLAG_BORDERLESS_WINDOWED_MODE))) { - ToggleBorderlessWindowed(); // NOTE: Window state flag updated inside function + ToggleBorderlessWindowed(); // NOTE: Window state flag updated inside function } // State change: FLAG_FULLSCREEN_MODE if ((FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) && (FLAG_IS_SET(flags, FLAG_FULLSCREEN_MODE))) { - ToggleFullscreen(); // NOTE: Window state flag updated inside function + ToggleFullscreen(); // NOTE: Window state flag updated inside function } // State change: FLAG_WINDOW_RESIZABLE @@ -894,7 +902,8 @@ Vector2 GetMonitorPosition(int monitor) if ((monitor >= 0) && (monitor < monitorCount)) { - int x, y; + int x = 0; + int y = 0; glfwGetMonitorPos(monitors[monitor], &x, &y); return (Vector2){ (float)x, (float)y }; @@ -1015,8 +1024,8 @@ Vector2 GetWindowPosition(void) // Get window scale DPI factor for current monitor Vector2 GetWindowScaleDPI(void) { - Vector2 scale = { 0 }; - glfwGetWindowContentScale(platform.handle, &scale.x, &scale.y); + Vector2 scale = { 1.0f, 1.0f }; + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) glfwGetWindowContentScale(platform.handle, &scale.x, &scale.y); return scale; } @@ -1122,7 +1131,7 @@ double GetTime(void) // NOTE: This function is only safe to use if you control the URL given // A user could craft a malicious string performing another action // Only call this function yourself not with user input or make sure to check the string yourself -// Ref: https://github.com/raysan5/raylib/issues/686 +// REF: https://github.com/raysan5/raylib/issues/686 void OpenURL(const char *url) { // Security check to (partially) avoid malicious code @@ -1234,8 +1243,8 @@ void PollInputEvents(void) // Map touch position to mouse position for convenience // WARNING: If the target desktop device supports touch screen, this behaviour should be reviewed! // TODO: GLFW does not support multi-touch input yet - // Ref: https://www.codeproject.com/Articles/668404/Programming-for-Multi-Touch - // Ref: https://docs.microsoft.com/en-us/windows/win32/wintouch/getting-started-with-multi-touch-messages + // REF: https://www.codeproject.com/Articles/668404/Programming-for-Multi-Touch + // REF: https://docs.microsoft.com/en-us/windows/win32/wintouch/getting-started-with-multi-touch-messages CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; // Check if gamepads are ready @@ -1328,7 +1337,8 @@ void PollInputEvents(void) CORE.Window.resizedLastFrame = false; - if ((CORE.Window.eventWaiting) || (IsWindowState(FLAG_WINDOW_MINIMIZED) && !IsWindowState(FLAG_WINDOW_ALWAYS_RUN))) + if ((CORE.Window.eventWaiting) || + (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED) && !FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_ALWAYS_RUN))) { glfwWaitEvents(); // Wait for in input events before continue (drawing is paused) CORE.Time.previous = GetTime(); @@ -1347,7 +1357,7 @@ void PollInputEvents(void) // 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 // 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) { (void)user; @@ -1433,31 +1443,27 @@ int InitPlatform(void) if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_TRANSPARENT)) glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE); // Transparent framebuffer else glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_FALSE); // Opaque framebuffer - // HACK: Most of this was written before GLFW_SCALE_FRAMEBUFFER existed and - // was enabled by default. Disabling it gets back the old behavior. A - // complete fix will require removing a lot of CORE.Window.render - // manipulation code - // NOTE: This currently doesn't work on macOS(see #5185), so we skip it there - // when FLAG_WINDOW_HIGHDPI is *unset* -#if !defined(__APPLE__) - glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_FALSE); -#endif - if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) { - // since we skipped it before, now make sure to set this on macOS #if defined(__APPLE__) glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_FALSE); #endif // Resize window content area based on the monitor content scale - // NOTE: This hint only has an effect on platforms where screen coordinates and pixels always map 1:1 such as Windows and X11 + // NOTE: This hint only has an effect on platforms where screen coordinates and + // pixels always map 1:1 such as Windows and X11 // On platforms like macOS the resolution of the framebuffer is changed independently of the window size - glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE); // Scale content area based on the monitor content scale where window is placed on + glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE); #if defined(__APPLE__) glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_TRUE); #endif } - else glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_FALSE); + else + { + glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_FALSE); +#if defined(__APPLE__) + glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_FALSE); +#endif + } // Mouse passthrough if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MOUSE_PASSTHROUGH)) glfwWindowHint(GLFW_MOUSE_PASSTHROUGH, GLFW_TRUE); @@ -1527,17 +1533,24 @@ int InitPlatform(void) GLFWmonitor *monitor = NULL; if (CORE.Window.fullscreen) { - // According to glfwCreateWindow(), if the user does not have a choice, fullscreen applications - // should default to the primary monitor - + // NOTE: Fullscreen applications default to the primary monitor monitor = glfwGetPrimaryMonitor(); if (!monitor) { - TRACELOG(LOG_WARNING, "GLFW: Failed to get primary monitor"); - return -1; + TRACELOG(LOG_WARNING, "GLFW: Failed to get primary monitor"); + return -1; } - SetDimensionsFromMonitor(monitor); + // Set dimensions from monitor + const GLFWvidmode *mode = glfwGetVideoMode(monitor); + + // Default display resolution to that of the current mode + CORE.Window.display.width = mode->width; + CORE.Window.display.height = mode->height; + + // Set screen width/height to the display width/height if they are 0 + 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; // 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)) @@ -1626,7 +1639,15 @@ int InitPlatform(void) if (monitorIndex < monitorCount) { monitor = monitors[monitorIndex]; - SetDimensionsFromMonitor(monitor); + const GLFWvidmode *mode = glfwGetVideoMode(monitor); + + // Default display resolution to that of the current mode + CORE.Window.display.width = mode->width; + CORE.Window.display.height = mode->height; + + // Set screen width/height to the display width/height if they are 0 + 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 (requestWindowedFullscreen) glfwSetWindowSize(platform.handle, CORE.Window.screen.width, CORE.Window.screen.height); } @@ -1638,6 +1659,7 @@ int InitPlatform(void) return -1; } + // NOTE: Not considering scale factor now, considered below CORE.Window.render.width = CORE.Window.screen.width; CORE.Window.render.height = CORE.Window.screen.height; } @@ -1668,16 +1690,15 @@ int InitPlatform(void) if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) { // NOTE: On APPLE platforms system should manage window/input scaling and also framebuffer scaling - // Framebuffer scaling should be activated with: glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_TRUE); - #if !defined(__APPLE__) + // Framebuffer scaling is activated with: glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_TRUE); glfwGetFramebufferSize(platform.handle, &fbWidth, &fbHeight); // Screen scaling matrix is required in case desired screen area is different from display area CORE.Window.screenScale = MatrixScale((float)fbWidth/CORE.Window.screen.width, (float)fbHeight/CORE.Window.screen.height, 1.0f); - +#if !defined(__APPLE__) // Mouse input scaling for the new screen size SetMouseScale((float)CORE.Window.screen.width/fbWidth, (float)CORE.Window.screen.height/fbHeight); - #endif +#endif } CORE.Window.render.width = fbWidth; @@ -1734,28 +1755,24 @@ int InitPlatform(void) // Initialize input events callbacks //---------------------------------------------------------------------------- // Set window callback events - glfwSetWindowSizeCallback(platform.handle, WindowSizeCallback); // NOTE: Resizing not allowed by default! + glfwSetWindowSizeCallback(platform.handle, WindowSizeCallback); // NOTE: Resizing is not enabled by default + glfwSetFramebufferSizeCallback(platform.handle, FramebufferSizeCallback); glfwSetWindowPosCallback(platform.handle, WindowPosCallback); glfwSetWindowMaximizeCallback(platform.handle, WindowMaximizeCallback); glfwSetWindowIconifyCallback(platform.handle, WindowIconifyCallback); glfwSetWindowFocusCallback(platform.handle, WindowFocusCallback); glfwSetDropCallback(platform.handle, WindowDropCallback); - - if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) - { - glfwSetWindowContentScaleCallback(platform.handle, WindowContentScaleCallback); - } + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) glfwSetWindowContentScaleCallback(platform.handle, WindowContentScaleCallback); // Set input callback events glfwSetKeyCallback(platform.handle, KeyCallback); glfwSetCharCallback(platform.handle, CharCallback); glfwSetMouseButtonCallback(platform.handle, MouseButtonCallback); - glfwSetCursorPosCallback(platform.handle, MouseCursorPosCallback); // Track mouse position changes + glfwSetCursorPosCallback(platform.handle, MouseCursorPosCallback); // Track mouse position changes glfwSetScrollCallback(platform.handle, MouseScrollCallback); glfwSetCursorEnterCallback(platform.handle, CursorEnterCallback); glfwSetJoystickCallback(JoystickCallback); - - glfwSetInputMode(platform.handle, GLFW_LOCK_KEY_MODS, GLFW_TRUE); // Enable lock keys modifiers (CAPS, NUM) + glfwSetInputMode(platform.handle, GLFW_LOCK_KEY_MODS, GLFW_TRUE); // Enable lock keys modifiers (CAPS, NUM) // Retrieve gamepad names for (int i = 0; i < MAX_GAMEPADS; i++) @@ -1813,79 +1830,116 @@ void ClosePlatform(void) #endif } -// GLFW3 Error Callback, runs on GLFW3 error +//---------------------------------------------------------------------------------- +// Module Internal Functions Definition +// NOTE: Those functions are only required for current platform +//---------------------------------------------------------------------------------- + +// GLFW3: Error callback, runs on GLFW3 error static void ErrorCallback(int error, const char *description) { TRACELOG(LOG_WARNING, "GLFW: Error: %i Description: %s", error, description); } -// GLFW3 WindowSize Callback, runs when window is resizedLastFrame +// GLFW3: Window size change callback, runs when window is resized // NOTE: Window resizing not enabled by default, use SetConfigFlags() static void WindowSizeCallback(GLFWwindow *window, int width, int height) { + // Nothing to do for now on window resize... + //TRACELOG(LOG_INFO, "GLFW3: Window size callback called [%i,%i]", width, height); +} + +// GLFW3: Framebuffer size change callback, runs when framebuffer is resized +// WARNING: If FLAG_WINDOW_HIGHDPI is set, WindowContentScaleCallback() is called before this function +static void FramebufferSizeCallback(GLFWwindow *window, int width, int height) +{ + //TRACELOG(LOG_INFO, "GLFW3: Window framebuffer size callback called [%i,%i]", width, height); + // WARNING: On window minimization, callback is called, // but we don't want to change internal screen values, it breaks things if ((width == 0) || (height == 0)) return; // Reset viewport and projection matrix for new size + // NOTE: Stores current render size: CORE.Window.render SetupViewport(width, height); + // Set render size CORE.Window.currentFbo.width = width; CORE.Window.currentFbo.height = height; CORE.Window.resizedLastFrame = true; - if (IsWindowFullscreen()) return; - - // if we are doing automatic DPI scaling, then the "screen" size is divided by the window scale - if (IsWindowState(FLAG_WINDOW_HIGHDPI)) + // Check if render size was actually scaled for high-dpi + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) { - width = (int)(width/GetWindowScaleDPI().x); - height = (int)(height/GetWindowScaleDPI().y); + // Set screen size to logical pixel size, considering content scaling + Vector2 scaleDpi = GetWindowScaleDPI(); + CORE.Window.screen.width = (int)((float)width/scaleDpi.x); + CORE.Window.screen.height = (int)((float)height/scaleDpi.y); + } + else + { + // Set screen size to render size (physical pixel size) + CORE.Window.screen.width = width; + CORE.Window.screen.height = height; } - - // Set render size - CORE.Window.render.width = width; - CORE.Window.render.height = height; - - // Set current screen size - CORE.Window.screen.width = width; - CORE.Window.screen.height = height; // WARNING: If using a render texture, it is not scaled to new size } -static void WindowPosCallback(GLFWwindow* window, int x, int y) + +// GLFW3: Window content scale callback, runs on monitor content scale change detected +// WARNING: If FLAG_WINDOW_HIGHDPI is not set, this function is not called +static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float scaley) +{ + TRACELOG(LOG_INFO, "GLFW3: Window content scale changed, scale: [%.2f,%.2f]", scalex, scaley); + + float fbWidth = (float)CORE.Window.screen.width*scalex; + float fbHeight = (float)CORE.Window.screen.height*scaley; + + // 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); + CORE.Window.screenScale = MatrixScale(scalex, scaley, 1.0f); + +#if !defined(__APPLE__) + // Mouse input scaling for the new screen size + SetMouseScale((float)CORE.Window.screen.width/fbWidth, (float)CORE.Window.screen.height/fbHeight); +#endif + + CORE.Window.render.width = (int)fbWidth; + CORE.Window.render.height = (int)fbHeight; + CORE.Window.currentFbo.width = (int)fbWidth; + CORE.Window.currentFbo.height = (int)fbHeight; +} + +// GLFW3: Window position callback, runs when window position changes +static void WindowPosCallback(GLFWwindow *window, int x, int y) { // Set current window position CORE.Window.position.x = x; CORE.Window.position.y = y; } -static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float scaley) -{ - CORE.Window.screenScale = MatrixScale(scalex, scaley, 1.0f); -} -// GLFW3 WindowIconify Callback, runs when window is minimized/restored +// GLFW3: Window iconify callback, runs when window is minimized/restored static void WindowIconifyCallback(GLFWwindow *window, int iconified) { if (iconified) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); // The window was iconified else FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); // The window was restored } -// GLFW3 WindowMaximize Callback, runs when window is maximized/restored +// GLFW3: Window maximize callback, runs when window is maximized/restored static void WindowMaximizeCallback(GLFWwindow *window, int maximized) { if (maximized) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); // The window was maximized else FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); // The window was restored } -// GLFW3 WindowFocus Callback, runs when window get/lose focus +// GLFW3: Window focus callback, runs when window get/lose focus static void WindowFocusCallback(GLFWwindow *window, int focused) { if (focused) FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); // The window was focused else FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); // The window lost focus } -// GLFW3 Window Drop Callback, runs when drop files into window +// GLFW3: Window drop callback, runs when files are dropped into window static void WindowDropCallback(GLFWwindow *window, int count, const char **paths) { if (count > 0) @@ -1913,7 +1967,7 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths } } -// GLFW3 Keyboard Callback, runs on key pressed +// GLFW3: Keyboard callback, runs on key pressed static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods) { if (key < 0) return; // Security check, macOS fn key generates -1 @@ -1940,13 +1994,13 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i if ((key == CORE.Input.Keyboard.exitKey) && (action == GLFW_PRESS)) glfwSetWindowShouldClose(platform.handle, GLFW_TRUE); } -// GLFW3 Char Callback, get unicode codepoint value +// GLFW3: Char callback, runs on key pressed to get unicode codepoint value static void CharCallback(GLFWwindow *window, unsigned int codepoint) { // NOTE: Registers any key down considering OS keyboard layout but // does not detect action events, those should be managed by user... - // Ref: https://github.com/glfw/glfw/issues/668#issuecomment-166794907 - // Ref: https://www.glfw.org/docs/latest/input_guide.html#input_char + // REF: https://github.com/glfw/glfw/issues/668#issuecomment-166794907 + // REF: https://www.glfw.org/docs/latest/input_guide.html#input_char // Check if there is space available in the queue if (CORE.Input.Keyboard.charPressedQueueCount < MAX_CHAR_PRESSED_QUEUE) @@ -1957,7 +2011,7 @@ static void CharCallback(GLFWwindow *window, unsigned int codepoint) } } -// GLFW3 Mouse Button Callback, runs on mouse button pressed +// GLFW3: Mouse button callback, runs on mouse button pressed static void MouseButtonCallback(GLFWwindow *window, int button, int action, int mods) { // WARNING: GLFW could only return GLFW_PRESS (1) or GLFW_RELEASE (0) for now, @@ -1993,7 +2047,7 @@ static void MouseButtonCallback(GLFWwindow *window, int button, int action, int #endif } -// GLFW3 Cursor Position Callback, runs on mouse move +// GLFW3: Cursor position callback, runs on mouse movement static void MouseCursorPosCallback(GLFWwindow *window, double x, double y) { CORE.Input.Mouse.currentPosition.x = (float)x; @@ -2024,20 +2078,20 @@ static void MouseCursorPosCallback(GLFWwindow *window, double x, double y) #endif } -// GLFW3 Scrolling Callback, runs on mouse wheel +// GLFW3: Mouse wheel scroll callback, runs on mouse wheel changes static void MouseScrollCallback(GLFWwindow *window, double xoffset, double yoffset) { CORE.Input.Mouse.currentWheelMove = (Vector2){ (float)xoffset, (float)yoffset }; } -// GLFW3 CursorEnter Callback, when cursor enters the window +// GLFW3: Cursor ennter callback, when cursor enters the window static void CursorEnterCallback(GLFWwindow *window, int enter) { if (enter) CORE.Input.Mouse.cursorOnScreen = true; else CORE.Input.Mouse.cursorOnScreen = false; } -// GLFW3 Joystick Connected/Disconnected Callback +// GLFW3: Joystick connected/disconnected callback static void JoystickCallback(int jid, int event) { if (event == GLFW_CONNECTED) @@ -2053,20 +2107,6 @@ static void JoystickCallback(int jid, int event) } } -// Set screen dimensions from monitor/display dimensions -static void SetDimensionsFromMonitor(GLFWmonitor *monitor) -{ - const GLFWvidmode *mode = glfwGetVideoMode(monitor); - - // Default display resolution to that of the current mode - CORE.Window.display.width = mode->width; - CORE.Window.display.height = mode->height; - - // Set screen width/height to the display width/height if they are 0 - 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; -} - #ifdef _WIN32 # define WIN32_CLIPBOARD_IMPLEMENTATION # include "../external/win32_clipboard.h" diff --git a/src/platforms/rcore_desktop_rgfw.c b/src/platforms/rcore_desktop_rgfw.c index 7a2464eb9..39ac8fb32 100644 --- a/src/platforms/rcore_desktop_rgfw.c +++ b/src/platforms/rcore_desktop_rgfw.c @@ -48,11 +48,6 @@ * **********************************************************************************************/ -#ifndef RAYLIB_H /* this should never actually happen, it's only here for IDEs */ -#include "raylib.h" -#include "../rcore.c" -#endif - #if defined(PLATFORM_WEB_RGFW) #define RGFW_NO_GL_HEADER #endif diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index 36235a6c8..add1de6ad 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -57,7 +57,7 @@ // SDL base library (window/rendered, input, timing... functionality) #ifdef USING_SDL3_PROJECT #include "SDL3/SDL.h" -#elif USING_SDL2_PROJECT +#elif defined(USING_SDL2_PROJECT) #include "SDL2/SDL.h" #else #include "SDL.h" @@ -71,7 +71,7 @@ // SDL OpenGL functionality (if required, instead of internal renderer) #ifdef USING_SDL3_PROJECT #include "SDL3/SDL_opengl.h" - #elif USING_SDL2_PROJECT + #elif defined(USING_SDL2_PROJECT) #include "SDL2/SDL_opengl.h" #else #include "SDL_opengl.h" @@ -679,6 +679,7 @@ void ClearWindowState(unsigned int flags) { TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_TRANSPARENT is not supported on PLATFORM_DESKTOP_SDL"); } + if (FLAG_IS_SET(flags, FLAG_WINDOW_HIGHDPI)) { // NOTE: There also doesn't seem to be a feature to disable high DPI once enabled TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_HIGHDPI is not supported on PLATFORM_DESKTOP_SDL"); @@ -1041,7 +1042,7 @@ int GetMonitorPhysicalWidth(int monitor) SDL_DisplayMode mode; SDL_GetCurrentDisplayMode(monitor, &mode); // Calculate size on inches, then convert to millimeter - if (ddpi > 0.0f) width = (mode.w/ddpi)*25.4f; + if (ddpi > 0.0f) width = (int)((mode.w/ddpi)*25.4f); } else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor"); @@ -1065,7 +1066,7 @@ int GetMonitorPhysicalHeight(int monitor) SDL_DisplayMode mode; SDL_GetCurrentDisplayMode(monitor, &mode); // Calculate size on inches, then convert to millimeter - if (ddpi > 0.0f) height = (mode.h/ddpi)*25.4f; + if (ddpi > 0.0f) height = (int)((mode.h/ddpi)*25.4f); } else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor"); @@ -1127,14 +1128,15 @@ Vector2 GetWindowScaleDPI(void) { Vector2 scale = { 1.0f, 1.0f }; -#ifndef USING_VERSION_SDL3 - // NOTE: SDL_GetWindowDisplayScale was only added on SDL3 - // Ref: https://wiki.libsdl.org/SDL3/SDL_GetWindowDisplayScale - // TODO: Implement the window scale factor calculation manually - TRACELOG(LOG_WARNING, "GetWindowScaleDPI() not implemented on target platform"); -#else +#if defined(USING_VERSION_SDL3) + // NOTE: SDL_GetWindowDisplayScale added on SDL3 + // REF: https://wiki.libsdl.org/SDL3/SDL_GetWindowDisplayScale scale.x = SDL_GetWindowDisplayScale(platform.window); scale.y = scale.x; +#else + // NOTE: SDL_GetWindowDisplayScale not available on SDL2 + // TODO: Implement the window scale factor calculation manually + TRACELOG(LOG_WARNING, "GetWindowScaleDPI() not implemented on target platform"); #endif return scale; @@ -1195,7 +1197,7 @@ Image GetClipboardImage(void) if (fileData) { - image = LoadImageFromMemory(imageExtensions[i], fileData, dataSize); + image = LoadImageFromMemory(imageExtensions[i], fileData, (int)dataSize); if (IsImageValid(image)) { TRACELOG(LOG_INFO, "Clipboard: Got image from clipboard successfully: %s", imageExtensions[i]); @@ -1279,7 +1281,7 @@ double GetTime(void) // NOTE: This function is only safe to use if you control the URL given // A user could craft a malicious string performing another action // Only call this function yourself not with user input or make sure to check the string yourself -// Ref: https://github.com/raysan5/raylib/issues/686 +// REF: https://github.com/raysan5/raylib/issues/686 void OpenURL(const char *url) { // Security check to (partially) avoid malicious code @@ -1454,7 +1456,7 @@ void PollInputEvents(void) } break; - // Window events are also polled (Minimized, maximized, close...) + // Window events are also polled (minimized, maximized, close...) #ifndef USING_VERSION_SDL3 // SDL3 states: @@ -1473,7 +1475,7 @@ void PollInputEvents(void) const int height = event.window.data2; SetupViewport(width, height); // if we are doing automatic DPI scaling, then the "screen" size is divided by the window scale - if (IsWindowState(FLAG_WINDOW_HIGHDPI)) + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) { CORE.Window.screen.width = (int)(width/GetWindowScaleDPI().x); CORE.Window.screen.height = (int)(height/GetWindowScaleDPI().y); @@ -1488,7 +1490,8 @@ void PollInputEvents(void) CORE.Window.resizedLastFrame = true; #ifndef USING_VERSION_SDL3 - // Manually detect if the window was maximized (due to SDL2 restore being unreliable on some platforms) to remove the FLAG_WINDOW_MAXIMIZED accordingly + // Manually detect if the window was maximized (due to SDL2 restore being unreliable on some platforms) + // to remove the FLAG_WINDOW_MAXIMIZED accordingly if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED)) { int borderTop = 0; @@ -1504,14 +1507,8 @@ void PollInputEvents(void) #endif } break; - case SDL_WINDOWEVENT_ENTER: - { - CORE.Input.Mouse.cursorOnScreen = true; - } break; - case SDL_WINDOWEVENT_LEAVE: - { - CORE.Input.Mouse.cursorOnScreen = false; - } break; + case SDL_WINDOWEVENT_ENTER: CORE.Input.Mouse.cursorOnScreen = true; break; + case SDL_WINDOWEVENT_LEAVE: CORE.Input.Mouse.cursorOnScreen = false; break; case SDL_WINDOWEVENT_MINIMIZED: { @@ -1750,7 +1747,11 @@ void PollInputEvents(void) { int button = -1; + #if defined(USING_VERSION_SDL3) switch (event.gbutton.button) + #else + switch (event.jbutton.button) + #endif { case SDL_CONTROLLER_BUTTON_Y: button = GAMEPAD_BUTTON_RIGHT_FACE_UP; break; case SDL_CONTROLLER_BUTTON_B: button = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT; break; @@ -1778,7 +1779,11 @@ void PollInputEvents(void) { for (int i = 0; i < MAX_GAMEPADS; i++) { + #if defined(USING_VERSION_SDL3) if (platform.gamepadId[i] == event.gbutton.which) + #else + if (platform.gamepadId[i] == event.jbutton.which) + #endif { CORE.Input.Gamepad.currentButtonState[i][button] = 1; CORE.Input.Gamepad.lastButtonPressed = button; @@ -1791,7 +1796,11 @@ void PollInputEvents(void) { int button = -1; + #if defined(USING_VERSION_SDL3) switch (event.gbutton.button) + #else + switch (event.jbutton.button) + #endif { case SDL_CONTROLLER_BUTTON_Y: button = GAMEPAD_BUTTON_RIGHT_FACE_UP; break; case SDL_CONTROLLER_BUTTON_B: button = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT; break; @@ -1819,7 +1828,11 @@ void PollInputEvents(void) { for (int i = 0; i < MAX_GAMEPADS; i++) { + #if defined(USING_VERSION_SDL3) if (platform.gamepadId[i] == event.gbutton.which) + #else + if (platform.gamepadId[i] == event.jbutton.which) + #endif { CORE.Input.Gamepad.currentButtonState[i][button] = 0; if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0; @@ -2054,28 +2067,23 @@ int InitPlatform(void) platform.gamepadId[i] = -1; // Set all gamepad initial instance ids as invalid to not conflict with instance id zero } - int numJoysticks = 0; - SDL_JoystickID *joysticks = SDL_GetJoysticks(&numJoysticks); // array of joystick IDs, they do not start from 0 + int numJoysticks = SDL_NumJoysticks(); - if (joysticks) + for (int i = 0; (i < numJoysticks) && (i < MAX_GAMEPADS); i++) { - for (int i = 0; (i < numJoysticks) && (i < MAX_GAMEPADS); i++) - { - platform.gamepad[i] = SDL_GameControllerOpen(joysticks[i]); - platform.gamepadId[i] = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(platform.gamepad[i])); + platform.gamepad[i] = SDL_GameControllerOpen(i); + platform.gamepadId[i] = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(platform.gamepad[i])); - if (platform.gamepad[i]) - { - CORE.Input.Gamepad.ready[i] = true; - CORE.Input.Gamepad.axisCount[i] = SDL_JoystickNumAxes(SDL_GameControllerGetJoystick(platform.gamepad[i])); - CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f; - CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f; - strncpy(CORE.Input.Gamepad.name[i], SDL_GameControllerNameForIndex(i), MAX_GAMEPAD_NAME_LENGTH - 1); - CORE.Input.Gamepad.name[i][MAX_GAMEPAD_NAME_LENGTH - 1] = '\0'; - } - else TRACELOG(LOG_WARNING, "PLATFORM: Unable to open game controller [ERROR: %s]", SDL_GetError()); + if (platform.gamepad[i]) + { + CORE.Input.Gamepad.ready[i] = true; + CORE.Input.Gamepad.axisCount[i] = SDL_JoystickNumAxes(SDL_GameControllerGetJoystick(platform.gamepad[i])); + CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f; + CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f; + strncpy(CORE.Input.Gamepad.name[i], SDL_GameControllerNameForIndex(i), MAX_GAMEPAD_NAME_LENGTH - 1); + CORE.Input.Gamepad.name[i][MAX_GAMEPAD_NAME_LENGTH - 1] = '\0'; } - SDL_free(joysticks); + else TRACELOG(LOG_WARNING, "PLATFORM: Unable to open game controller [ERROR: %s]", SDL_GetError()); } // Disable mouse events being interpreted as touch events @@ -2196,7 +2204,7 @@ static void UpdateTouchPointsSDL(SDL_TouchFingerEvent event) for (int i = 0; i < CORE.Input.Touch.pointCount; i++) { SDL_Finger *finger = SDL_GetTouchFinger(event.touchId, i); - CORE.Input.Touch.pointId[i] = finger->id; + CORE.Input.Touch.pointId[i] = (int)finger->id; CORE.Input.Touch.position[i].x = finger->x*CORE.Window.screen.width; CORE.Input.Touch.position[i].y = finger->y*CORE.Window.screen.height; CORE.Input.Touch.currentTouchState[i] = 1; diff --git a/src/platforms/rcore_desktop_win32.c b/src/platforms/rcore_desktop_win32.c index 8a4050332..29702921f 100644 --- a/src/platforms/rcore_desktop_win32.c +++ b/src/platforms/rcore_desktop_win32.c @@ -1239,7 +1239,7 @@ double GetTime(void) // NOTE: This function is only safe to use if you control the URL given // A user could craft a malicious string performing another action // Only call this function yourself not with user input or make sure to check the string yourself -// Ref: https://github.com/raysan5/raylib/issues/686 +// REF: https://github.com/raysan5/raylib/issues/686 void OpenURL(const char *url) { // Security check to (partially) avoid malicious code on target platform diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index 68d5b9685..640799b0a 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -220,7 +220,7 @@ static const short linuxToRaylibMap[KEYMAP_SIZE] = { 248, 0, 0, 0, 0, 0, 0, 0, // Gamepads are mapped according to: - // Ref: https://www.kernel.org/doc/html/next/input/gamepad.html + // REF: https://www.kernel.org/doc/html/next/input/gamepad.html // Those mappings are standardized, but that doesn't mean people follow // the standards, so this is more of an approximation [BTN_DPAD_UP] = GAMEPAD_BUTTON_LEFT_FACE_UP, @@ -1013,7 +1013,7 @@ double GetTime(void) // NOTE: This function is only safe to use if you control the URL given // A user could craft a malicious string performing another action // Only call this function yourself not with user input or make sure to check the string yourself -// Ref: https://github.com/raysan5/raylib/issues/686 +// REF: https://github.com/raysan5/raylib/issues/686 void OpenURL(const char *url) { TRACELOG(LOG_WARNING, "OpenURL() not implemented on target platform"); diff --git a/src/platforms/rcore_memory.c b/src/platforms/rcore_memory.c index f78b72fed..1b7a55fd8 100644 --- a/src/platforms/rcore_memory.c +++ b/src/platforms/rcore_memory.c @@ -383,7 +383,7 @@ double GetTime(void) // NOTE: This function is only safe to use if you control the URL given. // A user could craft a malicious string performing another action. // Only call this function yourself not with user input or make sure to check the string yourself. -// Ref: https://github.com/raysan5/raylib/issues/686 +// REF: https://github.com/raysan5/raylib/issues/686 void OpenURL(const char *url) { // Security check to (partially) avoid malicious code on target platform @@ -428,7 +428,7 @@ void SetMouseCursor(int cursor) TRACELOG(LOG_WARNING, "SetMouseCursor() not implemented on target platform"); } -// Get physical key name. +// Get physical key name const char *GetKeyName(int key) { TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform"); diff --git a/src/platforms/rcore_template.c b/src/platforms/rcore_template.c index bc03a3cdb..1f8c5242b 100644 --- a/src/platforms/rcore_template.c +++ b/src/platforms/rcore_template.c @@ -54,11 +54,6 @@ typedef struct { // TODO: Define the platform specific variables required - // Display data - EGLDisplay device; // Native display device (physical screen connection) - EGLSurface surface; // Surface to draw on, framebuffers (connected to context) - EGLContext context; // Graphic context, mode in which drawing can be done - EGLConfig config; // Graphic config } PlatformData; //---------------------------------------------------------------------------------- @@ -346,10 +341,10 @@ void SwapScreenBuffer(void) double GetTime(void) { double time = 0.0; + struct timespec ts = { 0 }; clock_gettime(CLOCK_MONOTONIC, &ts); unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec; - time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer() return time; @@ -366,7 +361,7 @@ void OpenURL(const char *url) if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character"); else { - // TODO: + // TODO: Load url using default browser } } @@ -462,86 +457,18 @@ int InitPlatform(void) CORE.Window.fullscreen = true; FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); - EGLint samples = 0; - EGLint sampleBuffer = 0; if (FLAG_IS_SET(CORE.Window.flags, FLAG_MSAA_4X_HINT)) { - samples = 4; - sampleBuffer = 1; + // TODO: Enable MSAA + TRACELOG(LOG_INFO, "DISPLAY: Trying to enable MSAA x4"); } - const EGLint framebufferAttribs[] = - { - EGL_RENDERABLE_TYPE, (rlGetVersion() == RL_OPENGL_ES_30)? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT, // Type of context support - EGL_RED_SIZE, 8, // RED color bit depth (alternative: 5) - EGL_GREEN_SIZE, 8, // GREEN color bit depth (alternative: 6) - EGL_BLUE_SIZE, 8, // BLUE color bit depth (alternative: 5) - //EGL_TRANSPARENT_TYPE, EGL_NONE, // Request transparent framebuffer (EGL_TRANSPARENT_RGB does not work on RPI) - EGL_DEPTH_SIZE, 16, // Depth buffer size (Required to use Depth testing!) - //EGL_STENCIL_SIZE, 8, // Stencil buffer size - EGL_SAMPLE_BUFFERS, sampleBuffer, // Activate MSAA - EGL_SAMPLES, samples, // 4x Antialiasing if activated (Free on MALI GPUs) - EGL_NONE - }; + // TODO: Init display and graphic device - const EGLint contextAttribs[] = - { - EGL_CONTEXT_CLIENT_VERSION, 2, - EGL_NONE - }; - - EGLint numConfigs = 0; - - // Get an EGL device connection - platform.device = eglGetDisplay(EGL_DEFAULT_DISPLAY); - if (platform.device == EGL_NO_DISPLAY) - { - TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device"); - return false; - } - - // Initialize the EGL device connection - if (eglInitialize(platform.device, NULL, NULL) == EGL_FALSE) - { - // If all of the calls to eglInitialize returned EGL_FALSE then an error has occurred. - TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device"); - return false; - } - - // Get an appropriate EGL framebuffer configuration - eglChooseConfig(platform.device, framebufferAttribs, &platform.config, 1, &numConfigs); - - // Set rendering API - eglBindAPI(EGL_OPENGL_ES_API); - - // Create an EGL rendering context - platform.context = eglCreateContext(platform.device, platform.config, EGL_NO_CONTEXT, contextAttribs); - if (platform.context == EGL_NO_CONTEXT) - { - TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL context"); - return -1; - } - - // Create an EGL window surface - EGLint displayFormat = 0; - - // EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is guaranteed to be accepted by ANativeWindow_setBuffersGeometry() - // As soon as we picked a EGLConfig, we can safely reconfigure the ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID - eglGetConfigAttrib(platform.device, platform.config, EGL_NATIVE_VISUAL_ID, &displayFormat); - - // Android specific call - ANativeWindow_setBuffersGeometry(platform.app->window, 0, 0, displayFormat); // Force use of native display size - - platform.surface = eglCreateWindowSurface(platform.device, platform.config, platform.app->window, NULL); - - // There must be at least one frame displayed before the buffers are swapped - eglSwapInterval(platform.device, 1); - - EGLBoolean result = eglMakeCurrent(platform.device, platform.surface, platform.surface, platform.context); - - // Check surface and context activation - if (result != EGL_FALSE) + // TODO: Check display, device and context activation + bool result = true; + if (result) { CORE.Window.ready = true; diff --git a/src/platforms/rcore_web.c b/src/platforms/rcore_web.c index 2d2f8d1c0..934f778c3 100644 --- a/src/platforms/rcore_web.c +++ b/src/platforms/rcore_web.c @@ -76,6 +76,13 @@ typedef struct { bool ourFullscreen; // Internal var to filter our handling of fullscreen vs the user handling of fullscreen int unmaximizedWidth; // Internal var to store the unmaximized window (canvas) width int unmaximizedHeight; // Internal var to store the unmaximized window (canvas) height + + char canvasId[64]; // Keep current canvas id where wasm app is running + // NOTE: Useful when trying to run multiple wasms in different canvases in same webpage + +#if defined(GRAPHICS_API_OPENGL_11_SOFTWARE) + unsigned int *pixels; // Pointer to pixel data buffer (RGBA 32bit format) +#endif } PlatformData; //---------------------------------------------------------------------------------- @@ -129,7 +136,7 @@ static void MouseEnterCallback(GLFWwindow *window, int enter); // Emscripten window callback events static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const EmscriptenFullscreenChangeEvent *event, void *userData); -// static EM_BOOL EmscriptenWindowResizedCallback(int eventType, const EmscriptenUiEvent *event, void *userData); +//static EM_BOOL EmscriptenWindowResizedCallback(int eventType, const EmscriptenUiEvent *event, void *userData); static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent *event, void *userData); static EM_BOOL EmscriptenFocusCallback(int eventType, const EmscriptenFocusEvent *focusEvent, void *userData); static EM_BOOL EmscriptenVisibilityChangeCallback(int eventType, const EmscriptenVisibilityChangeEvent *visibilityChangeEvent, void *userData); @@ -142,7 +149,11 @@ static EM_BOOL EmscriptenPointerlockCallback(int eventType, const EmscriptenPoin static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData); static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData); -static const char *GetCanvasId(void); +// JS: Set the canvas id provided by the module configuration +EM_JS(void, SetCanvasIdJs, (char *out, int outSize), { + var canvasId = "#" + Module.canvas.id; + stringToUTF8(canvasId, out, outSize); +}); //---------------------------------------------------------------------------------- // Module Functions Declaration @@ -159,7 +170,7 @@ static const char *GetCanvasId(void); bool WindowShouldClose(void) { // Emscripten Asyncify is required to run synchronous code in asynchronous JS - // Ref: https://emscripten.org/docs/porting/asyncify.html + // REF: https://emscripten.org/docs/porting/asyncify.html // WindowShouldClose() is not called on a web-ready raylib application if using emscripten_set_main_loop() // and encapsulating one frame execution on a UpdateDrawFrame() function, @@ -233,11 +244,11 @@ void ToggleFullscreen(void) // This option does not seem to work at all: // emscripten_request_pointerlock() and emscripten_request_fullscreen() are affected by web security, // the user must click once on the canvas to hide the pointer or transition to full screen - //emscripten_request_fullscreen("#canvas", false); + //emscripten_request_fullscreen(platform.canvasId, false); // Option 2: Request fullscreen for the canvas element with strategy // This option does not seem to work at all - // Ref: https://github.com/emscripten-core/emscripten/issues/5124 + // REF: https://github.com/emscripten-core/emscripten/issues/5124 // EmscriptenFullscreenStrategy strategy = { // .scaleMode = EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH, //EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT, // .canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF, @@ -245,7 +256,7 @@ void ToggleFullscreen(void) // .canvasResizedCallback = EmscriptenWindowResizedCallback, // .canvasResizedCallbackUserData = NULL // }; - //emscripten_request_fullscreen_strategy("#canvas", EM_FALSE, &strategy); + //emscripten_request_fullscreen_strategy(platform.canvasId, EM_FALSE, &strategy); // Option 3: Request fullscreen for the canvas element with strategy // It works as expected but only inside the browser (client area) @@ -256,10 +267,11 @@ void ToggleFullscreen(void) .canvasResizedCallback = EmscriptenWindowResizedCallback, .canvasResizedCallbackUserData = NULL }; - emscripten_enter_soft_fullscreen("#canvas", &strategy); + emscripten_enter_soft_fullscreen(platform.canvasId, &strategy); - int width, height; - emscripten_get_canvas_element_size("#canvas", &width, &height); + int width = 0; + int height = 0; + emscripten_get_canvas_element_size(platform.canvasId, &width, &height); TRACELOG(LOG_WARNING, "Emscripten: Enter fullscreen: Canvas size: %i x %i", width, height); CORE.Window.fullscreen = true; // Toggle fullscreen flag @@ -271,7 +283,7 @@ void ToggleFullscreen(void) //emscripten_exit_soft_fullscreen(); int width, height; - emscripten_get_canvas_element_size("#canvas", &width, &height); + emscripten_get_canvas_element_size(platform.canvasId, &width, &height); TRACELOG(LOG_WARNING, "Emscripten: Exit fullscreen: Canvas size: %i x %i", width, height); CORE.Window.fullscreen = false; // Toggle fullscreen flag @@ -866,7 +878,7 @@ void EnableCursor(void) // Disables cursor (lock cursor) void DisableCursor(void) { - emscripten_request_pointerlock(GetCanvasId(), 1); + emscripten_request_pointerlock(platform.canvasId, 1); // Set cursor position in the middle SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2); @@ -877,7 +889,32 @@ void DisableCursor(void) // Swap back buffer with front buffer (screen drawing) void SwapScreenBuffer(void) { +#if defined(GRAPHICS_API_OPENGL_11_SOFTWARE) + // Update framebuffer + rlCopyFramebuffer(0, 0, CORE.Window.render.width, CORE.Window.render.height, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, platform.pixels); + + // Copy framebuffer data into canvas + EM_ASM({ + const width = $0; + const height = $1; + const ptr = $2; + + // Get canvas and 2d context created + const canvas = Module.canvas; + const ctx = canvas.getContext('2d'); + + if (!Module.__img || (Module.__img.width !== width) || (Module.__img.height !== height)) { + Module.__img = ctx.createImageData(width, height); + } + + const src = HEAPU8.subarray(ptr, ptr + width*height*4); // RGBA (4 bytes) + Module.__img.data.set(src); + ctx.putImageData(Module.__img, 0, 0); + + }, CORE.Window.screen.width, CORE.Window.screen.height, platform.pixels); +#else glfwSwapBuffers(platform.handle); +#endif } //---------------------------------------------------------------------------------- @@ -968,7 +1005,7 @@ void SetMouseCursor(int cursor) } } -// Get physical key name. +// Get physical key name const char *GetKeyName(int key) { TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform"); @@ -1097,6 +1134,8 @@ void PollInputEvents(void) // Initialize platform: graphics, inputs and more int InitPlatform(void) { + SetCanvasIdJs(platform.canvasId, 64); // Get the current canvas id + glfwSetErrorCallback(ErrorCallback); // Initialize GLFW internal global state @@ -1206,7 +1245,21 @@ int InitPlatform(void) // Init fullscreen toggle required var: platform.ourFullscreen = false; - + +#if defined(GRAPHICS_API_OPENGL_11_SOFTWARE) + // Avoid creating a WebGL canvas, avoid calling glfwCreateWindow() + emscripten_set_canvas_element_size(platform.canvasId, CORE.Window.screen.width, CORE.Window.screen.height); + EM_ASM({ + const canvas = document.getElementById("canvas"); + Module.canvas = canvas; + }); + + // Load memory framebuffer with desired screen size + // NOTE: Despite using a software framebuffer for blitting, GLFW still creates a WebGL canvas, + // but it is not being used, on SwapScreenBuffer() the pure software renderer is used + // 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)); +#else if (CORE.Window.fullscreen) { // remember center for switchinging from fullscreen to window @@ -1281,6 +1334,7 @@ int InitPlatform(void) TRACELOG(LOG_WARNING, "GLFW: Failed to initialize Window"); return -1; } +#endif // WARNING: glfwCreateWindow() title doesn't work with emscripten emscripten_set_window_title((CORE.Window.title != 0)? CORE.Window.title : " "); @@ -1347,14 +1401,14 @@ int InitPlatform(void) //---------------------------------------------------------------------------- // Setup window events callbacks emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenFullscreenChangeCallback); - emscripten_set_blur_callback(GetCanvasId(), platform.handle, 1, EmscriptenFocusCallback); - emscripten_set_focus_callback(GetCanvasId(), platform.handle, 1, EmscriptenFocusCallback); + emscripten_set_blur_callback(platform.canvasId, platform.handle, 1, EmscriptenFocusCallback); + emscripten_set_focus_callback(platform.canvasId, platform.handle, 1, EmscriptenFocusCallback); emscripten_set_visibilitychange_callback(NULL, 1, EmscriptenVisibilityChangeCallback); // WARNING: Below resize code was breaking fullscreen mode for sample games and examples, it needs review - // Check fullscreen change events(note this is done on the window since most browsers don't support this on #canvas) + // Check fullscreen change events(note this is done on the window since most browsers don't support this on canvas) // emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenResizeCallback); - // Check Resize event (note this is done on the window since most browsers don't support this on #canvas) + // Check Resize event (note this is done on the window since most browsers don't support this on canvas) emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenResizeCallback); // Trigger resize callback to force initial size @@ -1362,15 +1416,15 @@ int InitPlatform(void) // Setup input events // NOTE: Keyboard callbacks only used to consume some events, libglfw.js takes care of the actual input - //emscripten_set_keypress_callback(GetCanvasId(), NULL, 1, EmscriptenKeyboardCallback); // WRNING: Breaks input - //emscripten_set_keydown_callback(GetCanvasId(), NULL, 1, EmscriptenKeyboardCallback); - emscripten_set_click_callback(GetCanvasId(), NULL, 1, EmscriptenMouseCallback); + //emscripten_set_keypress_callback(platform.canvasId, NULL, 1, EmscriptenKeyboardCallback); // WRNING: Breaks input + //emscripten_set_keydown_callback(platform.canvasId, NULL, 1, EmscriptenKeyboardCallback); + emscripten_set_click_callback(platform.canvasId, NULL, 1, EmscriptenMouseCallback); emscripten_set_pointerlockchange_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenPointerlockCallback); - emscripten_set_mousemove_callback(GetCanvasId(), NULL, 1, EmscriptenMouseMoveCallback); - emscripten_set_touchstart_callback(GetCanvasId(), NULL, 1, EmscriptenTouchCallback); - emscripten_set_touchend_callback(GetCanvasId(), NULL, 1, EmscriptenTouchCallback); - emscripten_set_touchmove_callback(GetCanvasId(), NULL, 1, EmscriptenTouchCallback); - emscripten_set_touchcancel_callback(GetCanvasId(), NULL, 1, EmscriptenTouchCallback); + emscripten_set_mousemove_callback(platform.canvasId, NULL, 1, EmscriptenMouseMoveCallback); + emscripten_set_touchstart_callback(platform.canvasId, NULL, 1, EmscriptenTouchCallback); + emscripten_set_touchend_callback(platform.canvasId, NULL, 1, EmscriptenTouchCallback); + emscripten_set_touchmove_callback(platform.canvasId, NULL, 1, EmscriptenTouchCallback); + emscripten_set_touchcancel_callback(platform.canvasId, NULL, 1, EmscriptenTouchCallback); emscripten_set_gamepadconnected_callback(NULL, 1, EmscriptenGamepadCallback); emscripten_set_gamepaddisconnected_callback(NULL, 1, EmscriptenGamepadCallback); //---------------------------------------------------------------------------- @@ -1512,8 +1566,8 @@ static void CharCallback(GLFWwindow *window, unsigned int key) // NOTE: Registers any key down considering OS keyboard layout but // does not detect action events, those should be managed by user... - // Ref: https://github.com/glfw/glfw/issues/668#issuecomment-166794907 - // Ref: https://www.glfw.org/docs/latest/input_guide.html#input_char + // REF: https://github.com/glfw/glfw/issues/668#issuecomment-166794907 + // REF: https://www.glfw.org/docs/latest/input_guide.html#input_char // Check if there is space available in the queue if (CORE.Input.Keyboard.charPressedQueueCount < MAX_CHAR_PRESSED_QUEUE) @@ -1691,7 +1745,7 @@ static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent // NOTE: emscripten_get_canvas_element_size() returns canvas.width and canvas.height but // we are looking for actual CSS size: canvas.style.width and canvas.style.height // EMSCRIPTEN_RESULT res = emscripten_get_canvas_element_size("#canvas", &canvasWidth, &canvasHeight); - emscripten_get_element_css_size(GetCanvasId(), &canvasWidth, &canvasHeight); + emscripten_get_element_css_size(platform.canvasId, &canvasWidth, &canvasHeight); for (int i = 0; (i < CORE.Input.Touch.pointCount) && (i < MAX_TOUCH_POINTS); i++) { @@ -1802,7 +1856,7 @@ static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent * if (height < (int)CORE.Window.screenMin.height) height = CORE.Window.screenMin.height; else if ((height > (int)CORE.Window.screenMax.height) && (CORE.Window.screenMax.height > 0)) height = CORE.Window.screenMax.height; - emscripten_set_canvas_element_size(GetCanvasId(), width, height); + emscripten_set_canvas_element_size(platform.canvasId, width, height); SetupViewport(width, height); // Reset viewport and projection matrix for new size @@ -1845,21 +1899,4 @@ static EM_BOOL EmscriptenVisibilityChangeCallback(int eventType, const Emscripte } //------------------------------------------------------------------------------------------------------- -// JS: Get the canvas id provided by the module configuration -EM_JS(char *, GetCanvasIdJs, (), { - var canvasId = "#" + Module.canvas.id; - var lengthBytes = lengthBytesUTF8(canvasId) + 1; - var stringOnWasmHeap = _malloc(lengthBytes); - stringToUTF8(canvasId, stringOnWasmHeap, lengthBytes); - return stringOnWasmHeap; -}); - -// Get canvas id (using embedded JS function) -static const char *GetCanvasId(void) -{ - static char *canvasId = NULL; - if (canvasId == NULL) canvasId = GetCanvasIdJs(); - return canvasId; -} - // EOF diff --git a/src/raudio.c b/src/raudio.c index d208bb6eb..c65aaa134 100644 --- a/src/raudio.c +++ b/src/raudio.c @@ -1140,7 +1140,7 @@ bool ExportWaveAsCode(Wave wave, const char *fileName) // Get file name from path and convert variable name to uppercase char varFileName[256] = { 0 }; - strcpy(varFileName, GetFileNameWithoutExt(fileName)); + strncpy(varFileName, GetFileNameWithoutExt(fileName), 256 - 1); for (int i = 0; varFileName[i] != '\0'; i++) if (varFileName[i] >= 'a' && varFileName[i] <= 'z') { varFileName[i] = varFileName[i] - 32; } // Add wave information @@ -2739,11 +2739,13 @@ static const char *GetFileExtension(const char *fileName) return dot; } -// String pointer reverse break: returns right-most occurrence of charset in s -static const char *strprbrk(const char *s, const char *charset) +// String pointer reverse break: returns right-most occurrence of charset in text +static const char *strprbrk(const char *text, const char *charset) { const char *latestMatch = NULL; - for (; s = strpbrk(s, charset), s != NULL; latestMatch = s++) { } + + for (; (text != NULL) && (text = strpbrk(text, charset)); latestMatch = text++) { } + return latestMatch; } @@ -2766,11 +2768,11 @@ static const char *GetFileNameWithoutExt(const char *filePath) static char fileName[MAX_FILENAMEWITHOUTEXT_LENGTH] = { 0 }; memset(fileName, 0, MAX_FILENAMEWITHOUTEXT_LENGTH); - if (filePath != NULL) strcpy(fileName, GetFileName(filePath)); // Get filename with extension + if (filePath != NULL) strncpy(fileName, GetFileName(filePath), MAX_FILENAMEWITHOUTEXT_LENGTH - 1); // Get filename with extension - int size = (int)strlen(fileName); // Get size in bytes + int fileNameLength = (int)strlen(fileName); // Get size in bytes - for (int i = 0; (i < size) && (i < MAX_FILENAMEWITHOUTEXT_LENGTH); i++) + for (int i = 0; (i < fileNameLength) && (i < MAX_FILENAMEWITHOUTEXT_LENGTH); i++) { if (fileName[i] == '.') { @@ -2864,7 +2866,8 @@ static bool SaveFileText(const char *fileName, char *text) if (file != NULL) { - int count = fprintf(file, "%s", text); + int count = 0; + if (text != NULL) 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); diff --git a/src/raylib.h b/src/raylib.h index 96dc316ae..ba80e40c7 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -334,10 +334,10 @@ typedef Camera3D Camera; // Camera type fallback, defaults to Camera3D // Camera2D, defines position/orientation in 2d space typedef struct Camera2D { - Vector2 offset; // Camera offset (displacement from target) - Vector2 target; // Camera target (rotation and zoom origin) - float rotation; // Camera rotation in degrees - float zoom; // Camera zoom (scaling), should be 1.0f by default + Vector2 offset; // Camera offset (screen space offset from window origin) + Vector2 target; // Camera target (world space target point that is mapped to screen space offset) + float rotation; // Camera rotation in degrees (pivots around target) + float zoom; // Camera zoom (scaling around target), must not be set to 0, set to 1.0f for no scale } Camera2D; // Mesh, vertex data and vao/vbo @@ -1145,7 +1145,7 @@ RLAPI const char *GetPrevDirectoryPath(const char *dirPath); // Get previ RLAPI const char *GetWorkingDirectory(void); // Get current working directory (uses static string) RLAPI const char *GetApplicationDirectory(void); // Get the directory of the running application (uses static string) RLAPI int MakeDirectory(const char *dirPath); // Create directories (including full path requested), returns 0 on success -RLAPI bool ChangeDirectory(const char *dir); // Change working directory, return true on success +RLAPI bool ChangeDirectory(const char *dirPath); // Change working directory, return true on success RLAPI bool IsPathFile(const char *path); // Check if a given path is a file or a directory RLAPI bool IsFileNameValid(const char *fileName); // Check if fileName is valid for the platform/OS RLAPI FilePathList LoadDirectoryFiles(const char *dirPath); // Load directory filepaths diff --git a/src/rcore.c b/src/rcore.c index 3a9a47359..1f47efcb9 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -113,11 +113,11 @@ #include // Required for: srand(), rand(), atexit() #include // Required for: sprintf() [Used in OpenURL()] -#include // Required for: strlen(), strcpy(), strcmp(), strrchr(), memset() +#include // Required for: strlen(), strncpy(), strcmp(), strrchr(), memset() #include // Required for: time() [Used in InitTimer()] #include // Required for: tan() [Used in BeginMode3D()], atan2f() [Used in LoadVrStereoConfig()] -#if defined(PLATFORM_MEMORY) +#if defined(PLATFORM_MEMORY) || defined(PLATFORM_WEB) #define SW_GL_FRAMEBUFFER_COPY_BGRA false #endif #define RLGL_IMPLEMENTATION @@ -387,11 +387,6 @@ RLAPI const char *raylib_version = RAYLIB_VERSION; // raylib version exported s CoreData CORE = { 0 }; // Global CORE state context -// Flag to note GPU acceleration is available, -// referenced from other modules to support GPU data loading -// NOTE: Useful to allow Texture, RenderTexture, Font.texture, Mesh.vaoId/vboId, Shader loading -bool isGpuReady = false; - #if defined(SUPPORT_SCREEN_CAPTURE) static int screenshotCounter = 0; // Screenshots counter #endif @@ -697,7 +692,6 @@ void InitWindow(int width, int height, const char *title) // Initialize rlgl default data (buffers and shaders) // NOTE: Current fbo size stored as globals in rlgl for convenience rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height); - isGpuReady = true; // Flag to note GPU has been initialized successfully // Setup default viewport SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height); @@ -822,30 +816,22 @@ int GetScreenHeight(void) // Get current render width which is equal to screen width*dpi scale int GetRenderWidth(void) { - if (CORE.Window.usingFbo) return CORE.Window.currentFbo.width; - int width = 0; -#if defined(__APPLE__) - Vector2 scale = GetWindowScaleDPI(); - width = (int)((float)CORE.Window.render.width*scale.x); -#else - width = CORE.Window.render.width; -#endif + + if (CORE.Window.usingFbo) return CORE.Window.currentFbo.width; + else width = CORE.Window.render.width; + return width; } // Get current screen height which is equal to screen height*dpi scale int GetRenderHeight(void) { - if (CORE.Window.usingFbo) return CORE.Window.currentFbo.height; - int height = 0; -#if defined(__APPLE__) - Vector2 scale = GetWindowScaleDPI(); - height = (int)((float)CORE.Window.render.height*scale.y); -#else - height = CORE.Window.render.height; -#endif + + if (CORE.Window.usingFbo) return CORE.Window.currentFbo.height; + else height = CORE.Window.render.height; + return height; } @@ -1266,7 +1252,14 @@ Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode) shader.id = rlLoadShaderCode(vsCode, fsCode); - if (shader.id == rlGetShaderIdDefault()) shader.locs = rlGetShaderLocsDefault(); + if (shader.id == 0) + { + // Shader could not be loaded but we still load the location points to avoid potential crashes + // NOTE: All locations set to -1 (no location) + shader.locs = (int *)RL_CALLOC(RL_MAX_SHADER_LOCATIONS, sizeof(int)); + for (int i = 0; i < RL_MAX_SHADER_LOCATIONS; i++) shader.locs[i] = -1; + } + else if (shader.id == rlGetShaderIdDefault()) shader.locs = rlGetShaderLocsDefault(); else if (shader.id > 0) { // After custom shader loading, we TRY to set default location names @@ -1282,9 +1275,9 @@ Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode) // NOTE: If any location is not found, loc point becomes -1 + // Load shader locations array + // NOTE: All locations set to -1 (no location) shader.locs = (int *)RL_CALLOC(RL_MAX_SHADER_LOCATIONS, sizeof(int)); - - // All locations reset to -1 (no location) for (int i = 0; i < RL_MAX_SHADER_LOCATIONS; i++) shader.locs[i] = -1; // Get handles to GLSL input attribute locations @@ -1659,8 +1652,8 @@ float GetFrameTime(void) // Wait for some time (stop program execution) // NOTE: Sleep() granularity could be around 10 ms, it means, Sleep() could // take longer than expected... for that reason we use the busy wait loop -// Ref: http://stackoverflow.com/questions/43057578/c-programming-win32-games-sleep-taking-longer-than-expected -// Ref: http://www.geisswerks.com/ryan/FAQS/timing.html --> All about timing on Win32! +// REF: http://stackoverflow.com/questions/43057578/c-programming-win32-games-sleep-taking-longer-than-expected +// REF: http://www.geisswerks.com/ryan/FAQS/timing.html --> All about timing on Win32! void WaitTime(double seconds) { if (seconds < 0) return; // Security check @@ -1742,8 +1735,33 @@ int GetRandomValue(int min, int max) { TRACELOG(LOG_WARNING, "Invalid GetRandomValue() arguments, range should not be higher than %i", RAND_MAX); } + + // NOTE: This one-line approach produces a non-uniform distribution, + // as stated by Donald Knuth in the book The Art of Programming, so + // using below approach for more uniform results + //value = (rand()%(abs(max - min) + 1) + min); - value = (rand()%(abs(max - min) + 1) + min); + // More uniform range solution + int range = (max - min) + 1; + + // Degenerate/overflow case: fall back to min (same behavior as "always min" instead of UB) + if (range <= 0) value = min; + else + { + // Rejection sampling to get a uniform integer in [min, max] + unsigned long c = (unsigned long)RAND_MAX + 1UL; // number of possible rand() results + unsigned long m = (unsigned long)range; // size of the target interval + unsigned long t = c - (c%m); // largest multiple of m <= c + unsigned long r = 0; + + for (;;) + { + r = (unsigned long)rand(); + if (r < t) break; // Only accept values within the fair region + } + + value = min + (int)(r%m); + } #endif return value; } @@ -1765,7 +1783,7 @@ int *LoadRandomSequence(unsigned int count, int min, int max) for (int i = 0; i < (int)count;) { - value = (rand()%(abs(max - min) + 1) + min); + value = GetRandomValue(min, max); dupValue = false; for (int j = 0; j < i; j++) @@ -1807,13 +1825,13 @@ void TakeScreenshot(const char *fileName) // Apply a scale if we are doing HIGHDPI auto-scaling Vector2 scale = { 1.0f, 1.0f }; - if (IsWindowState(FLAG_WINDOW_HIGHDPI)) scale = GetWindowScaleDPI(); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) scale = GetWindowScaleDPI(); unsigned char *imgData = rlReadScreenPixels((int)((float)CORE.Window.render.width*scale.x), (int)((float)CORE.Window.render.height*scale.y)); Image image = { imgData, (int)((float)CORE.Window.render.width*scale.x), (int)((float)CORE.Window.render.height*scale.y), 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 }; - char path[512] = { 0 }; - strcpy(path, TextFormat("%s/%s", CORE.Storage.basePath, fileName)); + char path[MAX_FILEPATH_LENGTH] = { 0 }; + strncpy(path, TextFormat("%s/%s", CORE.Storage.basePath, fileName), MAX_FILEPATH_LENGTH - 1); ExportImage(image, path); // WARNING: Module required: rtextures RL_FREE(imgData); @@ -1983,10 +2001,10 @@ bool IsFileExtension(const char *fileName, const char *ext) if (fileExt != NULL) { - int fileExtLen = (int)strlen(fileExt); + int fileExtLength = (int)strlen(fileExt); char fileExtLower[16] = { 0 }; char *fileExtLowerPtr = fileExtLower; - for (int i = 0; (i < fileExtLen) && (i < 16); i++) + for (int i = 0; (i < fileExtLength) && (i < 16); i++) { // Copy and convert to lower-case if ((fileExt[i] >= 'A') && (fileExt[i] <= 'Z')) fileExtLower[i] = fileExt[i] + 32; @@ -1994,13 +2012,13 @@ bool IsFileExtension(const char *fileName, const char *ext) } int extCount = 1; - int extLen = (int)strlen(ext); - char *extList = (char *)RL_CALLOC(extLen + 1, 1); + int extLength = (int)strlen(ext); + char *extList = (char *)RL_CALLOC(extLength + 1, 1); char *extListPtrs[MAX_FILE_EXTENSIONS] = { 0 }; - strcpy(extList, ext); + strncpy(extList, ext, extLength); extListPtrs[0] = extList; - for (int i = 0; i < extLen; i++) + for (int i = 0; i < extLength; i++) { // Convert to lower-case if extension is upper-case if ((extList[i] >= 'A') && (extList[i] <= 'Z')) extList[i] += 32; @@ -2105,11 +2123,11 @@ const char *GetFileExtension(const char *fileName) } // String pointer reverse break: returns right-most occurrence of charset in s -static const char *strprbrk(const char *s, const char *charset) +static const char *strprbrk(const char *text, const char *charset) { const char *latestMatch = NULL; - for (; s = strpbrk(s, charset), s != NULL; latestMatch = s++) { } + for (; (text != NULL) && (text = strpbrk(text, charset)); latestMatch = text++) { } return latestMatch; } @@ -2136,10 +2154,10 @@ const char *GetFileNameWithoutExt(const char *filePath) if (filePath != NULL) { - strcpy(fileName, GetFileName(filePath)); // Get filename.ext without path - int size = (int)strlen(fileName); // Get size in bytes + strncpy(fileName, GetFileName(filePath), MAX_FILENAME_LENGTH - 1); // Get filename.ext without path + int fileNameLenght = (int)strlen(fileName); // Get size in bytes - for (int i = size; i > 0; i--) // Reverse search '.' + for (int i = fileNameLenght; i > 0; i--) // Reverse search '.' { if (fileName[i] == '.') { @@ -2206,11 +2224,11 @@ const char *GetPrevDirectoryPath(const char *dirPath) { static char prevDirPath[MAX_FILEPATH_LENGTH] = { 0 }; memset(prevDirPath, 0, MAX_FILEPATH_LENGTH); - int pathLen = (int)strlen(dirPath); + int dirPathLength = (int)strlen(dirPath); - if (pathLen <= 3) strcpy(prevDirPath, dirPath); + if (dirPathLength <= 3) strncpy(prevDirPath, dirPath, MAX_FILEPATH_LENGTH - 1); - for (int i = (pathLen - 1); (i >= 0) && (pathLen > 3); i--) + for (int i = (dirPathLength - 1); (i >= 0) && (dirPathLength > 3); i--) { if ((dirPath[i] == '\\') || (dirPath[i] == '/')) { @@ -2297,8 +2315,8 @@ const char *GetApplicationDirectory(void) if (_NSGetExecutablePath(appDir, &size) == 0) { - int len = strlen(appDir); - for (int i = len; i >= 0; --i) + int appDirLength = (int)strlen(appDir); + for (int i = appDirLength; i >= 0; --i) { if (appDir[i] == '/') { @@ -2320,8 +2338,8 @@ const char *GetApplicationDirectory(void) if (sysctl(mib, 4, appDir, &size, NULL, 0) == 0) { - int len = strlen(appDir); - for (int i = len; i >= 0; --i) + int appDirLength = (int)strlen(appDir); + for (int i = appDirLength; i >= 0; --i) { if (appDir[i] == '/') { @@ -2416,12 +2434,12 @@ int MakeDirectory(const char *dirPath) if (DirectoryExists(dirPath)) return 0; // Path already exists (is valid) // Copy path string to avoid modifying original - int len = (int)strlen(dirPath) + 1; - char *pathcpy = (char *)RL_CALLOC(len, 1); - memcpy(pathcpy, dirPath, len); + int dirPathLength = (int)strlen(dirPath) + 1; + char *pathcpy = (char *)RL_CALLOC(dirPathLength, 1); + memcpy(pathcpy, dirPath, dirPathLength); // Iterate over pathcpy, create each subdirectory as needed - for (int i = 0; (i < len) && (pathcpy[i] != '\0'); i++) + for (int i = 0; (i < dirPathLength) && (pathcpy[i] != '\0'); i++) { if (pathcpy[i] == ':') i++; else @@ -2447,12 +2465,12 @@ int MakeDirectory(const char *dirPath) } // Change working directory, returns true on success -bool ChangeDirectory(const char *dir) +bool ChangeDirectory(const char *dirPath) { - bool result = CHDIR(dir); + bool result = CHDIR(dirPath); - if (result != 0) TRACELOG(LOG_WARNING, "SYSTEM: Failed to change to directory: %s", dir); - else TRACELOG(LOG_INFO, "SYSTEM: Working Directory: %s", dir); + if (result != 0) TRACELOG(LOG_WARNING, "SYSTEM: Failed to change to directory: %s", dirPath); + else TRACELOG(LOG_INFO, "SYSTEM: Working Directory: %s", dirPath); return (result == 0); } @@ -2473,10 +2491,10 @@ bool IsFileNameValid(const char *fileName) if ((fileName != NULL) && (fileName[0] != '\0')) { - int length = (int)strlen(fileName); + int fileNameLength = (int)strlen(fileName); bool allPeriods = true; - for (int i = 0; i < length; i++) + for (int i = 0; i < fileNameLength; i++) { // Check invalid characters if ((fileName[i] == '<') || @@ -2502,7 +2520,7 @@ bool IsFileNameValid(const char *fileName) if (valid) { // Check invalid DOS names - if (length >= 3) + if (fileNameLength >= 3) { if (((fileName[0] == 'C') && (fileName[1] == 'O') && (fileName[2] == 'N')) || // CON ((fileName[0] == 'P') && (fileName[1] == 'R') && (fileName[2] == 'N')) || // PRN @@ -2510,7 +2528,7 @@ bool IsFileNameValid(const char *fileName) ((fileName[0] == 'N') && (fileName[1] == 'U') && (fileName[2] == 'L'))) valid = false; // NUL } - if (length >= 4) + if (fileNameLength >= 4) { if (((fileName[0] == 'C') && (fileName[1] == 'O') && (fileName[2] == 'M') && ((fileName[3] >= '0') && (fileName[3] <= '9'))) || // COM0-9 ((fileName[0] == 'L') && (fileName[1] == 'P') && (fileName[2] == 'T') && ((fileName[3] >= '0') && (fileName[3] <= '9')))) valid = false; // LPT0-9 @@ -2683,6 +2701,9 @@ unsigned char *DecodeDataBase64(const char *text, int *outputSize) ['0'] = 52, ['1'] = 53, ['2'] = 54, ['3'] = 55, ['4'] = 56, ['5'] = 57, ['6'] = 58, ['7'] = 59, ['8'] = 60, ['9'] = 61, ['+'] = 62, ['/'] = 63 }; + + *outputSize = 0; + if (text == NULL) return NULL; // Compute expected size and padding int dataSize = (int)strlen(text); // WARNING: Expecting NULL terminated strings! @@ -2926,8 +2947,15 @@ unsigned int *ComputeSHA1(unsigned char *data, int dataSize) memcpy(msg, data, dataSize); msg[dataSize] = 128; // Write the '1' bit - unsigned int bitsLen = 8*dataSize; - msg[newDataSize-1] = bitsLen; + unsigned long long bitsLen = 8ULL * dataSize; + msg[newDataSize-1] = (unsigned char)(bitsLen); + msg[newDataSize-2] = (unsigned char)(bitsLen >> 8); + msg[newDataSize-3] = (unsigned char)(bitsLen >> 16); + msg[newDataSize-4] = (unsigned char)(bitsLen >> 24); + msg[newDataSize-5] = (unsigned char)(bitsLen >> 32); + msg[newDataSize-6] = (unsigned char)(bitsLen >> 40); + msg[newDataSize-7] = (unsigned char)(bitsLen >> 48); + msg[newDataSize-8] = (unsigned char)(bitsLen >> 56); // Process the message in successive 512-bit chunks for (int offset = 0; offset < newDataSize; offset += (512/8)) @@ -3787,14 +3815,7 @@ void SetupViewport(int width, int height) CORE.Window.render.height = height; // Set viewport width and height - // NOTE: We consider render size (scaled) and offset in case black bars are required and - // render area does not match full display area (this situation is only applicable on fullscreen mode) -#if defined(__APPLE__) - Vector2 scale = GetWindowScaleDPI(); - rlViewport(CORE.Window.renderOffset.x/2*scale.x, CORE.Window.renderOffset.y/2*scale.y, (CORE.Window.render.width)*scale.x, (CORE.Window.render.height)*scale.y); -#else rlViewport(CORE.Window.renderOffset.x/2, CORE.Window.renderOffset.y/2, CORE.Window.render.width, CORE.Window.render.height); -#endif rlMatrixMode(RL_PROJECTION); // Switch to projection matrix rlLoadIdentity(); // Reset current matrix (projection) @@ -3920,7 +3941,7 @@ static void ScanDirectoryFiles(const char *basePath, FilePathList *files, const { if (IsFileExtension(path, filter)) { - strcpy(files->paths[files->count], path); + strncpy(files->paths[files->count], path, MAX_FILEPATH_LENGTH - 1); files->count++; } } @@ -3928,14 +3949,14 @@ static void ScanDirectoryFiles(const char *basePath, FilePathList *files, const { if (strstr(filter, DIRECTORY_FILTER_TAG) != NULL) { - strcpy(files->paths[files->count], path); + strncpy(files->paths[files->count], path, MAX_FILEPATH_LENGTH - 1); files->count++; } } } else { - strcpy(files->paths[files->count], path); + strncpy(files->paths[files->count], path, MAX_FILEPATH_LENGTH - 1); files->count++; } } @@ -3979,13 +4000,13 @@ static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *fi { if (IsFileExtension(path, filter)) { - strcpy(files->paths[files->count], path); + strncpy(files->paths[files->count], path, MAX_FILEPATH_LENGTH - 1); files->count++; } } else { - strcpy(files->paths[files->count], path); + strncpy(files->paths[files->count], path, MAX_FILEPATH_LENGTH - 1); files->count++; } @@ -3999,7 +4020,7 @@ static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *fi { if ((filter != NULL) && (strstr(filter, DIRECTORY_FILTER_TAG) != NULL)) { - strcpy(files->paths[files->count], path); + strncpy(files->paths[files->count], path, MAX_FILEPATH_LENGTH - 1); files->count++; } @@ -4302,22 +4323,25 @@ const char *TextFormat(const char *text, ...) char *currentBuffer = buffers[index]; memset(currentBuffer, 0, MAX_TEXT_BUFFER_LENGTH); // Clear buffer before using - - va_list args; - va_start(args, text); - int requiredByteCount = vsnprintf(currentBuffer, MAX_TEXT_BUFFER_LENGTH, text, args); - va_end(args); - - // If requiredByteCount is larger than the MAX_TEXT_BUFFER_LENGTH, then overflow occurred - if (requiredByteCount >= MAX_TEXT_BUFFER_LENGTH) + + if (text != NULL) { - // Inserting "..." at the end of the string to mark as truncated - char *truncBuffer = buffers[index] + MAX_TEXT_BUFFER_LENGTH - 4; // Adding 4 bytes = "...\0" - snprintf(truncBuffer, 4, "..."); - } + va_list args; + va_start(args, text); + int requiredByteCount = vsnprintf(currentBuffer, MAX_TEXT_BUFFER_LENGTH, text, args); + va_end(args); - index += 1; // Move to next buffer for next function call - if (index >= MAX_TEXTFORMAT_BUFFERS) index = 0; + // If requiredByteCount is larger than the MAX_TEXT_BUFFER_LENGTH, then overflow occurred + if (requiredByteCount >= MAX_TEXT_BUFFER_LENGTH) + { + // Inserting "..." at the end of the string to mark as truncated + char *truncBuffer = buffers[index] + MAX_TEXT_BUFFER_LENGTH - 4; // Adding 4 bytes = "...\0" + snprintf(truncBuffer, 4, "..."); + } + + index += 1; // Move to next buffer for next function call + if (index >= MAX_TEXTFORMAT_BUFFERS) index = 0; + } return currentBuffer; } diff --git a/src/rlgl.h b/src/rlgl.h index 6884ad183..cda64896c 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -1153,6 +1153,7 @@ static double rlCullDistanceFar = RL_CULL_DISTANCE_FAR; #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) static rlglData RLGL = { 0 }; #endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 +static bool isGpuReady = false; #if defined(GRAPHICS_API_OPENGL_ES2) && !defined(GRAPHICS_API_OPENGL_ES3) // NOTE: VAO functionality is exposed through extensions (OES) @@ -1761,11 +1762,6 @@ void rlTextureParameters(unsigned int id, int param, int value) { glBindTexture(GL_TEXTURE_2D, id); -#if !defined(GRAPHICS_API_OPENGL_11) - // Reset anisotropy filter, in case it was set - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f); -#endif - switch (param) { case RL_TEXTURE_WRAP_S: @@ -1785,6 +1781,9 @@ void rlTextureParameters(unsigned int id, int param, int value) case RL_TEXTURE_FILTER_ANISOTROPIC: { #if !defined(GRAPHICS_API_OPENGL_11) + // Reset anisotropy filter, in case it was set + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f); + if (value <= RLGL.ExtSupported.maxAnisotropyLevel) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value); else if (RLGL.ExtSupported.maxAnisotropyLevel > 0.0f) { @@ -2283,6 +2282,8 @@ static void GLAPIENTRY rlDebugMessageCallback(GLenum source, GLenum type, GLuint // Initialize rlgl: OpenGL extensions, default buffers/shaders/textures, OpenGL states void rlglInit(int width, int height) { + isGpuReady = true; + // Enable OpenGL debug context if required #if defined(RLGL_ENABLE_OPENGL_DEBUG_CONTEXT) && defined(GRAPHICS_API_OPENGL_43) if ((glDebugMessageCallback != NULL) && (glDebugMessageControl != NULL)) @@ -2395,6 +2396,7 @@ void rlglClose(void) #if defined(GRAPHICS_API_OPENGL_11_SOFTWARE) swClose(); // Unload sofware renderer resources #endif + isGpuReady = false; } // Load OpenGL extensions @@ -2492,12 +2494,12 @@ void rlLoadExtensions(void *loader) const char *extensions = (const char *)glGetString(GL_EXTENSIONS); // One big const string // NOTE: We have to duplicate string because glGetString() returns a const string - int size = strlen(extensions) + 1; // Get extensions string size in bytes - char *extensionsDup = (char *)RL_CALLOC(size, sizeof(char)); - strcpy(extensionsDup, extensions); + int extensionsLength = (int)strlen(extensions); // Get extensions string size in bytes + char *extensionsDup = (char *)RL_CALLOC(extensionsLength + 1, sizeof(char)); // Allocate space for copy with additional EOL byte + strncpy(extensionsDup, extensions, extensionsLength); extList[numExt] = extensionsDup; - for (int i = 0; i < size; i++) + for (int i = 0; i < extensionsLength; i++) { if (extensionsDup[i] == ' ') { @@ -2799,6 +2801,7 @@ int *rlGetShaderLocsDefault(void) rlRenderBatch rlLoadRenderBatch(int numBuffers, int bufferElements) { rlRenderBatch batch = { 0 }; + if (!isGpuReady) { TRACELOG(RL_LOG_WARNING, "GL: GPU is not ready to load data, trying to load before InitWindow()?"); return batch; } #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) // Initialize CPU (RAM) vertex buffers (position, texcoord, color data and indexes) @@ -3253,6 +3256,7 @@ bool rlCheckRenderBatchLimit(int vCount) unsigned int rlLoadTexture(const void *data, int width, int height, int format, int mipmapCount) { unsigned int id = 0; + if (!isGpuReady) { TRACELOG(RL_LOG_WARNING, "GL: GPU is not ready to load data, trying to load before InitWindow()?"); return id; } glBindTexture(GL_TEXTURE_2D, 0); // Free any old binding @@ -3349,8 +3353,8 @@ unsigned int rlLoadTexture(const void *data, int width, int height, int format, mipWidth /= 2; mipHeight /= 2; - mipOffset += mipSize; // Increment offset position to next mipmap - if (data != NULL) dataPtr += mipSize; // Increment data pointer to next mipmap + mipOffset += mipSize; // Increment offset position to next mipmap + if (data != NULL) dataPtr += mipSize; // Increment data pointer to next mipmap // Security check for NPOT textures if (mipWidth < 1) mipWidth = 1; @@ -3384,10 +3388,18 @@ unsigned int rlLoadTexture(const void *data, int width, int height, int format, #if defined(GRAPHICS_API_OPENGL_33) if (mipmapCount > 1) { - // Activate Trilinear filtering if mipmaps are available + // Activate trilinear filtering if mipmaps are available glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, mipmapCount); // Required for user-defined mip count + + // Define the maximum number of mipmap levels to be used, 0 is base texture size + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, mipmapCount - 1); + + // Check if the loaded texture with mipmaps is complete, + // uncomplete textures will draw in black if mipmap filtering is required + //GLint complete = 0; + //glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_IMMUTABLE_FORMAT, &complete); } #endif @@ -3409,6 +3421,7 @@ unsigned int rlLoadTexture(const void *data, int width, int height, int format, unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer) { unsigned int id = 0; + if (!isGpuReady) { TRACELOG(RL_LOG_WARNING, "GL: GPU is not ready to load data, trying to load before InitWindow()?"); return id; } #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) // In case depth textures not supported, we force renderbuffer usage @@ -3467,6 +3480,7 @@ unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer) unsigned int rlLoadTextureCubemap(const void *data, int size, int format, int mipmapCount) { unsigned int id = 0; + if (!isGpuReady) { TRACELOG(RL_LOG_WARNING, "GL: GPU is not ready to load data, trying to load before InitWindow()?"); return id; } #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) int mipSize = size; @@ -3811,6 +3825,7 @@ unsigned char *rlReadScreenPixels(int width, int height) unsigned int rlLoadFramebuffer(void) { 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 (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) glGenFramebuffers(1, &fboId); // Create the framebuffer object @@ -3903,7 +3918,7 @@ void rlUnloadFramebuffer(unsigned int id) // TODO: Review warning retrieving object name in WebGL // WARNING: WebGL: INVALID_ENUM: getFramebufferAttachmentParameter: invalid parameter name - // Ref: https://registry.khronos.org/webgl/specs/latest/1.0/ + // REF: https://registry.khronos.org/webgl/specs/latest/1.0/ glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &depthId); unsigned int depthIdU = (unsigned int)depthId; @@ -3926,6 +3941,7 @@ void rlUnloadFramebuffer(unsigned int id) unsigned int rlLoadVertexBuffer(const void *buffer, int size, bool dynamic) { unsigned int id = 0; + if (!isGpuReady) { TRACELOG(RL_LOG_WARNING, "GL: GPU is not ready to load data, trying to load before InitWindow()?"); return id; } #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) glGenBuffers(1, &id); @@ -3940,6 +3956,7 @@ unsigned int rlLoadVertexBuffer(const void *buffer, int size, bool dynamic) unsigned int rlLoadVertexBufferElement(const void *buffer, int size, bool dynamic) { unsigned int id = 0; + if (!isGpuReady) { TRACELOG(RL_LOG_WARNING, "GL: GPU is not ready to load data, trying to load before InitWindow()?"); return id; } #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) glGenBuffers(1, &id); @@ -4105,12 +4122,12 @@ void rlDisableStatePointer(int vertexAttribType) unsigned int rlLoadVertexArray(void) { unsigned int vaoId = 0; + if (!isGpuReady) { TRACELOG(RL_LOG_WARNING, "GL: GPU is not ready to load data, trying to load before InitWindow()?"); return vaoId; } + #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - if (RLGL.ExtSupported.vao) - { - glGenVertexArrays(1, &vaoId); - } + if (RLGL.ExtSupported.vao) glGenVertexArrays(1, &vaoId); #endif + return vaoId; } @@ -4165,6 +4182,7 @@ void rlUnloadVertexBuffer(unsigned int vboId) unsigned int rlLoadShaderCode(const char *vsCode, const char *fsCode) { unsigned int id = 0; + if (!isGpuReady) { TRACELOG(RL_LOG_WARNING, "GL: GPU is not ready to load data, trying to load before InitWindow()?"); return id; } #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) unsigned int vertexShaderId = 0; @@ -4307,6 +4325,7 @@ unsigned int rlCompileShader(const char *shaderCode, int type) unsigned int rlLoadShaderProgram(unsigned int vShaderId, unsigned int fShaderId) { unsigned int programId = 0; + if (!isGpuReady) { TRACELOG(RL_LOG_WARNING, "GL: GPU is not ready to load data, trying to load before InitWindow()?"); return programId; } #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) GLint success = 0; @@ -4470,7 +4489,7 @@ void rlSetUniformMatrices(int locIndex, const Matrix *matrices, int count) glUniformMatrix4fv(locIndex, count, true, (const float *)matrices); #elif defined(GRAPHICS_API_OPENGL_ES2) // WARNING: WebGL does not support Matrix transpose ("true" parameter) - // Ref: https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/uniformMatrix + // REF: https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/uniformMatrix glUniformMatrix4fv(locIndex, count, false, (const float *)matrices); #endif } @@ -5205,24 +5224,36 @@ static int rlGetPixelDataSize(int width, int height, int format) case RL_PIXELFORMAT_COMPRESSED_ETC1_RGB: case RL_PIXELFORMAT_COMPRESSED_ETC2_RGB: case RL_PIXELFORMAT_COMPRESSED_PVRT_RGB: - case RL_PIXELFORMAT_COMPRESSED_PVRT_RGBA: bpp = 4; break; + case RL_PIXELFORMAT_COMPRESSED_PVRT_RGBA: // 8 bytes per each 4x4 block + { + int blockWidth = (width + 3)/4; + int blockHeight = (height + 3)/4; + dataSize = blockWidth*blockHeight*8; + } break; case RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA: case RL_PIXELFORMAT_COMPRESSED_DXT5_RGBA: case RL_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA: - case RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: bpp = 8; break; - case RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: bpp = 2; break; + case RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: // 16 bytes per each 4x4 block + { + int blockWidth = (width + 3)/4; + int blockHeight = (height + 3)/4; + dataSize = blockWidth*blockHeight*16; + } break; + case RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: // 4 bytes per each 4x4 block + { + int blockWidth = (width + 3)/4; + int blockHeight = (height + 3)/4; + dataSize = blockWidth*blockHeight*4; + } break; default: break; } - double bytesPerPixel = (double)bpp/8.0; - dataSize = (int)(bytesPerPixel*width*height); // Total data size in bytes - - // Most compressed formats works on 4x4 blocks, - // if texture is smaller, minimum dataSize is 8 or 16 - if ((width < 4) && (height < 4)) + // Compute dataSize for uncompressed texture data (no blocks) + if ((format >= RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE) && + (format <= RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16)) { - if ((format >= RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) && (format < RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA)) dataSize = 8; - else if ((format >= RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA) && (format < RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA)) dataSize = 16; + double bytesPerPixel = (double)bpp/8.0; + dataSize = (int)(bytesPerPixel*width*height); // Total data size in bytes } return dataSize; diff --git a/src/rmodels.c b/src/rmodels.c index fad6ae78b..40af4afc4 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -127,10 +127,13 @@ // Defines and Macros //---------------------------------------------------------------------------------- #ifndef MAX_MATERIAL_MAPS - #define MAX_MATERIAL_MAPS 12 // Maximum number of maps supported + #define MAX_MATERIAL_MAPS 12 // Maximum number of maps supported #endif #ifndef MAX_MESH_VERTEX_BUFFERS - #define MAX_MESH_VERTEX_BUFFERS 9 // Maximum vertex buffers (VBO) per mesh + #define MAX_MESH_VERTEX_BUFFERS 9 // Maximum vertex buffers (VBO) per mesh +#endif +#ifndef MAX_FILEPATH_LENGTH + #define MAX_FILEPATH_LENGTH 4096 // Maximum length for filepaths (Linux PATH_MAX default value) #endif //---------------------------------------------------------------------------------- @@ -1282,6 +1285,8 @@ void UploadMesh(Mesh *mesh, bool dynamic) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) mesh->vaoId = rlLoadVertexArray(); + if (mesh->vaoId == 0) return; + rlEnableVertexArray(mesh->vaoId); // NOTE: Vertex attributes must be uploaded considering default locations points and available vertex data @@ -1470,6 +1475,8 @@ void DrawMesh(Mesh mesh, Material material, Matrix transform) // Bind shader program rlEnableShader(material.shader.id); + if (material.shader.locs == NULL) return; + // Send required data to shader (matrices, values) //----------------------------------------------------- // Upload to shader material.colDiffuse @@ -2060,7 +2067,7 @@ bool ExportMeshAsCode(Mesh mesh, const char *fileName) // Get file name from path and convert variable name to uppercase char varFileName[256] = { 0 }; - strcpy(varFileName, GetFileNameWithoutExt(fileName)); + strncpy(varFileName, GetFileNameWithoutExt(fileName), 256 - 1); // NOTE: Using function provided by [rcore] module for (int i = 0; varFileName[i] != '\0'; i++) if ((varFileName[i] >= 'a') && (varFileName[i] <= 'z')) { varFileName[i] = varFileName[i] - 32; } // Add image information @@ -3651,7 +3658,7 @@ void GenMeshTangents(Mesh *mesh) for (int t = 0; t < mesh->triangleCount; t++) { // Get triangle vertex indices - int i0, i1, i2; + int i0 = 0, i1 = 0, i2 = 0; if (mesh->indices != NULL) { @@ -4146,7 +4153,9 @@ RayCollision GetRayCollisionMesh(Ray ray, Mesh mesh, Matrix transform) // Test against all triangles in mesh for (int i = 0; i < triangleCount; i++) { - Vector3 a, b, c; + Vector3 a = { 0 }; + Vector3 b = { 0 }; + Vector3 c = { 0 }; Vector3 *vertdata = (Vector3 *)mesh.vertices; if (mesh.indices) @@ -4189,8 +4198,10 @@ RayCollision GetRayCollisionTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3 RayCollision collision = { 0 }; Vector3 edge1 = { 0 }; Vector3 edge2 = { 0 }; - Vector3 p, q, tv; - float det, invDet, u, v, t; + Vector3 p = { 0 }; + Vector3 q = { 0 }; + Vector3 tv = { 0 }; + float det = 0.0f, invDet = 0.0f, u = 0.0f, v = 0.0f, t = 0.0f; // Find vectors for two edges sharing V1 edge1 = Vector3Subtract(p2, p1); @@ -4306,8 +4317,8 @@ static Model LoadOBJ(const char *fileName) return model; } - char currentDir[1024] = { 0 }; - strcpy(currentDir, GetWorkingDirectory()); // Save current working directory + char currentDir[MAX_FILEPATH_LENGTH] = { 0 }; + strncpy(currentDir, GetWorkingDirectory(), MAX_FILEPATH_LENGTH - 1); // Save current working directory const char *workingDir = GetDirectoryPath(fileName); // Switch to OBJ directory for material path correctness if (CHDIR(workingDir) != 0) TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to change working directory", workingDir); @@ -5025,10 +5036,8 @@ static ModelAnimation *LoadModelAnimationsIQM(const char *fileName, int *animCou for (unsigned int j = 0; j < iqmHeader->num_poses; j++) { // If animations and skeleton are in the same file, copy bone names to anim - if (iqmHeader->num_joints > 0) - memcpy(animations[a].bones[j].name, fileDataPtr + iqmHeader->ofs_text + joints[j].name, BONE_NAME_LENGTH*sizeof(char)); - else - strcpy(animations[a].bones[j].name, "ANIMJOINTNAME"); // Default bone name otherwise + if (iqmHeader->num_joints > 0) memcpy(animations[a].bones[j].name, fileDataPtr + iqmHeader->ofs_text + joints[j].name, BONE_NAME_LENGTH*sizeof(char)); + else memcpy(animations[a].bones[j].name, "ANIMJOINTNAME", 13); // Default bone name otherwise animations[a].bones[j].parent = poses[j].parent; } @@ -5578,6 +5587,56 @@ static Model LoadGLTF(const char *fileName) vertices[3*k+2] = vt.z; } } + else if ((attribute->type == cgltf_type_vec3) && (attribute->component_type == cgltf_component_type_r_16u)) + { + // Init raylib mesh vertices to copy glTF attribute data + model.meshes[meshIndex].vertexCount = (int)attribute->count; + model.meshes[meshIndex].vertices = (float *)RL_MALLOC(attribute->count*3*sizeof(float)); + + // Load data into a temp buffer to be converted to raylib data type + unsigned short *temp = (unsigned short *)RL_MALLOC(attribute->count*3*sizeof(unsigned short)); + LOAD_ATTRIBUTE(attribute, 3, unsigned short, temp); + + // Convert data to raylib vertex data type (float) the matrix will scale it to the correct size as a float + for (unsigned int t = 0; t < attribute->count*3; t++) model.meshes[meshIndex].vertices[t] = (float)temp[t]; + + RL_FREE(temp); + + // Transform the vertices + float *vertices = model.meshes[meshIndex].vertices; + for (unsigned int k = 0; k < attribute->count; k++) + { + Vector3 vt = Vector3Transform((Vector3){ vertices[3*k], vertices[3*k + 1], vertices[3*k + 2] }, worldMatrix); + vertices[3*k] = vt.x; + vertices[3*k + 1] = vt.y; + vertices[3*k + 2] = vt.z; + } + } + else if ((attribute->type == cgltf_type_vec3) && (attribute->component_type == cgltf_component_type_r_16)) + { + // Init raylib mesh vertices to copy glTF attribute data + model.meshes[meshIndex].vertexCount = (int)attribute->count; + model.meshes[meshIndex].vertices = (float *)RL_MALLOC(attribute->count*3*sizeof(float)); + + // Load data into a temp buffer to be converted to raylib data type + short *temp = (short *)RL_MALLOC(attribute->count*3*sizeof(short)); + LOAD_ATTRIBUTE(attribute, 3, short, temp); + + // Convert data to raylib vertex data type (float) the matrix will scale it to the correct size as a float + for (unsigned int t = 0; t < attribute->count*3; t++) model.meshes[meshIndex].vertices[t] = (float)temp[t]; + + RL_FREE(temp); + + // Transform the vertices + float *vertices = model.meshes[meshIndex].vertices; + for (unsigned int k = 0; k < attribute->count; k++) + { + Vector3 vt = Vector3Transform((Vector3){ vertices[3*k], vertices[3*k + 1], vertices[3*k + 2] }, worldMatrix); + vertices[3*k] = vt.x; + vertices[3*k + 1] = vt.y; + vertices[3*k + 2] = vt.z; + } + } else TRACELOG(LOG_WARNING, "MODEL: [%s] Vertices attribute data format not supported, use vec3 float", fileName); } } @@ -5606,6 +5665,78 @@ static Model LoadGLTF(const char *fileName) normals[3*k+2] = nt.z; } } + else if ((attribute->type == cgltf_type_vec3) && (attribute->component_type == cgltf_component_type_r_16)) + { + // Init raylib mesh normals to copy glTF attribute data + model.meshes[meshIndex].normals = (float *)RL_MALLOC(attribute->count*3*sizeof(float)); + + // Load data into a temp buffer to be converted to raylib data type + short *temp = (short *)RL_MALLOC(attribute->count*3*sizeof(short)); + LOAD_ATTRIBUTE(attribute, 3, short, temp); + + // Convert data to raylib normal data type (float) + for (unsigned int t = 0; t < attribute->count*3; t++) model.meshes[meshIndex].normals[t] = (float)temp[t]; + + RL_FREE(temp); + + // Transform the normals + float *normals = model.meshes[meshIndex].normals; + for (unsigned int k = 0; k < attribute->count; k++) + { + Vector3 nt = Vector3Normalize(Vector3Transform((Vector3){ normals[3*k], normals[3*k + 1], normals[3*k + 2] }, worldMatrixNormals)); + normals[3*k] = nt.x; + normals[3*k + 1] = nt.y; + normals[3*k + 2] = nt.z; + } + } + else if ((attribute->type == cgltf_type_vec3) && (attribute->component_type == cgltf_component_type_r_8u)) + { + // Init raylib mesh normals to copy glTF attribute data + model.meshes[meshIndex].normals = (float *)RL_MALLOC(attribute->count*3*sizeof(float)); + + // Load data into a temp buffer to be converted to raylib data type + unsigned char *temp = (unsigned char *)RL_MALLOC(attribute->count*3*sizeof(unsigned char)); + LOAD_ATTRIBUTE(attribute, 3, unsigned char, temp); + + // Convert data to raylib normal data type (float) + for (unsigned int t = 0; t < attribute->count*3; t++) model.meshes[meshIndex].normals[t] = (float)temp[t]; + + RL_FREE(temp); + + // Transform the normals + float *normals = model.meshes[meshIndex].normals; + for (unsigned int k = 0; k < attribute->count; k++) + { + Vector3 nt = Vector3Normalize(Vector3Transform((Vector3){ normals[3*k], normals[3*k + 1], normals[3*k + 2] }, worldMatrixNormals)); + normals[3*k] = nt.x; + normals[3*k + 1] = nt.y; + normals[3*k + 2] = nt.z; + } + } + else if ((attribute->type == cgltf_type_vec3) && (attribute->component_type == cgltf_component_type_r_8)) + { + // Init raylib mesh normals to copy glTF attribute data + model.meshes[meshIndex].normals = (float *)RL_MALLOC(attribute->count*3*sizeof(float)); + + // Load data into a temp buffer to be converted to raylib data type + char *temp = (char *)RL_MALLOC(attribute->count*3*sizeof(char)); + LOAD_ATTRIBUTE(attribute, 3, char, temp); + + // Convert data to raylib normal data type (float) + for (unsigned int t = 0; t < attribute->count*3; t++) model.meshes[meshIndex].normals[t] = (float)temp[t]; + + RL_FREE(temp); + + // Transform the normals + float *normals = model.meshes[meshIndex].normals; + for (unsigned int k = 0; k < attribute->count; k++) + { + Vector3 nt = Vector3Normalize(Vector3Transform((Vector3){ normals[3*k], normals[3*k + 1], normals[3*k + 2] }, worldMatrixNormals)); + normals[3*k] = nt.x; + normals[3*k + 1] = nt.y; + normals[3*k + 2] = nt.z; + } + } else TRACELOG(LOG_WARNING, "MODEL: [%s] Normals attribute data format not supported, use vec3 float", fileName); } } @@ -5874,8 +6005,8 @@ static Model LoadGLTF(const char *fileName) //---------------------------------------------------------------------------------------------------- // Load animation data - // Ref: https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#skins - // Ref: https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#skinned-mesh-attributes + // REF: https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#skins + // REF: https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#skinned-mesh-attributes // // LIMITATIONS: // - Only supports 1 armature per file, and skips loading it if there are multiple armatures @@ -6848,7 +6979,7 @@ static Model LoadM3D(const char *fileName) // Add a special "no bone" bone model.bones[i].parent = -1; - strcpy(model.bones[i].name, "NO BONE"); + memcpy(model.bones[i].name, "NO BONE", 7); model.bindPose[i].translation.x = 0.0f; model.bindPose[i].translation.y = 0.0f; model.bindPose[i].translation.z = 0.0f; @@ -6940,7 +7071,7 @@ static ModelAnimation *LoadModelAnimationsM3D(const char *fileName, int *animCou // A special, never transformed "no bone" bone, used for boneless vertices animations[a].bones[i].parent = -1; - strcpy(animations[a].bones[i].name, "NO BONE"); + memcpy(animations[a].bones[i].name, "NO BONE", 7); // M3D stores frames at arbitrary intervals with sparse skeletons. We need full skeletons at // regular intervals, so let the M3D SDK do the heavy lifting and calculate interpolated bones diff --git a/src/rtext.c b/src/rtext.c index c17fbe9bf..7c25fde0b 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -67,7 +67,7 @@ #include // Required for: malloc(), free() #include // Required for: vsprintf() -#include // Required for: strcmp(), strstr(), strcpy(), strncpy() [Used in TextReplace()], sscanf() [Used in LoadBMFont()] +#include // Required for: strcmp(), strstr(), strncpy() [Used in TextReplace()], sscanf() [Used in LoadBMFont()] #include // Required for: va_list, va_start(), vsprintf(), va_end() [Used in TextFormat()] #include // Required for: toupper(), tolower() [Used in TextToUpper(), TextToLower()] @@ -127,13 +127,12 @@ //---------------------------------------------------------------------------------- // Global variables //---------------------------------------------------------------------------------- -extern bool isGpuReady; #if defined(SUPPORT_DEFAULT_FONT) // Default font provided by raylib // NOTE: Default font is loaded on InitWindow() and disposed on CloseWindow() [module: core] static Font defaultFont = { 0 }; #endif -static int textLineSpacing = 2; // Text vertical line spacing in pixels (between lines) +static int textLineSpacing = 2; // Text vertical line spacing in pixels (between lines) //---------------------------------------------------------------------------------- // Other Modules Functions Declaration (required by text) @@ -164,12 +163,11 @@ extern void LoadFontDefault(void) { #define BIT_CHECK(a,b) ((a) & (1u << (b))) - // check to see if we have allready allocated the font for an image, and if we don't need to upload, then just return - if (defaultFont.glyphs != NULL && !isGpuReady) - return; + // Check to see if we have already allocated the font for an image, and if we don't need to upload, then just return + if (defaultFont.glyphs != NULL) return; // NOTE: Using UTF-8 encoding table for Unicode U+0000..U+00FF Basic Latin + Latin-1 Supplement - // Ref: http://www.utf8-chartable.de/unicode-utf8-table.pl + // REF: http://www.utf8-chartable.de/unicode-utf8-table.pl defaultFont.glyphCount = 224; // Number of glyphs included in our default font defaultFont.glyphPadding = 0; // Characters padding @@ -264,17 +262,14 @@ extern void LoadFontDefault(void) counter++; } - if (isGpuReady) - { - defaultFont.texture = LoadTextureFromImage(imFont); + defaultFont.texture = LoadTextureFromImage(imFont); - // we have already loaded the font glyph data an image, and the GPU is ready, we are done - // if we don't do this, we will leak memory by reallocating the glyphs and rects - if (defaultFont.glyphs != NULL) - { - UnloadImage(imFont); - return; - } + // we have already loaded the font glyph data an image, and the GPU is ready, we are done + // if we don't do this, we will leak memory by reallocating the glyphs and rects + if (defaultFont.glyphs != NULL) + { + UnloadImage(imFont); + return; } // Reconstruct charSet using charsWidth[], charsHeight, charsDivisor, glyphCount @@ -331,7 +326,7 @@ extern void LoadFontDefault(void) extern void UnloadFontDefault(void) { for (int i = 0; i < defaultFont.glyphCount; i++) UnloadImage(defaultFont.glyphs[i].image); - if (isGpuReady) UnloadTexture(defaultFont.texture); + UnloadTexture(defaultFont.texture); RL_FREE(defaultFont.glyphs); RL_FREE(defaultFont.recs); defaultFont.glyphCount = 0; @@ -385,17 +380,15 @@ Font LoadFont(const char *fileName) { Image image = LoadImage(fileName); if (image.data != NULL) font = LoadFontFromImage(image, MAGENTA, FONT_TTF_DEFAULT_FIRST_CHAR); + else font = GetFontDefault(); UnloadImage(image); } - if (isGpuReady) + if (font.texture.id == 0) TRACELOG(LOG_WARNING, "FONT: [%s] Failed to load font texture -> Using default font", fileName); + else { - if (font.texture.id == 0) TRACELOG(LOG_WARNING, "FONT: [%s] Failed to load font texture -> Using default font", fileName); - else - { - SetTextureFilter(font.texture, TEXTURE_FILTER_POINT); // By default, we set point filter (the best performance) - TRACELOG(LOG_INFO, "FONT: Data loaded successfully (%i pixel size | %i glyphs)", font.baseSize, font.glyphCount); - } + SetTextureFilter(font.texture, TEXTURE_FILTER_POINT); // By default, we set point filter (the best performance) + TRACELOG(LOG_INFO, "FONT: Data loaded successfully (%i pixel size | %i glyphs)", font.baseSize, font.glyphCount); } return font; @@ -516,7 +509,7 @@ Font LoadFontFromImage(Image image, Color key, int firstChar) }; // Set font with all data parsed from image - if (isGpuReady) font.texture = LoadTextureFromImage(fontClear); // Convert processed image to OpenGL texture + font.texture = LoadTextureFromImage(fontClear); // Convert processed image to OpenGL texture font.glyphCount = index; font.glyphPadding = 0; @@ -585,7 +578,7 @@ Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int font.glyphPadding = FONT_TTF_DEFAULT_CHARS_PADDING; Image atlas = GenImageFontAtlas(font.glyphs, &font.recs, font.glyphCount, font.baseSize, font.glyphPadding, 0); - if (isGpuReady) font.texture = LoadTextureFromImage(atlas); + font.texture = LoadTextureFromImage(atlas); // Update glyphs[i].image to use alpha, required to be used on ImageDrawText() for (int i = 0; i < font.glyphCount; i++) @@ -656,7 +649,9 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz // Calculate font basic metrics // NOTE: ascent is equivalent to font baseline - int ascent, descent, lineGap; + int ascent = 0; + int descent = 0; + int lineGap = 0; stbtt_GetFontVMetrics(&fontInfo, &ascent, &descent, &lineGap); // In case no chars count provided, default to 95 @@ -705,7 +700,11 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz switch (type) { case FONT_DEFAULT: - case FONT_BITMAP: glyphs[k].image.data = stbtt_GetCodepointBitmap(&fontInfo, scaleFactor, scaleFactor, cp, &cpWidth, &cpHeight, &glyphs[k].offsetX, &glyphs[k].offsetY); break; + case FONT_BITMAP: + { + glyphs[k].image.data = stbtt_GetCodepointBitmap(&fontInfo, scaleFactor, scaleFactor, cp, + &cpWidth, &cpHeight, &glyphs[k].offsetX, &glyphs[k].offsetY); + } break; case FONT_SDF: { if (cp != 32) @@ -1009,7 +1008,7 @@ void UnloadFont(Font font) if (font.texture.id != GetFontDefault().texture.id) { UnloadFontData(font.glyphs, font.glyphCount); - if (isGpuReady) UnloadTexture(font.texture); + UnloadTexture(font.texture); RL_FREE(font.recs); TRACELOGD("FONT: Unloaded font data from RAM and VRAM"); @@ -1340,8 +1339,7 @@ Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing { Vector2 textSize = { 0 }; - if ((isGpuReady && (font.texture.id == 0)) || - (text == NULL) || (text[0] == '\0')) return textSize; // Security check + if ((font.texture.id == 0) || (text == NULL) || (text[0] == '\0')) return textSize; // Security check int size = TextLength(text); // Get size in bytes of text int tempByteCounter = 0; // Used to count longer text line num chars @@ -1453,29 +1451,31 @@ Rectangle GetGlyphAtlasRec(Font font, int codepoint) char **LoadTextLines(const char *text, int *count) { char **lines = NULL; + int lineCount = 0; - if (text == NULL) { *count = 0; return lines; } - - int lineCount = 1; - int textSize = (int)strlen(text); - - // First text scan pass to get required line count - for (int i = 0; i < textSize; i++) + if (text != NULL) { - if (text[i] == '\n') lineCount++; - } + int textLength = TextLength(text); + lineCount = 1; - lines = (char **)RL_CALLOC(lineCount, sizeof(char *)); - for (int i = 0, l = 0, lineLen = 0; i <= textSize; i++) - { - if ((text[i] == '\n') || (text[i] == '\0')) + // First text scan pass to get required line count + for (int i = 0; i < textLength; i++) { - lines[l] = (char *)RL_CALLOC(lineLen + 1, 1); - strncpy(lines[l], &text[i - lineLen], lineLen); - lineLen = 0; - l++; + if (text[i] == '\n') lineCount++; + } + + lines = (char **)RL_CALLOC(lineCount, sizeof(char *)); + for (int i = 0, l = 0, lineLen = 0; i <= textLength; i++) + { + if ((text[i] == '\n') || (text[i] == '\0')) + { + lines[l] = (char *)RL_CALLOC(lineLen + 1, 1); + strncpy(lines[l], &text[i - lineLen], lineLen); + lineLen = 0; + l++; + } + else lineLen++; } - else lineLen++; } *count = lineCount; @@ -1517,23 +1517,26 @@ const char *TextFormat(const char *text, ...) static int index = 0; char *currentBuffer = buffers[index]; - memset(currentBuffer, 0, MAX_TEXT_BUFFER_LENGTH); // Clear buffer before using - - va_list args; - va_start(args, text); - int requiredByteCount = vsnprintf(currentBuffer, MAX_TEXT_BUFFER_LENGTH, text, args); - va_end(args); - - // If requiredByteCount is larger than the MAX_TEXT_BUFFER_LENGTH, then overflow occurred - if (requiredByteCount >= MAX_TEXT_BUFFER_LENGTH) + memset(currentBuffer, 0, MAX_TEXT_BUFFER_LENGTH); // Clear buffer before using + + if (text != NULL) { - // Inserting "..." at the end of the string to mark as truncated - char *truncBuffer = buffers[index] + MAX_TEXT_BUFFER_LENGTH - 4; // Adding 4 bytes = "...\0" - snprintf(truncBuffer, 4, "..."); - } + va_list args; + va_start(args, text); + int requiredByteCount = vsnprintf(currentBuffer, MAX_TEXT_BUFFER_LENGTH, text, args); + va_end(args); - index += 1; // Move to next buffer for next function call - if (index >= MAX_TEXTFORMAT_BUFFERS) index = 0; + // If requiredByteCount is larger than the MAX_TEXT_BUFFER_LENGTH, then overflow occurred + if (requiredByteCount >= MAX_TEXT_BUFFER_LENGTH) + { + // Inserting "..." at the end of the string to mark as truncated + char *truncBuffer = buffers[index] + MAX_TEXT_BUFFER_LENGTH - 4; // Adding 4 bytes = "...\0" + snprintf(truncBuffer, 4, "..."); + } + + index += 1; // Move to next buffer for next function call + if (index >= MAX_TEXTFORMAT_BUFFERS) index = 0; + } return currentBuffer; } @@ -1545,13 +1548,16 @@ int TextToInteger(const char *text) int value = 0; int sign = 1; - if ((text[0] == '+') || (text[0] == '-')) + if (text != NULL) { - if (text[0] == '-') sign = -1; - text++; - } + if ((text[0] == '+') || (text[0] == '-')) + { + if (text[0] == '-') sign = -1; + text++; + } - for (int i = 0; ((text[i] >= '0') && (text[i] <= '9')); i++) value = value*10 + (int)(text[i] - '0'); + for (int i = 0; ((text[i] >= '0') && (text[i] <= '9')); i++) value = value*10 + (int)(text[i] - '0'); + } return value*sign; } @@ -1564,22 +1570,25 @@ float TextToFloat(const char *text) float value = 0.0f; float sign = 1.0f; - if ((text[0] == '+') || (text[0] == '-')) + if (text != NULL) { - if (text[0] == '-') sign = -1.0f; - text++; - } - - int i = 0; - for (; ((text[i] >= '0') && (text[i] <= '9')); i++) value = value*10.0f + (float)(text[i] - '0'); - - if (text[i++] == '.') - { - float divisor = 10.0f; - for (; ((text[i] >= '0') && (text[i] <= '9')); i++) + if ((text[0] == '+') || (text[0] == '-')) { - value += ((float)(text[i] - '0'))/divisor; - divisor = divisor*10.0f; + if (text[0] == '-') sign = -1.0f; + text++; + } + + int i = 0; + for (; ((text[i] >= '0') && (text[i] <= '9')); i++) value = value*10.0f + (float)(text[i] - '0'); + + if (text[i++] == '.') + { + float divisor = 10.0f; + for (; ((text[i] >= '0') && (text[i] <= '9')); i++) + { + value += ((float)(text[i] - '0'))/divisor; + divisor = divisor*10.0f; + } } } @@ -1631,26 +1640,23 @@ const char *TextSubtext(const char *text, int position, int length) static char buffer[MAX_TEXT_BUFFER_LENGTH] = { 0 }; memset(buffer, 0, MAX_TEXT_BUFFER_LENGTH); - int textLength = TextLength(text); - - if (position >= textLength) + if (text != NULL) { - return buffer; //First char is already '\0' by memset + int textLength = TextLength(text); + + if (position >= textLength) return buffer; // First char is already '\0' by memset + + int maxLength = textLength - position; + if (length > maxLength) length = maxLength; + if (length >= MAX_TEXT_BUFFER_LENGTH) length = MAX_TEXT_BUFFER_LENGTH - 1; + + // NOTE: Alternative: memcpy(buffer, text + position, length) + + for (int c = 0; c < length; c++) buffer[c] = text[position + c]; + + buffer[length] = '\0'; } - int maxLength = textLength - position; - if (length > maxLength) length = maxLength; - if (length >= MAX_TEXT_BUFFER_LENGTH) length = MAX_TEXT_BUFFER_LENGTH - 1; - - // NOTE: Alternative: memcpy(buffer, text + position, length) - - for (int c = 0 ; c < length ; c++) - { - buffer[c] = text[position + c]; - } - - buffer[length] = '\0'; - return buffer; } @@ -1684,7 +1690,7 @@ char *GetTextBetween(const char *text, const char *begin, const char *end) if (beginIndex > -1) { - int beginLen = (int)strlen(begin); + int beginLen = TextLength(begin); int endIndex = TextFindIndex(text + beginIndex + beginLen, end); if (endIndex > -1) @@ -1700,84 +1706,86 @@ char *GetTextBetween(const char *text, const char *begin, const char *end) } // Replace text string -// REQUIRES: strstr(), strncpy(), strcpy() +// REQUIRES: strstr(), strncpy() // TODO: If (replacement == "") remove "search" text // WARNING: Allocated memory must be manually freed char *TextReplace(const char *text, const char *search, const char *replacement) { char *result = NULL; - if (!text || !search) return NULL; // Sanity check - - char *insertPoint = NULL; // Next insert point - char *temp = NULL; // Temp pointer - int searchLen = 0; // Search string length of (the string to remove) - int replaceLen = 0; // Replacement length (the string to replace by) - int lastReplacePos = 0; // Distance between next search and end of last replace - int count = 0; // Number of replacements - - searchLen = TextLength(search); - if (searchLen == 0) return NULL; // Empty search causes infinite loop during count - - replaceLen = TextLength(replacement); - - // Count the number of replacements needed - insertPoint = (char *)text; - for (count = 0; (temp = strstr(insertPoint, search)); count++) insertPoint = temp + searchLen; - - // Allocate returning string and point temp to it - temp = result = (char *)RL_MALLOC(TextLength(text) + (replaceLen - searchLen)*count + 1); - - if (!result) return NULL; // Memory could not be allocated - - // First time through the loop, all the variable are set correctly from here on, - // - 'temp' points to the end of the result string - // - 'insertPoint' points to the next occurrence of replace in text - // - 'text' points to the remainder of text after "end of replace" - while (count--) + if ((text != NULL) && (search != NULL)) { - insertPoint = (char *)strstr(text, search); - lastReplacePos = (int)(insertPoint - text); - temp = strncpy(temp, text, lastReplacePos) + lastReplacePos; - temp = strcpy(temp, replacement) + replaceLen; - text += lastReplacePos + searchLen; // Move to next "end of replace" - } + char *insertPoint = NULL; // Next insert point + char *temp = NULL; // Temp pointer + int searchLen = 0; // Search string length of (the string to remove) + int replaceLen = 0; // Replacement length (the string to replace by) + int lastReplacePos = 0; // Distance between next search and end of last replace + int count = 0; // Number of replacements - // Copy remaind text part after replacement to result (pointed by moving temp) - strcpy(temp, text); + searchLen = TextLength(search); + if (searchLen == 0) return NULL; // Empty search causes infinite loop during count + + replaceLen = TextLength(replacement); + + // Count the number of replacements needed + insertPoint = (char *)text; + for (count = 0; (temp = strstr(insertPoint, search)); count++) insertPoint = temp + searchLen; + + // Allocate returning string and point temp to it + temp = result = (char *)RL_MALLOC(TextLength(text) + (replaceLen - searchLen)*count + 1); + + if (!result) return NULL; // Memory could not be allocated + + // First time through the loop, all the variable are set correctly from here on, + // - 'temp' points to the end of the result string + // - 'insertPoint' points to the next occurrence of replace in text + // - 'text' points to the remainder of text after "end of replace" + while (count--) + { + insertPoint = (char *)strstr(text, search); + lastReplacePos = (int)(insertPoint - text); + temp = strncpy(temp, text, lastReplacePos) + lastReplacePos; + temp = strcpy(temp, replacement) + replaceLen; + text += lastReplacePos + searchLen; // Move to next "end of replace" + } + + // Copy remaind text part after replacement to result (pointed by moving temp) + strcpy(temp, text); + } return result; } // Replace text between two specific strings -// REQUIRES: strlen(), strncpy() +// REQUIRES: strncpy() // NOTE: If (replacement == NULL) remove "begin"[ ]"end" text // WARNING: Returned string must be freed by user char *TextReplaceBetween(const char *text, const char *begin, const char *end, const char *replacement) { char *result = NULL; - if (!text || !begin || !end) return NULL; // Sanity check - - int beginIndex = TextFindIndex(text, begin); - - if (beginIndex > -1) + if ((text != NULL) && (begin != NULL) && (end != NULL)) { - int beginLen = (int)strlen(begin); - int endIndex = TextFindIndex(text + beginIndex + beginLen, end); + int beginIndex = TextFindIndex(text, begin); - if (endIndex > -1) + if (beginIndex > -1) { - endIndex += (beginIndex + beginLen); + int beginLen = TextLength(begin); + int endIndex = TextFindIndex(text + beginIndex + beginLen, end); - int textLen = (int)strlen(text); - int replaceLen = (replacement == NULL)? 0 : (int)strlen(replacement); - int toreplaceLen = endIndex - beginIndex - beginLen; - result = (char *)RL_CALLOC(textLen + replaceLen - toreplaceLen + 1, sizeof(char)); + if (endIndex > -1) + { + endIndex += (beginIndex + beginLen); - strncpy(result, text, beginIndex + beginLen); // Copy first text part - if (replacement != NULL) strncpy(result + beginIndex + beginLen, replacement, replaceLen); // Copy replacement (if provided) - strncpy(result + beginIndex + beginLen + replaceLen, text + endIndex, textLen - endIndex); // Copy end text part + int textLen = TextLength(text); + int replaceLen = (replacement == NULL)? 0 : TextLength(replacement); + int toreplaceLen = endIndex - beginIndex - beginLen; + result = (char *)RL_CALLOC(textLen + replaceLen - toreplaceLen + 1, sizeof(char)); + + strncpy(result, text, beginIndex + beginLen); // Copy first text part + if (replacement != NULL) strncpy(result + beginIndex + beginLen, replacement, replaceLen); // Copy replacement (if provided) + strncpy(result + beginIndex + beginLen + replaceLen, text + endIndex, textLen - endIndex); // Copy end text part + } } } @@ -1788,16 +1796,21 @@ char *TextReplaceBetween(const char *text, const char *begin, const char *end, c // WARNING: Allocated memory must be manually freed char *TextInsert(const char *text, const char *insert, int position) { - int textLen = TextLength(text); - int insertLen = TextLength(insert); + char *result = NULL; - char *result = (char *)RL_MALLOC(textLen + insertLen + 1); + if ((text != NULL) && (insert != NULL)) + { + int textLen = TextLength(text); + int insertLen = TextLength(insert); - for (int i = 0; i < position; i++) result[i] = text[i]; - for (int i = position; i < insertLen + position; i++) result[i] = insert[i]; - for (int i = (insertLen + position); i < (textLen + insertLen); i++) result[i] = text[i]; + result = (char *)RL_MALLOC(textLen + insertLen + 1); - result[textLen + insertLen] = '\0'; // Make sure text string is valid! + for (int i = 0; i < position; i++) result[i] = text[i]; + for (int i = position; i < insertLen + position; i++) result[i] = insert[i]; + for (int i = (insertLen + position); i < (textLen + insertLen); i++) result[i] = text[i]; + + result[textLen + insertLen] = '\0'; // Add EOL + } return result; } @@ -1879,11 +1892,13 @@ char **TextSplit(const char *text, char delimiter, int *count) // Append text at specific position and move cursor // WARNING: It's up to the user to make sure appended text does not overflow the buffer! -// REQUIRES: strcpy() void TextAppend(char *text, const char *append, int *position) { - strcpy(text + *position, append); - *position += TextLength(append); + if ((text != NULL) && (append != NULL)) + { + TextCopy(text + *position, append); + *position += TextLength(append); + } } // Find first text occurrence within a string @@ -1891,11 +1906,13 @@ void TextAppend(char *text, const char *append, int *position) int TextFindIndex(const char *text, const char *search) { int position = -1; - if (text == NULL) return position; - char *ptr = (char *)strstr(text, search); + if (text != NULL) + { + char *ptr = (char *)strstr(text, search); - if (ptr != NULL) position = (int)(ptr - text); + if (ptr != NULL) position = (int)(ptr - text); + } return position; } @@ -2029,24 +2046,29 @@ char *TextToCamel(const char *text) // WARNING: Allocated memory must be manually freed char *LoadUTF8(const int *codepoints, int length) { - // We allocate enough memory to fit all possible codepoints - // NOTE: 5 bytes for every codepoint should be enough - char *text = (char *)RL_CALLOC(length*5, 1); - const char *utf8 = NULL; - int size = 0; - - for (int i = 0, bytes = 0; i < length; i++) + char *text = NULL; + + if ((codepoints != NULL) && (length > 0)) { - utf8 = CodepointToUTF8(codepoints[i], &bytes); - memcpy(text + size, utf8, bytes); - size += bytes; - } + // We allocate enough memory to fit all possible codepoints + // NOTE: 5 bytes for every codepoint should be enough + text = (char *)RL_CALLOC(length*5, 1); + const char *utf8 = NULL; + int size = 0; - // Create second buffer and copy data manually to it - char *temp = (char *)RL_CALLOC(size + 1, 1); - memcpy(temp, text, size); - RL_FREE(text); - text = temp; + for (int i = 0, bytes = 0; i < length; i++) + { + utf8 = CodepointToUTF8(codepoints[i], &bytes); + memcpy(text + size, utf8, bytes); + size += bytes; + } + + // Create second buffer and copy data manually to it + char *temp = (char *)RL_CALLOC(size + 1, 1); + memcpy(temp, text, size); + RL_FREE(text); + text = temp; + } return text; } @@ -2060,28 +2082,31 @@ void UnloadUTF8(char *text) // Load all codepoints from a UTF-8 text string, codepoints count returned by parameter int *LoadCodepoints(const char *text, int *count) { - int textLength = TextLength(text); - - int codepointSize = 0; + int *codepoints = NULL; int codepointCount = 0; - - // Allocate a big enough buffer to store as many codepoints as text bytes - int *codepoints = (int *)RL_CALLOC(textLength, sizeof(int)); - - for (int i = 0; i < textLength; codepointCount++) + + if (text != NULL) { - codepoints[codepointCount] = GetCodepointNext(text + i, &codepointSize); - i += codepointSize; + int textLength = TextLength(text); + + // Allocate a big enough buffer to store as many codepoints as text bytes + int *codepoints = (int *)RL_CALLOC(textLength, sizeof(int)); + + int codepointSize = 0; + for (int i = 0; i < textLength; codepointCount++) + { + codepoints[codepointCount] = GetCodepointNext(text + i, &codepointSize); + i += codepointSize; + } + + // Create second buffer and copy data manually to it + int *temp = (int *)RL_CALLOC(codepointCount, sizeof(int)); + for (int i = 0; i < codepointCount; i++) temp[i] = codepoints[i]; + RL_FREE(codepoints); + codepoints = temp; } - // Create second buffer and copy data manually to it - int *temp = (int *)RL_CALLOC(codepointCount, sizeof(int)); - for (int i = 0; i < codepointCount; i++) temp[i] = codepoints[i]; - RL_FREE(codepoints); - codepoints = temp; - *count = codepointCount; - return codepoints; } @@ -2098,14 +2123,15 @@ int GetCodepointCount(const char *text) unsigned int length = 0; const char *ptr = text; - while (*ptr != '\0') + if (ptr != NULL) { - int next = 0; - GetCodepointNext(ptr, &next); - - ptr += next; - - length++; + while (*ptr != '\0') + { + int next = 0; + GetCodepointNext(ptr, &next); + ptr += next; + length++; + } } return length; @@ -2170,11 +2196,14 @@ int GetCodepoint(const char *text, int *codepointSize) 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ - // NOTE: on decode errors we return as soon as possible + int codepoint = 0x3f; // Codepoint (defaults to '?') - int octet = (unsigned char)(text[0]); // The first UTF8 octet *codepointSize = 1; + if (text == NULL) return codepoint; + + // NOTE: on decode errors we return as soon as possible + int octet = (unsigned char)(text[0]); // The first UTF8 octet if (octet <= 0x7f) { @@ -2266,6 +2295,7 @@ int GetCodepointNext(const char *text, int *codepointSize) const char *ptr = text; int codepoint = 0x3f; // Codepoint (defaults to '?') *codepointSize = 1; + if (text == NULL) return codepoint; // Get current codepoint and bytes processed if (0xf0 == (0xf8 & ptr[0])) @@ -2304,15 +2334,15 @@ int GetCodepointPrevious(const char *text, int *codepointSize) { const char *ptr = text; int codepoint = 0x3f; // Codepoint (defaults to '?') - int cpSize = 0; - *codepointSize = 0; + *codepointSize = 1; + if (text == NULL) return codepoint; // Move to previous codepoint do ptr--; while (((0x80 & ptr[0]) != 0) && ((0xc0 & ptr[0]) == 0x80)); + int cpSize = 0; codepoint = GetCodepointNext(ptr, &cpSize); - if (codepoint != 0) *codepointSize = cpSize; return codepoint; @@ -2450,7 +2480,7 @@ static Font LoadBMFont(const char *fileName) RL_FREE(imFonts); - if (isGpuReady) font.texture = LoadTextureFromImage(fullFont); + font.texture = LoadTextureFromImage(fullFont); // Fill font characters info data font.baseSize = fontSize; @@ -2459,7 +2489,15 @@ static Font LoadBMFont(const char *fileName) font.glyphs = (GlyphInfo *)RL_MALLOC(glyphCount*sizeof(GlyphInfo)); font.recs = (Rectangle *)RL_MALLOC(glyphCount*sizeof(Rectangle)); - int charId, charX, charY, charWidth, charHeight, charOffsetX, charOffsetY, charAdvanceX, pageID; + int charId = 0; + int charX = 0; + int charY = 0; + int charWidth = 0; + int charHeight = 0; + int charOffsetX = 0; + int charOffsetY = 0; + int charAdvanceX = 0; + int pageID = 0; for (int i = 0; i < glyphCount; i++) { @@ -2492,7 +2530,7 @@ static Font LoadBMFont(const char *fileName) UnloadImage(fullFont); UnloadFileText(fileText); - if (isGpuReady && (font.texture.id == 0)) + if (font.texture.id == 0) { UnloadFont(font); font = GetFontDefault(); diff --git a/src/rtextures.c b/src/rtextures.c index 17065822a..4208b40bd 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -771,7 +771,7 @@ bool ExportImageAsCode(Image image, const char *fileName) // Get file name from path and convert variable name to uppercase char varFileName[256] = { 0 }; - strcpy(varFileName, GetFileNameWithoutExt(fileName)); + strncpy(varFileName, GetFileNameWithoutExt(fileName), 256 - 1); // NOTE: Using function provided by [rcore] module for (int i = 0; varFileName[i] != '\0'; i++) if ((varFileName[i] >= 'a') && (varFileName[i] <= 'z')) { varFileName[i] = varFileName[i] - 32; } // Add image information @@ -1125,17 +1125,19 @@ Image GenImageCellular(int width, int height, int tileSize) Image GenImageText(int width, int height, const char *text) { Image image = { 0 }; - - int textLength = (int)strlen(text); - int imageViewSize = width*height; - + + int imageSize = width*height; image.width = width; image.height = height; image.format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE; - image.data = RL_CALLOC(imageViewSize, 1); + image.data = RL_CALLOC(imageSize, 1); image.mipmaps = 1; - memcpy(image.data, text, (textLength > imageViewSize)? imageViewSize : textLength); + if (text != NULL) + { + int textLength = (int)strlen(text); + memcpy(image.data, text, (textLength > imageSize)? imageSize : textLength); + } return image; } @@ -1484,8 +1486,9 @@ Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Co { Image imText = { 0 }; #if defined(SUPPORT_MODULE_RTEXT) - int size = (int)strlen(text); // Get size in bytes of text - + if (text == NULL) return imText; + + int textLength = (int)strlen(text); // Get length of text in bytes int textOffsetX = 0; // Image drawing position X int textOffsetY = 0; // Offset between lines (on linebreak '\n') @@ -1496,7 +1499,7 @@ Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Co // Create image to store text imText = GenImageColor((int)imSize.x, (int)imSize.y, BLANK); - for (int i = 0; i < size;) + for (int i = 0; i < textLength;) { // Get next codepoint from byte string and glyph index in font int codepointByteCount = 0; @@ -1724,7 +1727,8 @@ void ImageResizeNN(Image *image, int newWidth, int newHeight) int xRatio = (int)((image->width << 16)/newWidth) + 1; int yRatio = (int)((image->height << 16)/newHeight) + 1; - int x2, y2; + int x2 = 0; + int y2 = 0; for (int y = 0; y < newHeight; y++) { for (int x = 0; x < newWidth; x++) @@ -2485,8 +2489,13 @@ void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp) Color oldPixel = WHITE; Color newPixel = WHITE; - int rError, gError, bError; - unsigned short rPixel, gPixel, bPixel, aPixel; // Used for 16bit pixel composition + int rError = 0; + int gError = 0; + int bError = 0; + unsigned short rPixel = 0; // Used for 16bit pixel composition + unsigned short gPixel = 0; + unsigned short bPixel = 0; + unsigned short aPixel = 0; #define MIN(a,b) (((a)<(b))?(a):(b)) @@ -4003,7 +4012,9 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color // [-] GetPixelColor(): Get Vector4 instead of Color, easier for ColorAlphaBlend() // [ ] TODO: Support 16bit and 32bit (float) channels drawing - Color colSrc, colDst, blend; + Color colSrc = { 0 }; + Color colDst = { 0 }; + Color blend = { 0 }; bool blendRequired = true; // Fast path: Avoid blend if source has no alpha to blend @@ -4200,7 +4211,7 @@ TextureCubemap LoadTextureCubemap(Image image, int layout) /*else if (layout == CUBEMAP_LAYOUT_PANORAMA) { // TODO: Implement panorama by converting image to square faces... - // Ref: https://github.com/denivip/panorama/blob/master/panorama.cpp + // REF: https://github.com/denivip/panorama/blob/master/panorama.cpp } */ else { @@ -4678,17 +4689,23 @@ void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle dest, bottomBorder = patchHeight - topBorder; } - Vector2 vertA, vertB, vertC, vertD; - vertA.x = 0.0f; // outer left - vertA.y = 0.0f; // outer top - vertB.x = leftBorder; // inner left - vertB.y = topBorder; // inner top - vertC.x = patchWidth - rightBorder; // inner right - vertC.y = patchHeight - bottomBorder; // inner bottom - vertD.x = patchWidth; // outer right - vertD.y = patchHeight; // outer bottom + Vector2 vertA = { 0 }; + Vector2 vertB = { 0 }; + Vector2 vertC = { 0 }; + Vector2 vertD = { 0 }; + vertA.x = 0.0f; // Outer left + vertA.y = 0.0f; // Outer top + vertB.x = leftBorder; // Inner left + vertB.y = topBorder; // Inner top + vertC.x = patchWidth - rightBorder; // Inner right + vertC.y = patchHeight - bottomBorder; // Inner bottom + vertD.x = patchWidth; // Outer right + vertD.y = patchHeight; // Outer bottom - Vector2 coordA, coordB, coordC, coordD; + Vector2 coordA = { 0 }; + Vector2 coordB = { 0 }; + Vector2 coordC = { 0 }; + Vector2 coordD = { 0 }; coordA.x = nPatchInfo.source.x/width; coordA.y = nPatchInfo.source.y/height; coordB.x = (nPatchInfo.source.x + leftBorder)/width; @@ -4904,7 +4921,9 @@ Vector3 ColorToHSV(Color color) { Vector3 hsv = { 0 }; Vector3 rgb = { (float)color.r/255.0f, (float)color.g/255.0f, (float)color.b/255.0f }; - float min, max, delta; + float min = 0.0f; + float max = 0.0f; + float delta = 0.0f; min = rgb.x < rgb.y? rgb.x : rgb.y; min = min < rgb.z? min : rgb.z; @@ -5407,7 +5426,7 @@ int GetPixelDataSize(int width, int height, int format) // Module Internal Functions Definition //---------------------------------------------------------------------------------- // Convert half-float (stored as unsigned short) to float -// Ref: https://stackoverflow.com/questions/1659440/32-bit-to-16-bit-floating-point-conversion/60047308#60047308 +// REF: https://stackoverflow.com/questions/1659440/32-bit-to-16-bit-floating-point-conversion/60047308#60047308 static float HalfToFloat(unsigned short x) { float result = 0.0f; diff --git a/src/utils.c b/src/utils.c index 892f96cf4..09158893a 100644 --- a/src/utils.c +++ b/src/utils.c @@ -105,7 +105,7 @@ void TraceLog(int logType, const char *text, ...) { #if defined(SUPPORT_TRACELOG) // Message has level below current threshold, don't emit - if (logType < logTypeLevel) return; + if ((logType < logTypeLevel) || (text == NULL)) return; va_list args; va_start(args, text); @@ -142,8 +142,8 @@ void TraceLog(int logType, const char *text, ...) default: break; } - unsigned int textSize = (unsigned int)strlen(text); - memcpy(buffer + strlen(buffer), text, (textSize < (MAX_TRACELOG_MSG_LENGTH - 12))? textSize : (MAX_TRACELOG_MSG_LENGTH - 12)); + 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); @@ -313,7 +313,7 @@ bool ExportDataAsCode(const unsigned char *data, int dataSize, const char *fileN // Get file name from path char varFileName[256] = { 0 }; - strcpy(varFileName, GetFileNameWithoutExt(fileName)); + strncpy(varFileName, GetFileNameWithoutExt(fileName), 256 - 1); for (int i = 0; varFileName[i] != '\0'; i++) { // Convert variable name to uppercase @@ -446,7 +446,7 @@ void InitAssetManager(AAssetManager *manager, const char *dataPath) } // Replacement for fopen() -// Ref: https://developer.android.com/ndk/reference/group/asset +// REF: https://developer.android.com/ndk/reference/group/asset FILE *android_fopen(const char *fileName, const char *mode) { if (mode[0] == 'w') @@ -454,7 +454,7 @@ FILE *android_fopen(const char *fileName, const char *mode) // 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 + // 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) diff --git a/tools/rexm/reports/examples_issues.md b/tools/rexm/reports/examples_issues.md index 081170806..14e7a61c5 100644 --- a/tools/rexm/reports/examples_issues.md +++ b/tools/rexm/reports/examples_issues.md @@ -21,9 +21,10 @@ Example elements validated: | **EXAMPLE NAME** | [C] | [CAT]| [INFO]|[PNG]|[WPNG]| [RES]| [MK] |[MKWEB]| [VCX]| [SOL]|[RDME]|[JS] | [WOUT]|[WMETA]| |:---------------------------------|:---:|:----:|:-----:|:---:|:----:|:----:|:----:|:-----:|:----:|:----:|:----:|:---:|:-----:|:-----:| | core_highdpi_testbed | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| rlgl_standalone | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| rlgl_compute_shader | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| easings_testbed | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| raylib_opengl_interop | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | -| embedded_files_loading | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| web_basic_window | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shaders_game_of_life | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | +| rlgl_standalone | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | +| rlgl_compute_shader | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | +| easings_testbed | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| raylib_opengl_interop | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ❌ | ✔ | ❌ | ✔ | ✔ | +| embedded_files_loading | ✔ | ❌ | ❌ | ✔ | ✔ | ❌ | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | +| web_basic_window | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | diff --git a/tools/rexm/reports/examples_validation.md b/tools/rexm/reports/examples_validation.md index 831dbd978..45c195415 100644 --- a/tools/rexm/reports/examples_validation.md +++ b/tools/rexm/reports/examples_validation.md @@ -104,6 +104,7 @@ Example elements validated: | shapes_rlgl_color_wheel | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_rlgl_triangle | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_ball_physics | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_penrose_tile | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_logo_raylib | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_srcrec_dstrec | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_image_drawing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | @@ -132,6 +133,7 @@ Example elements validated: | textures_screen_buffer | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_textured_curve | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_sprite_stacking | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| textures_cellular_automata | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_sprite_fonts | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_font_spritefont | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_font_filters | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | @@ -147,6 +149,7 @@ Example elements validated: | text_codepoints_loading | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_inline_styling | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_words_alignment | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| text_strings_management | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | models_animation_playing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | models_billboard_rendering | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | models_box_collisions | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | @@ -206,6 +209,7 @@ Example elements validated: | shaders_lightmap_rendering | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_rounded_rectangle | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_depth_rendering | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shaders_game_of_life | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | | audio_module_playing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | audio_music_stream | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | audio_raw_stream | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | @@ -215,9 +219,9 @@ Example elements validated: | audio_sound_multi | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | audio_sound_positioning | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | audio_spectrum_visualizer | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| rlgl_standalone | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| rlgl_compute_shader | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| easings_testbed | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| raylib_opengl_interop | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | -| embedded_files_loading | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| web_basic_window | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| rlgl_standalone | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | +| rlgl_compute_shader | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | +| easings_testbed | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| raylib_opengl_interop | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ❌ | ✔ | ❌ | ✔ | ✔ | +| embedded_files_loading | ✔ | ❌ | ❌ | ✔ | ✔ | ❌ | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | +| web_basic_window | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 72b962874..aa491ff23 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -72,6 +72,12 @@ // Create local commit with changes on example renaming //#define RENAME_AUTO_COMMIT_CREATION +#if defined(__GNUC__) // GCC and Clang + #pragma GCC diagnostic push + // Avoid GCC/Clang complaining about sprintf() second parameter not being a string literal (being TextFormat()) + #pragma GCC diagnostic ignored "-Wformat-security" +#endif + //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- @@ -1002,6 +1008,7 @@ int main(int argc, char *argv[]) LOG("INFO: Scanning available example (.c) files to be added to collection...\n"); FilePathList clist = LoadDirectoryFilesEx(exBasePath, ".c", true); + // Load examples collection list file (raylib/examples/examples_list.txt) char *exList = LoadFileText(exCollectionFilePath); char *exListUpdated = (char *)RL_CALLOC(REXM_MAX_BUFFER_SIZE, 1); bool listUpdated = false; @@ -1018,7 +1025,7 @@ int main(int argc, char *argv[]) for (int i = 1; i < lineCount; i++) { - if ((TextFindIndex(exListUpdated, exListLines[i]) == -1) || (exListLines[i][0] == '#')) + if ((TextFindIndex(exListUpdated, exListLines[i]) == -1) || (exListLines[i][0] == '#')) exListUpdatedOffset += sprintf(exListUpdated + exListUpdatedOffset, "%s\n", exListLines[i]); else listUpdated = true; } @@ -2322,7 +2329,7 @@ static rlExampleInfo *LoadExampleInfo(const char *exFileName) // Example found in collection exInfo = (rlExampleInfo *)RL_CALLOC(1, sizeof(rlExampleInfo)); - strcpy(exInfo->name, GetFileNameWithoutExt(exFileName)); + strncpy(exInfo->name, GetFileNameWithoutExt(exFileName), 128 - 1); strncpy(exInfo->category, exInfo->name, TextFindIndex(exInfo->name, "_")); char *exText = LoadFileText(exFileName); @@ -2505,7 +2512,7 @@ static char **LoadExampleResourcePaths(const char *filePath, int *resPathCount) if (!end) break; // WARNING: Some paths could be for saving files, not loading, those "resource" files must be omitted - // HACK: Just check previous position from pointer for function name including the string and the index "distance" + // TODO: HACK: Just check previous position from pointer for function name including the string and the index "distance" // This is a quick solution, the good one would be getting the data loading function names... int functionIndex01 = TextFindIndex(ptr - 40, "ExportImage"); // Check ExportImage() int functionIndex02 = TextFindIndex(ptr - 10, "TraceLog"); // Check TraceLog() @@ -2863,8 +2870,8 @@ static void UpdateWebMetadata(const char *exHtmlPath, const char *exFilePath) char exTitle[64] = { 0 }; // Example title: fileName without extension, replacing underscores by spaces // Get example name: replace underscore by spaces - strcpy(exName, GetFileNameWithoutExt(exHtmlPathCopy)); - strcpy(exTitle, exName); + strncpy(exName, GetFileNameWithoutExt(exHtmlPathCopy), 64 - 1); + strncpy(exTitle, exName, 64 - 1); for (int i = 0; (i < 256) && (exTitle[i] != '\0'); i++) { if (exTitle[i] == '_') exTitle[i] = ' '; } // Get example category from exName: copy until first underscore @@ -2917,3 +2924,6 @@ static bool TextInList(const char *text, const char **list, int listCount) return result; } +#if defined(__GNUC__) // GCC and Clang + #pragma GCC diagnostic pop +#endif diff --git a/tools/rlparser/output/raylib_api.json b/tools/rlparser/output/raylib_api.json index a1af3c9fc..66d8e9f30 100644 --- a/tools/rlparser/output/raylib_api.json +++ b/tools/rlparser/output/raylib_api.json @@ -769,22 +769,22 @@ { "type": "Vector2", "name": "offset", - "description": "Camera offset (displacement from target)" + "description": "Camera offset (screen space offset from window origin)" }, { "type": "Vector2", "name": "target", - "description": "Camera target (rotation and zoom origin)" + "description": "Camera target (world space target point that is mapped to screen space offset)" }, { "type": "float", "name": "rotation", - "description": "Camera rotation in degrees" + "description": "Camera rotation in degrees (pivots around target)" }, { "type": "float", "name": "zoom", - "description": "Camera zoom (scaling), should be 1.0f by default" + "description": "Camera zoom (scaling around target), must not be set to 0, set to 1.0f for no scale" } ] }, @@ -4646,7 +4646,7 @@ "params": [ { "type": "const char *", - "name": "dir" + "name": "dirPath" } ] }, diff --git a/tools/rlparser/output/raylib_api.lua b/tools/rlparser/output/raylib_api.lua index 20043c12d..192ad963a 100644 --- a/tools/rlparser/output/raylib_api.lua +++ b/tools/rlparser/output/raylib_api.lua @@ -769,22 +769,22 @@ return { { type = "Vector2", name = "offset", - description = "Camera offset (displacement from target)" + description = "Camera offset (screen space offset from window origin)" }, { type = "Vector2", name = "target", - description = "Camera target (rotation and zoom origin)" + description = "Camera target (world space target point that is mapped to screen space offset)" }, { type = "float", name = "rotation", - description = "Camera rotation in degrees" + description = "Camera rotation in degrees (pivots around target)" }, { type = "float", name = "zoom", - description = "Camera zoom (scaling), should be 1.0f by default" + description = "Camera zoom (scaling around target), must not be set to 0, set to 1.0f for no scale" } } }, @@ -4167,7 +4167,7 @@ return { description = "Change working directory, return true on success", returnType = "bool", params = { - {type = "const char *", name = "dir"} + {type = "const char *", name = "dirPath"} } }, { diff --git a/tools/rlparser/output/raylib_api.txt b/tools/rlparser/output/raylib_api.txt index 3578e41df..f60f8fc81 100644 --- a/tools/rlparser/output/raylib_api.txt +++ b/tools/rlparser/output/raylib_api.txt @@ -399,10 +399,10 @@ Struct 13: Camera3D (5 fields) Struct 14: Camera2D (4 fields) Name: Camera2D Description: Camera2D, defines position/orientation in 2d space - Field[1]: Vector2 offset // Camera offset (displacement from target) - Field[2]: Vector2 target // Camera target (rotation and zoom origin) - Field[3]: float rotation // Camera rotation in degrees - Field[4]: float zoom // Camera zoom (scaling), should be 1.0f by default + Field[1]: Vector2 offset // Camera offset (screen space offset from window origin) + Field[2]: Vector2 target // Camera target (world space target point that is mapped to screen space offset) + Field[3]: float rotation // Camera rotation in degrees (pivots around target) + Field[4]: float zoom // Camera zoom (scaling around target), must not be set to 0, set to 1.0f for no scale Struct 15: Mesh (17 fields) Name: Mesh Description: Mesh, vertex data and vao/vbo @@ -1763,7 +1763,7 @@ Function 143: ChangeDirectory() (1 input parameters) Name: ChangeDirectory Return type: bool Description: Change working directory, return true on success - Param[1]: dir (type: const char *) + Param[1]: dirPath (type: const char *) Function 144: IsPathFile() (1 input parameters) Name: IsPathFile Return type: bool diff --git a/tools/rlparser/output/raylib_api.xml b/tools/rlparser/output/raylib_api.xml index ea7792612..1bbeb175c 100644 --- a/tools/rlparser/output/raylib_api.xml +++ b/tools/rlparser/output/raylib_api.xml @@ -155,10 +155,10 @@ - - - - + + + + @@ -1111,7 +1111,7 @@ - +