From ddb827fb6faa963a5c67dcc79d17d2d65e77c5e7 Mon Sep 17 00:00:00 2001 From: Kivi <35783191+KiviTK@users.noreply.github.com> Date: Wed, 24 Dec 2025 08:59:51 +0100 Subject: [PATCH 001/232] Fixed LoadCodepoints declaring a new local variable shadowing `codpoints` (#5430) --- src/rtext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rtext.c b/src/rtext.c index 7c25fde0b..e4b439d28 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -2090,7 +2090,7 @@ int *LoadCodepoints(const char *text, int *count) 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)); + codepoints = (int *)RL_CALLOC(textLength, sizeof(int)); int codepointSize = 0; for (int i = 0; i < textLength; codepointCount++) From a1e84caa8c26b36d6bfbc4a64b731fdeae1dacf2 Mon Sep 17 00:00:00 2001 From: Krzysztof Szenk Date: Wed, 24 Dec 2025 09:04:41 +0100 Subject: [PATCH 002/232] RGFW also requires RGBA8 images as window icons, as raylib already reports in raylib.h (#5431) --- src/platforms/rcore_desktop_rgfw.c | 52 ++++++++---------------------- 1 file changed, 13 insertions(+), 39 deletions(-) diff --git a/src/platforms/rcore_desktop_rgfw.c b/src/platforms/rcore_desktop_rgfw.c index 2671538d8..39ac8fb32 100644 --- a/src/platforms/rcore_desktop_rgfw.c +++ b/src/platforms/rcore_desktop_rgfw.c @@ -522,46 +522,15 @@ void ClearWindowState(unsigned int flags) } } -int RGFW_formatToChannels(int format) -{ - switch (format) - { - case PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: - case PIXELFORMAT_UNCOMPRESSED_R16: // 16 bpp (1 channel - half float) - case PIXELFORMAT_UNCOMPRESSED_R32: // 32 bpp (1 channel - float) - return 1; - case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: // 8*2 bpp (2 channels) - case PIXELFORMAT_UNCOMPRESSED_R5G6B5: // 16 bpp - case PIXELFORMAT_UNCOMPRESSED_R8G8B8: // 24 bpp - case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: // 16 bpp (1 bit alpha) - case PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: // 16 bpp (4 bit alpha) - case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: // 32 bpp - return 2; - case PIXELFORMAT_UNCOMPRESSED_R32G32B32: // 32*3 bpp (3 channels - float) - case PIXELFORMAT_UNCOMPRESSED_R16G16B16: // 16*3 bpp (3 channels - half float) - case PIXELFORMAT_COMPRESSED_DXT1_RGB: // 4 bpp (no alpha) - case PIXELFORMAT_COMPRESSED_ETC1_RGB: // 4 bpp - case PIXELFORMAT_COMPRESSED_ETC2_RGB: // 4 bpp - case PIXELFORMAT_COMPRESSED_PVRT_RGB: // 4 bpp - return 3; - case PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: // 32*4 bpp (4 channels - float) - case PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: // 16*4 bpp (4 channels - half float) - case PIXELFORMAT_COMPRESSED_DXT1_RGBA: // 4 bpp (1 bit alpha) - case PIXELFORMAT_COMPRESSED_DXT3_RGBA: // 8 bpp - case PIXELFORMAT_COMPRESSED_DXT5_RGBA: // 8 bpp - case PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA: // 8 bpp - case PIXELFORMAT_COMPRESSED_PVRT_RGBA: // 4 bpp - case PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: // 8 bpp - case PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: // 2 bpp - return 4; - default: return 4; - } -} - // Set icon for window void SetWindowIcon(Image image) { - RGFW_window_setIcon(platform.window, (u8 *)image.data, RGFW_AREA(image.width, image.height), RGFW_formatToChannels(image.format)); + if (image.format != PIXELFORMAT_UNCOMPRESSED_R8G8B8A8) + { + TRACELOG(LOG_WARNING, "RGFW: Window icon image must be in R8G8B8A8 pixel format"); + return; + } + RGFW_window_setIcon(platform.window, (u8 *)image.data, RGFW_AREA(image.width, image.height), 4); } // Set icon for window @@ -578,12 +547,17 @@ void SetWindowIcons(Image *images, int count) for (int i = 0; i < count; i++) { + if (images[i].format != PIXELFORMAT_UNCOMPRESSED_R8G8B8A8) + { + TRACELOG(LOG_WARNING, "RGFW: Window icon image must be in R8G8B8A8 pixel format"); + continue; + } if ((bigIcon == NULL) || ((images[i].width > bigIcon->width) && (images[i].height > bigIcon->height))) bigIcon = &images[i]; if ((smallIcon == NULL) || ((images[i].width < smallIcon->width) && (images[i].height > smallIcon->height))) smallIcon = &images[i]; } - if (smallIcon != NULL) RGFW_window_setIconEx(platform.window, (u8 *)smallIcon->data, RGFW_AREA(smallIcon->width, smallIcon->height), RGFW_formatToChannels(smallIcon->format), RGFW_iconWindow); - if (bigIcon != NULL) RGFW_window_setIconEx(platform.window, (u8 *)bigIcon->data, RGFW_AREA(bigIcon->width, bigIcon->height), RGFW_formatToChannels(bigIcon->format), RGFW_iconTaskbar); + if (smallIcon != NULL) RGFW_window_setIconEx(platform.window, (u8 *)smallIcon->data, RGFW_AREA(smallIcon->width, smallIcon->height), 4, RGFW_iconWindow); + if (bigIcon != NULL) RGFW_window_setIconEx(platform.window, (u8 *)bigIcon->data, RGFW_AREA(bigIcon->width, bigIcon->height), 4, RGFW_iconTaskbar); } } From 05f42aa119d53049f92aae4e60c3f325d4f52a6b Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 24 Dec 2025 18:02:04 +0100 Subject: [PATCH 003/232] Update core_highdpi_testbed.c --- examples/core/core_highdpi_testbed.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/core/core_highdpi_testbed.c b/examples/core/core_highdpi_testbed.c index 6a036bbfc..bf103fb31 100644 --- a/examples/core/core_highdpi_testbed.c +++ b/examples/core/core_highdpi_testbed.c @@ -27,7 +27,7 @@ int main(void) const int screenWidth = 800; const int screenHeight = 450; - SetConfigFlags(FLAG_WINDOW_HIGHDPI | FLAG_WINDOW_RESIZABLE); + SetConfigFlags(FLAG_WINDOW_RESIZABLE | FLAG_WINDOW_HIGHDPI); InitWindow(screenWidth, screenHeight, "raylib [core] example - highdpi testbed"); Vector2 scaleDpi = GetWindowScaleDPI(); From ced84333a9f7647f039b568e75af546b30e8a986 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 24 Dec 2025 18:02:24 +0100 Subject: [PATCH 004/232] Update rl_gputex.h --- src/external/rl_gputex.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/external/rl_gputex.h b/src/external/rl_gputex.h index 78d618db5..9c1092695 100644 --- a/src/external/rl_gputex.h +++ b/src/external/rl_gputex.h @@ -339,7 +339,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_ } } } - else if ((header->ddspf.flags == 0x40) && (header->ddspf.rgb_bit_count == 24)) // DDS_RGB, no compressed + else if ((header->ddspf.flags == 0x40) && (header->ddspf.rgb_bit_count == 24)) // DDS_RGB, no compressed { int data_size = image_pixel_size*3*sizeof(unsigned char); if (header->mipmap_count > 1) data_size = data_size + data_size/3; From 9103f6e0557f615c2295febff69c86a80fc0d2b9 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 24 Dec 2025 18:58:20 +0100 Subject: [PATCH 005/232] ADDED: New platform backend for Web: `Emscripten`, not dependant on GLFW.js -WIP- --- src/platforms/rcore_web_emscripten.c | 1701 ++++++++++++++++++++++++++ 1 file changed, 1701 insertions(+) create mode 100644 src/platforms/rcore_web_emscripten.c diff --git a/src/platforms/rcore_web_emscripten.c b/src/platforms/rcore_web_emscripten.c new file mode 100644 index 000000000..1ed719631 --- /dev/null +++ b/src/platforms/rcore_web_emscripten.c @@ -0,0 +1,1701 @@ +/********************************************************************************************** +* +* rcore_web_emscripten - Functions to manage window, graphics device and inputs +* +* PLATFORM: WEB - EMSCRIPTEN +* - HTML5 (WebAssembly) +* +* LIMITATIONS: +* - TBD +* +* POSSIBLE IMPROVEMENTS: +* - TBD +* +* ADDITIONAL NOTES: +* - TRACELOG() function is located in raylib [utils] module +* +* CONFIGURATION: +* #define RCORE_PLATFORM_CUSTOM_FLAG +* Custom flag for rcore on target platform -not used- +* +* DEPENDENCIES: +* - emscripten: Allow interaction between browser API and C +* - gestures: Gestures system for touch-ready devices (or simulated from mouse inputs) +* +* +* LICENSE: zlib/libpng +* +* Copyright (c) 2025 Ramon Santamaria (@raysan5) and contributors +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +#include // Emscripten functionality for C +#include // Emscripten HTML5 library + +#include // Required for: timespec, nanosleep(), select() - POSIX + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- +#if (_POSIX_C_SOURCE < 199309L) + #undef _POSIX_C_SOURCE + #define _POSIX_C_SOURCE 199309L // Required for: CLOCK_MONOTONIC if compiled with c99 without gnu ext. +#endif + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +typedef struct { + char canvasId[64]; // Current canvas id + EMSCRIPTEN_WEBGL_CONTEXT_HANDLE glContext; // OpenGL context + unsigned int *pixels; // Pointer to pixel data buffer (RGBA 32bit format) +} PlatformData; + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +extern CoreData CORE; // Global CORE state context + +static PlatformData platform = { 0 }; // Platform specific data + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +static const char cursorLUT[11][12] = { + "default", // 0 MOUSE_CURSOR_DEFAULT + "default", // 1 MOUSE_CURSOR_ARROW + "text", // 2 MOUSE_CURSOR_IBEAM + "crosshair", // 3 MOUSE_CURSOR_CROSSHAIR + "pointer", // 4 MOUSE_CURSOR_POINTING_HAND + "ew-resize", // 5 MOUSE_CURSOR_RESIZE_EW + "ns-resize", // 6 MOUSE_CURSOR_RESIZE_NS + "nwse-resize", // 7 MOUSE_CURSOR_RESIZE_NWSE + "nesw-resize", // 8 MOUSE_CURSOR_RESIZE_NESW + "move", // 9 MOUSE_CURSOR_RESIZE_ALL + "not-allowed" // 10 MOUSE_CURSOR_NOT_ALLOWED +}; + +//---------------------------------------------------------------------------------- +// Module Internal Functions Declaration +//---------------------------------------------------------------------------------- +int InitPlatform(void); // Initialize platform (graphics, inputs and more) +void ClosePlatform(void); // Close platform + +// Emscripten window callback events +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); +static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const EmscriptenFullscreenChangeEvent *event, void *userData); +// TODO: Implement GLFW3 alternative for drop callback, runs when drop files into browser/canvas +//static void WindowDropCallback(GLFWwindow *window, int count, const char **paths); + +// Emscripten input callback events +static EM_BOOL EmscriptenKeyboardCallback(int eventType, const EmscriptenKeyboardEvent *keyboardEvent, void *userData); +static EM_BOOL EmscriptenMouseCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData); +static EM_BOOL EmscriptenMouseMoveCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData); +static EM_BOOL EmscriptenMouseWheelCallback(int eventType, const EmscriptenWheelEvent *wheelEvent, void *userData); +static EM_BOOL EmscriptenPointerlockCallback(int eventType, const EmscriptenPointerlockChangeEvent *pointerlockChangeEvent, void *userData); +static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData); +static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData); + +// 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 +//---------------------------------------------------------------------------------- +// NOTE: Functions declaration is provided by raylib.h + +//---------------------------------------------------------------------------------- +// Module Functions Definition: Window and Graphics Device +//---------------------------------------------------------------------------------- + +// Check if application should close +// This will always return false on a web-build as web builds have no control over this functionality +// Sleep is handled in EndDrawing() for synchronous code +bool WindowShouldClose(void) +{ + // Emscripten Asyncify is required to run synchronous code in asynchronous JS + // 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, + // allowing the browser to manage execution asynchronously + + // Optionally we can manage the time we give-control-back-to-browser if required, + // but it seems below line could generate stuttering on some browsers + emscripten_sleep(12); + + return false; +} + +// Toggle fullscreen mode +void ToggleFullscreen(void) +{ + bool enterFullscreen = false; + + const bool wasFullscreen = EM_ASM_INT( { if (document.fullscreenElement) return 1; }, 0); + if (wasFullscreen) + { + if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) enterFullscreen = false; + else if (FLAG_IS_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE)) enterFullscreen = true; + else + { + const int canvasWidth = EM_ASM_INT( { return Module.canvas.width; }, 0); + const int canvasStyleWidth = EM_ASM_INT( { return parseInt(Module.canvas.style.width); }, 0); + if (canvasStyleWidth > canvasWidth) enterFullscreen = false; + else enterFullscreen = true; + } + + EM_ASM(document.exitFullscreen();); + + CORE.Window.fullscreen = false; + FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); + FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); + } + else enterFullscreen = true; + + if (enterFullscreen) + { + // NOTE: The setTimeouts handle the browser mode change delay + EM_ASM + ( + setTimeout(function() + { + Module.requestFullscreen(false, false); + }, 100); + ); + CORE.Window.fullscreen = true; + FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); + } + + // NOTE: Old notes below: + /* + EM_ASM + ( + // This strategy works well while using raylib minimal web shell for emscripten, + // it re-scales the canvas to fullscreen using monitor resolution, for tools this + // is a good strategy but maybe games prefer to keep current canvas resolution and + // display it in fullscreen, adjusting monitor resolution if possible + if (document.fullscreenElement) document.exitFullscreen(); + else Module.requestFullscreen(true, true); //false, true); + ); + */ + // EM_ASM(Module.requestFullscreen(false, false);); + /* + if (!CORE.Window.fullscreen) + { + // Option 1: Request fullscreen for the canvas element + // 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); + + // 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 + // EmscriptenFullscreenStrategy strategy = { + // .scaleMode = EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH, //EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT, + // .canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF, + // .filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT, + // .canvasResizedCallback = EmscriptenWindowResizedCallback, + // .canvasResizedCallbackUserData = NULL + // }; + //emscripten_request_fullscreen_strategy("#canvas", EM_FALSE, &strategy); + + // Option 3: Request fullscreen for the canvas element with strategy + // It works as expected but only inside the browser (client area) + EmscriptenFullscreenStrategy strategy = { + .scaleMode = EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT, + .canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF, + .filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT, + .canvasResizedCallback = EmscriptenWindowResizedCallback, + .canvasResizedCallbackUserData = NULL + }; + emscripten_enter_soft_fullscreen("#canvas", &strategy); + + int width = 0; + int height = 0; + emscripten_get_canvas_element_size("#canvas", &width, &height); + TRACELOG(LOG_WARNING, "Emscripten: Enter fullscreen: Canvas size: %i x %i", width, height); + + CORE.Window.fullscreen = true; // Toggle fullscreen flag + FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); + } + else + { + //emscripten_exit_fullscreen(); + //emscripten_exit_soft_fullscreen(); + + int width, height; + emscripten_get_canvas_element_size("#canvas", &width, &height); + TRACELOG(LOG_WARNING, "Emscripten: Exit fullscreen: Canvas size: %i x %i", width, height); + + CORE.Window.fullscreen = false; // Toggle fullscreen flag + FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); + } + */ +} + +// Toggle borderless windowed mode +void ToggleBorderlessWindowed(void) +{ + bool enterBorderless = false; + + const bool wasFullscreen = EM_ASM_INT( { if (document.fullscreenElement) return 1; }, 0); + if (wasFullscreen) + { + if (FLAG_IS_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE)) enterBorderless = false; + else if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) enterBorderless = true; + else + { + const int canvasWidth = EM_ASM_INT( { return Module.canvas.width; }, 0); + const int screenWidth = EM_ASM_INT( { return screen.width; }, 0); + if (screenWidth == canvasWidth) enterBorderless = false; + else enterBorderless = true; + } + + EM_ASM(document.exitFullscreen();); + + CORE.Window.fullscreen = false; + FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); + FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); + } + else enterBorderless = true; + + if (enterBorderless) + { + // 1. The setTimeouts handle the browser mode change delay + // 2. The style unset handles the possibility of a width="value%" like on the default shell.html file + EM_ASM + ( + setTimeout(function() + { + Module.requestFullscreen(false, true); + setTimeout(function() + { + canvas.style.width="unset"; + }, 100); + }, 100); + ); + FLAG_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); + } +} + +// Set window state: maximized, if resizable +void MaximizeWindow(void) +{ + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_RESIZABLE) && !FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED)) + { + const int tabWidth = EM_ASM_INT( return window.innerWidth; ); + const int tabHeight = EM_ASM_INT( return window.innerHeight; ); + + FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); + } +} + +// Set window state: minimized +void MinimizeWindow(void) +{ + TRACELOG(LOG_WARNING, "MinimizeWindow() not available on target platform"); +} + +// Restore window from being minimized/maximized +void RestoreWindow(void) +{ + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_RESIZABLE) && FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED)) + { + FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); + } +} + +// Set window configuration state using flags +void SetWindowState(unsigned int flags) +{ + if (!CORE.Window.ready) TRACELOG(LOG_WARNING, "WINDOW: SetWindowState does nothing before window initialization, Use \"SetConfigFlags\" instead"); + + // Check previous state and requested state to apply required changes + // NOTE: In most cases the functions already change the flags internally + + // State change: FLAG_VSYNC_HINT + if (FLAG_IS_SET(flags, FLAG_VSYNC_HINT)) + { + TRACELOG(LOG_WARNING, "SetWindowState(FLAG_VSYNC_HINT) not available on target platform"); + } + + // State change: FLAG_BORDERLESS_WINDOWED_MODE + if (FLAG_IS_SET(flags, FLAG_BORDERLESS_WINDOWED_MODE)) + { + // NOTE: Window state flag updated inside ToggleBorderlessWindowed() function + const bool wasFullscreen = EM_ASM_INT( { if (document.fullscreenElement) return 1; }, 0); + if (wasFullscreen) + { + const int canvasWidth = EM_ASM_INT( { return Module.canvas.width; }, 0); + const int canvasStyleWidth = EM_ASM_INT( { return parseInt(Module.canvas.style.width); }, 0); + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) || canvasStyleWidth > canvasWidth) ToggleBorderlessWindowed(); + } + else ToggleBorderlessWindowed(); + } + + // State change: FLAG_FULLSCREEN_MODE + if (FLAG_IS_SET(flags, FLAG_FULLSCREEN_MODE)) + { + // NOTE: Window state flag updated inside ToggleFullscreen() function + const bool wasFullscreen = EM_ASM_INT( { if (document.fullscreenElement) return 1; }, 0); + if (wasFullscreen) + { + const int canvasWidth = EM_ASM_INT( { return Module.canvas.width; }, 0); + const int screenWidth = EM_ASM_INT( { return screen.width; }, 0); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE) || (screenWidth == canvasWidth)) ToggleFullscreen(); + } + else ToggleFullscreen(); + } + + // State change: FLAG_WINDOW_RESIZABLE + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_RESIZABLE) != FLAG_IS_SET(flags, FLAG_WINDOW_RESIZABLE)) && FLAG_IS_SET(flags, FLAG_WINDOW_RESIZABLE)) + { + FLAG_SET(CORE.Window.flags, FLAG_WINDOW_RESIZABLE); + } + + // State change: FLAG_WINDOW_UNDECORATED + if (FLAG_IS_SET(flags, FLAG_WINDOW_UNDECORATED)) + { + TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_UNDECORATED) not available on target platform"); + } + + // State change: FLAG_WINDOW_HIDDEN + if (FLAG_IS_SET(flags, FLAG_WINDOW_HIDDEN)) + { + TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_HIDDEN) not available on target platform"); + } + + // State change: FLAG_WINDOW_MINIMIZED + if (FLAG_IS_SET(flags, FLAG_WINDOW_MINIMIZED)) + { + TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_MINIMIZED) not available on target platform"); + } + + // State change: FLAG_WINDOW_MAXIMIZED + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED) != FLAG_IS_SET(flags, FLAG_WINDOW_MAXIMIZED)) && FLAG_IS_SET(flags, FLAG_WINDOW_MAXIMIZED)) + { + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_RESIZABLE)) + { + const int tabWidth = EM_ASM_INT( return window.innerWidth; ); + const int tabHeight = EM_ASM_INT( return window.innerHeight; ); + + FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); + } + } + + // State change: FLAG_WINDOW_UNFOCUSED + if (FLAG_IS_SET(flags, FLAG_WINDOW_UNFOCUSED)) + { + TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_UNFOCUSED) not available on target platform"); + } + + // State change: FLAG_WINDOW_TOPMOST + if (FLAG_IS_SET(flags, FLAG_WINDOW_TOPMOST)) + { + TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_TOPMOST) not available on target platform"); + } + + // State change: FLAG_WINDOW_ALWAYS_RUN + if (FLAG_IS_SET(flags, FLAG_WINDOW_ALWAYS_RUN)) + { + TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_ALWAYS_RUN) not available on target platform"); + } + + // The following states can not be changed after window creation + // NOTE: Review for PLATFORM_WEB + + // State change: FLAG_WINDOW_TRANSPARENT + if (FLAG_IS_SET(flags, FLAG_WINDOW_TRANSPARENT)) + { + TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_TRANSPARENT) not available on target platform"); + } + + // State change: FLAG_WINDOW_HIGHDPI + if (FLAG_IS_SET(flags, FLAG_WINDOW_HIGHDPI)) + { + TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_HIGHDPI) not available on target platform"); + } + + // State change: FLAG_WINDOW_MOUSE_PASSTHROUGH + if (FLAG_IS_SET(flags, FLAG_WINDOW_MOUSE_PASSTHROUGH)) + { + TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_MOUSE_PASSTHROUGH) not available on target platform"); + } + + // State change: FLAG_MSAA_4X_HINT + if (FLAG_IS_SET(flags, FLAG_MSAA_4X_HINT)) + { + TRACELOG(LOG_WARNING, "SetWindowState(FLAG_MSAA_4X_HINT) not available on target platform"); + } + + // State change: FLAG_INTERLACED_HINT + if (FLAG_IS_SET(flags, FLAG_INTERLACED_HINT)) + { + TRACELOG(LOG_WARNING, "SetWindowState(FLAG_INTERLACED_HINT) not available on target platform"); + } +} + +// Clear window configuration state flags +void ClearWindowState(unsigned int flags) +{ + // Check previous state and requested state to apply required changes + // NOTE: In most cases the functions already change the flags internally + + // State change: FLAG_VSYNC_HINT + if (FLAG_IS_SET(flags, FLAG_VSYNC_HINT)) + { + TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_VSYNC_HINT) not available on target platform"); + } + + // State change: FLAG_BORDERLESS_WINDOWED_MODE + if (FLAG_IS_SET(flags, FLAG_BORDERLESS_WINDOWED_MODE)) + { + const bool wasFullscreen = EM_ASM_INT( { if (document.fullscreenElement) return 1; }, 0); + if (wasFullscreen) + { + const int canvasWidth = EM_ASM_INT( { return Module.canvas.width; }, 0); + const int screenWidth = EM_ASM_INT( { return screen.width; }, 0); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE) || (screenWidth == canvasWidth)) EM_ASM(document.exitFullscreen();); + } + + FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); + } + + // State change: FLAG_FULLSCREEN_MODE + if (FLAG_IS_SET(flags, FLAG_FULLSCREEN_MODE)) + { + const bool wasFullscreen = EM_ASM_INT( { if (document.fullscreenElement) return 1; }, 0); + if (wasFullscreen) + { + const int canvasWidth = EM_ASM_INT( { return Module.canvas.width; }, 0); + const int canvasStyleWidth = EM_ASM_INT( { return parseInt(Module.canvas.style.width); }, 0); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE) || (canvasStyleWidth > canvasWidth)) EM_ASM(document.exitFullscreen();); + } + + CORE.Window.fullscreen = false; + FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); + } + + // State change: FLAG_WINDOW_RESIZABLE + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_RESIZABLE) && FLAG_IS_SET(flags, FLAG_WINDOW_RESIZABLE)) + { + FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_RESIZABLE); + } + + // State change: FLAG_WINDOW_HIDDEN + if (FLAG_IS_SET(flags, FLAG_WINDOW_HIDDEN)) + { + TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_HIDDEN) not available on target platform"); + } + + // State change: FLAG_WINDOW_MINIMIZED + if (FLAG_IS_SET(flags, FLAG_WINDOW_MINIMIZED)) + { + TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_MINIMIZED) not available on target platform"); + } + + // State change: FLAG_WINDOW_MAXIMIZED + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED) && FLAG_IS_SET(flags, FLAG_WINDOW_MAXIMIZED)) + { + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_RESIZABLE)) + { + FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); + } + } + + // State change: FLAG_WINDOW_UNDECORATED + if (FLAG_IS_SET(flags, FLAG_WINDOW_UNDECORATED)) + { + TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_UNDECORATED) not available on target platform"); + } + + // State change: FLAG_WINDOW_UNFOCUSED + if (FLAG_IS_SET(flags, FLAG_WINDOW_UNFOCUSED)) + { + TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_UNFOCUSED) not available on target platform"); + } + + // State change: FLAG_WINDOW_TOPMOST + if (FLAG_IS_SET(flags, FLAG_WINDOW_TOPMOST)) + { + TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_TOPMOST) not available on target platform"); + } + + // State change: FLAG_WINDOW_ALWAYS_RUN + if (FLAG_IS_SET(flags, FLAG_WINDOW_ALWAYS_RUN)) + { + TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_ALWAYS_RUN) not available on target platform"); + } + + // The following states can not be changed after window creation + // NOTE: Review for PLATFORM_WEB + + // State change: FLAG_WINDOW_TRANSPARENT + if (FLAG_IS_SET(flags, FLAG_WINDOW_TRANSPARENT)) + { + TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_TRANSPARENT) not available on target platform"); + } + + // State change: FLAG_WINDOW_HIGHDPI + if (FLAG_IS_SET(flags, FLAG_WINDOW_HIGHDPI)) + { + TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_HIGHDPI) not available on target platform"); + } + + // State change: FLAG_WINDOW_MOUSE_PASSTHROUGH + if (FLAG_IS_SET(flags, FLAG_WINDOW_MOUSE_PASSTHROUGH)) + { + TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_MOUSE_PASSTHROUGH) not available on target platform"); + } + + // State change: FLAG_MSAA_4X_HINT + if (FLAG_IS_SET(flags, FLAG_MSAA_4X_HINT)) + { + TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_MSAA_4X_HINT) not available on target platform"); + } + + // State change: FLAG_INTERLACED_HINT + if (FLAG_IS_SET(flags, FLAG_INTERLACED_HINT)) + { + TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_INTERLACED_HINT) not available on target platform"); + } +} + +// Set icon for window +void SetWindowIcon(Image image) +{ + TRACELOG(LOG_WARNING, "SetWindowIcon() not available on target platform"); +} + +// Set icon for window, multiple images +void SetWindowIcons(Image *images, int count) +{ + TRACELOG(LOG_WARNING, "SetWindowIcons() not available on target platform"); +} + +// Set title for window +void SetWindowTitle(const char *title) +{ + CORE.Window.title = title; + emscripten_set_window_title(title); +} + +// Set window position on screen (windowed mode) +void SetWindowPosition(int x, int y) +{ + TRACELOG(LOG_WARNING, "SetWindowPosition() not available on target platform"); +} + +// Set monitor for the current window +void SetWindowMonitor(int monitor) +{ + TRACELOG(LOG_WARNING, "SetWindowMonitor() not available on target platform"); +} + +// Set window minimum dimensions (FLAG_WINDOW_RESIZABLE) +void SetWindowMinSize(int width, int height) +{ + CORE.Window.screenMin.width = width; + CORE.Window.screenMin.height = height; + + // Trigger the resize event once to update the window minimum width and height + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_RESIZABLE) != 0) EmscriptenResizeCallback(EMSCRIPTEN_EVENT_RESIZE, NULL, NULL); +} + +// Set window maximum dimensions (FLAG_WINDOW_RESIZABLE) +void SetWindowMaxSize(int width, int height) +{ + CORE.Window.screenMax.width = width; + CORE.Window.screenMax.height = height; + + // Trigger the resize event once to update the window maximum width and height + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_RESIZABLE) != 0) EmscriptenResizeCallback(EMSCRIPTEN_EVENT_RESIZE, NULL, NULL); +} + +// Set window dimensions +void SetWindowSize(int width, int height) +{ + // When resizing the canvas, several elements must be considered: + // - CSS canvas size: Web layout size, logical pixels + // - Canvas contained framebuffer resolution + // * Browser monitor, device pixel ratio (HighDPI) + + double canvasCssWidth = 0.0; + double canvasCssHeight = 0.0; + emscripten_get_element_css_size(platform.canvasId, &canvasCssWidth, &canvasCssHeight); + + // NOTE: emscripten_get_canvas_element_size() returns canvas framebuffer size, not CSS canvas size + + // Get device pixel ratio + // TODO: Should DPI be considered at this point? + double dpr = emscripten_get_device_pixel_ratio(); + + // Set canvas framebuffer size + emscripten_set_canvas_element_size(platform.canvasId, width*dpr, height*dpr); + + // Set canvas CSS size + // TODO: Consider canvas CSS style if already scaled 100% + EM_ASM({ Module.canvas.style.width = $0; }, width*dpr); + EM_ASM({ Module.canvas.style.height = $0; }, height*dpr); + + SetupViewport(width*dpr, height*dpr); // Reset viewport and projection matrix for new size +} + +// Set window opacity, value opacity is between 0.0 and 1.0 +void SetWindowOpacity(float opacity) +{ + if (opacity >= 1.0f) opacity = 1.0f; + else if (opacity <= 0.0f) opacity = 0.0f; + + EM_ASM({ Module.canvas.style.opacity = $0; }, opacity); +} + +// Set window focused +void SetWindowFocused(void) +{ + TRACELOG(LOG_WARNING, "SetWindowFocused() not available on target platform"); +} + +// Get native window handle +void *GetWindowHandle(void) +{ + TRACELOG(LOG_WARNING, "GetWindowHandle() not implemented on target platform"); + return NULL; +} + +// Get number of monitors +int GetMonitorCount(void) +{ + TRACELOG(LOG_WARNING, "GetMonitorCount() not implemented on target platform"); + return 1; +} + +// Get current monitor where window is placed +int GetCurrentMonitor(void) +{ + TRACELOG(LOG_WARNING, "GetCurrentMonitor() not implemented on target platform"); + return 0; +} + +// Get selected monitor position +Vector2 GetMonitorPosition(int monitor) +{ + TRACELOG(LOG_WARNING, "GetMonitorPosition() not implemented on target platform"); + return (Vector2){ 0, 0 }; +} + +// Get selected monitor width (currently used by monitor) +int GetMonitorWidth(int monitor) +{ + // Get the width of the user's entire screen in CSS logical pixels, + // no physical pixels, it would require multiplying by device pixel ratio + // NOTE: Returned value is limited to the current monitor where the browser window is located + int width = 0; + width = EM_ASM_INT( { return window.screen.width; }, 0); + return width; +} + +// Get selected monitor height (currently used by monitor) +int GetMonitorHeight(int monitor) +{ + // Get the height of the user's entire screen in CSS logical pixels, + // no physical pixels, it would require multiplying by device pixel ratio + // NOTE: Returned value is limited to the current monitor where the browser window is located + int height = 0; + height = EM_ASM_INT( { return window.screen.height; }, 0); + return height; +} + +// Get selected monitor physical width in millimetres +int GetMonitorPhysicalWidth(int monitor) +{ + TRACELOG(LOG_WARNING, "GetMonitorPhysicalWidth() not implemented on target platform"); + return 0; +} + +// Get selected monitor physical height in millimetres +int GetMonitorPhysicalHeight(int monitor) +{ + TRACELOG(LOG_WARNING, "GetMonitorPhysicalHeight() not implemented on target platform"); + return 0; +} + +// Get selected monitor refresh rate +int GetMonitorRefreshRate(int monitor) +{ + TRACELOG(LOG_WARNING, "GetMonitorRefreshRate() not implemented on target platform"); + return 0; +} + +// Get the human-readable, UTF-8 encoded name of the selected monitor +const char *GetMonitorName(int monitor) +{ + TRACELOG(LOG_WARNING, "GetMonitorName() not implemented on target platform"); + return ""; +} + +// Get window position XY on monitor +Vector2 GetWindowPosition(void) +{ + // Browser window position, top-left corner relative to the physical screen origin, expressed in CSS logical pixels + // NOTE: Returned position is relative to the current monitor where the browser window is located + Vector2 position = { 0, 0 }; + position.x = (float)EM_ASM_INT( { return window.screenX; }, 0); + position.y = (float)EM_ASM_INT( { return window.screenY; }, 0); + return position; +} + +// Get current monitor device pixel ratio +Vector2 GetWindowScaleDPI(void) +{ + // Get device pixel ratio + // NOTE: Returned scale is relative to the current monitor where the browser window is located + Vector2 scale = { 1.0f, 1.0f }; + scale.x = (float)EM_ASM_DOUBLE( { return window.devicePixelRatio; } ); + scale.y = scale.x; + return scale; +} + +// Set clipboard text content +void SetClipboardText(const char *text) +{ + // Security check to (partially) avoid malicious code + if (strchr(text, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided Clipboard could be potentially malicious, avoid [\'] character"); + else EM_ASM({ navigator.clipboard.writeText(UTF8ToString($0)); }, text); +} + +// Get clipboard text content +// NOTE: returned string is allocated and freed by GLFW +const char *GetClipboardText(void) +{ +/* + // Accessing clipboard data from browser is tricky due to security reasons + // The method to use is navigator.clipboard.readText() but this is an asynchronous method + // that will return at some moment after the function is called with the required data + emscripten_run_script_string("navigator.clipboard.readText() \ + .then(text => { document.getElementById('clipboard').innerText = text; console.log('Pasted content: ', text); }) \ + .catch(err => { console.error('Failed to read clipboard contents: ', err); });" + ); + + // The main issue is getting that data, one approach could be using ASYNCIFY and wait + // for the data but it requires adding Asyncify emscripten library on compilation + + // Another approach could be just copy the data in a HTML text field and try to retrieve it + // later on if available... and clean it for future accesses +*/ + return NULL; +} + +// Get clipboard image +Image GetClipboardImage(void) +{ + Image image = { 0 }; + + // NOTE: In theory, the new navigator.clipboard.read() can be used to return arbitrary data from clipboard (2024) + // REF: https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/read + TRACELOG(LOG_WARNING, "GetClipboardImage() not implemented on target platform"); + + return image; +} + +// Show mouse cursor +void ShowCursor(void) +{ + if (CORE.Input.Mouse.cursorHidden) + { + EM_ASM( { Module.canvas.style.cursor = UTF8ToString($0); }, cursorLUT[CORE.Input.Mouse.cursor]); + + CORE.Input.Mouse.cursorHidden = false; + } +} + +// Hides mouse cursor +void HideCursor(void) +{ + if (!CORE.Input.Mouse.cursorHidden) + { + EM_ASM(Module.canvas.style.cursor = 'none';); + + CORE.Input.Mouse.cursorHidden = true; + } +} + +// Enables cursor (unlock cursor) +void EnableCursor(void) +{ + emscripten_exit_pointerlock(); + + // Set cursor position in the middle + SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2); + + // NOTE: CORE.Input.Mouse.cursorLocked handled by EmscriptenPointerlockCallback() +} + +// Disables cursor (lock cursor) +void DisableCursor(void) +{ + emscripten_request_pointerlock(platform.canvasId, 1); + + // Set cursor position in the middle + SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2); + + // NOTE: CORE.Input.Mouse.cursorLocked handled by EmscriptenPointerlockCallback() +} + +// 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 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); +#endif +} + +//---------------------------------------------------------------------------------- +// Module Functions Definition: Misc +//---------------------------------------------------------------------------------- + +// Get elapsed time measure in seconds since InitTimer() +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() + */ + time = emscripten_get_now()*1000.0; + + return time; +} + +// Open URL with default system browser (if available) +// 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 +void OpenURL(const char *url) +{ + // Security check to (partially) avoid malicious code on target platform + if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character"); + else emscripten_run_script(TextFormat("window.open('%s', '_blank')", url)); +} + +//---------------------------------------------------------------------------------- +// Module Functions Definition: Inputs +//---------------------------------------------------------------------------------- + +// Set internal gamepad mappings +int SetGamepadMappings(const char *mappings) +{ + TRACELOG(LOG_INFO, "SetGamepadMappings not implemented in rcore_web.c"); + + return 0; +} + +// Set gamepad vibration +void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration) +{ + if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (duration > 0.0f)) + { + if (leftMotor < 0.0f) leftMotor = 0.0f; + if (leftMotor > 1.0f) leftMotor = 1.0f; + if (rightMotor < 0.0f) rightMotor = 0.0f; + if (rightMotor > 1.0f) rightMotor = 1.0f; + if (duration > MAX_GAMEPAD_VIBRATION_TIME) duration = MAX_GAMEPAD_VIBRATION_TIME; + duration *= 1000.0f; // Convert duration to ms + + // NOTE: [2024.10.21] Current browser support: + // - vibrationActuator API: Chrome, Edge, Opera, Safari, Android Chrome, Android Webview + // - hapticActuators API: Firefox + EM_ASM({ + try { navigator.getGamepads()[$0].vibrationActuator.playEffect('dual-rumble', { startDelay: 0, duration: $3, weakMagnitude: $1, strongMagnitude: $2 }); } + catch (e) + { + try { navigator.getGamepads()[$0].hapticActuators[0].pulse($2, $3); } + catch (e) { } + } + }, gamepad, leftMotor, rightMotor, duration); + } +} + +// Set mouse position XY +void SetMousePosition(int x, int y) +{ + // WARNING: Not supported by browser for security reasons +} + +// Set mouse cursor +void SetMouseCursor(int cursor) +{ + if (CORE.Input.Mouse.cursor != cursor) + { + if (!CORE.Input.Mouse.cursorLocked) EM_ASM( { Module.canvas.style.cursor = UTF8ToString($0); }, cursorLUT[cursor]); + CORE.Input.Mouse.cursor = cursor; + } +} + +// Get physical key name +const char *GetKeyName(int key) +{ + // TODO: Browser can definitely provide a key name e->key + TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform"); + return ""; +} + +// Register all input events +void PollInputEvents(void) +{ +#if defined(SUPPORT_GESTURES_SYSTEM) + // NOTE: Gestures update must be called every frame to reset gestures correctly + // because ProcessGestureEvent() is just called on an event, not every frame + UpdateGestures(); +#endif + + // Reset keys/chars pressed registered + CORE.Input.Keyboard.keyPressedQueueCount = 0; + CORE.Input.Keyboard.charPressedQueueCount = 0; + + // Reset last gamepad button/axis registered state + CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN + //CORE.Input.Gamepad.axisCount = 0; + + // Keyboard/Mouse input polling (automatically managed by GLFW3 through callback) + + // Register previous keys states + for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) + { + CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i]; + CORE.Input.Keyboard.keyRepeatInFrame[i] = 0; + } + + // Register previous mouse states + for (int i = 0; i < MAX_MOUSE_BUTTONS; i++) CORE.Input.Mouse.previousButtonState[i] = CORE.Input.Mouse.currentButtonState[i]; + + // Register previous mouse wheel state + CORE.Input.Mouse.previousWheelMove = CORE.Input.Mouse.currentWheelMove; + CORE.Input.Mouse.currentWheelMove = (Vector2){ 0.0f, 0.0f }; + + // Register previous mouse position + CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition; + + // Register previous touch states + for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.previousTouchState[i] = CORE.Input.Touch.currentTouchState[i]; + + // Reset touch positions + // TODO: It resets on target platform the mouse position and not filled again until a move-event, + // so, if mouse is not moved it returns a (0, 0) position... this behaviour should be reviewed! + //for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.position[i] = (Vector2){ 0, 0 }; + + // Get number of gamepads connected + int numGamepads = 0; + if (emscripten_sample_gamepad_data() == EMSCRIPTEN_RESULT_SUCCESS) numGamepads = emscripten_get_num_gamepads(); + + for (int i = 0; (i < numGamepads) && (i < MAX_GAMEPADS); i++) + { + // Register previous gamepad button states + for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) CORE.Input.Gamepad.previousButtonState[i][k] = CORE.Input.Gamepad.currentButtonState[i][k]; + + EmscriptenGamepadEvent gamepadState = { 0 }; + int result = emscripten_get_gamepad_status(i, &gamepadState); + + if (result == EMSCRIPTEN_RESULT_SUCCESS) + { + // Register buttons data for every connected gamepad + for (int j = 0; (j < gamepadState.numButtons) && (j < MAX_GAMEPAD_BUTTONS); j++) + { + GamepadButton button = -1; + + // Gamepad Buttons reference: https://www.w3.org/TR/gamepad/#gamepad-interface + switch (j) + { + case 0: button = GAMEPAD_BUTTON_RIGHT_FACE_DOWN; break; + case 1: button = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT; break; + case 2: button = GAMEPAD_BUTTON_RIGHT_FACE_LEFT; break; + case 3: button = GAMEPAD_BUTTON_RIGHT_FACE_UP; break; + case 4: button = GAMEPAD_BUTTON_LEFT_TRIGGER_1; break; + case 5: button = GAMEPAD_BUTTON_RIGHT_TRIGGER_1; break; + case 6: button = GAMEPAD_BUTTON_LEFT_TRIGGER_2; break; + case 7: button = GAMEPAD_BUTTON_RIGHT_TRIGGER_2; break; + case 8: button = GAMEPAD_BUTTON_MIDDLE_LEFT; break; + case 9: button = GAMEPAD_BUTTON_MIDDLE_RIGHT; break; + case 10: button = GAMEPAD_BUTTON_LEFT_THUMB; break; + case 11: button = GAMEPAD_BUTTON_RIGHT_THUMB; break; + case 12: button = GAMEPAD_BUTTON_LEFT_FACE_UP; break; + case 13: button = GAMEPAD_BUTTON_LEFT_FACE_DOWN; break; + case 14: button = GAMEPAD_BUTTON_LEFT_FACE_LEFT; break; + case 15: button = GAMEPAD_BUTTON_LEFT_FACE_RIGHT; break; + default: break; + } + + if (button + 1 != 0) // Check for valid button + { + if (gamepadState.digitalButton[j] == 1) + { + CORE.Input.Gamepad.currentButtonState[i][button] = 1; + CORE.Input.Gamepad.lastButtonPressed = button; + } + else CORE.Input.Gamepad.currentButtonState[i][button] = 0; + } + + //TRACELOGD("INPUT: Gamepad %d, button %d: Digital: %d, Analog: %g", gamepadState.index, j, gamepadState.digitalButton[j], gamepadState.analogButton[j]); + } + + // Register axis data for every connected gamepad + for (int j = 0; (j < gamepadState.numAxes) && (j < MAX_GAMEPAD_AXES); j++) + { + CORE.Input.Gamepad.axisState[i][j] = gamepadState.axis[j]; + } + + CORE.Input.Gamepad.axisCount[i] = gamepadState.numAxes; + } + } + + CORE.Window.resizedLastFrame = false; +} + +//---------------------------------------------------------------------------------- +// Module Internal Functions Definition +//---------------------------------------------------------------------------------- + +// Initialize platform: graphics, inputs and more +int InitPlatform(void) +{ + SetCanvasIdJs(platform.canvasId, 64); // Get the current canvas id + + // Initialize graphic device: display/window and graphic context + //---------------------------------------------------------------------------- + emscripten_set_canvas_element_size(platform.canvasId, CORE.Window.screen.width, CORE.Window.screen.height); + EmscriptenWebGLContextAttributes attribs = { 0 }; + emscripten_webgl_init_context_attributes(&attribs); + attribs.alpha = EM_TRUE; + attribs.depth = EM_TRUE; + attribs.stencil = EM_FALSE; + attribs.antialias = EM_FALSE; + + // Check window creation flags + //if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) CORE.Window.fullscreen = true; + + // Disable FLAG_WINDOW_MINIMIZED, not supported + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)) FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); + + // Disable FLAG_WINDOW_MAXIMIZED, not supported + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED)) FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); + + // Disable FLAG_WINDOW_TOPMOST, not supported + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_TOPMOST)) FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_TOPMOST); + + // NOTE: Some other flags are not supported on HTML5 + + // TODO: Scale content area based on the monitor content scale where window is placed on + + // Request MSAA (usually x4 on WebGL 1.0) + if (FLAG_IS_SET(CORE.Window.flags, FLAG_MSAA_4X_HINT)) attribs.antialias = EM_TRUE; + + // Check selection OpenGL version + if (rlGetVersion() == RL_OPENGL_11_SOFTWARE) + { + // Avoid creating a WebGL canvas, create 2d canvas for software rendering + emscripten_set_canvas_element_size(platform.canvasId, CORE.Window.screen.width, CORE.Window.screen.height); + EM_ASM({ + const canvas = document.getElementById(platform.canvasId); + Module.canvas = canvas; + }); + + // Load memory framebuffer with desired screen size + platform.pixels = (unsigned int *)RL_CALLOC(CORE.Window.screen.width*CORE.Window.screen.height, sizeof(unsigned int)); + } + else if (rlGetVersion() == RL_OPENGL_ES_20) // Request OpenGL ES 2.0 context --> WebGL 1.0 + { + attribs.majorVersion = 1; // WebGL 1.0 requested + attribs.minorVersion = 0; + + // Create WebGL context + platform.glContext = emscripten_webgl_create_context(platform.canvasId, &attribs); + if (platform.glContext == 0) return 0; + + emscripten_webgl_make_context_current(platform.glContext); + } + else if (rlGetVersion() == RL_OPENGL_ES_30) // Request OpenGL ES 3.0 context --> WebGL 2.0 + { + attribs.majorVersion = 2; // WebGL 2.0 requested + attribs.minorVersion = 0; + + // Create WebGL context + platform.glContext = emscripten_webgl_create_context(platform.canvasId, &attribs); + if (platform.glContext == 0) return 0; + + emscripten_webgl_make_context_current(platform.glContext); + } + + // NOTE: Getting video modes is not implemented in emscripten GLFW3 version + CORE.Window.display.width = CORE.Window.screen.width; + CORE.Window.display.height = CORE.Window.screen.height; + CORE.Window.render.width = CORE.Window.screen.width; + CORE.Window.render.height = CORE.Window.screen.height; + + // Set default window title + emscripten_set_window_title((CORE.Window.title != 0)? CORE.Window.title : " "); + + // Check context activation + if ((platform.glContext != 0) || (platform.pixels != NULL)) + { + CORE.Window.ready = true; + + int fbWidth = CORE.Window.screen.width; + int fbHeight = CORE.Window.screen.height; + + CORE.Window.render.width = fbWidth; + CORE.Window.render.height = fbHeight; + CORE.Window.currentFbo.width = fbWidth; + CORE.Window.currentFbo.height = fbHeight; + + TRACELOG(LOG_INFO, "DISPLAY: Device initialized successfully"); + TRACELOG(LOG_INFO, " > Display size: %i x %i", CORE.Window.display.width, CORE.Window.display.height); + TRACELOG(LOG_INFO, " > Screen size: %i x %i", CORE.Window.screen.width, CORE.Window.screen.height); + TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height); + TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y); + } + else + { + TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphics device"); + return -1; + } + + // Load OpenGL extensions + // NOTE: GL procedures address loader is required to load extensions + if (platform.glContext != 0) rlLoadExtensions(emscripten_webgl_get_proc_address); + //---------------------------------------------------------------------------- + + // Initialize events callbacks + //---------------------------------------------------------------------------- + // Setup window/canvas events callbacks + emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenFullscreenChangeCallback); + emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenResizeCallback); + emscripten_set_blur_callback(platform.canvasId, NULL, 1, EmscriptenFocusCallback); + emscripten_set_focus_callback(platform.canvasId, NULL, 1, EmscriptenFocusCallback); + emscripten_set_visibilitychange_callback(NULL, 1, EmscriptenVisibilityChangeCallback); + + // Setup input events + emscripten_set_keypress_callback(platform.canvasId, NULL, 1, EmscriptenKeyboardCallback); + emscripten_set_keydown_callback(platform.canvasId, NULL, 1, EmscriptenKeyboardCallback); + emscripten_set_keyup_callback(platform.canvasId, NULL, 1, EmscriptenKeyboardCallback); + + emscripten_set_click_callback(platform.canvasId, NULL, 1, EmscriptenMouseCallback); + //emscripten_set_dblclick_callback(platform.canvasId, NULL, 1, EmscriptenMouseCallback); + emscripten_set_mousedown_callback(platform.canvasId, NULL, 1, EmscriptenMouseCallback); + emscripten_set_mouseup_callback(platform.canvasId, NULL, 1, EmscriptenMouseCallback); + emscripten_set_mousemove_callback(platform.canvasId, NULL, 1, EmscriptenMouseCallback); + emscripten_set_mousemove_callback(platform.canvasId, NULL, 1, EmscriptenMouseMoveCallback); + emscripten_set_wheel_callback(platform.canvasId, NULL, 1, EmscriptenMouseWheelCallback); + emscripten_set_pointerlockchange_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenPointerlockCallback); + + 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); + + // Trigger resize callback to force initial size + EmscriptenResizeCallback(EMSCRIPTEN_EVENT_RESIZE, NULL, NULL); + //---------------------------------------------------------------------------- + + // Initialize timing system + //---------------------------------------------------------------------------- + InitTimer(); + //---------------------------------------------------------------------------- + + // Initialize storage system + //---------------------------------------------------------------------------- + CORE.Storage.basePath = GetWorkingDirectory(); + //---------------------------------------------------------------------------- + + TRACELOG(LOG_INFO, "PLATFORM: WEB: Initialized successfully"); + + return 0; +} + +// Close platform +// NOTE: Platform closing is managed by browser, so, +// this function is actually not required, but still +// implementing some logic behaviour +void ClosePlatform(void) +{ + if (platform.pixels != NULL) RL_FREE(platform.pixels); + if (platform.glContext != 0) emscripten_webgl_destroy_context(platform.glContext); +} + +// Emscripten callback functions, called on specific browser events +//------------------------------------------------------------------------------------------------------- +// Emscripten: Called on resize event +static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent *event, void *userData) +{ + // Don't resize non-resizeable windows + if (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_RESIZABLE)) return 1; +/* + // Set current screen size + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) + { + Vector2 windowScaleDPI = GetWindowScaleDPI(); + + CORE.Window.screen.width = (unsigned int)(width/windowScaleDPI.x); + CORE.Window.screen.height = (unsigned int)(height/windowScaleDPI.y); + } + else + { + CORE.Window.screen.width = width; + CORE.Window.screen.height = height; + } +*/ + // This event is called whenever the window changes sizes, + // so the size of the canvas object is explicitly retrieved below + int width = EM_ASM_INT( return window.innerWidth; ); + int height = EM_ASM_INT( return window.innerHeight; ); + + if (width < (int)CORE.Window.screenMin.width) width = CORE.Window.screenMin.width; + else if ((width > (int)CORE.Window.screenMax.width) && (CORE.Window.screenMax.width > 0)) width = CORE.Window.screenMax.width; + + 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(platform.canvasId, width, height); + + SetupViewport(width, height); // Reset viewport and projection matrix for new size + + CORE.Window.currentFbo.width = width; + CORE.Window.currentFbo.height = height; + CORE.Window.resizedLastFrame = true; + + if (IsWindowFullscreen()) return 1; + + // Set current screen size + CORE.Window.screen.width = width; + CORE.Window.screen.height = height; + + // NOTE: Postprocessing texture is not scaled to new size + + return 0; +} + +// Emscripten: Called on windows focus change events +static EM_BOOL EmscriptenFocusCallback(int eventType, const EmscriptenFocusEvent *focusEvent, void *userData) +{ + EM_BOOL consumed = 1; + + switch (eventType) + { + case EMSCRIPTEN_EVENT_BLUR: FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); break; // The canvas lost focus + case EMSCRIPTEN_EVENT_FOCUS: FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); break; + default: consumed = 0; break; + } + + return consumed; +} + +// Emscripten: Called on visibility change events +static EM_BOOL EmscriptenVisibilityChangeCallback(int eventType, const EmscriptenVisibilityChangeEvent *visibilityChangeEvent, void *userData) +{ + if (visibilityChangeEvent->hidden) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN); // The window was hidden + else FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_HIDDEN); // The window was restored + + return 1; // The event was consumed by the callback handler +} + +// Emscripten: Called on fullscreen change events +// TODO: Review fullscreen strategy +static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const EmscriptenFullscreenChangeEvent *event, void *userData) +{ + // NOTE: Reset the fullscreen flags if the user left fullscreen manually by pressing the Escape key + const bool wasFullscreen = EM_ASM_INT( { if (document.fullscreenElement) return 1; }, 0); + if (!wasFullscreen) + { + CORE.Window.fullscreen = false; + FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); + FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); + } + + return 1; // The event was consumed by the callback handler +} + +/* +// GLFW3: Called on file-drop over the window +// TODO: Implement Emscripten (or HTML5/JS) alternative +static void WindowDropCallback(GLFWwindow *window, int count, const char **paths) +{ + if (count > 0) + { + // In case previous dropped filepaths have not been freed, we free them + if (CORE.Window.dropFileCount > 0) + { + for (unsigned int i = 0; i < CORE.Window.dropFileCount; i++) RL_FREE(CORE.Window.dropFilepaths[i]); + + RL_FREE(CORE.Window.dropFilepaths); + + CORE.Window.dropFileCount = 0; + CORE.Window.dropFilepaths = NULL; + } + + // WARNING: Paths are freed by GLFW when the callback returns, we must keep an internal copy + CORE.Window.dropFileCount = count; + CORE.Window.dropFilepaths = (char **)RL_CALLOC(CORE.Window.dropFileCount, sizeof(char *)); + + for (unsigned int i = 0; i < CORE.Window.dropFileCount; i++) + { + CORE.Window.dropFilepaths[i] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); + strcpy(CORE.Window.dropFilepaths[i], paths[i]); + } + } +} +*/ + +// Emscripten: Called on key events +// TODO: keyCodes should be mapped to raylib/GLFW3 Key values +static EM_BOOL EmscriptenKeyboardCallback(int eventType, const EmscriptenKeyboardEvent *keyboardEvent, void *userData) +{ + switch (eventType) + { + case EMSCRIPTEN_EVENT_KEYPRESS: + { + if (keyboardEvent->repeat) CORE.Input.Keyboard.keyRepeatInFrame[keyboardEvent->keyCode] = 1; + } break; + case EMSCRIPTEN_EVENT_KEYDOWN: + { + CORE.Input.Keyboard.currentKeyState[keyboardEvent->keyCode] = 1; + } break; + case EMSCRIPTEN_EVENT_KEYUP: + { + CORE.Input.Keyboard.currentKeyState[keyboardEvent->keyCode] = 0; + } break; + default: break; + } + + // TODO: Add char codes + //unsigned int charCode + // Check if there is space available in the queue for characters to be added + /* + if (CORE.Input.Keyboard.charPressedQueueCount < MAX_CHAR_PRESSED_QUEUE) + { + // Add character to the queue + CORE.Input.Keyboard.charPressedQueue[CORE.Input.Keyboard.charPressedQueueCount] = keyboardEvent->charCode; + CORE.Input.Keyboard.charPressedQueueCount++; + } + */ + /* + // Check if there is space available in the key queue + if ((CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE) && (eventType == EMSCRIPTEN_EVENT_KEYPRESS)) + { + // Add character to the queue + CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = keyboardEvent->keyCode; + CORE.Input.Keyboard.keyPressedQueueCount++; + } + + // Check the exit key to set close window + //if ((keyboardEvent->keyCode == CORE.Input.Keyboard.exitKey) && (eventType == EMSCRIPTEN_EVENT_KEYPRESS)) CORE.Window.shouldClose = true; + */ + + return 1; // The event was consumed by the callback handler +} + +// Emscripten: Called on mouse input events +static EM_BOOL EmscriptenMouseCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData) +{ + switch (eventType) + { + case EMSCRIPTEN_EVENT_MOUSEENTER: CORE.Input.Mouse.cursorOnScreen = true; break; + case EMSCRIPTEN_EVENT_MOUSELEAVE: CORE.Input.Mouse.cursorOnScreen = false; break; + case EMSCRIPTEN_EVENT_MOUSEDOWN: + { + // NOTE: Emscripten and raylib buttons indices are not aligned + if (mouseEvent->button == 0) CORE.Input.Mouse.currentButtonState[MOUSE_BUTTON_LEFT] = 1; + else if (mouseEvent->button == 1) CORE.Input.Mouse.currentButtonState[MOUSE_BUTTON_MIDDLE] = 1; + else if (mouseEvent->button == 2) CORE.Input.Mouse.currentButtonState[MOUSE_BUTTON_RIGHT] = 1; + + //CORE.Input.Touch.currentTouchState[button] = action; + } break; + case EMSCRIPTEN_EVENT_MOUSEUP: + { + if (mouseEvent->button == 0) CORE.Input.Mouse.currentButtonState[MOUSE_BUTTON_LEFT] = 0; + else if (mouseEvent->button == 1) CORE.Input.Mouse.currentButtonState[MOUSE_BUTTON_MIDDLE] = 0; + else if (mouseEvent->button == 2) CORE.Input.Mouse.currentButtonState[MOUSE_BUTTON_RIGHT] = 0; + } break; + default: break; + } + +#if defined(SUPPORT_GESTURES_SYSTEM) && defined(SUPPORT_MOUSE_GESTURES) + // Process mouse events as touches to be able to use mouse-gestures + GestureEvent gestureEvent = { 0 }; + + // Register touch actions + if ((CORE.Input.Mouse.currentButtonState[MOUSE_BUTTON_LEFT] == 1) && (CORE.Input.Mouse.previousButtonState[MOUSE_BUTTON_LEFT] == 0)) gestureEvent.touchAction = TOUCH_ACTION_DOWN; + else if ((CORE.Input.Mouse.currentButtonState[MOUSE_BUTTON_LEFT] == 0) && (CORE.Input.Mouse.previousButtonState[MOUSE_BUTTON_LEFT] == 1)) gestureEvent.touchAction = TOUCH_ACTION_UP; + + // NOTE: TOUCH_ACTION_MOVE event is registered in MouseMoveCallback() + + // Assign a pointer ID + gestureEvent.pointId[0] = 0; + + // Register touch points count + gestureEvent.pointCount = 1; + + // Register touch points position, only one point registered + gestureEvent.position[0] = GetMousePosition(); + + // Normalize gestureEvent.position[0] for CORE.Window.screen.width and CORE.Window.screen.height + gestureEvent.position[0].x /= (float)GetScreenWidth(); + gestureEvent.position[0].y /= (float)GetScreenHeight(); + + // Gesture data is sent to gestures-system for processing + // Prevent calling ProcessGestureEvent() when Emscripten is present and there's a touch gesture, so EmscriptenTouchCallback() can handle it itself + if (GetMouseX() != 0 || GetMouseY() != 0) ProcessGestureEvent(gestureEvent); +#endif + + return 1; // The event was consumed by the callback handler +} + +// Emscripten: Called on mouse move events +static EM_BOOL EmscriptenMouseMoveCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData) +{ + if (CORE.Input.Mouse.cursorLocked) + { + CORE.Input.Mouse.previousPosition.x = CORE.Input.Mouse.lockedPosition.x - mouseEvent->movementX; + CORE.Input.Mouse.previousPosition.y = CORE.Input.Mouse.lockedPosition.y - mouseEvent->movementY; + } + else + { + // Get mouse position in canvas CSS pixels + float mouseCssX = (float)mouseEvent->canvasX; + float mouseCssY = (float)mouseEvent->canvasY; + + // Get canvas sizes + double cssWidth = 0.0; + double cssHeight = 0.0; + emscripten_get_element_css_size(platform.canvasId, &cssWidth, &cssHeight); + + int fbWidth = 0; + int fbHeight = 0; + emscripten_get_canvas_element_size(platform.canvasId, &fbWidth, &fbHeight); + + // Convert CSS to framebuffer coordinates + float scaleX = (float)fbWidth/(float)cssWidth; + float scaleY = (float)fbHeight/(float)cssHeight; + + int mouseX = (int)(mouseCssX*scaleX); + int mouseY = (int)(mouseCssY*scaleY); + + CORE.Input.Mouse.currentPosition.x = mouseX;//(float)mouseEvent->canvasX; + CORE.Input.Mouse.currentPosition.y = mouseY;//(float)mouseEvent->canvasY; + + // Shorter alternative: + //double dpr = emscripten_get_device_pixel_ratio(); + //int mouseX = (int)(e->canvasX*dpr); + //int mouseY = (int)(e->canvasY*dpr); + + CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; + } + +#if defined(SUPPORT_GESTURES_SYSTEM) && defined(SUPPORT_MOUSE_GESTURES) + // Process mouse events as touches to be able to use mouse-gestures + GestureEvent gestureEvent = { 0 }; + + gestureEvent.touchAction = TOUCH_ACTION_MOVE; + + // Assign a pointer ID + gestureEvent.pointId[0] = 0; + + // Register touch points count + gestureEvent.pointCount = 1; + + // Register touch points position, only one point registered + gestureEvent.position[0] = CORE.Input.Touch.position[0]; + + // Normalize gestureEvent.position[0] for CORE.Window.screen.width and CORE.Window.screen.height + gestureEvent.position[0].x /= (float)GetScreenWidth(); + gestureEvent.position[0].y /= (float)GetScreenHeight(); + + // Gesture data is sent to gestures-system for processing + ProcessGestureEvent(gestureEvent); +#endif + + return 1; // The event was consumed by the callback handler +} + +// Emscripten: Called on mouse wheel events +static EM_BOOL EmscriptenMouseWheelCallback(int eventType, const EmscriptenWheelEvent *wheelEvent, void *userData) +{ + if (eventType == EMSCRIPTEN_EVENT_WHEEL) + { + CORE.Input.Mouse.currentWheelMove.x = (float)wheelEvent->deltaX; + CORE.Input.Mouse.currentWheelMove.y = (float)wheelEvent->deltaY; + } + + return 1; // The event was consumed by the callback handler +} + +// Emscripten: Called on pointer lock events +static EM_BOOL EmscriptenPointerlockCallback(int eventType, const EmscriptenPointerlockChangeEvent *pointerlockChangeEvent, void *userData) +{ + CORE.Input.Mouse.cursorLocked = EM_ASM_INT( { if (document.pointerLockElement) return 1; }, 0); + + if (CORE.Input.Mouse.cursorLocked) + { + CORE.Input.Mouse.lockedPosition = CORE.Input.Mouse.currentPosition; + CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.lockedPosition; + } + + return 1; // The event was consumed by the callback handler +} + +// Emscripten: Called on connect/disconnect gamepads events +static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData) +{ + /* + TRACELOGD("%s: timeStamp: %g, connected: %d, index: %ld, numAxes: %d, numButtons: %d, id: \"%s\", mapping: \"%s\"", + eventType != 0? emscripten_event_type_to_string(eventType) : "Gamepad state", + gamepadEvent->timestamp, gamepadEvent->connected, gamepadEvent->index, gamepadEvent->numAxes, gamepadEvent->numButtons, gamepadEvent->id, gamepadEvent->mapping); + + for (int i = 0; i < gamepadEvent->numAxes; i++) TRACELOGD("Axis %d: %g", i, gamepadEvent->axis[i]); + for (int i = 0; i < gamepadEvent->numButtons; i++) TRACELOGD("Button %d: Digital: %d, Analog: %g", i, gamepadEvent->digitalButton[i], gamepadEvent->analogButton[i]); + */ + + if (gamepadEvent->connected && (gamepadEvent->index < MAX_GAMEPADS)) + { + CORE.Input.Gamepad.ready[gamepadEvent->index] = true; + snprintf(CORE.Input.Gamepad.name[gamepadEvent->index], MAX_GAMEPAD_NAME_LENGTH, "%s", gamepadEvent->id); + } + else CORE.Input.Gamepad.ready[gamepadEvent->index] = false; + + return 1; // The event was consumed by the callback handler +} + +// Emscripten: Called on touch input events +static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData) +{ + // Register touch points count + CORE.Input.Touch.pointCount = touchEvent->numTouches; + + double canvasWidth = 0.0; + double canvasHeight = 0.0; + // 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(platform.canvasId, &canvasWidth, &canvasHeight); + + for (int i = 0; (i < CORE.Input.Touch.pointCount) && (i < MAX_TOUCH_POINTS); i++) + { + // Register touch points id + CORE.Input.Touch.pointId[i] = touchEvent->touches[i].identifier; + + // Register touch points position + CORE.Input.Touch.position[i] = (Vector2){touchEvent->touches[i].targetX, touchEvent->touches[i].targetY}; + + // Normalize gestureEvent.position[x] for CORE.Window.screen.width and CORE.Window.screen.height + CORE.Input.Touch.position[i].x *= ((float)GetScreenWidth()/(float)canvasWidth); + CORE.Input.Touch.position[i].y *= ((float)GetScreenHeight()/(float)canvasHeight); + + if (eventType == EMSCRIPTEN_EVENT_TOUCHSTART) CORE.Input.Touch.currentTouchState[i] = 1; + else if (eventType == EMSCRIPTEN_EVENT_TOUCHEND) CORE.Input.Touch.currentTouchState[i] = 0; + } + + // Update mouse position if we detect a single touch + if (CORE.Input.Touch.pointCount == 1) + { + CORE.Input.Mouse.currentPosition.x = CORE.Input.Touch.position[0].x; + CORE.Input.Mouse.currentPosition.y = CORE.Input.Touch.position[0].y; + } + +#if defined(SUPPORT_GESTURES_SYSTEM) + GestureEvent gestureEvent = { 0 }; + gestureEvent.pointCount = CORE.Input.Touch.pointCount; + + // Register touch actions + if (eventType == EMSCRIPTEN_EVENT_TOUCHSTART) gestureEvent.touchAction = TOUCH_ACTION_DOWN; + else if (eventType == EMSCRIPTEN_EVENT_TOUCHEND) gestureEvent.touchAction = TOUCH_ACTION_UP; + else if (eventType == EMSCRIPTEN_EVENT_TOUCHMOVE) gestureEvent.touchAction = TOUCH_ACTION_MOVE; + else if (eventType == EMSCRIPTEN_EVENT_TOUCHCANCEL) gestureEvent.touchAction = TOUCH_ACTION_CANCEL; + + for (int i = 0; (i < gestureEvent.pointCount) && (i < MAX_TOUCH_POINTS); i++) + { + gestureEvent.pointId[i] = CORE.Input.Touch.pointId[i]; + gestureEvent.position[i] = CORE.Input.Touch.position[i]; + + // Normalize gestureEvent.position[i] + gestureEvent.position[i].x /= (float)GetScreenWidth(); + gestureEvent.position[i].y /= (float)GetScreenHeight(); + } + + // Gesture data is sent to gestures system for processing + ProcessGestureEvent(gestureEvent); +#endif + + if (eventType == EMSCRIPTEN_EVENT_TOUCHEND) + { + // Identify the EMSCRIPTEN_EVENT_TOUCHEND and remove it from the list + for (int i = 0; i < CORE.Input.Touch.pointCount; i++) + { + if (touchEvent->touches[i].isChanged) + { + // Move all touch points one position up + for (int j = i; j < CORE.Input.Touch.pointCount - 1; j++) + { + CORE.Input.Touch.pointId[j] = CORE.Input.Touch.pointId[j + 1]; + CORE.Input.Touch.position[j] = CORE.Input.Touch.position[j + 1]; + } + // Decrease touch points count to remove the last one + CORE.Input.Touch.pointCount--; + break; + } + } + // Clamp pointCount to avoid negative values + if (CORE.Input.Touch.pointCount < 0) CORE.Input.Touch.pointCount = 0; + } + + return 1; // The event was consumed by the callback handler +} +//------------------------------------------------------------------------------------------------------- + +// EOF From fc843dc5572379482377ba4f33f6f53f47e3f69a Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 24 Dec 2025 19:21:43 +0100 Subject: [PATCH 006/232] Create SECURITY.md --- SECURITY.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..48a825e37 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,18 @@ +# Security Policy + +## Supported Versions + +Most considerations of errors and defects can be handled using the project Issues and/or Discussions. + +| Version | Supported | +| ------- | ------------------ | +| 6.0.x | :white_check_mark: | +| < 5.5 | :x: | + +## Reporting a Vulnerability + +Discovered vulnerability can be directly reported using the project Issues and/or Discussions. + +_TODO: Tell them where to go, how often they can expect to get an update on a +reported vulnerability, what to expect if the vulnerability is accepted or +declined, etc._ From 20dd4641c8caff962b5037bf1f1eb5471ae3598e Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 24 Dec 2025 19:35:06 +0100 Subject: [PATCH 007/232] REVIEWED: Potential security concerns while copying unbounded text data between strings Note that issue has been reported by CodeQL static analysis system --- src/platforms/rcore_desktop_glfw.c | 2 +- src/platforms/rcore_desktop_sdl.c | 8 ++++---- src/platforms/rcore_web.c | 2 +- src/platforms/rcore_web_emscripten.c | 2 +- src/rtext.c | 17 +++++++++++------ 5 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index efa146fd0..471050839 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -1962,7 +1962,7 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths for (unsigned int i = 0; i < CORE.Window.dropFileCount; i++) { CORE.Window.dropFilepaths[i] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); - strcpy(CORE.Window.dropFilepaths[i], paths[i]); + strncpy(CORE.Window.dropFilepaths[i], paths[i], MAX_FILEPATH_LENGTH - 1); } } } diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index add1de6ad..612707cea 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -1431,9 +1431,9 @@ void PollInputEvents(void) // Event memory is now managed by SDL, so you should not free the data in SDL_EVENT_DROP_FILE, // and if you want to hold onto the text in SDL_EVENT_TEXT_EDITING and SDL_EVENT_TEXT_INPUT events, // you should make a copy of it. SDL_TEXTINPUTEVENT_TEXT_SIZE is no longer necessary and has been removed - strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.data); + strncpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.data, MAX_FILEPATH_LENGTH - 1); #else - strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file); + strncpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file, MAX_FILEPATH_LENGTH - 1); SDL_free(event.drop.file); #endif @@ -1444,9 +1444,9 @@ void PollInputEvents(void) CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); #if defined(USING_VERSION_SDL3) - strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.data); + strncpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.data, MAX_FILEPATH_LENGTH - 1); #else - strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file); + strncpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file, MAX_FILEPATH_LENGTH - 1); SDL_free(event.drop.file); #endif diff --git a/src/platforms/rcore_web.c b/src/platforms/rcore_web.c index 934f778c3..adfdace74 100644 --- a/src/platforms/rcore_web.c +++ b/src/platforms/rcore_web.c @@ -1531,7 +1531,7 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths for (unsigned int i = 0; i < CORE.Window.dropFileCount; i++) { CORE.Window.dropFilepaths[i] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); - strcpy(CORE.Window.dropFilepaths[i], paths[i]); + strncpy(CORE.Window.dropFilepaths[i], paths[i], MAX_FILEPATH_LENGTH - 1); } } } diff --git a/src/platforms/rcore_web_emscripten.c b/src/platforms/rcore_web_emscripten.c index 1ed719631..25b477734 100644 --- a/src/platforms/rcore_web_emscripten.c +++ b/src/platforms/rcore_web_emscripten.c @@ -1387,7 +1387,7 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths for (unsigned int i = 0; i < CORE.Window.dropFileCount; i++) { CORE.Window.dropFilepaths[i] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); - strcpy(CORE.Window.dropFilepaths[i], paths[i]); + strncpy(CORE.Window.dropFilepaths[i], paths[i], MAX_FILEPATH_LENGTH - 1); } } } diff --git a/src/rtext.c b/src/rtext.c index e4b439d28..453ed4507 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -1597,14 +1597,13 @@ float TextToFloat(const char *text) #if defined(SUPPORT_TEXT_MANIPULATION) // Copy one string to another, returns bytes copied +// NOTE: Alternative implementation to strcpy(dst, src) from C standard library int TextCopy(char *dst, const char *src) { int bytes = 0; if ((src != NULL) && (dst != NULL)) { - // NOTE: Alternative: use strcpy(dst, src) - while (*src != '\0') { *dst = *src; @@ -1717,11 +1716,13 @@ char *TextReplace(const char *text, const char *search, const char *replacement) { char *insertPoint = NULL; // Next insert point char *temp = NULL; // Temp pointer + int textLen = 0; // Text string length 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 + textLen = TextLength(text); searchLen = TextLength(search); if (searchLen == 0) return NULL; // Empty search causes infinite loop during count @@ -1732,7 +1733,8 @@ char *TextReplace(const char *text, const char *search, const char *replacement) 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); + int tempLen = textLen + (replaceLen - searchLen)*count + 1; + temp = result = (char *)RL_MALLOC(tempLen); if (!result) return NULL; // Memory could not be allocated @@ -1744,13 +1746,16 @@ char *TextReplace(const char *text, const char *search, const char *replacement) { insertPoint = (char *)strstr(text, search); lastReplacePos = (int)(insertPoint - text); - temp = strncpy(temp, text, lastReplacePos) + lastReplacePos; - temp = strcpy(temp, replacement) + replaceLen; + temp = strncpy(temp, text, tempLen - 1) + lastReplacePos; + tempLen -= lastReplacePos; + temp = strncpy(temp, replacement, tempLen - 1) + replaceLen; + tempLen -= replaceLen; + text += lastReplacePos + searchLen; // Move to next "end of replace" } // Copy remaind text part after replacement to result (pointed by moving temp) - strcpy(temp, text); + strncpy(temp, text, tempLen - 1); } return result; From 101502103a559afdff6938dc0c739eb5d0870912 Mon Sep 17 00:00:00 2001 From: Dan Vu Date: Wed, 24 Dec 2025 20:58:40 +0100 Subject: [PATCH 008/232] Fixed FLAG_IS_SET to check if all bits in the flag are set in the value (#5441) --- src/rcore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rcore.c b/src/rcore.c index 1f47efcb9..6f16b605b 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -273,7 +273,7 @@ #define FLAG_SET(n, f) ((n) |= (f)) #define FLAG_CLEAR(n, f) ((n) &= ~(f)) #define FLAG_TOGGLE(n, f) ((n) ^= (f)) -#define FLAG_IS_SET(n, f) (((n) & (f)) > 0) +#define FLAG_IS_SET(n, f) (((n) & (f)) == (f)) //---------------------------------------------------------------------------------- // Types and Structures Definition From 5e14ac5a2ed19071e8159455f5534aedf6b301dd Mon Sep 17 00:00:00 2001 From: Alvin De Cruz Date: Sat, 27 Dec 2025 03:42:32 +0800 Subject: [PATCH 009/232] #5387 - Fix keyboard input detected as gamepad on some Android devices (#5439) * [rcore][android] Fix keyboard input detected as gamepad on some devices (#5387) * [core] Add keyboard vs gamepad input test example (#5387) --- .../core/core_input_keyboard_gamepad_test.c | 173 ++++++++++++++++++ src/platforms/rcore_android.c | 7 +- 2 files changed, 178 insertions(+), 2 deletions(-) create mode 100644 examples/core/core_input_keyboard_gamepad_test.c diff --git a/examples/core/core_input_keyboard_gamepad_test.c b/examples/core/core_input_keyboard_gamepad_test.c new file mode 100644 index 000000000..d1f9106f7 --- /dev/null +++ b/examples/core/core_input_keyboard_gamepad_test.c @@ -0,0 +1,173 @@ +/******************************************************************************************* +* +* raylib [core] example - Keyboard vs Gamepad Input Test +* +* Example complexity rating: [★☆☆☆] 1/4 +* +* This example is a diagnostic tool to verify that keyboard input is not +* incorrectly detected as gamepad input on Android devices. +* +* Issue reference: https://github.com/raysan5/raylib/issues/5387 +* +* 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 raylib contributors +* +********************************************************************************************/ + +#include "raylib.h" + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [core] example - keyboard vs gamepad test"); + + Vector2 ballPosition = { (float)screenWidth/2, (float)screenHeight/2 }; + int lastKeyPressed = 0; + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) + { + // Update + //---------------------------------------------------------------------------------- + + // Track keyboard input + if (IsKeyDown(KEY_RIGHT)) ballPosition.x += 4.0f; + if (IsKeyDown(KEY_LEFT)) ballPosition.x -= 4.0f; + if (IsKeyDown(KEY_UP)) ballPosition.y -= 4.0f; + if (IsKeyDown(KEY_DOWN)) ballPosition.y += 4.0f; + + // Keep ball on screen + if (ballPosition.x < 25) ballPosition.x = 25; + if (ballPosition.x > screenWidth - 25) ballPosition.x = screenWidth - 25; + if (ballPosition.y < 25) ballPosition.y = 25; + if (ballPosition.y > screenHeight - 25) ballPosition.y = screenHeight - 25; + + // Track last key pressed + int key = GetKeyPressed(); + if (key != 0) lastKeyPressed = key; + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + // Title + DrawText("KEYBOARD vs GAMEPAD INPUT TEST", 180, 10, 20, DARKGRAY); + DrawText("Issue #5387: Keyboard detected as gamepad on some Android devices", 120, 35, 14, GRAY); + + // Divider + DrawLine(0, 60, screenWidth, 60, LIGHTGRAY); + + // Keyboard section + DrawText("KEYBOARD INPUT", 20, 75, 18, DARKBLUE); + DrawRectangle(20, 100, 360, 80, Fade(BLUE, 0.1f)); + + DrawText(TextFormat("Arrow Keys: [%s] [%s] [%s] [%s]", + IsKeyDown(KEY_UP) ? "UP" : "--", + IsKeyDown(KEY_DOWN) ? "DN" : "--", + IsKeyDown(KEY_LEFT) ? "LT" : "--", + IsKeyDown(KEY_RIGHT) ? "RT" : "--"), 30, 110, 16, BLACK); + + DrawText(TextFormat("Last Key Pressed: %d", lastKeyPressed), 30, 135, 16, DARKGRAY); + DrawText(TextFormat("Any Key Down: %s", (IsKeyDown(KEY_UP) || IsKeyDown(KEY_DOWN) || + IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_RIGHT)) ? "YES" : "NO"), 30, 155, 16, DARKGRAY); + + // Gamepad section + DrawText("GAMEPAD STATUS", 420, 75, 18, DARKGREEN); + DrawRectangle(420, 100, 360, 80, Fade(GREEN, 0.1f)); + + bool gamepadReady = IsGamepadAvailable(0); + DrawText(TextFormat("Gamepad 0 Available: %s", gamepadReady ? "YES" : "NO"), + 430, 110, 16, gamepadReady ? RED : DARKGREEN); + + if (gamepadReady) + { + DrawText(TextFormat("D-Pad: [%s] [%s] [%s] [%s]", + IsGamepadButtonDown(0, GAMEPAD_BUTTON_LEFT_FACE_UP) ? "UP" : "--", + IsGamepadButtonDown(0, GAMEPAD_BUTTON_LEFT_FACE_DOWN) ? "DN" : "--", + IsGamepadButtonDown(0, GAMEPAD_BUTTON_LEFT_FACE_LEFT) ? "LT" : "--", + IsGamepadButtonDown(0, GAMEPAD_BUTTON_LEFT_FACE_RIGHT) ? "RT" : "--"), + 430, 135, 16, RED); + + DrawText(TextFormat("Gamepad Name: %.20s", GetGamepadName(0)), 430, 155, 14, DARKGRAY); + } + else + { + DrawText("No gamepad detected", 430, 135, 16, DARKGREEN); + } + + // Divider + DrawLine(0, 190, screenWidth, 190, LIGHTGRAY); + + // Test result section + DrawText("TEST RESULT", 20, 200, 18, MAROON); + + bool keyboardActive = IsKeyDown(KEY_UP) || IsKeyDown(KEY_DOWN) || + IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_RIGHT); + + if (keyboardActive && gamepadReady) + { + // BUG DETECTED: Keyboard is triggering gamepad detection + DrawRectangle(20, 225, 760, 50, Fade(RED, 0.3f)); + DrawText("BUG DETECTED: Keyboard input is being detected as gamepad!", 30, 235, 18, RED); + DrawText("The fix for issue #5387 may not be working correctly.", 30, 258, 14, DARKGRAY); + } + else if (keyboardActive && !gamepadReady) + { + // CORRECT: Keyboard works without triggering gamepad + DrawRectangle(20, 225, 760, 50, Fade(GREEN, 0.3f)); + DrawText("PASS: Keyboard input detected correctly (no phantom gamepad)", 30, 235, 18, DARKGREEN); + DrawText("Issue #5387 fix is working as expected.", 30, 258, 14, DARKGRAY); + } + else if (!keyboardActive && gamepadReady) + { + // Gamepad is connected (might be real or might be bug on idle) + DrawRectangle(20, 225, 760, 50, Fade(ORANGE, 0.3f)); + DrawText("INFO: Gamepad detected - press keyboard keys to test", 30, 235, 18, ORANGE); + DrawText("If gamepad stays active while pressing keyboard = BUG", 30, 258, 14, DARKGRAY); + } + else + { + // Idle state + DrawRectangle(20, 225, 760, 50, Fade(GRAY, 0.1f)); + DrawText("WAITING: Press arrow keys to test keyboard input", 30, 235, 18, GRAY); + DrawText("Gamepad should NOT become available when pressing keyboard keys", 30, 258, 14, DARKGRAY); + } + + // Ball controlled by keyboard + DrawText("Ball Control (Arrow Keys):", 20, 295, 16, DARKGRAY); + DrawCircleV(ballPosition, 25, MAROON); + DrawCircleLines((int)ballPosition.x, (int)ballPosition.y, 25, DARKGRAY); + + // Instructions + DrawRectangle(0, screenHeight - 45, screenWidth, 45, Fade(BLACK, 0.05f)); + DrawText("Instructions: Press keyboard arrow keys - the ball should move and gamepad should stay 'NO'", + 20, screenHeight - 35, 14, DARKGRAY); + DrawText("If gamepad becomes 'YES' while pressing keyboard = issue #5387 is NOT fixed", + 20, screenHeight - 18, 14, DARKGRAY); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); + //-------------------------------------------------------------------------------------- + + return 0; +} diff --git a/src/platforms/rcore_android.c b/src/platforms/rcore_android.c index 20a85a6a4..f3911d41b 100644 --- a/src/platforms/rcore_android.c +++ b/src/platforms/rcore_android.c @@ -1238,8 +1238,11 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) //int32_t AKeyEvent_getMetaState(event); // Handle gamepad button presses and releases - if (FLAG_IS_SET(source, AINPUT_SOURCE_JOYSTICK) || - FLAG_IS_SET(source, AINPUT_SOURCE_GAMEPAD)) + // NOTE: Skip gamepad handling if this is a keyboard event, as some devices + // report both AINPUT_SOURCE_KEYBOARD and AINPUT_SOURCE_GAMEPAD flags + if ((FLAG_IS_SET(source, AINPUT_SOURCE_JOYSTICK) || + FLAG_IS_SET(source, AINPUT_SOURCE_GAMEPAD)) && + !FLAG_IS_SET(source, AINPUT_SOURCE_KEYBOARD)) { // For now we'll assume a single gamepad which we "detect" on its input event CORE.Input.Gamepad.ready[0] = true; From aee6734cffb5666bdd04115c60db6257bcd5401e Mon Sep 17 00:00:00 2001 From: Dino <84743074+LeapersEdge@users.noreply.github.com> Date: Fri, 26 Dec 2025 20:46:09 +0100 Subject: [PATCH 010/232] fix: set correct default axes for gamepads that are not connected (inside rcore_desktop_glfw.c) (#5444) * fix: set correct default axes for gamepads that are not connected `glfwGetGamepadState` will set all gamepad state variables to 0.0 if required gamepad is not connected, but `RecordAutomationEvent()` inside rcore.c expects trigger axes to be -1.0f when gamepad is not connected. Since SDL and RGFW return -1.0f in such case, this change is aligning it with them * updated comment in rcore_desktop_glfw.c --- src/platforms/rcore_desktop_glfw.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index 471050839..368dd5de8 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -1266,8 +1266,14 @@ void PollInputEvents(void) // Get current gamepad state // NOTE: There is no callback available, so we get it manually GLFWgamepadstate state = { 0 }; - glfwGetGamepadState(i, &state); // This remapps all gamepads so they have their buttons mapped like an xbox controller - + int isGamepadConnected = glfwGetGamepadState(i, &state); // This remapps all gamepads so they have their buttons mapped like an xbox controller + if (!isGamepadConnected) + { + // setting axes to expected resting value instead of GLFW's 0.0f default when gamepad isnt connected + state.axes[GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f; + state.axes[GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f; + } + const unsigned char *buttons = state.buttons; for (int k = 0; (buttons != NULL) && (k < MAX_GAMEPAD_BUTTONS); k++) From 64bd27bd08aa7bf25d4daa6b5d28d3aa6ae4bb12 Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 26 Dec 2025 20:49:03 +0100 Subject: [PATCH 011/232] Update rcore_desktop_glfw.c --- src/platforms/rcore_desktop_glfw.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index 368dd5de8..824184368 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -1266,10 +1266,10 @@ void PollInputEvents(void) // Get current gamepad state // NOTE: There is no callback available, so we get it manually GLFWgamepadstate state = { 0 }; - int isGamepadConnected = glfwGetGamepadState(i, &state); // This remapps all gamepads so they have their buttons mapped like an xbox controller - if (!isGamepadConnected) + int result = glfwGetGamepadState(i, &state); // This remaps all gamepads so they have their buttons mapped like an xbox controller + if (result == GLFW_FALSE) // No joystick is connected, no gamepad mapping or an error occurred { - // setting axes to expected resting value instead of GLFW's 0.0f default when gamepad isnt connected + // Setting axes to expected resting value instead of GLFW 0.0f default when gamepad is not connected state.axes[GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f; state.axes[GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f; } From 25a54d87e6ebeb70ef20443fb4e010195b958ead Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 26 Dec 2025 21:09:53 +0100 Subject: [PATCH 012/232] Update rcore_desktop_win32.c --- src/platforms/rcore_desktop_win32.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/platforms/rcore_desktop_win32.c b/src/platforms/rcore_desktop_win32.c index 29702921f..ce9d86cc2 100644 --- a/src/platforms/rcore_desktop_win32.c +++ b/src/platforms/rcore_desktop_win32.c @@ -1877,13 +1877,23 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara } break; case WM_DPICHANGED: { + // Get current dpi scale factor + float scalex = HIWORD(wParam)/96.0f; + float scaley = LOWORD(wParam)/96.0f; + RECT *suggestedRect = (RECT *)lparam; // Never set the window size to anything other than the suggested rect here // Doing so can cause a window to stutter between monitors when transitioning between them - int result = (int)SetWindowPos(hwnd, NULL, suggestedRect->left, suggestedRect->top, - suggestedRect->right - suggestedRect->left, suggestedRect->bottom - suggestedRect->top, SWP_NOZORDER | SWP_NOACTIVATE); + int result = (int)SetWindowPos(hwnd, NULL, + suggestedRect->left, suggestedRect->top, + suggestedRect->right - suggestedRect->left, + suggestedRect->bottom - suggestedRect->top, + SWP_NOZORDER | SWP_NOACTIVATE); + if (result == 0) TRACELOG(LOG_ERROR, "Failed to set window position [ERROR: %lu]", GetLastError()); + + // TODO: Update screen data, render size, screen scaling, viewport... } break; case WM_SETCURSOR: From 84dfe6a4cf6ab18c8e7d7c2701a93eae5c28dbc0 Mon Sep 17 00:00:00 2001 From: TheLazyIndianTechie Date: Sat, 27 Dec 2025 18:52:24 +0530 Subject: [PATCH 013/232] [rmodels] Fix glTF animation framerate calculation (#4472) (#5445) - Changed GLTF_ANIMDELAY (17ms, ~58.82fps) to GLTF_FRAMERATE (60.0fps) - Updated frameCount calculation: (animDuration * 60) instead of (animDuration * 1000 / 17) - Updated time calculation: j / 60.0f instead of (j * 17) / 1000.0f This fixes animation frame count misalignment when importing glTF models exported at standard 60fps. Animations that were 27+ frames shorter than expected on 1350-frame sequences will now import correctly. --- src/rmodels.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rmodels.c b/src/rmodels.c index 40af4afc4..665b94147 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -6353,7 +6353,7 @@ static bool GetPoseAtTimeGLTF(cgltf_interpolation_type interpolationType, cgltf_ return true; } -#define GLTF_ANIMDELAY 17 // Animation frames delay, (~1000 ms/60 FPS = 16.666666* ms) +#define GLTF_FRAMERATE 60.0f // glTF animation framerate (frames per second) static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCount) { @@ -6473,13 +6473,13 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo if (animData.name != NULL) strncpy(animations[i].name, animData.name, sizeof(animations[i].name) - 1); - animations[i].frameCount = (int)(animDuration*1000.0f/GLTF_ANIMDELAY) + 1; + animations[i].frameCount = (int)(animDuration*GLTF_FRAMERATE) + 1; animations[i].framePoses = (Transform **)RL_MALLOC(animations[i].frameCount*sizeof(Transform *)); for (int j = 0; j < animations[i].frameCount; j++) { animations[i].framePoses[j] = (Transform *)RL_MALLOC(animations[i].boneCount*sizeof(Transform)); - float time = ((float) j*GLTF_ANIMDELAY)/1000.0f; + float time = (float)j / GLTF_FRAMERATE; for (int k = 0; k < animations[i].boneCount; k++) { From 538bf820374db46493f46e89f228934ca686726e Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 27 Dec 2025 14:35:38 +0100 Subject: [PATCH 014/232] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 875792f18..815088fc0 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,7 @@ contributors ------------ - + license From e4491b40b52078370fe4b4e088d17bde6d562310 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 27 Dec 2025 14:43:46 +0100 Subject: [PATCH 015/232] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 815088fc0..694937a70 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,7 @@ contributors ------------ - + license From 05f5143603ba4db9b3157e981926a42c55c4c766 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 27 Dec 2025 15:05:18 +0100 Subject: [PATCH 016/232] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 694937a70..37e37c7c4 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,7 @@ contributors ------------ - + license From da1a76604f76c82c490f7cf0d063fae49326c1ed Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 28 Dec 2025 16:05:42 +0100 Subject: [PATCH 017/232] REMOVED: `CORE.Window.fullscreen`, using available flag instead --- src/platforms/rcore_android.c | 1 - src/platforms/rcore_desktop_glfw.c | 20 ++++++++----------- src/platforms/rcore_desktop_rgfw.c | 10 ++++------ src/platforms/rcore_desktop_sdl.c | 11 ++--------- src/platforms/rcore_template.c | 1 - src/platforms/rcore_web.c | 20 +++++-------------- src/platforms/rcore_web_emscripten.c | 12 ++---------- src/rcore.c | 29 ++++++++++++++-------------- 8 files changed, 35 insertions(+), 69 deletions(-) diff --git a/src/platforms/rcore_android.c b/src/platforms/rcore_android.c index f3911d41b..cca4f4d39 100644 --- a/src/platforms/rcore_android.c +++ b/src/platforms/rcore_android.c @@ -885,7 +885,6 @@ void ClosePlatform(void) // NOTE: returns false in case graphic device could not be created static int InitGraphicsDevice(void) { - CORE.Window.fullscreen = true; FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); EGLint samples = 0; diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index 824184368..ed8b1b542 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -176,7 +176,7 @@ bool WindowShouldClose(void) // Toggle fullscreen mode void ToggleFullscreen(void) { - if (!CORE.Window.fullscreen) + if (!FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) { // Store previous window position (in case we exit fullscreen) CORE.Window.previousPosition = CORE.Window.position; @@ -192,8 +192,6 @@ void ToggleFullscreen(void) { TRACELOG(LOG_WARNING, "GLFW: Failed to get monitor"); - CORE.Window.fullscreen = false; - FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); glfwSetWindowMonitor(platform.handle, NULL, 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE); } @@ -666,7 +664,7 @@ void SetWindowMonitor(int monitor) if ((monitor >= 0) && (monitor < monitorCount)) { - if (CORE.Window.fullscreen) + if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) { TRACELOG(LOG_INFO, "GLFW: Selected fullscreen monitor: [%i] %s", monitor, glfwGetMonitorName(monitors[monitor])); @@ -1422,8 +1420,6 @@ int InitPlatform(void) unsigned int requestedWindowFlags = CORE.Window.flags; // Check window creation flags - if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) CORE.Window.fullscreen = true; - if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)) glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // Visible window else glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE); // Window initially hidden @@ -1536,11 +1532,14 @@ int InitPlatform(void) // REF: https://github.com/raysan5/raylib/issues/1554 glfwSetJoystickCallback(NULL); - GLFWmonitor *monitor = NULL; - if (CORE.Window.fullscreen) + if ((CORE.Window.screen.width == 0) || (CORE.Window.screen.height == 0)) FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); + + // Init window in fullscreen mode if requested + // NOTE: Keeping original screen size for toggle + if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) { // NOTE: Fullscreen applications default to the primary monitor - monitor = glfwGetPrimaryMonitor(); + GLFWmonitor *monitor = glfwGetPrimaryMonitor(); if (!monitor) { TRACELOG(LOG_WARNING, "GLFW: Failed to get primary monitor"); @@ -1614,9 +1613,6 @@ int InitPlatform(void) TRACELOG(LOG_WARNING, "GLFW: Failed to initialize Window"); return -1; } - - // NOTE: Full-screen change, not working properly... - //glfwSetWindowMonitor(platform.handle, glfwGetPrimaryMonitor(), 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE); } else { diff --git a/src/platforms/rcore_desktop_rgfw.c b/src/platforms/rcore_desktop_rgfw.c index 39ac8fb32..04e461ded 100644 --- a/src/platforms/rcore_desktop_rgfw.c +++ b/src/platforms/rcore_desktop_rgfw.c @@ -290,14 +290,13 @@ bool WindowShouldClose(void) // Toggle fullscreen mode void ToggleFullscreen(void) { - if (!CORE.Window.fullscreen) + if (!FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) { // Store previous window position (in case we exit fullscreen) CORE.Window.previousPosition = CORE.Window.position; CORE.Window.previousScreen = CORE.Window.screen; platform.mon = RGFW_window_getMonitor(platform.window); - CORE.Window.fullscreen = true; FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); RGFW_monitor_scaleToWindow(platform.mon, platform.window); @@ -305,7 +304,6 @@ void ToggleFullscreen(void) } else { - CORE.Window.fullscreen = false; FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); if (platform.mon.mode.area.w) @@ -331,7 +329,9 @@ void ToggleFullscreen(void) // Toggle borderless windowed mode void ToggleBorderlessWindowed(void) { - if (CORE.Window.fullscreen) + if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) ToggleFullscreen(); + + if (FLAG_IS_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE)) { CORE.Window.previousPosition = CORE.Window.position; CORE.Window.previousScreen = CORE.Window.screen; @@ -348,8 +348,6 @@ void ToggleBorderlessWindowed(void) CORE.Window.position = CORE.Window.previousPosition; RGFW_window_resize(platform.window, RGFW_AREA(CORE.Window.previousScreen.width, CORE.Window.previousScreen.height)); } - - CORE.Window.fullscreen = !CORE.Window.fullscreen; } // Set window state: maximized, if resizable diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index 612707cea..952268ca6 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -472,13 +472,11 @@ void ToggleFullscreen(void) { SDL_SetWindowFullscreen(platform.window, 0); FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); - CORE.Window.fullscreen = false; } else { SDL_SetWindowFullscreen(platform.window, SDL_WINDOW_FULLSCREEN); FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); - CORE.Window.fullscreen = true; } } else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor"); @@ -554,7 +552,7 @@ void SetWindowState(unsigned int flags) #endif { SDL_SetWindowFullscreen(platform.window, SDL_WINDOW_FULLSCREEN); - CORE.Window.fullscreen = true; + FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); } else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor"); } @@ -644,7 +642,6 @@ void ClearWindowState(unsigned int flags) if (FLAG_IS_SET(flags, FLAG_FULLSCREEN_MODE)) { SDL_SetWindowFullscreen(platform.window, 0); - CORE.Window.fullscreen = false; } if (FLAG_IS_SET(flags, FLAG_WINDOW_RESIZABLE)) { @@ -1937,11 +1934,7 @@ int InitPlatform(void) FLAG_SET(flags, SDL_WINDOW_MOUSE_CAPTURE); // Window has mouse captured // Check window creation flags - if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) - { - CORE.Window.fullscreen = true; - FLAG_SET(flags, SDL_WINDOW_FULLSCREEN); - } + if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) FLAG_SET(flags, SDL_WINDOW_FULLSCREEN); //if (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)) FLAG_SET(flags, SDL_WINDOW_HIDDEN); if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNDECORATED)) FLAG_SET(flags, SDL_WINDOW_BORDERLESS); diff --git a/src/platforms/rcore_template.c b/src/platforms/rcore_template.c index 1f8c5242b..b22d3f2f5 100644 --- a/src/platforms/rcore_template.c +++ b/src/platforms/rcore_template.c @@ -454,7 +454,6 @@ int InitPlatform(void) // raylib uses OpenGL so, platform should create that kind of connection // Below example illustrates that process using EGL library //---------------------------------------------------------------------------- - CORE.Window.fullscreen = true; FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); if (FLAG_IS_SET(CORE.Window.flags, FLAG_MSAA_4X_HINT)) diff --git a/src/platforms/rcore_web.c b/src/platforms/rcore_web.c index adfdace74..e138de302 100644 --- a/src/platforms/rcore_web.c +++ b/src/platforms/rcore_web.c @@ -204,7 +204,6 @@ void ToggleFullscreen(void) EM_ASM(document.exitFullscreen();); - CORE.Window.fullscreen = false; FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); } @@ -213,14 +212,12 @@ void ToggleFullscreen(void) if (enterFullscreen) { // NOTE: The setTimeouts handle the browser mode change delay - EM_ASM - ( - setTimeout(function() - { + EM_ASM( + setTimeout(function(){ Module.requestFullscreen(false, false); }, 100); ); - CORE.Window.fullscreen = true; + FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); } @@ -238,7 +235,7 @@ void ToggleFullscreen(void) */ // EM_ASM(Module.requestFullscreen(false, false);); /* - if (!CORE.Window.fullscreen) + if (!FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) { // Option 1: Request fullscreen for the canvas element // This option does not seem to work at all: @@ -274,7 +271,6 @@ void ToggleFullscreen(void) 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 FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); } else @@ -286,7 +282,6 @@ void ToggleFullscreen(void) 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 FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); } */ @@ -313,7 +308,6 @@ void ToggleBorderlessWindowed(void) EM_ASM(document.exitFullscreen();); - CORE.Window.fullscreen = false; FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); } @@ -545,7 +539,6 @@ void ClearWindowState(unsigned int flags) if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE) || (canvasStyleWidth > canvasWidth)) EM_ASM(document.exitFullscreen();); } - CORE.Window.fullscreen = false; FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); } @@ -1155,8 +1148,6 @@ int InitPlatform(void) // glfwWindowHint(GLFW_AUX_BUFFERS, 0); // Number of auxiliar buffers // Check window creation flags - if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) CORE.Window.fullscreen = true; - if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)) glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // Visible window else glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE); // Window initially hidden @@ -1260,7 +1251,7 @@ int InitPlatform(void) // 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) + if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) { // remember center for switchinging from fullscreen to window if ((CORE.Window.screen.height == CORE.Window.display.height) && (CORE.Window.screen.width == CORE.Window.display.width)) @@ -1830,7 +1821,6 @@ static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const Emscripte const bool wasFullscreen = EM_ASM_INT( { if (document.fullscreenElement) return 1; }, 0); if (!wasFullscreen) { - CORE.Window.fullscreen = false; FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); } diff --git a/src/platforms/rcore_web_emscripten.c b/src/platforms/rcore_web_emscripten.c index 25b477734..aeead6d9b 100644 --- a/src/platforms/rcore_web_emscripten.c +++ b/src/platforms/rcore_web_emscripten.c @@ -167,7 +167,6 @@ void ToggleFullscreen(void) EM_ASM(document.exitFullscreen();); - CORE.Window.fullscreen = false; FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); } @@ -183,7 +182,7 @@ void ToggleFullscreen(void) Module.requestFullscreen(false, false); }, 100); ); - CORE.Window.fullscreen = true; + FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); } @@ -201,7 +200,7 @@ void ToggleFullscreen(void) */ // EM_ASM(Module.requestFullscreen(false, false);); /* - if (!CORE.Window.fullscreen) + if (!FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) { // Option 1: Request fullscreen for the canvas element // This option does not seem to work at all: @@ -237,7 +236,6 @@ void ToggleFullscreen(void) emscripten_get_canvas_element_size("#canvas", &width, &height); TRACELOG(LOG_WARNING, "Emscripten: Enter fullscreen: Canvas size: %i x %i", width, height); - CORE.Window.fullscreen = true; // Toggle fullscreen flag FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); } else @@ -249,7 +247,6 @@ void ToggleFullscreen(void) emscripten_get_canvas_element_size("#canvas", &width, &height); TRACELOG(LOG_WARNING, "Emscripten: Exit fullscreen: Canvas size: %i x %i", width, height); - CORE.Window.fullscreen = false; // Toggle fullscreen flag FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); } */ @@ -275,7 +272,6 @@ void ToggleBorderlessWindowed(void) EM_ASM(document.exitFullscreen();); - CORE.Window.fullscreen = false; FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); } @@ -494,7 +490,6 @@ void ClearWindowState(unsigned int flags) if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE) || (canvasStyleWidth > canvasWidth)) EM_ASM(document.exitFullscreen();); } - CORE.Window.fullscreen = false; FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); } @@ -1117,8 +1112,6 @@ int InitPlatform(void) attribs.antialias = EM_FALSE; // Check window creation flags - //if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) CORE.Window.fullscreen = true; - // Disable FLAG_WINDOW_MINIMIZED, not supported if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)) FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); @@ -1354,7 +1347,6 @@ static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const Emscripte const bool wasFullscreen = EM_ASM_INT( { if (document.fullscreenElement) return 1; }, 0); if (!wasFullscreen) { - CORE.Window.fullscreen = false; FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); } diff --git a/src/rcore.c b/src/rcore.c index 6f16b605b..d0a57048d 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -287,20 +287,19 @@ typedef struct CoreData { const char *title; // Window text title const pointer unsigned int flags; // Configuration flags (bit based), keeps window state bool ready; // Check if window has been initialized successfully - bool fullscreen; // Check if fullscreen mode is enabled bool shouldClose; // Check if window set for closing bool resizedLastFrame; // Check if window has been resized last frame bool eventWaiting; // Wait for events before ending frame bool usingFbo; // Using FBO (RenderTexture) for rendering instead of default framebuffer - Point position; // Window position (required on fullscreen toggle) - Point previousPosition; // Window previous position (required on borderless windowed toggle) Size display; // Display width and height (monitor, device-screen, LCD, ...) - Size screen; // Screen width and height (used render area) - Size previousScreen; // Screen previous width and height (required on borderless windowed toggle) - Size currentFbo; // Current render width and height (depends on active fbo) - Size render; // Framebuffer width and height (render area, including black bars if required) - Point renderOffset; // Offset from render area (must be divided by 2) + Size screen; // Screen current width and height + Point position; // Window current position + Size previousScreen; // Screen previous width and height (required on fullscreen/borderless-windowed toggle) + Point previousPosition; // Window previous position (required on fullscreeen/borderless-windowed toggle) + Size render; // Screen framebuffer width and height + Point renderOffset; // Screen framebuffer render offset (Not required anymore?) + Size currentFbo; // Current framebuffer render width and height (depends on active render texture) Size screenMin; // Screen minimum width and height (for resizable window) Size screenMax; // Screen maximum width and height (for resizable window) Matrix screenScale; // Matrix to scale screen (framebuffer rendering) @@ -762,31 +761,31 @@ bool IsWindowReady(void) // Check if window is currently fullscreen bool IsWindowFullscreen(void) { - return CORE.Window.fullscreen; + return FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); } // Check if window is currently hidden bool IsWindowHidden(void) { - return (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)); + return FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN); } // Check if window has been minimized bool IsWindowMinimized(void) { - return (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)); + return FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); } // Check if window has been maximized bool IsWindowMaximized(void) { - return (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED)); + return FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); } // Check if window has the focus bool IsWindowFocused(void) { - return (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED)); + return !FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); } // Check if window has been resizedLastFrame @@ -798,7 +797,7 @@ bool IsWindowResized(void) // Check if one specific window flag is enabled bool IsWindowState(unsigned int flag) { - return (FLAG_IS_SET(CORE.Window.flags, flag)); + return FLAG_IS_SET(CORE.Window.flags, flag); } // Get current screen width @@ -1100,7 +1099,7 @@ void BeginScissorMode(int x, int y, int width, int height) rlScissor((int)(x*scale.x), (int)(GetScreenHeight()*scale.y - (((y + height)*scale.y))), (int)(width*scale.x), (int)(height*scale.y)); } #else - if (!CORE.Window.usingFbo && (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI))) + if (!CORE.Window.usingFbo && FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) { Vector2 scale = GetWindowScaleDPI(); rlScissor((int)(x*scale.x), (int)(CORE.Window.currentFbo.height - (y + height)*scale.y), (int)(width*scale.x), (int)(height*scale.y)); From 37bc3f50120f752bc2767a32a11f1fcffd6906e0 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 28 Dec 2025 16:07:59 +0100 Subject: [PATCH 018/232] REMOVED: `SetupFramebuffer()`, most platforms do not need it any more Kept only for platforms that could potentially need it --- src/platforms/rcore_android.c | 80 +++++++++++++++++++++++++++++ src/platforms/rcore_desktop_rgfw.c | 12 ++--- src/platforms/rcore_desktop_win32.c | 3 +- src/platforms/rcore_drm.c | 80 +++++++++++++++++++++++++++++ src/rcore.c | 79 ---------------------------- 5 files changed, 164 insertions(+), 90 deletions(-) diff --git a/src/platforms/rcore_android.c b/src/platforms/rcore_android.c index cca4f4d39..f150bf638 100644 --- a/src/platforms/rcore_android.c +++ b/src/platforms/rcore_android.c @@ -267,6 +267,8 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd); static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event); // Process Android inputs static GamepadButton AndroidTranslateGamepadButton(int button); // Map Android gamepad button to raylib gamepad button +static void SetupFramebuffer(int width, int height); // Setup main framebuffer (required by InitPlatform()) + //---------------------------------------------------------------------------------- // Module Functions Declaration //---------------------------------------------------------------------------------- @@ -1419,4 +1421,82 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) return 0; } +// Compute framebuffer size relative to screen size and display size +// NOTE: Global variables CORE.Window.render.width/CORE.Window.render.height and CORE.Window.renderOffset.x/CORE.Window.renderOffset.y can be modified +static void SetupFramebuffer(int width, int height) +{ + // Calculate CORE.Window.render.width and CORE.Window.render.height, we have the display size (input params) and the desired screen size (global var) + if ((CORE.Window.screen.width > CORE.Window.display.width) || (CORE.Window.screen.height > CORE.Window.display.height)) + { + TRACELOG(LOG_WARNING, "DISPLAY: Downscaling required: Screen size (%ix%i) is bigger than display size (%ix%i)", CORE.Window.screen.width, CORE.Window.screen.height, CORE.Window.display.width, CORE.Window.display.height); + + // Downscaling to fit display with border-bars + float widthRatio = (float)CORE.Window.display.width/(float)CORE.Window.screen.width; + float heightRatio = (float)CORE.Window.display.height/(float)CORE.Window.screen.height; + + if (widthRatio <= heightRatio) + { + CORE.Window.render.width = CORE.Window.display.width; + CORE.Window.render.height = (int)round((float)CORE.Window.screen.height*widthRatio); + CORE.Window.renderOffset.x = 0; + CORE.Window.renderOffset.y = (CORE.Window.display.height - CORE.Window.render.height); + } + else + { + CORE.Window.render.width = (int)round((float)CORE.Window.screen.width*heightRatio); + CORE.Window.render.height = CORE.Window.display.height; + CORE.Window.renderOffset.x = (CORE.Window.display.width - CORE.Window.render.width); + CORE.Window.renderOffset.y = 0; + } + + // Screen scaling required + float scaleRatio = (float)CORE.Window.render.width/(float)CORE.Window.screen.width; + CORE.Window.screenScale = MatrixScale(scaleRatio, scaleRatio, 1.0f); + + // NOTE: We render to full display resolution! + // We just need to calculate above parameters for downscale matrix and offsets + CORE.Window.render.width = CORE.Window.display.width; + CORE.Window.render.height = CORE.Window.display.height; + + TRACELOG(LOG_WARNING, "DISPLAY: Downscale matrix generated, content will be rendered at (%ix%i)", CORE.Window.render.width, CORE.Window.render.height); + } + else if ((CORE.Window.screen.width < CORE.Window.display.width) || (CORE.Window.screen.height < CORE.Window.display.height)) + { + // Required screen size is smaller than display size + TRACELOG(LOG_INFO, "DISPLAY: Upscaling required: Screen size (%ix%i) smaller than display size (%ix%i)", CORE.Window.screen.width, CORE.Window.screen.height, CORE.Window.display.width, CORE.Window.display.height); + + if ((CORE.Window.screen.width == 0) || (CORE.Window.screen.height == 0)) + { + CORE.Window.screen.width = CORE.Window.display.width; + CORE.Window.screen.height = CORE.Window.display.height; + } + + // Upscaling to fit display with border-bars + float displayRatio = (float)CORE.Window.display.width/(float)CORE.Window.display.height; + float screenRatio = (float)CORE.Window.screen.width/(float)CORE.Window.screen.height; + + if (displayRatio <= screenRatio) + { + CORE.Window.render.width = CORE.Window.screen.width; + CORE.Window.render.height = (int)round((float)CORE.Window.screen.width/displayRatio); + CORE.Window.renderOffset.x = 0; + CORE.Window.renderOffset.y = (CORE.Window.render.height - CORE.Window.screen.height); + } + else + { + CORE.Window.render.width = (int)round((float)CORE.Window.screen.height*displayRatio); + CORE.Window.render.height = CORE.Window.screen.height; + CORE.Window.renderOffset.x = (CORE.Window.render.width - CORE.Window.screen.width); + CORE.Window.renderOffset.y = 0; + } + } + else + { + CORE.Window.render.width = CORE.Window.screen.width; + CORE.Window.render.height = CORE.Window.screen.height; + CORE.Window.renderOffset.x = 0; + CORE.Window.renderOffset.y = 0; + } +} + // EOF diff --git a/src/platforms/rcore_desktop_rgfw.c b/src/platforms/rcore_desktop_rgfw.c index 04e461ded..558b6de55 100644 --- a/src/platforms/rcore_desktop_rgfw.c +++ b/src/platforms/rcore_desktop_rgfw.c @@ -383,7 +383,7 @@ void SetWindowState(unsigned int flags) } if (FLAG_IS_SET(flags, FLAG_FULLSCREEN_MODE)) { - if (!CORE.Window.fullscreen) ToggleFullscreen(); + ToggleFullscreen(); } if (FLAG_IS_SET(flags, FLAG_WINDOW_RESIZABLE)) { @@ -457,7 +457,7 @@ void ClearWindowState(unsigned int flags) } if (FLAG_IS_SET(flags, FLAG_FULLSCREEN_MODE)) { - if (CORE.Window.fullscreen) ToggleFullscreen(); + ToggleFullscreen(); } if (FLAG_IS_SET(flags, FLAG_WINDOW_RESIZABLE)) { @@ -508,7 +508,7 @@ void ClearWindowState(unsigned int flags) } if (FLAG_IS_SET(flags, FLAG_BORDERLESS_WINDOWED_MODE)) { - if (CORE.Window.fullscreen) ToggleBorderlessWindowed(); + ToggleBorderlessWindowed(); } if (FLAG_IS_SET(flags, FLAG_MSAA_4X_HINT)) { @@ -1256,13 +1256,11 @@ int InitPlatform(void) // Check window creation flags if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) { - CORE.Window.fullscreen = true; FLAG_SET(flags, RGFW_windowFullscreen); } if (FLAG_IS_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE)) { - CORE.Window.fullscreen = true; FLAG_SET(flags, RGFW_windowedFullscreen); } @@ -1313,10 +1311,6 @@ int InitPlatform(void) CORE.Window.display.width = CORE.Window.screen.width; CORE.Window.display.height = CORE.Window.screen.height; #endif - // TODO: Is this needed by raylib now? - // If so, rcore_desktop_sdl should be updated too - //SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height); - if (FLAG_IS_SET(CORE.Window.flags, FLAG_VSYNC_HINT)) RGFW_window_swapInterval(platform.window, 1); RGFW_window_makeCurrent(platform.window); diff --git a/src/platforms/rcore_desktop_win32.c b/src/platforms/rcore_desktop_win32.c index ce9d86cc2..973fafa68 100644 --- a/src/platforms/rcore_desktop_win32.c +++ b/src/platforms/rcore_desktop_win32.c @@ -2049,8 +2049,7 @@ static void HandleWindowResize(HWND hwnd, int *width, int *height) // TODO: Update framebuffer on resize CORE.Window.currentFbo.width = (int)clientSize.cx; CORE.Window.currentFbo.height = (int)clientSize.cy; - //glViewport(0, 0, clientSize.cx, clientSize.cy); - //SetupFramebuffer(0, 0); + //SetupViewport(0, 0, clientSize.cx, clientSize.cy); SetupViewport(clientSize.cx, clientSize.cy); CORE.Window.resizedLastFrame = true; diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index 640799b0a..0aeab3ab4 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -265,6 +265,8 @@ static int FindMatchingConnectorMode(const drmModeConnector *connector, const dr static int FindExactConnectorMode(const drmModeConnector *connector, uint width, uint height, uint fps, bool allowInterlaced); // Search exactly matching DRM connector mode in connector's list static int FindNearestConnectorMode(const drmModeConnector *connector, uint width, uint height, uint fps, bool allowInterlaced); // Search the nearest matching DRM connector mode in connector's list +static void SetupFramebuffer(int width, int height); // Setup main framebuffer (required by InitPlatform()) + //---------------------------------------------------------------------------------- // Module Functions Declaration //---------------------------------------------------------------------------------- @@ -2479,4 +2481,82 @@ static int FindNearestConnectorMode(const drmModeConnector *connector, uint widt return nearestIndex; } +// Compute framebuffer size relative to screen size and display size +// NOTE: Global variables CORE.Window.render.width/CORE.Window.render.height and CORE.Window.renderOffset.x/CORE.Window.renderOffset.y can be modified +static void SetupFramebuffer(int width, int height) +{ + // Calculate CORE.Window.render.width and CORE.Window.render.height, we have the display size (input params) and the desired screen size (global var) + if ((CORE.Window.screen.width > CORE.Window.display.width) || (CORE.Window.screen.height > CORE.Window.display.height)) + { + TRACELOG(LOG_WARNING, "DISPLAY: Downscaling required: Screen size (%ix%i) is bigger than display size (%ix%i)", CORE.Window.screen.width, CORE.Window.screen.height, CORE.Window.display.width, CORE.Window.display.height); + + // Downscaling to fit display with border-bars + float widthRatio = (float)CORE.Window.display.width/(float)CORE.Window.screen.width; + float heightRatio = (float)CORE.Window.display.height/(float)CORE.Window.screen.height; + + if (widthRatio <= heightRatio) + { + CORE.Window.render.width = CORE.Window.display.width; + CORE.Window.render.height = (int)round((float)CORE.Window.screen.height*widthRatio); + CORE.Window.renderOffset.x = 0; + CORE.Window.renderOffset.y = (CORE.Window.display.height - CORE.Window.render.height); + } + else + { + CORE.Window.render.width = (int)round((float)CORE.Window.screen.width*heightRatio); + CORE.Window.render.height = CORE.Window.display.height; + CORE.Window.renderOffset.x = (CORE.Window.display.width - CORE.Window.render.width); + CORE.Window.renderOffset.y = 0; + } + + // Screen scaling required + float scaleRatio = (float)CORE.Window.render.width/(float)CORE.Window.screen.width; + CORE.Window.screenScale = MatrixScale(scaleRatio, scaleRatio, 1.0f); + + // NOTE: We render to full display resolution! + // We just need to calculate above parameters for downscale matrix and offsets + CORE.Window.render.width = CORE.Window.display.width; + CORE.Window.render.height = CORE.Window.display.height; + + TRACELOG(LOG_WARNING, "DISPLAY: Downscale matrix generated, content will be rendered at (%ix%i)", CORE.Window.render.width, CORE.Window.render.height); + } + else if ((CORE.Window.screen.width < CORE.Window.display.width) || (CORE.Window.screen.height < CORE.Window.display.height)) + { + // Required screen size is smaller than display size + TRACELOG(LOG_INFO, "DISPLAY: Upscaling required: Screen size (%ix%i) smaller than display size (%ix%i)", CORE.Window.screen.width, CORE.Window.screen.height, CORE.Window.display.width, CORE.Window.display.height); + + if ((CORE.Window.screen.width == 0) || (CORE.Window.screen.height == 0)) + { + CORE.Window.screen.width = CORE.Window.display.width; + CORE.Window.screen.height = CORE.Window.display.height; + } + + // Upscaling to fit display with border-bars + float displayRatio = (float)CORE.Window.display.width/(float)CORE.Window.display.height; + float screenRatio = (float)CORE.Window.screen.width/(float)CORE.Window.screen.height; + + if (displayRatio <= screenRatio) + { + CORE.Window.render.width = CORE.Window.screen.width; + CORE.Window.render.height = (int)round((float)CORE.Window.screen.width/displayRatio); + CORE.Window.renderOffset.x = 0; + CORE.Window.renderOffset.y = (CORE.Window.render.height - CORE.Window.screen.height); + } + else + { + CORE.Window.render.width = (int)round((float)CORE.Window.screen.height*displayRatio); + CORE.Window.render.height = CORE.Window.screen.height; + CORE.Window.renderOffset.x = (CORE.Window.render.width - CORE.Window.screen.width); + CORE.Window.renderOffset.y = 0; + } + } + else + { + CORE.Window.render.width = CORE.Window.screen.width; + CORE.Window.render.height = CORE.Window.screen.height; + CORE.Window.renderOffset.x = 0; + CORE.Window.renderOffset.y = 0; + } +} + // EOF diff --git a/src/rcore.c b/src/rcore.c index d0a57048d..565eb915c 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -492,7 +492,6 @@ extern int InitPlatform(void); // Initialize platform (graphics, inputs extern void ClosePlatform(void); // Close platform static void InitTimer(void); // Initialize timer, hi-resolution if available (required by InitPlatform()) -static void SetupFramebuffer(int width, int height); // Setup main framebuffer (required by InitPlatform()) static void SetupViewport(int width, int height); // Set viewport for a provided width and height static void ScanDirectoryFiles(const char *basePath, FilePathList *list, const char *filter); // Scan all files and directories in a base path @@ -3827,84 +3826,6 @@ void SetupViewport(int width, int height) rlLoadIdentity(); // Reset current matrix (modelview) } -// Compute framebuffer size relative to screen size and display size -// NOTE: Global variables CORE.Window.render.width/CORE.Window.render.height and CORE.Window.renderOffset.x/CORE.Window.renderOffset.y can be modified -void SetupFramebuffer(int width, int height) -{ - // Calculate CORE.Window.render.width and CORE.Window.render.height, we have the display size (input params) and the desired screen size (global var) - if ((CORE.Window.screen.width > CORE.Window.display.width) || (CORE.Window.screen.height > CORE.Window.display.height)) - { - TRACELOG(LOG_WARNING, "DISPLAY: Downscaling required: Screen size (%ix%i) is bigger than display size (%ix%i)", CORE.Window.screen.width, CORE.Window.screen.height, CORE.Window.display.width, CORE.Window.display.height); - - // Downscaling to fit display with border-bars - float widthRatio = (float)CORE.Window.display.width/(float)CORE.Window.screen.width; - float heightRatio = (float)CORE.Window.display.height/(float)CORE.Window.screen.height; - - if (widthRatio <= heightRatio) - { - CORE.Window.render.width = CORE.Window.display.width; - CORE.Window.render.height = (int)round((float)CORE.Window.screen.height*widthRatio); - CORE.Window.renderOffset.x = 0; - CORE.Window.renderOffset.y = (CORE.Window.display.height - CORE.Window.render.height); - } - else - { - CORE.Window.render.width = (int)round((float)CORE.Window.screen.width*heightRatio); - CORE.Window.render.height = CORE.Window.display.height; - CORE.Window.renderOffset.x = (CORE.Window.display.width - CORE.Window.render.width); - CORE.Window.renderOffset.y = 0; - } - - // Screen scaling required - float scaleRatio = (float)CORE.Window.render.width/(float)CORE.Window.screen.width; - CORE.Window.screenScale = MatrixScale(scaleRatio, scaleRatio, 1.0f); - - // NOTE: We render to full display resolution! - // We just need to calculate above parameters for downscale matrix and offsets - CORE.Window.render.width = CORE.Window.display.width; - CORE.Window.render.height = CORE.Window.display.height; - - TRACELOG(LOG_WARNING, "DISPLAY: Downscale matrix generated, content will be rendered at (%ix%i)", CORE.Window.render.width, CORE.Window.render.height); - } - else if ((CORE.Window.screen.width < CORE.Window.display.width) || (CORE.Window.screen.height < CORE.Window.display.height)) - { - // Required screen size is smaller than display size - TRACELOG(LOG_INFO, "DISPLAY: Upscaling required: Screen size (%ix%i) smaller than display size (%ix%i)", CORE.Window.screen.width, CORE.Window.screen.height, CORE.Window.display.width, CORE.Window.display.height); - - if ((CORE.Window.screen.width == 0) || (CORE.Window.screen.height == 0)) - { - CORE.Window.screen.width = CORE.Window.display.width; - CORE.Window.screen.height = CORE.Window.display.height; - } - - // Upscaling to fit display with border-bars - float displayRatio = (float)CORE.Window.display.width/(float)CORE.Window.display.height; - float screenRatio = (float)CORE.Window.screen.width/(float)CORE.Window.screen.height; - - if (displayRatio <= screenRatio) - { - CORE.Window.render.width = CORE.Window.screen.width; - CORE.Window.render.height = (int)round((float)CORE.Window.screen.width/displayRatio); - CORE.Window.renderOffset.x = 0; - CORE.Window.renderOffset.y = (CORE.Window.render.height - CORE.Window.screen.height); - } - else - { - CORE.Window.render.width = (int)round((float)CORE.Window.screen.height*displayRatio); - CORE.Window.render.height = CORE.Window.screen.height; - CORE.Window.renderOffset.x = (CORE.Window.render.width - CORE.Window.screen.width); - CORE.Window.renderOffset.y = 0; - } - } - else - { - CORE.Window.render.width = CORE.Window.screen.width; - CORE.Window.render.height = CORE.Window.screen.height; - CORE.Window.renderOffset.x = 0; - CORE.Window.renderOffset.y = 0; - } -} - // Scan all files and directories in a base path // WARNING: files.paths[] must be previously allocated and // contain enough space to store all required paths From 1d8e011eee6129005648b3dd105a19f355d82a41 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 28 Dec 2025 16:08:08 +0100 Subject: [PATCH 019/232] Update rcore_drm.c --- src/platforms/rcore_drm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index 0aeab3ab4..366477aac 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -1149,7 +1149,6 @@ int InitPlatform(void) // Initialize graphic device: display/window and graphic context //---------------------------------------------------------------------------- - CORE.Window.fullscreen = true; FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); #if defined(DEFAULT_GRAPHIC_DEVICE_DRM) From 8cfb99f275dcd48ce6c91a289d2c9914bae2035b Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 28 Dec 2025 16:08:19 +0100 Subject: [PATCH 020/232] Minor comment tweaks --- src/rcore.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/rcore.c b/src/rcore.c index 565eb915c..ea38300f1 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -315,17 +315,17 @@ typedef struct CoreData { struct { struct { int exitKey; // Default exit key - char currentKeyState[MAX_KEYBOARD_KEYS]; // Registers current frame key state - char previousKeyState[MAX_KEYBOARD_KEYS]; // Registers previous frame key state + char currentKeyState[MAX_KEYBOARD_KEYS]; // Registers current frame key state + char previousKeyState[MAX_KEYBOARD_KEYS]; // Registers previous frame key state // NOTE: Since key press logic involves comparing previous vs currrent key state, // key repeats needs to be handled specially - char keyRepeatInFrame[MAX_KEYBOARD_KEYS]; // Registers key repeats for current frame + char keyRepeatInFrame[MAX_KEYBOARD_KEYS]; // Registers key repeats for current frame - int keyPressedQueue[MAX_KEY_PRESSED_QUEUE]; // Input keys queue + int keyPressedQueue[MAX_KEY_PRESSED_QUEUE]; // Input keys queue int keyPressedQueueCount; // Input keys queue count - int charPressedQueue[MAX_CHAR_PRESSED_QUEUE]; // Input characters queue (unicode) + int charPressedQueue[MAX_CHAR_PRESSED_QUEUE]; // Input characters queue (unicode) int charPressedQueueCount; // Input characters queue count } Keyboard; @@ -341,8 +341,8 @@ typedef struct CoreData { bool cursorLocked; // Track if cursor is locked (disabled) bool cursorOnScreen; // Tracks if cursor is inside client area - char currentButtonState[MAX_MOUSE_BUTTONS]; // Registers current mouse button state - char previousButtonState[MAX_MOUSE_BUTTONS]; // Registers previous mouse button state + char currentButtonState[MAX_MOUSE_BUTTONS]; // Registers current mouse button state + char previousButtonState[MAX_MOUSE_BUTTONS]; // Registers previous mouse button state Vector2 currentWheelMove; // Registers current mouse wheel variation Vector2 previousWheelMove; // Registers previous mouse wheel variation From 297dcc07b850beafc3ad79609f762e54c0be7f84 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 28 Dec 2025 16:08:34 +0100 Subject: [PATCH 021/232] Update core_highdpi_testbed.c --- examples/core/core_highdpi_testbed.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/examples/core/core_highdpi_testbed.c b/examples/core/core_highdpi_testbed.c index bf103fb31..d34951fc0 100644 --- a/examples/core/core_highdpi_testbed.c +++ b/examples/core/core_highdpi_testbed.c @@ -49,6 +49,7 @@ int main(void) scaleDpi = GetWindowScaleDPI(); if (IsKeyPressed(KEY_SPACE)) ToggleBorderlessWindowed(); + if (IsKeyPressed(KEY_F)) ToggleFullscreen(); //---------------------------------------------------------------------------------- // Draw @@ -58,12 +59,12 @@ int main(void) ClearBackground(RAYWHITE); // Draw grid - for (int h = 0; h < 20; h++) + for (int h = 0; h < GetScreenHeight()/gridSpacing + 1; h++) { DrawText(TextFormat("%02i", h*gridSpacing), 4, h*gridSpacing - 4, 10, GRAY); DrawLine(24, h*gridSpacing, GetScreenWidth(), h*gridSpacing, LIGHTGRAY); } - for (int v = 0; v < 40; v++) + for (int v = 0; v < GetScreenWidth()/gridSpacing + 1; v++) { DrawText(TextFormat("%02i", v*gridSpacing), v*gridSpacing - 10, 4, 10, GRAY); DrawLine(v*gridSpacing, 20, v*gridSpacing, GetScreenHeight(), LIGHTGRAY); @@ -76,6 +77,10 @@ int main(void) 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 reference rectangles, top-left and bottom-right corners + DrawRectangle(0, 0, 30, 60, RED); + DrawRectangle(GetScreenWidth() - 30, GetScreenHeight() - 60, 30, 60, BLUE); + // Draw mouse position DrawCircleV(GetMousePosition(), 20, MAROON); DrawRectangle(mousePos.x - 25, mousePos.y, 50, 2, BLACK); From 2cf8983e18c3a5869d0a6fa00549bb65e923d606 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 28 Dec 2025 16:11:42 +0100 Subject: [PATCH 022/232] WARNING: REDESIGNED: Fullscreen modes, use current display resolution Considering multi-monitor and multi-ppi configurations Fullscreen-exclusive scales to available display resolution, ignoring content scaling Windowed-borderless scales to available logical resolution considering HighDPI **if requested** --- src/platforms/rcore_desktop_glfw.c | 226 +++++++++++++---------------- 1 file changed, 103 insertions(+), 123 deletions(-) diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index ed8b1b542..9b360771f 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -178,41 +178,56 @@ void ToggleFullscreen(void) { if (!FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) { - // Store previous window position (in case we exit fullscreen) + // Store previous screen data (in case exiting fullscreen) CORE.Window.previousPosition = CORE.Window.position; + CORE.Window.previousScreen = CORE.Window.screen; + // Use current monitor the window is on to get fullscreen required size int monitorCount = 0; int monitorIndex = GetCurrentMonitor(); GLFWmonitor **monitors = glfwGetMonitors(&monitorCount); - - // Use current monitor, so we correctly get the display the window is on GLFWmonitor *monitor = (monitorIndex < monitorCount)? monitors[monitorIndex] : NULL; - if (monitor == NULL) + if (monitor != NULL) { - TRACELOG(LOG_WARNING, "GLFW: Failed to get monitor"); + // Get current monitor video mode + const GLFWvidmode *mode = glfwGetVideoMode(monitors[monitorIndex]); + CORE.Window.display.width = mode->width; + CORE.Window.display.height = mode->height; + CORE.Window.position = (Point){ 0, 0 }; + CORE.Window.screen = (Size){ CORE.Window.display.width, CORE.Window.display.height }; - glfwSetWindowMonitor(platform.handle, NULL, 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE); - } - else - { - CORE.Window.fullscreen = true; + // Set fullscreen flag to be processed on FramebufferSizeCallback() accordingly FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); + // WARNING: This function launches FramebufferSizeCallback() glfwSetWindowMonitor(platform.handle, monitor, 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE); } + else TRACELOG(LOG_WARNING, "GLFW: Failed to get monitor"); } else { - CORE.Window.fullscreen = false; + // Restore previous window position and size + CORE.Window.position = CORE.Window.previousPosition; + CORE.Window.screen = CORE.Window.previousScreen; + + // Set fullscreen flag to be processed on FramebufferSizeCallback() accordingly + // and considered by GetWindowScaleDPI() FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); - glfwSetWindowMonitor(platform.handle, NULL, CORE.Window.previousPosition.x, CORE.Window.previousPosition.y, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE); +#if !defined(__APPLE__) + // Make sure to restore render size considering HighDPI scaling + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) + { + Vector2 scaleDpi = GetWindowScaleDPI(); + CORE.Window.screen.width *= scaleDpi.x; + CORE.Window.screen.height *= scaleDpi.y; + } +#endif - // we update the window position right away - CORE.Window.position.x = CORE.Window.previousPosition.x; - CORE.Window.position.y = CORE.Window.previousPosition.y; + glfwSetWindowMonitor(platform.handle, NULL, CORE.Window.position.x, CORE.Window.position.y, + CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE); } // Try to enable GPU V-Sync, so frames are limited to screen refresh rate (60Hz -> 60 FPS) @@ -224,13 +239,8 @@ void ToggleFullscreen(void) void ToggleBorderlessWindowed(void) { // Leave fullscreen before attempting to set borderless windowed mode - bool wasOnFullscreen = false; - if (CORE.Window.fullscreen) - { - // Fullscreen already saves the previous position so it does not need to be set here again - ToggleFullscreen(); - wasOnFullscreen = true; - } + // NOTE: Fullscreen already saves the previous position so it does not need to be set again later + if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) ToggleFullscreen(); int monitorCount = 0; GLFWmonitor **monitors = glfwGetMonitors(&monitorCount); @@ -246,7 +256,7 @@ void ToggleBorderlessWindowed(void) { // Store screen position and size // NOTE: If it was on fullscreen, screen position was already stored, so skip setting it here - if (!wasOnFullscreen) CORE.Window.previousPosition = CORE.Window.position; + CORE.Window.previousPosition = CORE.Window.position; CORE.Window.previousScreen = CORE.Window.screen; // Set undecorated flag @@ -261,15 +271,8 @@ void ToggleBorderlessWindowed(void) const int monitorHeight = mode->height; // Set screen position and size - glfwSetWindowMonitor( - platform.handle, - monitors[monitor], - monitorPosX, - monitorPosY, - monitorWidth, - monitorHeight, - mode->refreshRate - ); + glfwSetWindowMonitor(platform.handle, monitors[monitor], monitorPosX, monitorPosY, + monitorWidth, monitorHeight, mode->refreshRate); // Refocus window glfwFocusWindow(platform.handle); @@ -278,39 +281,32 @@ void ToggleBorderlessWindowed(void) } else { + // Restore previous screen values + CORE.Window.position = CORE.Window.previousPosition; + CORE.Window.screen = CORE.Window.previousScreen; + // Remove undecorated flag 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 + // Make sure to restore size considering HighDPI scaling 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; + CORE.Window.screen.width *= scaleDpi.x; + CORE.Window.screen.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( - platform.handle, - NULL, - CORE.Window.previousPosition.x, - CORE.Window.previousPosition.y, - CORE.Window.previousScreen.width, - CORE.Window.previousScreen.height, - mode->refreshRate - ); + // Return to previous screen size and position + glfwSetWindowMonitor(platform.handle, NULL, CORE.Window.position.x, CORE.Window.position.y, + CORE.Window.screen.width, CORE.Window.screen.height, mode->refreshRate); // Refocus window glfwFocusWindow(platform.handle); FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); - - CORE.Window.position.x = CORE.Window.previousPosition.x; - CORE.Window.position.y = CORE.Window.previousPosition.y; } } else TRACELOG(LOG_WARNING, "GLFW: Failed to find video mode for selected monitor"); @@ -1023,7 +1019,8 @@ Vector2 GetWindowPosition(void) Vector2 GetWindowScaleDPI(void) { Vector2 scale = { 1.0f, 1.0f }; - if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) glfwGetWindowContentScale(platform.handle, &scale.x, &scale.y); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI) && !FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) + glfwGetWindowContentScale(platform.handle, &scale.x, &scale.y); return scale; } @@ -1553,59 +1550,20 @@ int InitPlatform(void) 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 + // Check if user requested some screen size + if ((CORE.Window.screen.width == 0) || (CORE.Window.screen.height == 0)) + { + // Set some default screen size in case user decides to exit fullscreen mode + CORE.Window.previousScreen.width = 800; + CORE.Window.previousScreen.height = 450; + CORE.Window.previousPosition.x = CORE.Window.display.width/2 - 800/2; + CORE.Window.previousPosition.y = CORE.Window.display.height/2 - 450/2; + } + + // Set screen width/height to the display width/height if (CORE.Window.screen.width == 0) CORE.Window.screen.width = CORE.Window.display.width; if (CORE.Window.screen.height == 0) CORE.Window.screen.height = CORE.Window.display.height; - // Remember center for switching from fullscreen to window - if ((CORE.Window.screen.height == CORE.Window.display.height) && (CORE.Window.screen.width == CORE.Window.display.width)) - { - // If screen width/height equal to the display, we can't calculate the window pos for toggling full-screened/windowed - // Toggling full-screened/windowed with pos(0, 0) can cause problems in some platforms, such as X11 - CORE.Window.position.x = CORE.Window.display.width/4; - CORE.Window.position.y = CORE.Window.display.height/4; - } - else - { - CORE.Window.position.x = CORE.Window.display.width/2 - CORE.Window.screen.width/2; - CORE.Window.position.y = CORE.Window.display.height/2 - CORE.Window.screen.height/2; - } - - if (CORE.Window.position.x < 0) CORE.Window.position.x = 0; - if (CORE.Window.position.y < 0) CORE.Window.position.y = 0; - - // Obtain recommended CORE.Window.display.width/CORE.Window.display.height from a valid videomode for the monitor - int count = 0; - const GLFWvidmode *modes = glfwGetVideoModes(monitor, &count); - - // Get closest video mode to desired CORE.Window.screen.width/CORE.Window.screen.height - for (int i = 0; i < count; i++) - { - if ((unsigned int)modes[i].width >= CORE.Window.screen.width) - { - if ((unsigned int)modes[i].height >= CORE.Window.screen.height) - { - CORE.Window.display.width = modes[i].width; - CORE.Window.display.height = modes[i].height; - break; - } - } - } - - TRACELOG(LOG_INFO, "SYSTEM: Closest fullscreen videomode: %i x %i", CORE.Window.display.width, CORE.Window.display.height); - - // NOTE: ISSUE: Closest videomode could not match monitor aspect-ratio, for example, - // for a desired screen size of 800x450 (16:9), closest supported videomode is 800x600 (4:3), - // framebuffer is rendered correctly but once displayed on a 16:9 monitor, it gets stretched - // by the sides to fit all monitor space... - - // Try to setup the most appropriate fullscreen framebuffer for the requested screenWidth/screenHeight - // It considers device display resolution mode and setups a framebuffer with black bars if required (render size/offset) - // Modified global variables: CORE.Window.screen.width/CORE.Window.screen.height - CORE.Window.render.width/CORE.Window.render.height - CORE.Window.renderOffset.x/CORE.Window.renderOffset.y - CORE.Window.screenScale - // TODO: It is a quite cumbersome solution to display size vs requested size, it should be reviewed or removed... - // HighDPI monitors are properly considered in a following similar function: SetupViewport() - SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height); - platform.handle = glfwCreateWindow(CORE.Window.display.width, CORE.Window.display.height, (CORE.Window.title != 0)? CORE.Window.title : " ", monitor, NULL); if (!platform.handle) { @@ -1616,14 +1574,11 @@ int InitPlatform(void) } else { - // No-fullscreen window creation - bool requestWindowedFullscreen = (CORE.Window.screen.height == 0) && (CORE.Window.screen.width == 0); - // Default to at least one pixel in size, as creation with a zero dimension is not allowed - int creationWidth = (CORE.Window.screen.width != 0)? CORE.Window.screen.width : 1; - int creationHeight = (CORE.Window.screen.height != 0)? CORE.Window.screen.height : 1; + if (CORE.Window.screen.width == 0) CORE.Window.screen.width = 1; + if (CORE.Window.screen.height == 0) CORE.Window.screen.height = 1; - platform.handle = glfwCreateWindow(creationWidth, creationHeight, (CORE.Window.title != 0)? CORE.Window.title : " ", NULL, NULL); + platform.handle = glfwCreateWindow(CORE.Window.screen.width, CORE.Window.screen.height, (CORE.Window.title != 0)? CORE.Window.title : " ", NULL, NULL); if (!platform.handle) { glfwTerminate(); @@ -1632,7 +1587,7 @@ int InitPlatform(void) } // After the window was created, determine the monitor that the window manager assigned - // Derive display sizes, and, if possible, window size in case it was zero at beginning + // Derive display sizes and, if possible, window size in case it was zero at beginning int monitorCount = 0; int monitorIndex = GetCurrentMonitor(); @@ -1640,7 +1595,7 @@ int InitPlatform(void) if (monitorIndex < monitorCount) { - monitor = monitors[monitorIndex]; + GLFWmonitor *monitor = monitors[monitorIndex]; const GLFWvidmode *mode = glfwGetVideoMode(monitor); // Default display resolution to that of the current mode @@ -1651,7 +1606,7 @@ int InitPlatform(void) 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); + glfwSetWindowSize(platform.handle, CORE.Window.screen.width, CORE.Window.screen.height); } else { @@ -1693,6 +1648,8 @@ int InitPlatform(void) { // 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); + + // Get current framebuffer size, on high-dpi it could be bigger than screen size glfwGetFramebufferSize(platform.handle, &fbWidth, &fbHeight); // Screen scaling matrix is required in case desired screen area is different from display area @@ -1726,6 +1683,11 @@ int InitPlatform(void) if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return -1; } else { + int monitorCount = 0; + int monitorIndex = GetCurrentMonitor(); + GLFWmonitor **monitors = glfwGetMonitors(&monitorCount); + GLFWmonitor *monitor = monitors[monitorIndex]; + // Try to center window on screen but avoiding window-bar outside of screen int monitorX = 0; int monitorY = 0; @@ -1733,7 +1695,7 @@ int InitPlatform(void) int monitorHeight = 0; glfwGetMonitorWorkarea(monitor, &monitorX, &monitorY, &monitorWidth, &monitorHeight); - // Here CORE.Window.render.width/height should be used instead of + // TODO: Here CORE.Window.render.width/height should be used instead of // CORE.Window.screen.width/height to center the window correctly when the high dpi flag is enabled int posX = monitorX + (monitorWidth - (int)CORE.Window.render.width)/2; int posY = monitorY + (monitorHeight - (int)CORE.Window.render.height)/2; @@ -1855,7 +1817,7 @@ static void WindowSizeCallback(GLFWwindow *window, int width, int height) // 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); + 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 @@ -1870,19 +1832,38 @@ static void FramebufferSizeCallback(GLFWwindow *window, int width, int height) CORE.Window.currentFbo.height = height; CORE.Window.resizedLastFrame = true; - // Check if render size was actually scaled for high-dpi - if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) - { - // 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 + if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) { + // On fullscreen mode, strategy is ignoring high-dpi and + // use the all available display size + // Set screen size to render size (physical pixel size) CORE.Window.screen.width = width; CORE.Window.screen.height = height; + CORE.Window.screenScale = MatrixScale(1.0f, 1.0f, 1.0f); + SetMouseScale(1.0f, 1.0f); + } + else // Window mode (including borderless window) + { + // Check if render size was actually scaled for high-dpi + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) + { + // 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); + CORE.Window.screenScale = MatrixScale(scaleDpi.x, scaleDpi.y, 1.0f); +#if !defined(__APPLE__) + // Mouse input scaling for the new screen size + SetMouseScale(1.0f/scaleDpi.x, 1.0f/scaleDpi.y); +#endif + } + else + { + // Set screen size to render size (physical pixel size) + CORE.Window.screen.width = width; + CORE.Window.screen.height = height; + } } // WARNING: If using a render texture, it is not scaled to new size @@ -1903,13 +1884,12 @@ static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float s #if !defined(__APPLE__) // Mouse input scaling for the new screen size - SetMouseScale((float)CORE.Window.screen.width/fbWidth, (float)CORE.Window.screen.height/fbHeight); + SetMouseScale(1.0f/scalex, 1.0f/scaley); #endif CORE.Window.render.width = (int)fbWidth; CORE.Window.render.height = (int)fbHeight; - CORE.Window.currentFbo.width = (int)fbWidth; - CORE.Window.currentFbo.height = (int)fbHeight; + CORE.Window.currentFbo = CORE.Window.render; } // GLFW3: Window position callback, runs when window position changes From 11c248aa820ffd35a8684ad68b521fd101095418 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 28 Dec 2025 16:20:43 +0100 Subject: [PATCH 023/232] Update rcore_web.c --- src/platforms/rcore_web.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/platforms/rcore_web.c b/src/platforms/rcore_web.c index e138de302..b52ca1bf0 100644 --- a/src/platforms/rcore_web.c +++ b/src/platforms/rcore_web.c @@ -1290,18 +1290,6 @@ int InitPlatform(void) TRACELOG(LOG_WARNING, "SYSTEM: Closest fullscreen videomode: %i x %i", CORE.Window.display.width, CORE.Window.display.height); - // NOTE: ISSUE: Closest videomode could not match monitor aspect-ratio, for example, - // for a desired screen size of 800x450 (16:9), closest supported videomode is 800x600 (4:3), - // framebuffer is rendered correctly but once displayed on a 16:9 monitor, it gets stretched - // by the sides to fit all monitor space... - - // Try to setup the most appropriate fullscreen framebuffer for the requested screenWidth/screenHeight - // It considers device display resolution mode and setups a framebuffer with black bars if required (render size/offset) - // Modified global variables: CORE.Window.screen.width/CORE.Window.screen.height - CORE.Window.render.width/CORE.Window.render.height - CORE.Window.renderOffset.x/CORE.Window.renderOffset.y - CORE.Window.screenScale - // TODO: It is a quite cumbersome solution to display size vs requested size, it should be reviewed or removed... - // HighDPI monitors are properly considered in a following similar function: SetupViewport() - SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height); - platform.handle = glfwCreateWindow(CORE.Window.display.width, CORE.Window.display.height, (CORE.Window.title != 0)? CORE.Window.title : " ", glfwGetPrimaryMonitor(), NULL); // NOTE: Full-screen change, not working properly... From c0c8ee9dc8240e2567aed5e1b37f8d9261f400ea Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 28 Dec 2025 18:15:47 +0100 Subject: [PATCH 024/232] Update rcore_desktop_glfw.c --- src/platforms/rcore_desktop_glfw.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index 9b360771f..ef5f5ed4f 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -267,12 +267,15 @@ void ToggleBorderlessWindowed(void) int monitorPosX = 0; int monitorPosY = 0; glfwGetMonitorPos(monitors[monitor], &monitorPosX, &monitorPosY); - const int monitorWidth = mode->width; - const int monitorHeight = mode->height; + CORE.Window.position.x = monitorPosX; + CORE.Window.position.x = monitorPosY; + + CORE.Window.screen.width = mode->width; + CORE.Window.screen.height = mode->height; // Set screen position and size - glfwSetWindowMonitor(platform.handle, monitors[monitor], monitorPosX, monitorPosY, - monitorWidth, monitorHeight, mode->refreshRate); + glfwSetWindowMonitor(platform.handle, monitors[monitor], CORE.Window.position.x, CORE.Window.position.y, + CORE.Window.screen.width, CORE.Window.screen.height, mode->refreshRate); // Refocus window glfwFocusWindow(platform.handle); @@ -1817,7 +1820,7 @@ static void WindowSizeCallback(GLFWwindow *window, int width, int height) // 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); + //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 @@ -1873,7 +1876,7 @@ static void FramebufferSizeCallback(GLFWwindow *window, int width, int height) // 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); + //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; From 4176c518c74b3571bef7113dbb90a4a656e3012f Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 28 Dec 2025 18:40:44 +0100 Subject: [PATCH 025/232] Update rcore_desktop_glfw.c --- src/platforms/rcore_desktop_glfw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index ef5f5ed4f..f5b3711c5 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -268,7 +268,7 @@ void ToggleBorderlessWindowed(void) int monitorPosY = 0; glfwGetMonitorPos(monitors[monitor], &monitorPosX, &monitorPosY); CORE.Window.position.x = monitorPosX; - CORE.Window.position.x = monitorPosY; + CORE.Window.position.y = monitorPosY; CORE.Window.screen.width = mode->width; CORE.Window.screen.height = mode->height; From 8871d7648d6edb2fb3de70f5feba613df84ecf92 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 28 Dec 2025 19:49:38 +0100 Subject: [PATCH 026/232] Update core_highdpi_testbed.c --- examples/core/core_highdpi_testbed.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/examples/core/core_highdpi_testbed.c b/examples/core/core_highdpi_testbed.c index d34951fc0..8142a1a1b 100644 --- a/examples/core/core_highdpi_testbed.c +++ b/examples/core/core_highdpi_testbed.c @@ -33,6 +33,7 @@ int main(void) Vector2 scaleDpi = GetWindowScaleDPI(); Vector2 mousePos = GetMousePosition(); int currentMonitor = GetCurrentMonitor(); + Vector2 windowPos = GetWindowPosition(); int gridSpacing = 40; // Grid spacing in pixels @@ -47,6 +48,7 @@ int main(void) mousePos = GetMousePosition(); currentMonitor = GetCurrentMonitor(); scaleDpi = GetWindowScaleDPI(); + windowPos = GetWindowPosition(); if (IsKeyPressed(KEY_SPACE)) ToggleBorderlessWindowed(); if (IsKeyPressed(KEY_F)) ToggleFullscreen(); @@ -73,9 +75,10 @@ int main(void) // Draw UI info 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); + DrawText(TextFormat("WINDOW POSITION: %ix%i", windowPos.x, windowPos.y), 50, 90, 20, DARKGRAY); + DrawText(TextFormat("SCREEN SIZE: %ix%i", GetScreenWidth(), GetScreenHeight()), 50, 130, 20, DARKGRAY); + DrawText(TextFormat("RENDER SIZE: %ix%i", GetRenderWidth(), GetRenderHeight()), 50, 170, 20, DARKGRAY); + DrawText(TextFormat("SCALE FACTOR: %.1fx%.1f", scaleDpi.x, scaleDpi.y), 50, 210, 20, GRAY); // Draw reference rectangles, top-left and bottom-right corners DrawRectangle(0, 0, 30, 60, RED); From 8a75439c255088a0cc4c12becb42de57900ade08 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 28 Dec 2025 19:51:04 +0100 Subject: [PATCH 027/232] REVIEWED: Fullscreen modes on Linux (X11 over XWayland) It does not work as expected... :( --- src/platforms/rcore_desktop_glfw.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index f5b3711c5..88120be78 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -196,11 +196,16 @@ void ToggleFullscreen(void) CORE.Window.display.height = mode->height; CORE.Window.position = (Point){ 0, 0 }; - CORE.Window.screen = (Size){ CORE.Window.display.width, CORE.Window.display.height }; + CORE.Window.screen = CORE.Window.display; // Set fullscreen flag to be processed on FramebufferSizeCallback() accordingly FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); + // NOTE: X11 requires undecorating the window before switching to + // fullscreen to avoid issues with framebuffer scaling + glfwSetWindowAttrib(platform.handle, GLFW_DECORATED, GLFW_FALSE); + FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNDECORATED); + // WARNING: This function launches FramebufferSizeCallback() glfwSetWindowMonitor(platform.handle, monitor, 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE); } @@ -226,8 +231,14 @@ void ToggleFullscreen(void) } #endif + // WARNING: This function launches FramebufferSizeCallback() glfwSetWindowMonitor(platform.handle, NULL, CORE.Window.position.x, CORE.Window.position.y, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE); + + // NOTE: X11 requires restoring the decorated window after switching from + // fullscreen to avoid issues with framebuffer scaling + glfwSetWindowAttrib(platform.handle, GLFW_DECORATED, GLFW_TRUE); + FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNDECORATED); } // Try to enable GPU V-Sync, so frames are limited to screen refresh rate (60Hz -> 60 FPS) From 6450a48c750862aa40a24b34187b98dff87aabd2 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 28 Dec 2025 20:03:51 +0100 Subject: [PATCH 028/232] Update core_highdpi_testbed.c --- examples/core/core_highdpi_testbed.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/core/core_highdpi_testbed.c b/examples/core/core_highdpi_testbed.c index 8142a1a1b..a925527db 100644 --- a/examples/core/core_highdpi_testbed.c +++ b/examples/core/core_highdpi_testbed.c @@ -75,7 +75,7 @@ int main(void) // Draw UI info DrawText(TextFormat("CURRENT MONITOR: %i/%i (%ix%i)", currentMonitor + 1, GetMonitorCount(), GetMonitorWidth(currentMonitor), GetMonitorHeight(currentMonitor)), 50, 50, 20, DARKGRAY); - DrawText(TextFormat("WINDOW POSITION: %ix%i", windowPos.x, windowPos.y), 50, 90, 20, DARKGRAY); + DrawText(TextFormat("WINDOW POSITION: %ix%i", (int)windowPos.x, (int)windowPos.y), 50, 90, 20, DARKGRAY); DrawText(TextFormat("SCREEN SIZE: %ix%i", GetScreenWidth(), GetScreenHeight()), 50, 130, 20, DARKGRAY); DrawText(TextFormat("RENDER SIZE: %ix%i", GetRenderWidth(), GetRenderHeight()), 50, 170, 20, DARKGRAY); DrawText(TextFormat("SCALE FACTOR: %.1fx%.1f", scaleDpi.x, scaleDpi.y), 50, 210, 20, GRAY); From 890ca8d6870585f9e3499eb0e7a327af2cabaa1b Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 28 Dec 2025 20:04:44 +0100 Subject: [PATCH 029/232] REVIEWED: `GetWindowPosition()`, return internal value --- src/platforms/rcore_desktop_glfw.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index 88120be78..1593f0306 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -1021,12 +1021,7 @@ const char *GetMonitorName(int monitor) // Get window position XY on monitor Vector2 GetWindowPosition(void) { - int x = 0; - int y = 0; - - glfwGetWindowPos(platform.handle, &x, &y); - - return (Vector2){ (float)x, (float)y }; + return (Vector2){ (float)CORE.Window.position.x, (float)CORE.Window.position.y }; } // Get window scale DPI factor for current monitor From a334a54eacc90b93ce68e1bcb092ce1d08088a93 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 28 Dec 2025 20:09:15 +0100 Subject: [PATCH 030/232] Update rcore_desktop_glfw.c --- src/platforms/rcore_desktop_glfw.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index 1593f0306..1741187e4 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -275,12 +275,7 @@ void ToggleBorderlessWindowed(void) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNDECORATED); // Get monitor position and size - int monitorPosX = 0; - int monitorPosY = 0; - glfwGetMonitorPos(monitors[monitor], &monitorPosX, &monitorPosY); - CORE.Window.position.x = monitorPosX; - CORE.Window.position.y = monitorPosY; - + glfwGetMonitorPos(monitors[monitor], &CORE.Window.position.x, &CORE.Window.position.y); CORE.Window.screen.width = mode->width; CORE.Window.screen.height = mode->height; From eb3cc183ccce0670054c3accad61e759515bbe58 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 28 Dec 2025 20:29:01 +0100 Subject: [PATCH 031/232] REVIEWED: FIXED: Windows fullscreen, after breaking it due to X11/Wayland changes --- src/platforms/rcore_desktop_glfw.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index 1741187e4..42e8f3867 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -201,11 +201,12 @@ void ToggleFullscreen(void) // Set fullscreen flag to be processed on FramebufferSizeCallback() accordingly FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); +#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND) // NOTE: X11 requires undecorating the window before switching to // fullscreen to avoid issues with framebuffer scaling glfwSetWindowAttrib(platform.handle, GLFW_DECORATED, GLFW_FALSE); FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNDECORATED); - +#endif // WARNING: This function launches FramebufferSizeCallback() glfwSetWindowMonitor(platform.handle, monitor, 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE); } @@ -235,10 +236,12 @@ void ToggleFullscreen(void) glfwSetWindowMonitor(platform.handle, NULL, CORE.Window.position.x, CORE.Window.position.y, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE); +#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND) // NOTE: X11 requires restoring the decorated window after switching from // fullscreen to avoid issues with framebuffer scaling glfwSetWindowAttrib(platform.handle, GLFW_DECORATED, GLFW_TRUE); FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNDECORATED); +#endif } // Try to enable GPU V-Sync, so frames are limited to screen refresh rate (60Hz -> 60 FPS) From 8f8346048ce12596094dbd4f63c004fb1d5587e5 Mon Sep 17 00:00:00 2001 From: Meowster <142757105+meowstr@users.noreply.github.com> Date: Sun, 28 Dec 2025 17:50:10 -0500 Subject: [PATCH 032/232] Add chicken scheme to BINDINGS.md (#5449) * Add chicken scheme to BINDINGS.md * Fix typo --- BINDINGS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/BINDINGS.md b/BINDINGS.md index ee7da46f4..37274b3be 100644 --- a/BINDINGS.md +++ b/BINDINGS.md @@ -21,6 +21,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers | [claw-raylib](https://github.com/bohonghuang/claw-raylib) | **auto** | [Common Lisp](https://common-lisp.net) | Apache-2.0 | | [raylib](https://github.com/fosskers/raylib) | 5.5 | [Common Lisp](https://common-lisp.net) | MPL-2.0 | | [chez-raylib](https://github.com/Yunoinsky/chez-raylib) | **auto** | [Chez Scheme](https://cisco.github.io/ChezScheme) | GPLv3 | +| [chicken-raylib](https://github.com/meowstr/chicken-raylib) | 5.5 | [CHICKEN Scheme](https://wiki.call-cc.org) | MIT | | [CLIPSraylib](https://github.com/mrryanjohnston/CLIPSraylib) | **auto** | [CLIPS](https://www.clipsrules.net/) | MIT | | [raylib-cr](https://github.com/sol-vin/raylib-cr) | 4.6-dev (5e1a81) | [Crystal](https://crystal-lang.org) | Apache-2.0 | | [ray-cyber](https://github.com/fubark/ray-cyber) | **5.0** | [Cyber](https://cyberscript.dev) | MIT | From 58d414bcf878bfa11c6afc871e9d6444d0f0e307 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 29 Dec 2025 12:39:40 +0100 Subject: [PATCH 033/232] REVIEWED: `InitPlatform()`, code simplification --- src/platforms/rcore_desktop_glfw.c | 57 ++++++++++++++---------------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index 42e8f3867..a1c0024aa 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -1565,13 +1565,18 @@ int InitPlatform(void) CORE.Window.previousScreen.height = 450; CORE.Window.previousPosition.x = CORE.Window.display.width/2 - 800/2; CORE.Window.previousPosition.y = CORE.Window.display.height/2 - 450/2; + + // Set screen width/height to the display width/height + if (CORE.Window.screen.width == 0) CORE.Window.screen.width = CORE.Window.display.width; + if (CORE.Window.screen.height == 0) CORE.Window.screen.height = CORE.Window.display.height; + } + else + { + CORE.Window.previousScreen = CORE.Window.screen; + CORE.Window.screen = CORE.Window.display; } - // Set screen width/height to the display width/height - if (CORE.Window.screen.width == 0) CORE.Window.screen.width = CORE.Window.display.width; - if (CORE.Window.screen.height == 0) CORE.Window.screen.height = CORE.Window.display.height; - - platform.handle = glfwCreateWindow(CORE.Window.display.width, CORE.Window.display.height, (CORE.Window.title != 0)? CORE.Window.title : " ", monitor, NULL); + platform.handle = glfwCreateWindow(CORE.Window.screen.width, CORE.Window.screen.height, (CORE.Window.title != 0)? CORE.Window.title : " ", monitor, NULL); if (!platform.handle) { glfwTerminate(); @@ -1630,13 +1635,13 @@ int InitPlatform(void) glfwMakeContextCurrent(platform.handle); result = glfwGetError(NULL); + if ((result != GLFW_NO_WINDOW_CONTEXT) && (result != GLFW_PLATFORM_ERROR)) CORE.Window.ready = true; // Checking context activation - // Check context activation - if ((result != GLFW_NO_WINDOW_CONTEXT) && (result != GLFW_PLATFORM_ERROR)) + if (CORE.Window.ready) { - CORE.Window.ready = true; + // Setup additional windows configs and register required window size info - glfwSwapInterval(0); // No V-Sync by default + glfwSwapInterval(0); // No V-Sync by default // Try to enable GPU V-Sync, so frames are limited to screen refresh rate (60Hz -> 60 FPS) // NOTE: V-Sync can be enabled by graphic driver configuration, it doesn't need @@ -1677,25 +1682,13 @@ int InitPlatform(void) TRACELOG(LOG_INFO, " > Screen size: %i x %i", CORE.Window.screen.width, CORE.Window.screen.height); TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height); TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y); - } - else - { - TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphics device"); - return -1; - } - if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)) MinimizeWindow(); - - // If graphic device is no properly initialized, we end program - if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return -1; } - else - { + // Try to center window on screen but avoiding window-bar outside of screen int monitorCount = 0; int monitorIndex = GetCurrentMonitor(); GLFWmonitor **monitors = glfwGetMonitors(&monitorCount); GLFWmonitor *monitor = monitors[monitorIndex]; - // Try to center window on screen but avoiding window-bar outside of screen int monitorX = 0; int monitorY = 0; int monitorWidth = 0; @@ -1704,15 +1697,19 @@ int InitPlatform(void) // TODO: Here CORE.Window.render.width/height should be used instead of // CORE.Window.screen.width/height to center the window correctly when the high dpi flag is enabled - int posX = monitorX + (monitorWidth - (int)CORE.Window.render.width)/2; - int posY = monitorY + (monitorHeight - (int)CORE.Window.render.height)/2; - if (posX < monitorX) posX = monitorX; - if (posY < monitorY) posY = monitorY; - SetWindowPosition(posX, posY); + CORE.Window.position.x = monitorX + (monitorWidth - (int)CORE.Window.screen.width)/2; + CORE.Window.position.y = monitorY + (monitorHeight - (int)CORE.Window.screen.height)/2; + //if (CORE.Window.position.x < monitorX) CORE.Window.position.x = monitorX; + //if (CORE.Window.position.y < monitorY) CORE.Window.position.y = monitorY; - // Update CORE.Window.position here so it is correct from the start - CORE.Window.position.x = posX; - CORE.Window.position.y = posY; + SetWindowPosition(CORE.Window.position.x, CORE.Window.position.y); + + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)) MinimizeWindow(); + } + else + { + TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphics device"); + return -1; } // Apply window flags requested previous to initialization From 00f42e419913c0165d27b74eaa6369717c89540c Mon Sep 17 00:00:00 2001 From: Padmadev D <128023777+padmadevd@users.noreply.github.com> Date: Mon, 29 Dec 2025 17:20:12 +0530 Subject: [PATCH 034/232] [rcore] [android] fixed gesture system not reporting GESTURE_NONE (#5452) in android gesture system is not reporting GESTURE_NONE, specified in the issue https://github.com/raysan5/raylib/issues/5010 so, automatically GESTURE_SWIPE, TAP, DOUBLE_TAP, also will not be reported. in this commit it is fixed. --- src/platforms/rcore_android.c | 106 +++++++++++++++++++--------------- 1 file changed, 60 insertions(+), 46 deletions(-) diff --git a/src/platforms/rcore_android.c b/src/platforms/rcore_android.c index f150bf638..cc012c4fe 100644 --- a/src/platforms/rcore_android.c +++ b/src/platforms/rcore_android.c @@ -1336,30 +1336,17 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) } } - if ((flags == AMOTION_EVENT_ACTION_POINTER_UP) || (flags == AMOTION_EVENT_ACTION_UP) || (flags == AMOTION_EVENT_ACTION_HOVER_EXIT)) - { - // One of the touchpoints is released, remove it from touch point arrays - if (flags == AMOTION_EVENT_ACTION_HOVER_EXIT) - { - // If the touchPoint is hover, remove it from hoverPoints - for (int i = 0; i < MAX_TOUCH_POINTS; i++) - { - if (touchRaw.hoverPoints[i] == touchRaw.pointId[pointerIndex]) - { - touchRaw.hoverPoints[i] = -1; - break; - } - } - } - for (int i = pointerIndex; (i < touchRaw.pointCount - 1) && (i < MAX_TOUCH_POINTS - 1); i++) - { - touchRaw.pointId[i] = touchRaw.pointId[i+1]; - touchRaw.position[i] = touchRaw.position[i+1]; - } - touchRaw.pointCount--; - } +#if defined(SUPPORT_GESTURES_SYSTEM) + GestureEvent gestureEvent = { 0 }; + + gestureEvent.pointCount = 0; + + // Register touch actions + if (flags == AMOTION_EVENT_ACTION_DOWN) gestureEvent.touchAction = TOUCH_ACTION_DOWN; + else if (flags == AMOTION_EVENT_ACTION_UP) gestureEvent.touchAction = TOUCH_ACTION_UP; + else if (flags == AMOTION_EVENT_ACTION_MOVE) gestureEvent.touchAction = TOUCH_ACTION_MOVE; + else if (flags == AMOTION_EVENT_ACTION_CANCEL) gestureEvent.touchAction = TOUCH_ACTION_CANCEL; - int pointCount = 0; for (int i = 0; (i < touchRaw.pointCount) && (i < MAX_TOUCH_POINTS); i++) { // If the touchPoint is hover, Ignore it @@ -1375,35 +1362,62 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) } if (hover) continue; - CORE.Input.Touch.pointId[pointCount] = touchRaw.pointId[i]; - CORE.Input.Touch.position[pointCount] = touchRaw.position[i]; - pointCount++; - } - CORE.Input.Touch.pointCount = pointCount; - -#if defined(SUPPORT_GESTURES_SYSTEM) - GestureEvent gestureEvent = { 0 }; - - gestureEvent.pointCount = CORE.Input.Touch.pointCount; - - // Register touch actions - if (flags == AMOTION_EVENT_ACTION_DOWN) gestureEvent.touchAction = TOUCH_ACTION_DOWN; - else if (flags == AMOTION_EVENT_ACTION_UP) gestureEvent.touchAction = TOUCH_ACTION_UP; - else if (flags == AMOTION_EVENT_ACTION_MOVE) gestureEvent.touchAction = TOUCH_ACTION_MOVE; - else if (flags == AMOTION_EVENT_ACTION_CANCEL) gestureEvent.touchAction = TOUCH_ACTION_CANCEL; - - for (int i = 0; (i < gestureEvent.pointCount) && (i < MAX_TOUCH_POINTS); i++) - { - gestureEvent.pointId[i] = CORE.Input.Touch.pointId[i]; - gestureEvent.position[i] = CORE.Input.Touch.position[i]; - gestureEvent.position[i].x /= (float)GetScreenWidth(); - gestureEvent.position[i].y /= (float)GetScreenHeight(); + gestureEvent.pointId[gestureEvent.pointCount] = touchRaw.pointId[i]; + gestureEvent.position[gestureEvent.pointCount] = touchRaw.position[i]; + gestureEvent.position[gestureEvent.pointCount].x /= (float)GetScreenWidth(); + gestureEvent.position[gestureEvent.pointCount].y /= (float)GetScreenHeight(); + gestureEvent.pointCount++; } // Gesture data is sent to gestures system for processing ProcessGestureEvent(gestureEvent); #endif + if (flags == AMOTION_EVENT_ACTION_HOVER_EXIT) + { + // Hover exited. So, remove it from hoverPoints + for (int i = 0; i < MAX_TOUCH_POINTS; i++) + { + if (touchRaw.hoverPoints[i] == touchRaw.pointId[pointerIndex]) + { + touchRaw.hoverPoints[i] = -1; + break; + } + } + } + + if ((flags == AMOTION_EVENT_ACTION_POINTER_UP) || (flags == AMOTION_EVENT_ACTION_UP)) + { + // One of the touchpoints is released, remove it from touch point arrays + for (int i = pointerIndex; (i < touchRaw.pointCount - 1) && (i < MAX_TOUCH_POINTS - 1); i++) + { + touchRaw.pointId[i] = touchRaw.pointId[i+1]; + touchRaw.position[i] = touchRaw.position[i+1]; + } + touchRaw.pointCount--; + } + + CORE.Input.Touch.pointCount = 0; + for (int i = 0; (i < touchRaw.pointCount) && (i < MAX_TOUCH_POINTS); i++) + { + // If the touchPoint is hover, Ignore it + bool hover = false; + for (int j = 0; j < MAX_TOUCH_POINTS; j++) + { + // Check if the touchPoint is in hoverPointers + if (touchRaw.hoverPoints[j] == touchRaw.pointId[i]) + { + hover = true; + break; + } + } + if (hover) continue; + + CORE.Input.Touch.pointId[CORE.Input.Touch.pointCount] = touchRaw.pointId[i]; + CORE.Input.Touch.position[CORE.Input.Touch.pointCount] = touchRaw.position[i]; + CORE.Input.Touch.pointCount++; + } + // When all touchpoints are tapped and released really quickly, this event is generated if (flags == AMOTION_EVENT_ACTION_CANCEL) CORE.Input.Touch.pointCount = 0; From 1c6f6831613163d3724e15b322f45a458a011354 Mon Sep 17 00:00:00 2001 From: MULTi <78434796+MULTidll@users.noreply.github.com> Date: Mon, 29 Dec 2025 17:24:30 +0530 Subject: [PATCH 035/232] [rcore][drm] Improved touch input handling and multitouch support, closes #4842 (#5447) * Improved touch input handling and multitouch support in drm platform * revert * made some fixes for the touch issue in drm platform * updated touch input handling by adding multitouch support * improved how it handles the multitouch * added cleanup * Remove touch last update tracking to simplify touch input handling * improved multitouch support by tracking touch positions and IDs for each slot * Better touch input handling * Increase maximum touch points from 8 to 10 and enhance touchscreen prioritization logic * Refactor touch input handling to use slot index as ID for stability and simplify touch clearing logic * Improve touch input handling by activating slot 0 based on mouse click or touch events * touch event handling to use tracking ID for unique touch identification * Add multitouch detection to PollMouseEvents for improved touch handling * Fix conditional formatting in PollMouseEvents for clarity * Refactor conditional statements in PollMouseEvents and InitPlatform for improved readability * Fix formatting in PollMouseEvents for improved readability --- src/config.h | 2 +- src/platforms/rcore_drm.c | 253 +++++++++++++++++++++++++++++++------- 2 files changed, 212 insertions(+), 43 deletions(-) diff --git a/src/config.h b/src/config.h index b749f8952..9f54edd23 100644 --- a/src/config.h +++ b/src/config.h @@ -105,7 +105,7 @@ #define MAX_GAMEPAD_AXES 8 // Maximum number of axes supported (per gamepad) #define MAX_GAMEPAD_BUTTONS 32 // Maximum number of buttons supported (per gamepad) #define MAX_GAMEPAD_VIBRATION_TIME 2.0f // Maximum vibration time in seconds -#define MAX_TOUCH_POINTS 8 // Maximum number of touch points supported +#define MAX_TOUCH_POINTS 10 // Maximum number of touch points supported #define MAX_KEY_PRESSED_QUEUE 16 // Maximum number of keys in the key input queue #define MAX_CHAR_PRESSED_QUEUE 16 // Maximum number of characters in the char input queue diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index 366477aac..b97eac5f5 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -135,8 +135,12 @@ typedef struct { char currentButtonStateEvdev[MAX_MOUSE_BUTTONS]; // Holds the new mouse state for the next polling event to grab bool cursorRelative; // Relative cursor mode int mouseFd; // File descriptor for the evdev mouse/touch/gestures + bool mouseIsTouch; // Check if the current mouse device is actually a touchscreen Rectangle absRange; // Range of values for absolute pointing devices (touchscreens) int touchSlot; // Hold the touch slot number of the currently being sent multitouch block + bool touchActive[MAX_TOUCH_POINTS]; // Track which touch points are currently active + Vector2 touchPosition[MAX_TOUCH_POINTS]; // Track touch positions for each slot + int touchId[MAX_TOUCH_POINTS]; // Track touch IDs for each slot // Gamepad data int gamepadStreamFd[MAX_GAMEPADS]; // Gamepad device file descriptor @@ -1115,9 +1119,6 @@ void PollInputEvents(void) // Register previous touch states for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.previousTouchState[i] = CORE.Input.Touch.currentTouchState[i]; - // Reset touch positions to invalid state - for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.position[i] = (Vector2){ -1, -1 }; - // Map touch position to mouse position for convenience // NOTE: For DRM touchscreen devices, this mapping is disabled to avoid false touch detection // CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; @@ -1565,7 +1566,11 @@ int InitPlatform(void) if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)) MinimizeWindow(); // If graphic device is no properly initialized, we end program - if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return -1; } + if (!CORE.Window.ready) + { + TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); + return -1; + } else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor())/2 - CORE.Window.screen.width/2, GetMonitorHeight(GetCurrentMonitor())/2 - CORE.Window.screen.height/2); // Set some default window flags @@ -1883,7 +1888,14 @@ static void InitEvdevInput(void) { CORE.Input.Touch.position[i].x = -1; CORE.Input.Touch.position[i].y = -1; + platform.touchActive[i] = false; + platform.touchPosition[i].x = -1; + platform.touchPosition[i].y = -1; + platform.touchId[i] = -1; } + + // Initialize touch slot + platform.touchSlot = 0; // Reset keyboard key state for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) @@ -2047,17 +2059,49 @@ static void ConfigureEvdevDevice(char *device) const char *deviceKindStr = "unknown"; if (isMouse || isTouch) { - deviceKindStr = "mouse"; - if (platform.mouseFd != -1) close(platform.mouseFd); - platform.mouseFd = fd; + bool prioritize = false; - if (absAxisCount > 0) + // Priority logic: Touchscreens override Mice. + // 1. No device set yet? Take it. + if (platform.mouseFd == -1) prioritize = true; + // 2. Current is Mouse, New is Touch? Upgrade to Touch. + else if (isTouch && !platform.mouseIsTouch) prioritize = true; + // 3. Current is Touch, New is Touch? Use the new one (Last one found wins, standard behavior). + else if (isTouch && platform.mouseIsTouch) prioritize = true; + // 4. Current is Mouse, New is Mouse? Use the new one. + else if (!isTouch && !platform.mouseIsTouch) prioritize = true; + // 5. Current is Touch, New is Mouse? IGNORE the mouse. Keep the touchscreen. + else prioritize = false; + + if (prioritize) { - platform.absRange.x = absinfo[ABS_X].info.minimum; - platform.absRange.width = absinfo[ABS_X].info.maximum - absinfo[ABS_X].info.minimum; + deviceKindStr = isTouch ? "touchscreen" : "mouse"; + + if (platform.mouseFd != -1) + { + TRACELOG(LOG_INFO, "INPUT: Overwriting previous input device with new %s", deviceKindStr); + close(platform.mouseFd); + } + + platform.mouseFd = fd; + platform.mouseIsTouch = isTouch; - platform.absRange.y = absinfo[ABS_Y].info.minimum; - platform.absRange.height = absinfo[ABS_Y].info.maximum - absinfo[ABS_Y].info.minimum; + if (absAxisCount > 0) + { + platform.absRange.x = absinfo[ABS_X].info.minimum; + platform.absRange.width = absinfo[ABS_X].info.maximum - absinfo[ABS_X].info.minimum; + + platform.absRange.y = absinfo[ABS_Y].info.minimum; + platform.absRange.height = absinfo[ABS_Y].info.maximum - absinfo[ABS_Y].info.minimum; + } + + TRACELOG(LOG_INFO, "INPUT: Initialized input device %s as %s", device, deviceKindStr); + } + else + { + TRACELOG(LOG_INFO, "INPUT: Ignoring device %s (keeping higher priority %s device)", device, platform.mouseIsTouch ? "touchscreen" : "mouse"); + close(fd); + return; } } else if (isGamepad && !isMouse && !isKeyboard && (platform.gamepadCount < MAX_GAMEPADS)) @@ -2231,6 +2275,7 @@ static void PollMouseEvents(void) struct input_event event = { 0 }; int touchAction = -1; // 0-TOUCH_ACTION_UP, 1-TOUCH_ACTION_DOWN, 2-TOUCH_ACTION_MOVE + static bool isMultitouch = false; // Detect if device supports MT events // Try to read data from the mouse/touch/gesture and only continue if successful while (read(fd, &event, sizeof(event)) == (int)sizeof(event)) @@ -2276,54 +2321,118 @@ static void PollMouseEvents(void) if (event.code == ABS_X) { CORE.Input.Mouse.currentPosition.x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange - CORE.Input.Touch.position[0].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange - - touchAction = 2; // TOUCH_ACTION_MOVE + + // Update single touch position only if it's active and no MT events are being used + if ((platform.touchActive[0]) && (!isMultitouch)) + { + platform.touchPosition[0].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; + if (touchAction == -1) touchAction = 2; // TOUCH_ACTION_MOVE + } } if (event.code == ABS_Y) { CORE.Input.Mouse.currentPosition.y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange - CORE.Input.Touch.position[0].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange - - touchAction = 2; // TOUCH_ACTION_MOVE + + // Update single touch position only if it's active and no MT events are being used + if ((platform.touchActive[0]) && (!isMultitouch)) + { + platform.touchPosition[0].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; + if (touchAction == -1) touchAction = 2; // TOUCH_ACTION_MOVE + } } // Multitouch movement - if (event.code == ABS_MT_SLOT) platform.touchSlot = event.value; // Remember the slot number for the folowing events - - if (event.code == ABS_MT_POSITION_X) + if ((event.code) == (ABS_MT_SLOT)) { - if (platform.touchSlot < MAX_TOUCH_POINTS) CORE.Input.Touch.position[platform.touchSlot].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange + platform.touchSlot = event.value; + isMultitouch = true; } - if (event.code == ABS_MT_POSITION_Y) + if ((event.code) == (ABS_MT_POSITION_X)) { - if (platform.touchSlot < MAX_TOUCH_POINTS) CORE.Input.Touch.position[platform.touchSlot].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange - } - - if (event.code == ABS_MT_TRACKING_ID) - { - if ((event.value < 0) && (platform.touchSlot < MAX_TOUCH_POINTS)) + isMultitouch = true; + if ((platform.touchSlot) < (MAX_TOUCH_POINTS)) { - // Touch has ended for this point - CORE.Input.Touch.position[platform.touchSlot].x = -1; - CORE.Input.Touch.position[platform.touchSlot].y = -1; + platform.touchPosition[platform.touchSlot].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; + + // If this slot is active, it's a move. If not, we are just updating the buffer for when it becomes active. + // Only set to MOVE if we haven't already detected a DOWN or UP event this frame + if (platform.touchActive[platform.touchSlot] && touchAction == -1) touchAction = 2; // TOUCH_ACTION_MOVE + } + } + + if ((event.code) == (ABS_MT_POSITION_Y)) + { + if ((platform.touchSlot) < (MAX_TOUCH_POINTS)) + { + platform.touchPosition[platform.touchSlot].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; + + // If this slot is active, it's a move. If not, we are just updating the buffer for when it becomes active. + // Only set to MOVE if we haven't already detected a DOWN or UP event this frame + if (platform.touchActive[platform.touchSlot] && touchAction == -1) touchAction = 2; // TOUCH_ACTION_MOVE + } + } + + if ((event.code) == (ABS_MT_TRACKING_ID)) + { + if ((platform.touchSlot) < (MAX_TOUCH_POINTS)) + { + if (event.value >= 0) + { + + platform.touchActive[platform.touchSlot] = true; + platform.touchId[platform.touchSlot] = event.value; // Use Tracking ID for unique IDs + + touchAction = 1; // TOUCH_ACTION_DOWN + } + else + { + // Touch has ended for this point + platform.touchActive[platform.touchSlot] = false; + platform.touchPosition[platform.touchSlot].x = -1; + platform.touchPosition[platform.touchSlot].y = -1; + platform.touchId[platform.touchSlot] = -1; + + // Force UP action if we haven't already set a DOWN action + // (DOWN takes priority over UP if both happen in one frame, though rare) + if (touchAction != 1) touchAction = 0; // TOUCH_ACTION_UP + } + } + } + + // Handle ABS_MT_PRESSURE (0x3a) if available, as some devices use it for lift-off + #ifndef ABS_MT_PRESSURE + #define ABS_MT_PRESSURE 0x3a + #endif + if ((event.code) == (ABS_MT_PRESSURE)) + { + if ((platform.touchSlot) < (MAX_TOUCH_POINTS)) + { + if (event.value <= 0) // Pressure 0 means lift + { + platform.touchActive[platform.touchSlot] = false; + platform.touchPosition[platform.touchSlot].x = -1; + platform.touchPosition[platform.touchSlot].y = -1; + platform.touchId[platform.touchSlot] = -1; + if (touchAction != 1) touchAction = 0; // TOUCH_ACTION_UP + } } } // Touchscreen tap - if (event.code == ABS_PRESSURE) + if ((event.code) == (ABS_PRESSURE)) { int previousMouseLeftButtonState = platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT]; - if (!event.value && previousMouseLeftButtonState) + if ((!event.value) && (previousMouseLeftButtonState)) { platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 0; - touchAction = 0; // TOUCH_ACTION_UP + + if (touchAction != 1) touchAction = 0; // TOUCH_ACTION_UP } - if (event.value && !previousMouseLeftButtonState) + if ((event.value) && (!previousMouseLeftButtonState)) { platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 1; touchAction = 1; // TOUCH_ACTION_DOWN @@ -2340,8 +2449,46 @@ static void PollMouseEvents(void) { platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = event.value; - if (event.value > 0) touchAction = 1; // TOUCH_ACTION_DOWN - else touchAction = 0; // TOUCH_ACTION_UP + if (event.value > 0) + { + bool activateSlot0 = false; + + if (event.code == BTN_LEFT) + { + activateSlot0 = true; // Mouse click always activates + } + else if (event.code == BTN_TOUCH) + { + bool anyActive = false; + for (int i = 0; i < MAX_TOUCH_POINTS; i++) { + if (platform.touchActive[i]) { anyActive = true; break; } + } + if (!anyActive) activateSlot0 = true; + } + + if (activateSlot0) + { + platform.touchActive[0] = true; + platform.touchId[0] = 0; + } + + touchAction = 1; // TOUCH_ACTION_DOWN + } + else + { + // Only clear touch 0 for actual mouse clicks (BTN_LEFT) + if (event.code == BTN_LEFT) + { + platform.touchActive[0] = false; + platform.touchPosition[0].x = -1; + platform.touchPosition[0].y = -1; + } + else if (event.code == BTN_TOUCH) + { + platform.touchSlot = 0; // Reset slot index to 0 + } + touchAction = 0; // TOUCH_ACTION_UP + } } if (event.code == BTN_RIGHT) platform.currentButtonStateEvdev[MOUSE_BUTTON_RIGHT] = event.value; @@ -2362,11 +2509,33 @@ static void PollMouseEvents(void) if (CORE.Input.Mouse.currentPosition.y > CORE.Window.screen.height/CORE.Input.Mouse.scale.y) CORE.Input.Mouse.currentPosition.y = CORE.Window.screen.height/CORE.Input.Mouse.scale.y; } - // Update touch point count - CORE.Input.Touch.pointCount = 0; + // Repack active touches into CORE.Input.Touch + int k = 0; for (int i = 0; i < MAX_TOUCH_POINTS; i++) { - if (CORE.Input.Touch.position[i].x >= 0) CORE.Input.Touch.pointCount++; + if (platform.touchActive[i]) + { + CORE.Input.Touch.position[k] = platform.touchPosition[i]; + CORE.Input.Touch.pointId[k] = platform.touchId[i]; + k++; + } + } + CORE.Input.Touch.pointCount = k; + + // Clear remaining slots + for (int i = k; i < MAX_TOUCH_POINTS; i++) + { + CORE.Input.Touch.position[i].x = -1; + CORE.Input.Touch.position[i].y = -1; + CORE.Input.Touch.pointId[i] = -1; + } + + // Debug logging + static int lastTouchCount = 0; + if (CORE.Input.Touch.pointCount != lastTouchCount && (touchAction == 0 || touchAction == 1)) + { + TRACELOG(LOG_DEBUG, "TOUCH: Count changed from %d to %d (action: %d)", lastTouchCount, CORE.Input.Touch.pointCount, touchAction); + lastTouchCount = CORE.Input.Touch.pointCount; } #if defined(SUPPORT_GESTURES_SYSTEM) @@ -2558,4 +2727,4 @@ static void SetupFramebuffer(int width, int height) } } -// EOF +// EOF \ No newline at end of file From 2b48cf67936eace2a4aa58f7e22c34170883f0a8 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 29 Dec 2025 13:06:05 +0100 Subject: [PATCH 036/232] Formating review --- src/platforms/rcore_drm.c | 104 ++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 60 deletions(-) diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index b97eac5f5..103d81975 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -2061,21 +2061,21 @@ static void ConfigureEvdevDevice(char *device) { bool prioritize = false; - // Priority logic: Touchscreens override Mice. - // 1. No device set yet? Take it. + // Priority logic: touchscreens override Mice + // 1. No device set yet? Take it if (platform.mouseFd == -1) prioritize = true; - // 2. Current is Mouse, New is Touch? Upgrade to Touch. + // 2. Current is mouse, new is touch? Upgrade to touch else if (isTouch && !platform.mouseIsTouch) prioritize = true; - // 3. Current is Touch, New is Touch? Use the new one (Last one found wins, standard behavior). + // 3. Current is touch, new is touch? Use the new one (last one found wins, standard behavior) else if (isTouch && platform.mouseIsTouch) prioritize = true; - // 4. Current is Mouse, New is Mouse? Use the new one. + // 4. Current is mouse, new is mouse? Use the new one else if (!isTouch && !platform.mouseIsTouch) prioritize = true; - // 5. Current is Touch, New is Mouse? IGNORE the mouse. Keep the touchscreen. + // 5. Current is touch, new is mouse? Ignore the mouse, keep the touchscreen else prioritize = false; if (prioritize) { - deviceKindStr = isTouch ? "touchscreen" : "mouse"; + deviceKindStr = isTouch? "touchscreen" : "mouse"; if (platform.mouseFd != -1) { @@ -2172,18 +2172,15 @@ static void PollKeyboardEvents(void) // If the event was a key, we know a working keyboard is connected, so disable the SSH keyboard platform.eventKeyboardMode = true; #endif - // Keyboard keys appear for codes 1 to 255, ignore everthing else if ((event.code >= 1) && (event.code <= 255)) { - // Lookup the scancode in the keymap to get a keycode keycode = linuxToRaylibMap[event.code]; // Make sure we got a valid keycode if ((keycode > 0) && (keycode < MAX_KEYBOARD_KEYS)) { - // WARNING: https://www.kernel.org/doc/Documentation/input/input.txt // Event interface: 'value' is the value the event carries. Either a relative change for EV_REL, // absolute new value for EV_ABS (joysticks ...), or 0 for EV_KEY for release, 1 for keypress and 2 for autorepeat @@ -2232,16 +2229,15 @@ static void PollGamepadEvents(void) { if (event.code < KEYMAP_SIZE) { - short keycodeRaylib = linuxToRaylibMap[event.code]; + short keycode = linuxToRaylibMap[event.code]; // raylib keycode - TRACELOG(LOG_DEBUG, "INPUT: Gamepad %2i: KEY_%s Keycode(linux): %4i Keycode(raylib): %4i", i, (event.value == 0)? "UP" : "DOWN", event.code, keycodeRaylib); + TRACELOG(LOG_DEBUG, "INPUT: Gamepad %2i: KEY_%s Keycode(linux): %4i Keycode(raylib): %4i", i, (event.value == 0)? "UP" : "DOWN", event.code, keycode); - if ((keycodeRaylib != 0) && (keycodeRaylib < MAX_GAMEPAD_BUTTONS)) + if ((keycode != 0) && (keycode < MAX_GAMEPAD_BUTTONS)) { // 1 - button pressed, 0 - button released - CORE.Input.Gamepad.currentButtonState[i][keycodeRaylib] = event.value; - - CORE.Input.Gamepad.lastButtonPressed = (event.value == 1)? keycodeRaylib : GAMEPAD_BUTTON_UNKNOWN; + CORE.Input.Gamepad.currentButtonState[i][keycode] = event.value; + CORE.Input.Gamepad.lastButtonPressed = (event.value == 1)? keycode : GAMEPAD_BUTTON_UNKNOWN; } } } @@ -2323,7 +2319,7 @@ static void PollMouseEvents(void) CORE.Input.Mouse.currentPosition.x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange // Update single touch position only if it's active and no MT events are being used - if ((platform.touchActive[0]) && (!isMultitouch)) + if (platform.touchActive[0] && !isMultitouch) { platform.touchPosition[0].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; if (touchAction == -1) touchAction = 2; // TOUCH_ACTION_MOVE @@ -2335,7 +2331,7 @@ static void PollMouseEvents(void) CORE.Input.Mouse.currentPosition.y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange // Update single touch position only if it's active and no MT events are being used - if ((platform.touchActive[0]) && (!isMultitouch)) + if (platform.touchActive[0] && !isMultitouch) { platform.touchPosition[0].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; if (touchAction == -1) touchAction = 2; // TOUCH_ACTION_MOVE @@ -2343,16 +2339,16 @@ static void PollMouseEvents(void) } // Multitouch movement - if ((event.code) == (ABS_MT_SLOT)) + if (event.code == ABS_MT_SLOT) { platform.touchSlot = event.value; isMultitouch = true; } - if ((event.code) == (ABS_MT_POSITION_X)) + if (event.code == ABS_MT_POSITION_X) { isMultitouch = true; - if ((platform.touchSlot) < (MAX_TOUCH_POINTS)) + if (platform.touchSlot < MAX_TOUCH_POINTS) { platform.touchPosition[platform.touchSlot].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; @@ -2362,9 +2358,9 @@ static void PollMouseEvents(void) } } - if ((event.code) == (ABS_MT_POSITION_Y)) + if (event.code == ABS_MT_POSITION_Y) { - if ((platform.touchSlot) < (MAX_TOUCH_POINTS)) + if (platform.touchSlot < MAX_TOUCH_POINTS) { platform.touchPosition[platform.touchSlot].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; @@ -2374,9 +2370,9 @@ static void PollMouseEvents(void) } } - if ((event.code) == (ABS_MT_TRACKING_ID)) + if (event.code == ABS_MT_TRACKING_ID) { - if ((platform.touchSlot) < (MAX_TOUCH_POINTS)) + if (platform.touchSlot < MAX_TOUCH_POINTS) { if (event.value >= 0) { @@ -2384,7 +2380,7 @@ static void PollMouseEvents(void) platform.touchActive[platform.touchSlot] = true; platform.touchId[platform.touchSlot] = event.value; // Use Tracking ID for unique IDs - touchAction = 1; // TOUCH_ACTION_DOWN + touchAction = 1; // TOUCH_ACTION_DOWN } else { @@ -2396,18 +2392,18 @@ static void PollMouseEvents(void) // Force UP action if we haven't already set a DOWN action // (DOWN takes priority over UP if both happen in one frame, though rare) - if (touchAction != 1) touchAction = 0; // TOUCH_ACTION_UP + if (touchAction != 1) touchAction = 0; // TOUCH_ACTION_UP } } } // Handle ABS_MT_PRESSURE (0x3a) if available, as some devices use it for lift-off #ifndef ABS_MT_PRESSURE - #define ABS_MT_PRESSURE 0x3a + #define ABS_MT_PRESSURE 0x3a #endif - if ((event.code) == (ABS_MT_PRESSURE)) + if (event.code == ABS_MT_PRESSURE) { - if ((platform.touchSlot) < (MAX_TOUCH_POINTS)) + if (platform.touchSlot < MAX_TOUCH_POINTS) { if (event.value <= 0) // Pressure 0 means lift { @@ -2415,30 +2411,28 @@ static void PollMouseEvents(void) platform.touchPosition[platform.touchSlot].x = -1; platform.touchPosition[platform.touchSlot].y = -1; platform.touchId[platform.touchSlot] = -1; - if (touchAction != 1) touchAction = 0; // TOUCH_ACTION_UP + if (touchAction != 1) touchAction = 0; // TOUCH_ACTION_UP } } } // Touchscreen tap - if ((event.code) == (ABS_PRESSURE)) + if (event.code == ABS_PRESSURE) { int previousMouseLeftButtonState = platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT]; - if ((!event.value) && (previousMouseLeftButtonState)) + if (!event.value && previousMouseLeftButtonState) { platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 0; - - if (touchAction != 1) touchAction = 0; // TOUCH_ACTION_UP + if (touchAction != 1) touchAction = 0; // TOUCH_ACTION_UP } - if ((event.value) && (!previousMouseLeftButtonState)) + if (event.value && !previousMouseLeftButtonState) { platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 1; - touchAction = 1; // TOUCH_ACTION_DOWN + touchAction = 1; // TOUCH_ACTION_DOWN } } - } // Button parsing @@ -2453,16 +2447,15 @@ static void PollMouseEvents(void) { bool activateSlot0 = false; - if (event.code == BTN_LEFT) - { - activateSlot0 = true; // Mouse click always activates - } + if (event.code == BTN_LEFT) activateSlot0 = true; // Mouse click always activates else if (event.code == BTN_TOUCH) { bool anyActive = false; - for (int i = 0; i < MAX_TOUCH_POINTS; i++) { + for (int i = 0; i < MAX_TOUCH_POINTS; i++) + { if (platform.touchActive[i]) { anyActive = true; break; } } + if (!anyActive) activateSlot0 = true; } @@ -2472,7 +2465,7 @@ static void PollMouseEvents(void) platform.touchId[0] = 0; } - touchAction = 1; // TOUCH_ACTION_DOWN + touchAction = 1; // TOUCH_ACTION_DOWN } else { @@ -2483,10 +2476,8 @@ static void PollMouseEvents(void) platform.touchPosition[0].x = -1; platform.touchPosition[0].y = -1; } - else if (event.code == BTN_TOUCH) - { - platform.touchSlot = 0; // Reset slot index to 0 - } + else if (event.code == BTN_TOUCH) platform.touchSlot = 0; // Reset slot index to 0 + touchAction = 0; // TOUCH_ACTION_UP } } @@ -2503,10 +2494,12 @@ static void PollMouseEvents(void) if (!CORE.Input.Mouse.cursorLocked) { if (CORE.Input.Mouse.currentPosition.x < 0) CORE.Input.Mouse.currentPosition.x = 0; - if (CORE.Input.Mouse.currentPosition.x > CORE.Window.screen.width/CORE.Input.Mouse.scale.x) CORE.Input.Mouse.currentPosition.x = CORE.Window.screen.width/CORE.Input.Mouse.scale.x; + if (CORE.Input.Mouse.currentPosition.x > CORE.Window.screen.width/CORE.Input.Mouse.scale.x) + CORE.Input.Mouse.currentPosition.x = CORE.Window.screen.width/CORE.Input.Mouse.scale.x; if (CORE.Input.Mouse.currentPosition.y < 0) CORE.Input.Mouse.currentPosition.y = 0; - if (CORE.Input.Mouse.currentPosition.y > CORE.Window.screen.height/CORE.Input.Mouse.scale.y) CORE.Input.Mouse.currentPosition.y = CORE.Window.screen.height/CORE.Input.Mouse.scale.y; + if (CORE.Input.Mouse.currentPosition.y > CORE.Window.screen.height/CORE.Input.Mouse.scale.y) + CORE.Input.Mouse.currentPosition.y = CORE.Window.screen.height/CORE.Input.Mouse.scale.y; } // Repack active touches into CORE.Input.Touch @@ -2520,6 +2513,7 @@ static void PollMouseEvents(void) k++; } } + CORE.Input.Touch.pointCount = k; // Clear remaining slots @@ -2529,20 +2523,11 @@ static void PollMouseEvents(void) CORE.Input.Touch.position[i].y = -1; CORE.Input.Touch.pointId[i] = -1; } - - // Debug logging - static int lastTouchCount = 0; - if (CORE.Input.Touch.pointCount != lastTouchCount && (touchAction == 0 || touchAction == 1)) - { - TRACELOG(LOG_DEBUG, "TOUCH: Count changed from %d to %d (action: %d)", lastTouchCount, CORE.Input.Touch.pointCount, touchAction); - lastTouchCount = CORE.Input.Touch.pointCount; - } #if defined(SUPPORT_GESTURES_SYSTEM) if (touchAction > -1) { GestureEvent gestureEvent = { 0 }; - gestureEvent.touchAction = touchAction; gestureEvent.pointCount = CORE.Input.Touch.pointCount; @@ -2553,7 +2538,6 @@ static void PollMouseEvents(void) } ProcessGestureEvent(gestureEvent); - touchAction = -1; } #endif From 752373867741e044244df0e64695463598a4a742 Mon Sep 17 00:00:00 2001 From: Hamza RAHAL <77698738+hmz-rhl@users.noreply.github.com> Date: Tue, 30 Dec 2025 20:11:37 +0100 Subject: [PATCH 037/232] Add hilbert curve example (#5454) --- examples/shapes/shapes_hilbert_curve.c | 187 +++++++++++++++++++++++ examples/shapes/shapes_hilbert_curve.png | Bin 0 -> 15288 bytes 2 files changed, 187 insertions(+) create mode 100644 examples/shapes/shapes_hilbert_curve.c create mode 100644 examples/shapes/shapes_hilbert_curve.png diff --git a/examples/shapes/shapes_hilbert_curve.c b/examples/shapes/shapes_hilbert_curve.c new file mode 100644 index 000000000..1af263b34 --- /dev/null +++ b/examples/shapes/shapes_hilbert_curve.c @@ -0,0 +1,187 @@ +/******************************************************************************************* +* +* raylib [shapes] example - hilbert curve example +* +* Example complexity rating: [★★★☆] 3/4 +* +* Example originally created with raylib 5.6, last time updated with raylib 5.6 +* +* Example contributed by Hamza RAHAL (@hmz-rhl) +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2025 Hamza RAHAL (@hmz-rhl) +* +********************************************************************************************/ + + +#include "raylib.h" +#include "raymath.h" +#include +#include + +const int screenWidth = 800; + +const int screenHeight = 450; + +int order = 2; + +int total; + +int counter = 0; + +Vector2 *hilbertPath = 0; + +const Vector2 hilbertPoints[4] = +{ + [0] = { + .x = 0, + .y = 0 + }, + [1] = { + .x = 0, + .y = 1 + }, + [2] = { + .x = 1, + .y = 1 + }, + [3] = { + .x = 1, + .y = 0 + }, +}; + +//------------------------------------------------------------------------------------ +// Module Functions Declaration +//------------------------------------------------------------------------------------ +Vector2 Hilbert(int index); + +void InitHilbertPath(void); + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + + InitWindow(screenWidth, screenHeight, "raylib [shapes] example - hilbert curve example"); + + SetTargetFPS(60); // Set our game to run at 60 frames-per-second + + InitHilbertPath(); + + //-------------------------------------------------------------------------------------- + + // Main game loop + //-------------------------------------------------------------------------------------- + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + if ((IsKeyPressed(KEY_UP)) && (order < 8)) + { + counter = 0; + ++order; + InitHilbertPath(); + } + else if((IsKeyPressed(KEY_DOWN)) && (order > 1)) + { + counter = 0; + --order; + InitHilbertPath(); + } + //---------------------------------------------------------------------------------- + + // Draw + //-------------------------------------------------------------------------- + BeginDrawing(); + DrawText(TextFormat("(press UP or DOWN to change)\norder : %d", order), screenWidth/2 + 70, 25, 20, WHITE); + + if(counter < total) + { + ClearBackground(BLACK); + for (int i = 1; i <= counter; i++) + { + DrawLineV(hilbertPath[i], hilbertPath[i-1], ColorFromHSV(((float)i / total) * 360.0f, 1.0f, 1.0f)); + } + counter += 1; + } + EndDrawing(); + //-------------------------------------------------------------------------- + } + //-------------------------------------------------------------------------------------- + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + MemFree(hilbertPath); + //-------------------------------------------------------------------------------------- + return 0; +} + +//------------------------------------------------------------------------------------ +// Module Functions Definition +//------------------------------------------------------------------------------------ + +// calculate U positions +Vector2 Hilbert(int index) +{ + + int hiblertIndex = index&3; + Vector2 vect = hilbertPoints[hiblertIndex]; + float temp; + int len; + + for (int j = 1; j < order; j++) + { + index = index>>2; + hiblertIndex = index&3; + len = 1<L25DS|?4aZm(`)LLPMDx!!?6_5^(B9X^{>D>eiiCHMqA9n2hvy(|6d+v9> z^L^*uJxTQTTu0Y4(nAo0?(XL5gCJUF2!d8pb-+6d0=}z75QkWI*EPNo9|Qyn1VeRf zJ-&;8qpkT8r_ZY37~Q~FY$J;13->&O*&Qd%Da9E~x=6zXmEiid!o`|DB>o|s#kSY7 z%E((s7DnfM3TB*wSKE@sz-~qjJ+w5(2Li8Jq0QgJ`o*+yokn>)$ z#vFh})-PA!oESQ?<-!OxOuQ|%1#gKl zYm@4D%i^~9Lj7p-w3JYnB~G8p7L>)-(&zXzyi*uqHt)*k&DPs~$xS`m`m;<oWjORZHLiB+ky1)41HvpmEb-3Ttwi$t6pJR%;r7L>z(W^JxRROGiUGx~lJN=0{s$POl@ zoQyo)z)kn+%`y*nP4_*F+mA}N=eU@*<=)8;sLpT+J~~$~*6)cOul;0(Tz9?Wxu=H# z^Gcf45;q}9M0o<{SbVP%kA%hTx``BrH2JStTM+3tYvu2q^k<(elid!s2)q=y$?w;u zO-4=w;dcq(OQ!^$C|%XMp}EA}E`3&H#tPG$8(B}kGxs6x>eNjNW|@Gq)NEy;*Miv$u^?JQJlQ;t>On+i}qPtYIU1@G}x5#$Nn87Z_{k{39|YCCCU`pj+xSXRgj{iT@s|Q+<^Tj z-jK=P{D4q7q#P`9Iv2I0O2qU+?nlEkD{4 zW?@Gv0)$yaO{KJi*b_SRFGN6u8>ZmCj#HJIdfP#*HX#xnN49fn%u3wU9x%^xW!EMyi?2*D^TWYx&?KJ)X~)P1*GT zjsu`o-yD&DD>`iIoFPpJqnfkXZ2J>6ZQlAKISorcke4gqOX9(c$qtY=pCaX+dXX&Y z06ut!F?2N+cy;6Ej#$YUO-jScYjK~T$6_SgaZYFdH$AClcaQQ`BANNjPRE5<6raE0 zGl0np7P|}x{}*aHJK?v4_YA(G04R&?ZI_UIODGLeNFh3)v|$5M4fxS~(lZk;igu z=ua3CY@_I^#o9gA(xB?>MXASWQtaJ>YWvcvD_R#2rf(8sBO$i-w{<3PjN$2GRDYi7YR#G7!=H^;T`H#S3 z(^=f>mM4NLvyI~WX>vmoD``!ukj44?9^7(t0uJOLeGRjg_rGQ6E1_Ck(te07wn zkHLKZm`w(A@{Uwx;Az?^EMmgsH6QxH5Qxk}6d(#Oy%%x;ashH-;uIFDBhiCG6d(#O zJ8{Sb$OXs+LK7hhub?0>?C~E@Q$r9;5&O literal 0 HcmV?d00001 From 6dfaf9fe7edfee08eac7bfabcc3dabcc5147530d Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 30 Dec 2025 21:19:54 +0100 Subject: [PATCH 038/232] REVIEWED: example `shapes_hilbert_curve` #5454 Make it more didactic and dynamic, avoid global variables --- examples/shapes/shapes_hilbert_curve.c | 233 ++++++++++++----------- examples/shapes/shapes_hilbert_curve.png | Bin 15288 -> 16975 bytes 2 files changed, 121 insertions(+), 112 deletions(-) diff --git a/examples/shapes/shapes_hilbert_curve.c b/examples/shapes/shapes_hilbert_curve.c index 1af263b34..8ea03c7c5 100644 --- a/examples/shapes/shapes_hilbert_curve.c +++ b/examples/shapes/shapes_hilbert_curve.c @@ -6,7 +6,7 @@ * * Example originally created with raylib 5.6, last time updated with raylib 5.6 * -* Example contributed by Hamza RAHAL (@hmz-rhl) +* Example contributed by Hamza RAHAL (@hmz-rhl) and reviewed by Ramon Santamaria (@raysan5) * * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software @@ -17,48 +17,18 @@ #include "raylib.h" -#include "raymath.h" -#include -#include -const int screenWidth = 800; +#define RAYGUI_IMPLEMENTATION +#include "raygui.h" -const int screenHeight = 450; - -int order = 2; - -int total; - -int counter = 0; - -Vector2 *hilbertPath = 0; - -const Vector2 hilbertPoints[4] = -{ - [0] = { - .x = 0, - .y = 0 - }, - [1] = { - .x = 0, - .y = 1 - }, - [2] = { - .x = 1, - .y = 1 - }, - [3] = { - .x = 1, - .y = 0 - }, -}; +#include // Required for: calloc(), free() //------------------------------------------------------------------------------------ // Module Functions Declaration //------------------------------------------------------------------------------------ -Vector2 Hilbert(int index); - -void InitHilbertPath(void); +static Vector2 *LoadHilbertPath(int order, float size, int *strokeCount); +static void UnloadHilbertPath(Vector2 *hilbertPath); +static Vector2 ComputeHilbertStep(int order, int index); //------------------------------------------------------------------------------------ // Program main entry point @@ -67,13 +37,23 @@ int main(void) { // Initialization //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; - InitWindow(screenWidth, screenHeight, "raylib [shapes] example - hilbert curve example"); + InitWindow(screenWidth, screenHeight, "raylib [shapes] example - hilbert curve"); - SetTargetFPS(60); // Set our game to run at 60 frames-per-second - - InitHilbertPath(); + int order = 2; + float size = GetScreenHeight(); + int strokeCount = 0; + Vector2 *hilbertPath = LoadHilbertPath(order, size, &strokeCount); + int prevOrder = order; + int prevSize = (int)size; // NOTE: Size from slider is float but for comparison we use int + int counter = 0; + float thick = 2.0f; + bool animate = true; + + SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- // Main game loop @@ -82,34 +62,52 @@ int main(void) { // Update //---------------------------------------------------------------------------------- - if ((IsKeyPressed(KEY_UP)) && (order < 8)) + // Check if order or size have changed to regenerate + // NOTE: Size from slider is float but for comparison we use int + if ((prevOrder != order) || (prevSize != (int)size)) { - counter = 0; - ++order; - InitHilbertPath(); - } - else if((IsKeyPressed(KEY_DOWN)) && (order > 1)) - { - counter = 0; - --order; - InitHilbertPath(); + UnloadHilbertPath(hilbertPath); + hilbertPath = LoadHilbertPath(order, size, &strokeCount); + + if (animate) counter = 0; + else counter = strokeCount; + + prevOrder = order; + prevSize = size; } //---------------------------------------------------------------------------------- // Draw //-------------------------------------------------------------------------- BeginDrawing(); - DrawText(TextFormat("(press UP or DOWN to change)\norder : %d", order), screenWidth/2 + 70, 25, 20, WHITE); - if(counter < total) - { - ClearBackground(BLACK); - for (int i = 1; i <= counter; i++) + ClearBackground(RAYWHITE); + + if (counter < strokeCount) { - DrawLineV(hilbertPath[i], hilbertPath[i-1], ColorFromHSV(((float)i / total) * 360.0f, 1.0f, 1.0f)); + // Draw Hilbert path animation, one stroke every frame + for (int i = 1; i <= counter; i++) + { + DrawLineEx(hilbertPath[i], hilbertPath[i - 1], thick, ColorFromHSV(((float)i/strokeCount)*360.0f, 1.0f, 1.0f)); + } + + counter += 1; } - counter += 1; - } + else + { + // Draw full Hilbert path + for (int i = 1; i < strokeCount; i++) + { + DrawLineEx(hilbertPath[i], hilbertPath[i - 1], thick, ColorFromHSV(((float)i/strokeCount)*360.0f, 1.0f, 1.0f)); + } + } + + // Draw UI using raygui + GuiCheckBox((Rectangle){ 450, 50, 20, 20 }, "ANIMATE GENERATION ON CHANGE", &animate); + GuiSpinner((Rectangle){ 585, 100, 180, 30 }, "HILBERT CURVE ORDER: ", &order, 2, 8, false); + GuiSlider((Rectangle){ 524, 150, 240, 24 }, "THICKNESS: ", NULL, &thick, 1.0f, 10.0f); + GuiSlider((Rectangle){ 524, 190, 240, 24 }, "TOTAL SIZE: ", NULL, &size, 10.0f, GetScreenHeight()*1.5f); + EndDrawing(); //-------------------------------------------------------------------------- } @@ -117,8 +115,9 @@ int main(void) // De-Initialization //-------------------------------------------------------------------------------------- + UnloadHilbertPath(hilbertPath); + CloseWindow(); // Close window and OpenGL context - MemFree(hilbertPath); //-------------------------------------------------------------------------------------- return 0; } @@ -126,62 +125,72 @@ int main(void) //------------------------------------------------------------------------------------ // Module Functions Definition //------------------------------------------------------------------------------------ - -// calculate U positions -Vector2 Hilbert(int index) +// Load the whole Hilbert Path (including each U and their link) +static Vector2 *LoadHilbertPath(int order, float size, int *strokeCount) { + int N = 1 << order; + float len = size/N; + *strokeCount = N*N; - int hiblertIndex = index&3; - Vector2 vect = hilbertPoints[hiblertIndex]; - float temp; - int len; - - for (int j = 1; j < order; j++) + Vector2 *hilbertPath = (Vector2 *)RL_CALLOC(*strokeCount, sizeof(Vector2)); + + for (int i = 0; i < *strokeCount; i++) { - index = index>>2; - hiblertIndex = index&3; - len = 1<> 2; + hilbertIndex = index&3; + len = 1 << j; + + switch (hilbertIndex) + { + case 0: + { + temp = vect.x; + vect.x = vect.y; + vect.y = temp; + } break; + case 2: vect.x += len; + case 1: vect.y += len; break; + case 3: + { + temp = len - 1 - vect.x; + vect.x = 2*len - 1 - vect.y; + vect.y = temp; + } break; + default: break; + } + } + + return vect; } diff --git a/examples/shapes/shapes_hilbert_curve.png b/examples/shapes/shapes_hilbert_curve.png index cbb3d0753b154bac0cc160d140ab5c27e59dbddb..af99cbc493115d0de96f50ce8391f5f6aae85028 100644 GIT binary patch literal 16975 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 FKLA35BUk_c literal 15288 zcmeHOYfuwc6y6O88B8z^js}!REJC&87$JZKffz7?%0r~;pshg=BZ$=&5kVfYAru<~ zw8a6cg>L25DS|?4aZm(`)LLPMDx!!?6_5^(B9X^{>D>eiiCHMqA9n2hvy(|6d+v9> z^L^*uJxTQTTu0Y4(nAo0?(XL5gCJUF2!d8pb-+6d0=}z75QkWI*EPNo9|Qyn1VeRf zJ-&;8qpkT8r_ZY37~Q~FY$J;13->&O*&Qd%Da9E~x=6zXmEiid!o`|DB>o|s#kSY7 z%E((s7DnfM3TB*wSKE@sz-~qjJ+w5(2Li8Jq0QgJ`o*+yokn>)$ z#vFh})-PA!oESQ?<-!OxOuQ|%1#gKl zYm@4D%i^~9Lj7p-w3JYnB~G8p7L>)-(&zXzyi*uqHt)*k&DPs~$xS`m`m;<oWjORZHLiB+ky1)41HvpmEb-3Ttwi$t6pJR%;r7L>z(W^JxRROGiUGx~lJN=0{s$POl@ zoQyo)z)kn+%`y*nP4_*F+mA}N=eU@*<=)8;sLpT+J~~$~*6)cOul;0(Tz9?Wxu=H# z^Gcf45;q}9M0o<{SbVP%kA%hTx``BrH2JStTM+3tYvu2q^k<(elid!s2)q=y$?w;u zO-4=w;dcq(OQ!^$C|%XMp}EA}E`3&H#tPG$8(B}kGxs6x>eNjNW|@Gq)NEy;*Miv$u^?JQJlQ;t>On+i}qPtYIU1@G}x5#$Nn87Z_{k{39|YCCCU`pj+xSXRgj{iT@s|Q+<^Tj z-jK=P{D4q7q#P`9Iv2I0O2qU+?nlEkD{4 zW?@Gv0)$yaO{KJi*b_SRFGN6u8>ZmCj#HJIdfP#*HX#xnN49fn%u3wU9x%^xW!EMyi?2*D^TWYx&?KJ)X~)P1*GT zjsu`o-yD&DD>`iIoFPpJqnfkXZ2J>6ZQlAKISorcke4gqOX9(c$qtY=pCaX+dXX&Y z06ut!F?2N+cy;6Ej#$YUO-jScYjK~T$6_SgaZYFdH$AClcaQQ`BANNjPRE5<6raE0 zGl0np7P|}x{}*aHJK?v4_YA(G04R&?ZI_UIODGLeNFh3)v|$5M4fxS~(lZk;igu z=ua3CY@_I^#o9gA(xB?>MXASWQtaJ>YWvcvD_R#2rf(8sBO$i-w{<3PjN$2GRDYi7YR#G7!=H^;T`H#S3 z(^=f>mM4NLvyI~WX>vmoD``!ukj44?9^7(t0uJOLeGRjg_rGQ6E1_Ck(te07wn zkHLKZm`w(A@{Uwx;Az?^EMmgsH6QxH5Qxk}6d(#Oy%%x;ashH-;uIFDBhiCG6d(#O zJ8{Sb$OXs+LK7hhub?0>?C~E@Q$r9;5&O From ebf2f61425899735c48f70dc5737c2b03a137e80 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 30 Dec 2025 22:03:36 +0100 Subject: [PATCH 039/232] Delete core_input_keyboard_gamepad_test.c --- .../core/core_input_keyboard_gamepad_test.c | 173 ------------------ 1 file changed, 173 deletions(-) delete mode 100644 examples/core/core_input_keyboard_gamepad_test.c diff --git a/examples/core/core_input_keyboard_gamepad_test.c b/examples/core/core_input_keyboard_gamepad_test.c deleted file mode 100644 index d1f9106f7..000000000 --- a/examples/core/core_input_keyboard_gamepad_test.c +++ /dev/null @@ -1,173 +0,0 @@ -/******************************************************************************************* -* -* raylib [core] example - Keyboard vs Gamepad Input Test -* -* Example complexity rating: [★☆☆☆] 1/4 -* -* This example is a diagnostic tool to verify that keyboard input is not -* incorrectly detected as gamepad input on Android devices. -* -* Issue reference: https://github.com/raysan5/raylib/issues/5387 -* -* 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 raylib contributors -* -********************************************************************************************/ - -#include "raylib.h" - -//------------------------------------------------------------------------------------ -// Program main entry point -//------------------------------------------------------------------------------------ -int main(void) -{ - // Initialization - //-------------------------------------------------------------------------------------- - const int screenWidth = 800; - const int screenHeight = 450; - - InitWindow(screenWidth, screenHeight, "raylib [core] example - keyboard vs gamepad test"); - - Vector2 ballPosition = { (float)screenWidth/2, (float)screenHeight/2 }; - int lastKeyPressed = 0; - - SetTargetFPS(60); - //-------------------------------------------------------------------------------------- - - // Main game loop - while (!WindowShouldClose()) - { - // Update - //---------------------------------------------------------------------------------- - - // Track keyboard input - if (IsKeyDown(KEY_RIGHT)) ballPosition.x += 4.0f; - if (IsKeyDown(KEY_LEFT)) ballPosition.x -= 4.0f; - if (IsKeyDown(KEY_UP)) ballPosition.y -= 4.0f; - if (IsKeyDown(KEY_DOWN)) ballPosition.y += 4.0f; - - // Keep ball on screen - if (ballPosition.x < 25) ballPosition.x = 25; - if (ballPosition.x > screenWidth - 25) ballPosition.x = screenWidth - 25; - if (ballPosition.y < 25) ballPosition.y = 25; - if (ballPosition.y > screenHeight - 25) ballPosition.y = screenHeight - 25; - - // Track last key pressed - int key = GetKeyPressed(); - if (key != 0) lastKeyPressed = key; - //---------------------------------------------------------------------------------- - - // Draw - //---------------------------------------------------------------------------------- - BeginDrawing(); - - ClearBackground(RAYWHITE); - - // Title - DrawText("KEYBOARD vs GAMEPAD INPUT TEST", 180, 10, 20, DARKGRAY); - DrawText("Issue #5387: Keyboard detected as gamepad on some Android devices", 120, 35, 14, GRAY); - - // Divider - DrawLine(0, 60, screenWidth, 60, LIGHTGRAY); - - // Keyboard section - DrawText("KEYBOARD INPUT", 20, 75, 18, DARKBLUE); - DrawRectangle(20, 100, 360, 80, Fade(BLUE, 0.1f)); - - DrawText(TextFormat("Arrow Keys: [%s] [%s] [%s] [%s]", - IsKeyDown(KEY_UP) ? "UP" : "--", - IsKeyDown(KEY_DOWN) ? "DN" : "--", - IsKeyDown(KEY_LEFT) ? "LT" : "--", - IsKeyDown(KEY_RIGHT) ? "RT" : "--"), 30, 110, 16, BLACK); - - DrawText(TextFormat("Last Key Pressed: %d", lastKeyPressed), 30, 135, 16, DARKGRAY); - DrawText(TextFormat("Any Key Down: %s", (IsKeyDown(KEY_UP) || IsKeyDown(KEY_DOWN) || - IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_RIGHT)) ? "YES" : "NO"), 30, 155, 16, DARKGRAY); - - // Gamepad section - DrawText("GAMEPAD STATUS", 420, 75, 18, DARKGREEN); - DrawRectangle(420, 100, 360, 80, Fade(GREEN, 0.1f)); - - bool gamepadReady = IsGamepadAvailable(0); - DrawText(TextFormat("Gamepad 0 Available: %s", gamepadReady ? "YES" : "NO"), - 430, 110, 16, gamepadReady ? RED : DARKGREEN); - - if (gamepadReady) - { - DrawText(TextFormat("D-Pad: [%s] [%s] [%s] [%s]", - IsGamepadButtonDown(0, GAMEPAD_BUTTON_LEFT_FACE_UP) ? "UP" : "--", - IsGamepadButtonDown(0, GAMEPAD_BUTTON_LEFT_FACE_DOWN) ? "DN" : "--", - IsGamepadButtonDown(0, GAMEPAD_BUTTON_LEFT_FACE_LEFT) ? "LT" : "--", - IsGamepadButtonDown(0, GAMEPAD_BUTTON_LEFT_FACE_RIGHT) ? "RT" : "--"), - 430, 135, 16, RED); - - DrawText(TextFormat("Gamepad Name: %.20s", GetGamepadName(0)), 430, 155, 14, DARKGRAY); - } - else - { - DrawText("No gamepad detected", 430, 135, 16, DARKGREEN); - } - - // Divider - DrawLine(0, 190, screenWidth, 190, LIGHTGRAY); - - // Test result section - DrawText("TEST RESULT", 20, 200, 18, MAROON); - - bool keyboardActive = IsKeyDown(KEY_UP) || IsKeyDown(KEY_DOWN) || - IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_RIGHT); - - if (keyboardActive && gamepadReady) - { - // BUG DETECTED: Keyboard is triggering gamepad detection - DrawRectangle(20, 225, 760, 50, Fade(RED, 0.3f)); - DrawText("BUG DETECTED: Keyboard input is being detected as gamepad!", 30, 235, 18, RED); - DrawText("The fix for issue #5387 may not be working correctly.", 30, 258, 14, DARKGRAY); - } - else if (keyboardActive && !gamepadReady) - { - // CORRECT: Keyboard works without triggering gamepad - DrawRectangle(20, 225, 760, 50, Fade(GREEN, 0.3f)); - DrawText("PASS: Keyboard input detected correctly (no phantom gamepad)", 30, 235, 18, DARKGREEN); - DrawText("Issue #5387 fix is working as expected.", 30, 258, 14, DARKGRAY); - } - else if (!keyboardActive && gamepadReady) - { - // Gamepad is connected (might be real or might be bug on idle) - DrawRectangle(20, 225, 760, 50, Fade(ORANGE, 0.3f)); - DrawText("INFO: Gamepad detected - press keyboard keys to test", 30, 235, 18, ORANGE); - DrawText("If gamepad stays active while pressing keyboard = BUG", 30, 258, 14, DARKGRAY); - } - else - { - // Idle state - DrawRectangle(20, 225, 760, 50, Fade(GRAY, 0.1f)); - DrawText("WAITING: Press arrow keys to test keyboard input", 30, 235, 18, GRAY); - DrawText("Gamepad should NOT become available when pressing keyboard keys", 30, 258, 14, DARKGRAY); - } - - // Ball controlled by keyboard - DrawText("Ball Control (Arrow Keys):", 20, 295, 16, DARKGRAY); - DrawCircleV(ballPosition, 25, MAROON); - DrawCircleLines((int)ballPosition.x, (int)ballPosition.y, 25, DARKGRAY); - - // Instructions - DrawRectangle(0, screenHeight - 45, screenWidth, 45, Fade(BLACK, 0.05f)); - DrawText("Instructions: Press keyboard arrow keys - the ball should move and gamepad should stay 'NO'", - 20, screenHeight - 35, 14, DARKGRAY); - DrawText("If gamepad becomes 'YES' while pressing keyboard = issue #5387 is NOT fixed", - 20, screenHeight - 18, 14, DARKGRAY); - - EndDrawing(); - //---------------------------------------------------------------------------------- - } - - // De-Initialization - //-------------------------------------------------------------------------------------- - CloseWindow(); - //-------------------------------------------------------------------------------------- - - return 0; -} From 6e70dece560e344089b11597efe97847ce435310 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 30 Dec 2025 22:05:37 +0100 Subject: [PATCH 040/232] Update minshell.html --- src/minshell.html | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/minshell.html b/src/minshell.html index ec7158841..6e2f137eb 100644 --- a/src/minshell.html +++ b/src/minshell.html @@ -54,6 +54,12 @@ // 'Ask where to save each file before downloading' - which you can set true/false. // If you enable this setting it would always ask you and bring the SaveAsDialog saveAs(blob, localFSname); + + // Alternative implementation to avoid FileSaver.js + //const link = document.createElement("a"); + //link.href = URL.createObjectURL(blob); + //link.download = localFSname; + //link.click(); } From fa1d4eb7fa01a37df79e7a0643cbb0f590e4dd84 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 30 Dec 2025 22:06:05 +0100 Subject: [PATCH 041/232] Update shapes_hilbert_curve.c --- examples/shapes/shapes_hilbert_curve.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/shapes/shapes_hilbert_curve.c b/examples/shapes/shapes_hilbert_curve.c index 8ea03c7c5..3f368ca03 100644 --- a/examples/shapes/shapes_hilbert_curve.c +++ b/examples/shapes/shapes_hilbert_curve.c @@ -1,6 +1,6 @@ /******************************************************************************************* * -* raylib [shapes] example - hilbert curve example +* raylib [shapes] example - hilbert curve * * Example complexity rating: [★★★☆] 3/4 * From f260f5fdd019a1eacab7f2d5edd91a9c2eb6a7a2 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 30 Dec 2025 22:06:18 +0100 Subject: [PATCH 042/232] Update Makefile --- examples/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/Makefile b/examples/Makefile index bc2afbb3c..9983d8705 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -575,6 +575,7 @@ SHAPES = \ shapes/shapes_easings_box \ shapes/shapes_easings_rectangles \ shapes/shapes_following_eyes \ + shapes/shapes_hilbert_curve \ shapes/shapes_kaleidoscope \ shapes/shapes_lines_bezier \ shapes/shapes_lines_drawing \ From 695f3535333594b4cb244e4ac1537e2affbe13d1 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 30 Dec 2025 22:07:23 +0100 Subject: [PATCH 043/232] Update Makefile.Web --- examples/Makefile.Web | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/Makefile.Web b/examples/Makefile.Web index f36113f15..2e74bd211 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -563,6 +563,7 @@ SHAPES = \ shapes/shapes_easings_box \ shapes/shapes_easings_rectangles \ shapes/shapes_following_eyes \ + shapes/shapes_hilbert_curve \ shapes/shapes_kaleidoscope \ shapes/shapes_lines_bezier \ shapes/shapes_lines_drawing \ @@ -914,6 +915,9 @@ shapes/shapes_easings_rectangles: shapes/shapes_easings_rectangles.c shapes/shapes_following_eyes: shapes/shapes_following_eyes.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) +shapes/shapes_hilbert_curve: shapes/shapes_hilbert_curve.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + shapes/shapes_kaleidoscope: shapes/shapes_kaleidoscope.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) From 4054fc42f382ee4f161e953fbee30ddbee03d6cf Mon Sep 17 00:00:00 2001 From: RANDRIA Luca Date: Wed, 31 Dec 2025 00:09:20 +0300 Subject: [PATCH 044/232] Remove stdio.h unused header (#5456) --- examples/text/text_words_alignment.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/text/text_words_alignment.c b/examples/text/text_words_alignment.c index a558d5b11..dbd9cd03e 100644 --- a/examples/text/text_words_alignment.c +++ b/examples/text/text_words_alignment.c @@ -19,8 +19,6 @@ #include "raymath.h" // Required for: Lerp() -#include - typedef enum TextAlignment { TEXT_ALIGN_LEFT = 0, TEXT_ALIGN_TOP = 0, From 0c3e10b262127a162841df2d61b64143c525c2f7 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 30 Dec 2025 22:49:43 +0100 Subject: [PATCH 045/232] REVIEWED: `FileExists()`, using macro --- src/rcore.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/rcore.c b/src/rcore.c index ea38300f1..af761cbb2 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -205,11 +205,13 @@ #define GETCWD _getcwd // NOTE: MSDN recommends not to use getcwd(), chdir() #define CHDIR _chdir #define MKDIR(dir) _mkdir(dir) + #define ACCESS(fn) _access(fn, 0) #else #include // Required for: getch(), chdir(), mkdir(), access() #define GETCWD getcwd #define CHDIR chdir #define MKDIR(dir) mkdir(dir, 0777) + #define ACCESS(fn) access(fn, F_OK) #endif //---------------------------------------------------------------------------------- @@ -1972,11 +1974,7 @@ bool FileExists(const char *fileName) { bool result = false; -#if defined(_WIN32) - if (_access(fileName, 0) != -1) result = true; -#else - if (access(fileName, F_OK) != -1) result = true; -#endif + if (ACCESS(fileName) != -1) result = true; // NOTE: Alternatively, stat() can be used instead of access() //#include From 9b183e0c5e5786a8a92e34e6a8f941586c12c39d Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 30 Dec 2025 23:21:10 +0100 Subject: [PATCH 046/232] REXM: Update examples and reports --- examples/Makefile.Web | 12 +- examples/README.md | 7 +- .../examples/shapes_hilbert_curve.vcxproj | 569 ++++++++++++++++++ projects/VS2022/raylib.sln | 29 +- tools/rexm/reports/examples_issues.md | 13 +- tools/rexm/reports/examples_validation.md | 17 +- 6 files changed, 622 insertions(+), 25 deletions(-) create mode 100644 projects/VS2022/examples/shapes_hilbert_curve.vcxproj diff --git a/examples/Makefile.Web b/examples/Makefile.Web index 2e74bd211..5718088ac 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -1371,15 +1371,15 @@ shaders/shaders_fog_rendering: shaders/shaders_fog_rendering.c 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/r_pentomino.png@resources/game_of_life/r_pentomino.png \ --preload-file shaders/resources/game_of_life/glider.png@resources/game_of_life/glider.png \ - --preload-file shaders/resources/game_of_life/glider_gun.png@resources/game_of_life/glider_gun.png \ + --preload-file shaders/resources/game_of_life/acorn.png@resources/game_of_life/acorn.png \ + --preload-file shaders/resources/game_of_life/spaceships.png@resources/game_of_life/spaceships.png \ + --preload-file shaders/resources/game_of_life/still_lifes.png@resources/game_of_life/still_lifes.png \ --preload-file shaders/resources/game_of_life/oscillators.png@resources/game_of_life/oscillators.png \ --preload-file shaders/resources/game_of_life/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 + --preload-file shaders/resources/game_of_life/glider_gun.png@resources/game_of_life/glider_gun.png \ + --preload-file shaders/resources/game_of_life/breeder.png@resources/game_of_life/breeder.png shaders/shaders_hot_reloading: shaders/shaders_hot_reloading.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ diff --git a/examples/README.md b/examples/README.md index 367bfa0ab..d9b03669d 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: 205] +## EXAMPLES COLLECTION [TOTAL: 206] ### category: core [47] @@ -69,11 +69,11 @@ Examples using raylib [core](../src/rcore.c) module platform functionality: wind | [core_directory_files](core/core_directory_files.c) | core_directory_files | ⭐☆☆☆ | 5.5 | 5.6 | [Hugo ARNAL](https://github.com/hugoarnal) | | [core_highdpi_testbed](core/core_highdpi_testbed.c) | core_highdpi_testbed | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) | | [core_screen_recording](core/core_screen_recording.c) | core_screen_recording | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) | -| [core_clipboard_text](core/core_clipboard_text.c) | core_clipboard_text | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ananth S](https://github.com/Ananth1839) | +| [core_clipboard_text](core/core_clipboard_text.c) | core_clipboard_text | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Ananth S](https://github.com/Ananth1839) | | [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 [38] +### category: shapes [39] Examples using raylib shapes drawing functionality, provided by raylib [shapes](../src/rshapes.c) module. @@ -117,6 +117,7 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes]( | [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) | +| [shapes_hilbert_curve](shapes/shapes_hilbert_curve.c) | shapes_hilbert_curve | ⭐⭐⭐☆ | 5.6 | 5.6 | [Hamza RAHAL](https://github.com/hmz-rhl) | ### category: textures [29] diff --git a/projects/VS2022/examples/shapes_hilbert_curve.vcxproj b/projects/VS2022/examples/shapes_hilbert_curve.vcxproj new file mode 100644 index 000000000..8fcbfab5f --- /dev/null +++ b/projects/VS2022/examples/shapes_hilbert_curve.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 + + + + {DC163251-16C3-4B72-B965-ACDBA0F02BD1} + Win32Proj + shapes_hilbert_curve + 10.0 + shapes_hilbert_curve + + + + 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/raylib.sln b/projects/VS2022/raylib.sln index 50fef1cf5..df2633843 100644 --- a/projects/VS2022/raylib.sln +++ b/projects/VS2022/raylib.sln @@ -431,6 +431,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_strings_management", " EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_cellular_automata", "examples\textures_cellular_automata.vcxproj", "{0A0FC982-6E31-401F-BA77-3C5E8AB02C68}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_hilbert_curve", "examples\shapes_hilbert_curve.vcxproj", "{DC163251-16C3-4B72-B965-ACDBA0F02BD1}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug.DLL|ARM64 = Debug.DLL|ARM64 @@ -5365,6 +5367,30 @@ Global {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 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|ARM64.Build.0 = Debug|ARM64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|x64.ActiveCfg = Debug|x64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|x64.Build.0 = Debug|x64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|x86.ActiveCfg = Debug|Win32 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|x86.Build.0 = Debug|Win32 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|ARM64.ActiveCfg = Release|ARM64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|ARM64.Build.0 = Release|ARM64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|x64.ActiveCfg = Release|x64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|x64.Build.0 = Release|x64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|x86.ActiveCfg = Release|Win32 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -5532,7 +5558,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} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {278D8859-20B1-428F-8448-064F46E1F021} {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} @@ -5582,6 +5608,7 @@ Global {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} + {DC163251-16C3-4B72-B965-ACDBA0F02BD1} = {278D8859-20B1-428F-8448-064F46E1F021} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29} diff --git a/tools/rexm/reports/examples_issues.md b/tools/rexm/reports/examples_issues.md index 14e7a61c5..081170806 100644 --- a/tools/rexm/reports/examples_issues.md +++ b/tools/rexm/reports/examples_issues.md @@ -21,10 +21,9 @@ Example elements validated: | **EXAMPLE NAME** | [C] | [CAT]| [INFO]|[PNG]|[WPNG]| [RES]| [MK] |[MKWEB]| [VCX]| [SOL]|[RDME]|[JS] | [WOUT]|[WMETA]| |:---------------------------------|:---:|:----:|:-----:|:---:|:----:|:----:|:----:|:-----:|:----:|:----:|:----:|:---:|:-----:|:-----:| | core_highdpi_testbed | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shaders_game_of_life | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | -| 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/reports/examples_validation.md b/tools/rexm/reports/examples_validation.md index 45c195415..6770f3c37 100644 --- a/tools/rexm/reports/examples_validation.md +++ b/tools/rexm/reports/examples_validation.md @@ -56,7 +56,7 @@ Example elements validated: | core_smooth_pixelperfect | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_random_sequence | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_automation_events | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| core_high_dpi | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| core_highdpi_demo | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_render_texture | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_undo_redo | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_viewport_scaling | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | @@ -209,7 +209,7 @@ Example elements validated: | shaders_lightmap_rendering | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_rounded_rectangle | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_depth_rendering | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shaders_game_of_life | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | +| shaders_game_of_life | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | audio_module_playing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | audio_music_stream | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | audio_raw_stream | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | @@ -219,9 +219,10 @@ 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 | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_hilbert_curve | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | From e534f14419b2c6ab67f4b3a99102d2bb3231f5cb Mon Sep 17 00:00:00 2001 From: CosmosShell Date: Wed, 31 Dec 2025 00:05:39 -0800 Subject: [PATCH 047/232] Fix window width calculation by adding wOffset (#5457) --- src/external/RGFW.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/external/RGFW.h b/src/external/RGFW.h index 7205bf9d8..0ab3858cf 100644 --- a/src/external/RGFW.h +++ b/src/external/RGFW.h @@ -6522,8 +6522,8 @@ LRESULT CALLBACK WndProcW(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) if (win->src.aspectRatio.w != 0 && win->src.aspectRatio.h != 0) { double aspectRatio = (double)win->src.aspectRatio.w / win->src.aspectRatio.h; - int width = windowRect.right - windowRect.left; - int height = windowRect.bottom - windowRect.top; + int width = (windowRect.right - windowRect.left) - win->src.wOffset; + int height = (windowRect.bottom - windowRect.top) - win->src.hOffset; int newHeight = (int)(width / aspectRatio); int newWidth = (int)(height * aspectRatio); @@ -6968,6 +6968,7 @@ RGFW_window* RGFW_createWindowPtr(const char* name, RGFW_rect rect, RGFW_windowF DestroyWindow(dummyWin); win->src.hOffset = (u32)(windowRect.bottom - windowRect.top) - (u32)(clientRect.bottom - clientRect.top); + win->src.wOffset = (u32)(windowRect.right - windowRect.left) - (u32)(clientRect.right - clientRect.left); win->src.window = CreateWindowW(Class.lpszClassName, (wchar_t*)wide_name, window_style, win->r.x, win->r.y, win->r.w, win->r.h + (i32)win->src.hOffset, 0, 0, inh, 0); SetPropW(win->src.window, L"RGFW", win); RGFW_window_resize(win, RGFW_AREA(win->r.w, win->r.h)); /* so WM_GETMINMAXINFO gets called again */ From 4af95a3a84129c4dc83da45f83ebbb05936e9d4a Mon Sep 17 00:00:00 2001 From: Alvin De Cruz Date: Wed, 31 Dec 2025 17:33:17 +0800 Subject: [PATCH 048/232] Use eglGetPlatformDisplayEXT on DRM platform for Mali compatibility (#5446) --- src/platforms/rcore_drm.c | 50 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index 103d81975..ff0118ac5 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -89,6 +89,10 @@ #define EGL_OPENGL_ES3_BIT 0x40 #endif +#ifndef EGL_PLATFORM_GBM_KHR + #define EGL_PLATFORM_GBM_KHR 0x31D7 +#endif + //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- @@ -1416,7 +1420,30 @@ int InitPlatform(void) EGLint numConfigs = 0; // Get an EGL device connection - platform.device = eglGetDisplay((EGLNativeDisplayType)platform.gbmDevice); + // Try eglGetPlatformDisplayEXT for better compatibility with some drivers (e.g. Mali Midgard) + // REF: https://github.com/raysan5/raylib/issues/5378 + platform.device = EGL_NO_DISPLAY; + const char *eglClientExtensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); + + if (eglClientExtensions != NULL) + { + if (strstr(eglClientExtensions, "EGL_EXT_platform_base") != NULL) + { + PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = + (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT"); + + if (eglGetPlatformDisplayEXT != NULL) + { + platform.device = eglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_KHR, platform.gbmDevice, NULL); + } + } + } + + if (platform.device == EGL_NO_DISPLAY) + { + platform.device = eglGetDisplay((EGLNativeDisplayType)platform.gbmDevice); + } + if (platform.device == EGL_NO_DISPLAY) { TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device"); @@ -1496,8 +1523,25 @@ int InitPlatform(void) } // Create an EGL window surface - platform.surface = eglCreateWindowSurface(platform.device, platform.config, (EGLNativeWindowType)platform.gbmSurface, NULL); - if (EGL_NO_SURFACE == platform.surface) + platform.surface = EGL_NO_SURFACE; + + if ((eglClientExtensions != NULL) && (strstr(eglClientExtensions, "EGL_EXT_platform_base") != NULL)) + { + PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC eglCreatePlatformWindowSurfaceEXT = + (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT"); + + if (eglCreatePlatformWindowSurfaceEXT != NULL) + { + platform.surface = eglCreatePlatformWindowSurfaceEXT(platform.device, platform.config, platform.gbmSurface, NULL); + } + } + + if (platform.surface == EGL_NO_SURFACE) + { + platform.surface = eglCreateWindowSurface(platform.device, platform.config, (EGLNativeWindowType)platform.gbmSurface, NULL); + } + + if (platform.surface == EGL_NO_SURFACE) { TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL window surface: 0x%04x", eglGetError()); return -1; From 25ce6465d580652f1149e8698f14b60339230093 Mon Sep 17 00:00:00 2001 From: McDubh <103212704+mcdubhghlas@users.noreply.github.com> Date: Wed, 31 Dec 2025 03:58:58 -0600 Subject: [PATCH 049/232] Added SSE to MatrixMultiply. (#5427) --- src/raymath.h | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/src/raymath.h b/src/raymath.h index 32dfd2b0a..67756a6d0 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -170,6 +170,11 @@ typedef struct float16 { #include // Required for: sinf(), cosf(), tan(), atan2f(), sqrtf(), floor(), fminf(), fmaxf(), fabsf() +#if defined(__SSE__) || defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 1) + #include + #define RAYMATH_SSE_ENABLED +#endif + //---------------------------------------------------------------------------------- // Module Functions Definition - Utils math //---------------------------------------------------------------------------------- @@ -1647,7 +1652,63 @@ RMAPI Matrix MatrixSubtract(Matrix left, Matrix right) RMAPI Matrix MatrixMultiply(Matrix left, Matrix right) { Matrix result = { 0 }; +#ifdef RAYMATH_SSE_ENABLED + // Load left side and right side. + __m128 c0 = _mm_set_ps(right.m12, right.m8, right.m4, right.m0); + __m128 c1 = _mm_set_ps(right.m13, right.m9, right.m5, right.m1); + __m128 c2 = _mm_set_ps(right.m14, right.m10, right.m6, right.m2); + __m128 c3 = _mm_set_ps(right.m15, right.m11, right.m7, right.m3); + // Transpose so c0..c3 become *rows* of the right matrix in semantic order. + _MM_TRANSPOSE4_PS(c0, c1, c2, c3); + __m128 row; + float tmp[4]; + + // Row 0 of result: [m0, m1, m2, m3] + row = _mm_mul_ps(_mm_set1_ps(left.m0), c0); + row = _mm_add_ps(row, _mm_mul_ps(_mm_set1_ps(left.m1), c1)); + row = _mm_add_ps(row, _mm_mul_ps(_mm_set1_ps(left.m2), c2)); + row = _mm_add_ps(row, _mm_mul_ps(_mm_set1_ps(left.m3), c3)); + _mm_storeu_ps(tmp, row); + result.m0 = tmp[0]; + result.m1 = tmp[1]; + result.m2 = tmp[2]; + result.m3 = tmp[3]; + + // Row 1 of result: [m4, m5, m6, m7] + row = _mm_mul_ps(_mm_set1_ps(left.m4), c0); + row = _mm_add_ps(row, _mm_mul_ps(_mm_set1_ps(left.m5), c1)); + row = _mm_add_ps(row, _mm_mul_ps(_mm_set1_ps(left.m6), c2)); + row = _mm_add_ps(row, _mm_mul_ps(_mm_set1_ps(left.m7), c3)); + _mm_storeu_ps(tmp, row); + result.m4 = tmp[0]; + result.m5 = tmp[1]; + result.m6 = tmp[2]; + result.m7 = tmp[3]; + + // Row 2 of result: [m8, m9, m10, m11] + row = _mm_mul_ps(_mm_set1_ps(left.m8), c0); + row = _mm_add_ps(row, _mm_mul_ps(_mm_set1_ps(left.m9), c1)); + row = _mm_add_ps(row, _mm_mul_ps(_mm_set1_ps(left.m10), c2)); + row = _mm_add_ps(row, _mm_mul_ps(_mm_set1_ps(left.m11), c3)); + _mm_storeu_ps(tmp, row); + result.m8 = tmp[0]; + result.m9 = tmp[1]; + result.m10 = tmp[2]; + result.m11 = tmp[3]; + + // Row 3 of result: [m12, m13, m14, m15] + row = _mm_mul_ps(_mm_set1_ps(left.m12), c0); + row = _mm_add_ps(row, _mm_mul_ps(_mm_set1_ps(left.m13), c1)); + row = _mm_add_ps(row, _mm_mul_ps(_mm_set1_ps(left.m14), c2)); + row = _mm_add_ps(row, _mm_mul_ps(_mm_set1_ps(left.m15), c3)); + _mm_storeu_ps(tmp, row); + result.m12 = tmp[0]; + result.m13 = tmp[1]; + result.m14 = tmp[2]; + result.m15 = tmp[3]; + +#else result.m0 = left.m0*right.m0 + left.m1*right.m4 + left.m2*right.m8 + left.m3*right.m12; result.m1 = left.m0*right.m1 + left.m1*right.m5 + left.m2*right.m9 + left.m3*right.m13; result.m2 = left.m0*right.m2 + left.m1*right.m6 + left.m2*right.m10 + left.m3*right.m14; @@ -1664,7 +1725,7 @@ RMAPI Matrix MatrixMultiply(Matrix left, Matrix right) result.m13 = left.m12*right.m1 + left.m13*right.m5 + left.m14*right.m9 + left.m15*right.m13; result.m14 = left.m12*right.m2 + left.m13*right.m6 + left.m14*right.m10 + left.m15*right.m14; result.m15 = left.m12*right.m3 + left.m13*right.m7 + left.m14*right.m11 + left.m15*right.m15; - +#endif return result; } From 02cca28b5f1b9acab403bfdad09605426bb18a23 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 31 Dec 2025 11:08:10 +0100 Subject: [PATCH 050/232] REVIEWED: `eglGetPlatformDisplay()` usage --- src/platforms/rcore_drm.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index ff0118ac5..c5b74b956 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -1420,30 +1420,26 @@ int InitPlatform(void) EGLint numConfigs = 0; // Get an EGL device connection - // Try eglGetPlatformDisplayEXT for better compatibility with some drivers (e.g. Mali Midgard) - // REF: https://github.com/raysan5/raylib/issues/5378 + // NOTE: eglGetPlatformDisplay() is preferred over eglGetDisplay() legacy call platform.device = EGL_NO_DISPLAY; +#if defined(EGL_VERSION_1_5) + platform.device = eglGetPlatformDisplay(EGL_PLATFORM_GBM_KHR, platform.gbmDevice, NULL); +#else + // Check if extension is available for eglGetPlatformDisplayEXT() + // NOTE: Better compatibility with some drivers (e.g. Mali Midgard) const char *eglClientExtensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); - if (eglClientExtensions != NULL) { if (strstr(eglClientExtensions, "EGL_EXT_platform_base") != NULL) { - PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = - (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT"); - - if (eglGetPlatformDisplayEXT != NULL) - { - platform.device = eglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_KHR, platform.gbmDevice, NULL); - } + PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT"); + if (eglGetPlatformDisplayEXT != NULL) platform.device = eglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_KHR, platform.gbmDevice, NULL); } } - if (platform.device == EGL_NO_DISPLAY) - { - platform.device = eglGetDisplay((EGLNativeDisplayType)platform.gbmDevice); - } - + // In case extension not found or display could not be retrieved, try useing legacy version + if (platform.device == EGL_NO_DISPLAY) platform.device = eglGetDisplay((EGLNativeDisplayType)platform.gbmDevice); +#endif if (platform.device == EGL_NO_DISPLAY) { TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device"); From 66755da4c8f6ae2f2be9accc1563077756f03dc7 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 31 Dec 2025 11:08:17 +0100 Subject: [PATCH 051/232] REVIEWED: `eglGetPlatformDisplay()` usage --- src/platforms/rcore_android.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/platforms/rcore_android.c b/src/platforms/rcore_android.c index cc012c4fe..e1dba72c8 100644 --- a/src/platforms/rcore_android.c +++ b/src/platforms/rcore_android.c @@ -919,7 +919,27 @@ static int InitGraphicsDevice(void) EGLint numConfigs = 0; // Get an EGL device connection - platform.device = eglGetDisplay(EGL_DEFAULT_DISPLAY); + // NOTE: eglGetPlatformDisplay() is preferred over eglGetDisplay() legacy call + platform.device = EGL_NO_DISPLAY; +#if defined(EGL_VERSION_1_5) + platform.device = eglGetPlatformDisplay(EGL_PLATFORM_GBM_KHR, platform.gbmDevice, NULL); +#else + // Check if extension is available for eglGetPlatformDisplayEXT() + // NOTE: Better compatibility with some drivers (e.g. Mali Midgard) + const char *eglClientExtensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); + if (eglClientExtensions != NULL) + { + if (strstr(eglClientExtensions, "EGL_EXT_platform_base") != NULL) + { + PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT"); + if (eglGetPlatformDisplayEXT != NULL) platform.device = eglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_KHR, platform.gbmDevice, NULL); + } + } + + // In case extension not found or display could not be retrieved, try useing legacy version + if (platform.device == EGL_NO_DISPLAY) platform.device = eglGetDisplay(EGL_DEFAULT_DISPLAY); +#endif + if (platform.device == EGL_NO_DISPLAY) { TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device"); From c124f2552bbdcd9030e57f22283f5dd6570bf484 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 31 Dec 2025 11:22:26 +0100 Subject: [PATCH 052/232] REVIEWED: SIMD instrinsics must be explicitly enabled by developer, only SSE supported at the moment #5316 --- src/raymath.h | 60 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/src/raymath.h b/src/raymath.h index 67756a6d0..8d5b1b2a9 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -19,17 +19,22 @@ * * CONFIGURATION: * #define RAYMATH_IMPLEMENTATION -* Generates the implementation of the library into the included file. +* Generates the implementation of the library into the included file * If not defined, the library is in header only mode and can be included in other headers -* or source files without problems. But only ONE file should hold the implementation. +* or source files without problems. But only ONE file should hold the implementation * * #define RAYMATH_STATIC_INLINE -* Define static inline functions code, so #include header suffices for use. -* This may use up lots of memory. +* Define static inline functions code, so #include header suffices for use +* This may use up lots of memory * * #define RAYMATH_DISABLE_CPP_OPERATORS * Disables C++ operator overloads for raymath types. * +* #define RAYMATH_USE_SIMD_INTRINSICS +* Try to enable SIMD intrinsics for MatrixMultiply() +* Note that users enabling it must be aware of the target platform where application will +* run to support the selected SIMD intrinsic, for now, only SSE is supported +* * LICENSE: zlib/libpng * * Copyright (c) 2015-2025 Ramon Santamaria (@raysan5) @@ -79,7 +84,6 @@ #endif #endif - //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- @@ -170,9 +174,35 @@ typedef struct float16 { #include // Required for: sinf(), cosf(), tan(), atan2f(), sqrtf(), floor(), fminf(), fmaxf(), fabsf() -#if defined(__SSE__) || defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 1) - #include - #define RAYMATH_SSE_ENABLED +#if defined(RAYMATH_USE_SIMD_INTRINSICS) + // SIMD is used on the most costly raymath function MatrixMultiply() + // NOTE: Only SSE intrinsics support implemented + // TODO: Consider support for other SIMD instrinsics + /* + #if defined(__SSE4_2__) + #define SW_HAS_SSE42 + #include + #elif defined(__SSE4_1__) + #define SW_HAS_SSE41 + #include + #elif defined(__SSSE3__) + #define SW_HAS_SSSE3 + #include + #elif defined(__SSE3__) + #define SW_HAS_SSE3 + #include + #elif defined(__SSE2__) || (defined(_M_AMD64) || defined(_M_X64)) // SSE2 x64 + #define SW_HAS_SSE2 + #include + #elif defined(__SSE__) + #define SW_HAS_SSE + #include + #endif + */ + #if defined(__SSE__) || defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP >= 1)) + #include + #define RAYMATH_SSE_ENABLED + #endif #endif //---------------------------------------------------------------------------------- @@ -1652,18 +1682,20 @@ RMAPI Matrix MatrixSubtract(Matrix left, Matrix right) RMAPI Matrix MatrixMultiply(Matrix left, Matrix right) { Matrix result = { 0 }; -#ifdef RAYMATH_SSE_ENABLED - // Load left side and right side. + +#if defined(RAYMATH_SSE_ENABLED) + // Load left side and right side __m128 c0 = _mm_set_ps(right.m12, right.m8, right.m4, right.m0); __m128 c1 = _mm_set_ps(right.m13, right.m9, right.m5, right.m1); __m128 c2 = _mm_set_ps(right.m14, right.m10, right.m6, right.m2); __m128 c3 = _mm_set_ps(right.m15, right.m11, right.m7, right.m3); - // Transpose so c0..c3 become *rows* of the right matrix in semantic order. + + // Transpose so c0..c3 become *rows* of the right matrix in semantic order _MM_TRANSPOSE4_PS(c0, c1, c2, c3); + float tmp[4] = { 0 }; __m128 row; - float tmp[4]; - + // Row 0 of result: [m0, m1, m2, m3] row = _mm_mul_ps(_mm_set1_ps(left.m0), c0); row = _mm_add_ps(row, _mm_mul_ps(_mm_set1_ps(left.m1), c1)); @@ -1707,7 +1739,6 @@ RMAPI Matrix MatrixMultiply(Matrix left, Matrix right) result.m13 = tmp[1]; result.m14 = tmp[2]; result.m15 = tmp[3]; - #else result.m0 = left.m0*right.m0 + left.m1*right.m4 + left.m2*right.m8 + left.m3*right.m12; result.m1 = left.m0*right.m1 + left.m1*right.m5 + left.m2*right.m9 + left.m3*right.m13; @@ -1726,6 +1757,7 @@ RMAPI Matrix MatrixMultiply(Matrix left, Matrix right) result.m14 = left.m12*right.m2 + left.m13*right.m6 + left.m14*right.m10 + left.m15*right.m14; result.m15 = left.m12*right.m3 + left.m13*right.m7 + left.m14*right.m11 + left.m15*right.m15; #endif + return result; } From 0133a4e6c6966e71567ecd663a1cdf43413042f5 Mon Sep 17 00:00:00 2001 From: Jeffery Myers Date: Wed, 31 Dec 2025 11:45:29 -0800 Subject: [PATCH 053/232] Make CameraMove up and right work with Z up cameras like the other functions do. (#5458) --- src/rcamera.h | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/rcamera.h b/src/rcamera.h index 3e9f83095..d67669a7b 100644 --- a/src/rcamera.h +++ b/src/rcamera.h @@ -252,8 +252,13 @@ void CameraMoveForward(Camera *camera, float distance, bool moveInWorldPlane) if (moveInWorldPlane) { - // Project vector onto world plane - forward.y = 0; + // Project vector onto world plane (the plane defined by the up vector) + if (fabsf(camera->up.z) > 0) + forward.z = 0; + else if (fabsf(camera->up.x) > 0) + forward.x = 0; + else + forward.y = 0; forward = Vector3Normalize(forward); } @@ -285,8 +290,14 @@ void CameraMoveRight(Camera *camera, float distance, bool moveInWorldPlane) if (moveInWorldPlane) { - // Project vector onto world plane - right.y = 0; + // Project vector onto world plane (the plane defined by the up vector) + if (fabsf(camera->up.z) > 0) + right.z = 0; + else if (fabsf(camera->up.x) > 0) + right.x = 0; + else + right.y = 0; + right = Vector3Normalize(right); } From 2377506843c9d397cdc5123841730ae8e53a5d84 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 31 Dec 2025 20:50:27 +0100 Subject: [PATCH 054/232] Update rcamera.h --- src/rcamera.h | 51 ++++++++++++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/src/rcamera.h b/src/rcamera.h index d67669a7b..12f3a9e09 100644 --- a/src/rcamera.h +++ b/src/rcamera.h @@ -50,14 +50,14 @@ // Function specifiers in case library is build/used as a shared library (Windows) // NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll #if defined(_WIN32) -#if defined(BUILD_LIBTYPE_SHARED) -#if defined(__TINYC__) -#define __declspec(x) __attribute__((x)) -#endif -#define RLAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll) -#elif defined(USE_LIBTYPE_SHARED) -#define RLAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll) -#endif + #if defined(BUILD_LIBTYPE_SHARED) + #if defined(__TINYC__) + #define __declspec(x) __attribute__((x)) + #endif + #define RLAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll) + #elif defined(USE_LIBTYPE_SHARED) + #define RLAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll) + #endif #endif #ifndef RLAPI @@ -191,19 +191,21 @@ RLAPI Matrix GetCameraProjectionMatrix(Camera *camera, float aspect); // IsKeyDown() // IsKeyPressed() // GetFrameTime() + +#include // Required for: fabsf() //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- -#define CAMERA_MOVE_SPEED 5.4f // Units per second -#define CAMERA_ROTATION_SPEED 0.03f -#define CAMERA_PAN_SPEED 0.2f +#define CAMERA_MOVE_SPEED 5.4f // Units per second +#define CAMERA_ROTATION_SPEED 0.03f +#define CAMERA_PAN_SPEED 0.2f // Camera mouse movement sensitivity -#define CAMERA_MOUSE_MOVE_SENSITIVITY 0.003f +#define CAMERA_MOUSE_MOVE_SENSITIVITY 0.003f // Camera orbital speed in CAMERA_ORBITAL mode -#define CAMERA_ORBITAL_SPEED 0.5f // Radians per second +#define CAMERA_ORBITAL_SPEED 0.5f // Radians per second //---------------------------------------------------------------------------------- // Types and Structures Definition @@ -253,12 +255,10 @@ void CameraMoveForward(Camera *camera, float distance, bool moveInWorldPlane) if (moveInWorldPlane) { // Project vector onto world plane (the plane defined by the up vector) - if (fabsf(camera->up.z) > 0) - forward.z = 0; - else if (fabsf(camera->up.x) > 0) - forward.x = 0; - else - forward.y = 0; + if (fabsf(camera->up.z) > 0) forward.z = 0; + else if (fabsf(camera->up.x) > 0) forward.x = 0; + else forward.y = 0; + forward = Vector3Normalize(forward); } @@ -291,12 +291,9 @@ void CameraMoveRight(Camera *camera, float distance, bool moveInWorldPlane) if (moveInWorldPlane) { // Project vector onto world plane (the plane defined by the up vector) - if (fabsf(camera->up.z) > 0) - right.z = 0; - else if (fabsf(camera->up.x) > 0) - right.x = 0; - else - right.y = 0; + if (fabsf(camera->up.z) > 0) right.z = 0; + else if (fabsf(camera->up.x) > 0) right.x = 0; + else right.y = 0; right = Vector3Normalize(right); } @@ -356,7 +353,7 @@ void CameraYaw(Camera *camera, float angle, bool rotateAroundTarget) // - lockView prevents camera overrotation (aka "somersaults") // - rotateAroundTarget defines if rotation is around target or around its position // - rotateUp rotates the up direction as well (typically only usefull in CAMERA_FREE) -// NOTE: angle must be provided in radians +// NOTE: [angle] must be provided in radians void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp) { // Up direction @@ -393,7 +390,7 @@ void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTa // Move position relative to target camera->position = Vector3Subtract(camera->target, targetPosition); } - else // rotate around camera.position + else // Rotate around camera.position { // Move target relative to position camera->target = Vector3Add(camera->position, targetPosition); From 83377a34884dd85ce6b72bf3b50247585e0bc843 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 31 Dec 2025 22:29:12 +0100 Subject: [PATCH 055/232] Update examples_list.txt --- examples/examples_list.txt | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/examples/examples_list.txt b/examples/examples_list.txt index 3310cf2d2..96d64ca84 100644 --- a/examples/examples_list.txt +++ b/examples/examples_list.txt @@ -1,11 +1,13 @@ # -# raylib examples list used to generate/update collection -# examples must be provided as: ;;;;;;;""; +# raylib examples list with available .c example files +# +# WARNING: List is not ordered by example name but by the display order on web, +# so it can not be automatically generated scanning available .c code files, only updated +# new examples are added at the end of each category; it's up to the user to reorder them as desired +# +# examples data is listed as: ;;;;;;;""; # # This list is used as the main reference by [rexm] tool for examples collection validation and management -# New examples must be added to this list and any possible rename must be made on this list first -# -# WARNING: List is not ordered by example name but by the display order on web # core;core_basic_window;★☆☆☆;1.0;1.0;2013;2025;"Ramon Santamaria";@raysan5 core;core_delta_time;★☆☆☆;5.5;5.6-dev;2025;2025;"Robin";@RobinsAviary @@ -92,6 +94,7 @@ shapes;shapes_rlgl_color_wheel;★★★☆;5.6-dev;5.6-dev;2025;2025;"Robin";@R shapes;shapes_rlgl_triangle;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Robin";@RobinsAviary shapes;shapes_ball_physics;★★☆☆;5.6-dev;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto shapes;shapes_penrose_tile;★★★★;5.5;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto +shapes;shapes_hilbert_curve;★★★☆;5.6;5.6;2025;2025;"Hamza RAHAL";@hmz-rhl textures;textures_logo_raylib;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5 textures;textures_srcrec_dstrec;★★★☆;1.3;1.3;2015;2025;"Ramon Santamaria";@raysan5 textures;textures_image_drawing;★★☆☆;1.4;1.4;2016;2025;"Ramon Santamaria";@raysan5 From f805e6cae82b945ff02c2381b8ab6d99e6a8f8cb Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 31 Dec 2025 22:46:36 +0100 Subject: [PATCH 056/232] REXM: Update `Makefile.Web` before trying to rebuild new example for web --- tools/rexm/rexm.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index aa491ff23..10b91e82f 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -1226,6 +1226,18 @@ int main(int argc, char *argv[]) // Actions to fix/review anything possible from validation results //------------------------------------------------------------------------------------------------ + // Update files: Makefile, Makefile.Web, README.md, examples.js + // Solves: VALID_NOT_IN_MAKEFILE, VALID_NOT_IN_MAKEFILE_WEB, VALID_NOT_IN_README, VALID_NOT_IN_JS + // WARNING: Makefile.Web needs to be updated before trying to rebuild web example! + UpdateRequiredFiles(); + for (int i = 0; i < exCollectionCount; i++) + { + exCollection[i].status &= ~VALID_NOT_IN_MAKEFILE; + exCollection[i].status &= ~VALID_NOT_IN_MAKEFILE_WEB; + exCollection[i].status &= ~VALID_NOT_IN_README; + exCollection[i].status &= ~VALID_NOT_IN_JS; + } + // Check examples "status" information for (int i = 0; i < exCollectionCount; i++) { @@ -1325,17 +1337,6 @@ int main(int argc, char *argv[]) } } } - - // Update files: Makefile, Makefile.Web, README.md, examples.js - // Solves: VALID_NOT_IN_MAKEFILE, VALID_NOT_IN_MAKEFILE_WEB, VALID_NOT_IN_README, VALID_NOT_IN_JS - UpdateRequiredFiles(); - for (int i = 0; i < exCollectionCount; i++) - { - exCollection[i].status &= ~VALID_NOT_IN_MAKEFILE; - exCollection[i].status &= ~VALID_NOT_IN_MAKEFILE_WEB; - exCollection[i].status &= ~VALID_NOT_IN_README; - exCollection[i].status &= ~VALID_NOT_IN_JS; - } //------------------------------------------------------------------------------------------------ } From ab1d9b38304ff30b6207565e4038e11200c6cbbd Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 31 Dec 2025 22:47:16 +0100 Subject: [PATCH 057/232] REXM: Check example exists (compilation worked) before trying to run it --- tools/rexm/rexm.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 10b91e82f..aab316503 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -1592,11 +1592,16 @@ int main(int argc, char *argv[]) FileRemove(TextFormat("%s/%s/%s.original.c", exBasePath, exCategory, exName)); // STEP 3: Run example on browser - // WARNING: Example download is asynchronous so reading fails on next step - // when looking for a file that could not have been downloaded yet - ChangeDirectory(TextFormat("%s", exBasePath)); - if (i == 0) system("start python -m http.server 8080"); // Init localhost just once - system(TextFormat("start explorer \"http:\\localhost:8080/%s/%s.html", exCategory, exName)); + if (FileExists(TextFormat("%s/%s/%s.html", exBasePath, exCategory, exName)) && + FileExists(TextFormat("%s/%s/%s.wasm", exBasePath, exCategory, exName)) && + FileExists(TextFormat("%s/%s/%s.js", exBasePath, exCategory, exName))) + { + // WARNING: Example download is asynchronous so reading fails on next step + // when looking for a file that could not have been downloaded yet + ChangeDirectory(TextFormat("%s", exBasePath)); + if (i == 0) system("start python -m http.server 8080"); // Init localhost just once + system(TextFormat("start explorer \"http:\\localhost:8080/%s/%s.html", exCategory, exName)); + } // NOTE: Example .log is automatically downloaded into system Downloads directory on browser-example exectution From cac02ab0639cdd70b99031c0f3ac98176de7c4b1 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 31 Dec 2025 22:48:07 +0100 Subject: [PATCH 058/232] REXM: REVIEWED: Add new example to collection list at the end of its category, instead of adding it at the end of the file --- tools/rexm/rexm.c | 115 ++++++++++++++++++++++++++-------------------- 1 file changed, 66 insertions(+), 49 deletions(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index aab316503..36152e560 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -207,8 +207,8 @@ static void UpdateSourceMetadata(const char *exSrcPath, const rlExampleInfo *inf // Update generated Web example .html file metadata static void UpdateWebMetadata(const char *exHtmlPath, const char *exFilePath); -// Check if text string is a list of strings -static bool TextInList(const char *text, const char **list, int listCount); +// Check if text string is in a list of strings and get index, -1 if not found +static int GetTextListIndex(const char *text, const char **list, int listCount); //------------------------------------------------------------------------------------ // Program main entry point @@ -1003,6 +1003,9 @@ int main(int argc, char *argv[]) VALID_INVALID_CATEGORY */ + // Validate and update examples collection list + // NOTE: New .c examples found are added at the end of its category + //--------------------------------------------------------------------------------------------------- // Scan available example .c files and add to collection missing ones // NOTE: Source of truth is what we have in the examples directories (on validation/update) LOG("INFO: Scanning available example (.c) files to be added to collection...\n"); @@ -1010,14 +1013,66 @@ int main(int argc, char *argv[]) // Load examples collection list file (raylib/examples/examples_list.txt) char *exList = LoadFileText(exCollectionFilePath); + int exListLen = (int)strlen(exList); + char *exListUpdated = (char *)RL_CALLOC(REXM_MAX_BUFFER_SIZE, 1); bool listUpdated = false; - int exListLen = (int)strlen(exList); - strcpy(exListUpdated, exList); + // Add new examples to the collection list if not found + // WARNING: Added to the end of category, order defines place on raylib webpage + for (unsigned int i = 0; i < clist.count; i++) + { + // NOTE: Skipping "examples_template" from checks + if (!TextIsEqual(GetFileNameWithoutExt(clist.paths[i]), "examples_template") && + (TextFindIndex(exList, GetFileNameWithoutExt(clist.paths[i])) == -1)) + { + // Get new example data + rlExampleInfo *exInfo = LoadExampleInfo(clist.paths[i]); - // Copy examples list into an update list - // NOTE: Checking and removing duplicate entries + // Get example category, -1 if not found in list + int catIndex = GetTextListIndex(exInfo->category, exCategories, REXM_MAX_EXAMPLE_CATEGORIES); + + if (catIndex > -1) + { + int nextCatIndex = catIndex + 1; + if (nextCatIndex > (REXM_MAX_EXAMPLE_CATEGORIES - 1)) nextCatIndex = -1; // EOF + + // Find position to add new example on list, just before the following category + // Category order: core, shapes, textures, text, models, shaders, audio, [others] + int exListNextCatIndex = -1; + if (nextCatIndex != -1) exListNextCatIndex = TextFindIndex(exList, exCategories[nextCatIndex]); + else exListNextCatIndex = exListLen; // EOF + + strncpy(exListUpdated, exList, exListNextCatIndex); + + // Get example difficulty stars + char starsText[16] = { 0 }; + for (int s = 0; s < 4; s++) + { + // NOTE: Every UTF-8 star are 3 bytes + if (s < exInfo->stars) strcpy(starsText + 3*s, "★"); + else strcpy(starsText + 3*s, "☆"); + } + + // Add new example to the list + int exListNewExLen = sprintf(exListUpdated + exListNextCatIndex, + TextFormat("%s;%s;%s;%s;%s;%i;%i;\"%s\";@%s\n", + exInfo->category, exInfo->name, starsText, exInfo->verCreated, + exInfo->verUpdated, exInfo->yearCreated, exInfo->yearReviewed, + exInfo->author, exInfo->authorGitHub)); + + // Add the following examples to the end of collection list + strncpy(exListUpdated + exListNextCatIndex + exListNewExLen, exList + exListNextCatIndex, exListLen - exListNextCatIndex); + + listUpdated = true; + } + + UnloadExampleInfo(exInfo); + } + } + + /* + // Check and remove duplicate example entries int lineCount = 0; char **exListLines = LoadTextLines(exList, &lineCount); int exListUpdatedOffset = 0; @@ -1031,46 +1086,7 @@ int main(int argc, char *argv[]) } UnloadTextLines(exListLines, lineCount); - - for (unsigned int i = 0; i < clist.count; i++) - { - // NOTE: Skipping "examples_template" from checks - if (!TextIsEqual(GetFileNameWithoutExt(clist.paths[i]), "examples_template") && - (TextFindIndex(exList, GetFileNameWithoutExt(clist.paths[i])) == -1)) - { - // TODO: Examples to be added in the list should be added at the end of their categories, - // not at the end of the file... - - // Add example to the examples collection list - // WARNING: Added to the end of the list, order must be set by users and - // defines placement on raylib webpage - rlExampleInfo *exInfo = LoadExampleInfo(clist.paths[i]); - - // Validate example category - // TODO: Should [others] category be considered? - if (TextInList(exInfo->category, exCategories, REXM_MAX_EXAMPLE_CATEGORIES))// && !TextIsEqual(exInfo->category, "others")) - { - // Get example difficulty stars - char starsText[16] = { 0 }; - for (int s = 0; s < 4; s++) - { - // NOTE: Every UTF-8 star are 3 bytes - if (s < exInfo->stars) strcpy(starsText + 3*s, "★"); - else strcpy(starsText + 3*s, "☆"); - } - - exListLen += sprintf(exListUpdated + exListLen, - TextFormat("%s;%s;%s;%s;%s;%i;%i;\"%s\";@%s\n", - exInfo->category, exInfo->name, starsText, exInfo->verCreated, - exInfo->verUpdated, exInfo->yearCreated, exInfo->yearReviewed, - exInfo->author, exInfo->authorGitHub)); - - listUpdated = true; - } - - UnloadExampleInfo(exInfo); - } - } + */ if (listUpdated) SaveFileText(exCollectionFilePath, exListUpdated); @@ -1078,6 +1094,7 @@ int main(int argc, char *argv[]) RL_FREE(exListUpdated); UnloadDirectoryFiles(clist); + //--------------------------------------------------------------------------------------------------- // Check all examples in collection [examples_list.txt] -> Source of truth! LOG("INFO: Validating examples in collection...\n"); @@ -2918,13 +2935,13 @@ static void UpdateWebMetadata(const char *exHtmlPath, const char *exFilePath) } // Check if text string is a list of strings -static bool TextInList(const char *text, const char **list, int listCount) +static int GetTextListIndex(const char *text, const char **list, int listCount) { - bool result = false; + int result = -1; for (int i = 0; i < listCount; i++) { - if (TextIsEqual(text, list[i])) { result = true; break; } + if (TextIsEqual(text, list[i])) { result = i; break; } } return result; From 95f72b162b7041ad699b59b0fdaf65e6424a26a1 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 31 Dec 2025 22:50:17 +0100 Subject: [PATCH 059/232] REVIEWED: `TextReplace()`, revert breaking change, needs to be reviewed again... -WIP- --- src/rtext.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/rtext.c b/src/rtext.c index 453ed4507..b0f77a767 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -1746,16 +1746,23 @@ char *TextReplace(const char *text, const char *search, const char *replacement) { insertPoint = (char *)strstr(text, search); lastReplacePos = (int)(insertPoint - text); - temp = strncpy(temp, text, tempLen - 1) + lastReplacePos; - tempLen -= lastReplacePos; - temp = strncpy(temp, replacement, tempLen - 1) + replaceLen; - tempLen -= replaceLen; + + // TODO: Review logic to avoid strcpy() + // OK - Those lines work + temp = strncpy(temp, text, lastReplacePos) + lastReplacePos; + temp = strcpy(temp, replacement) + replaceLen; + // WRONG - But not those ones + //temp = strncpy(temp, text, tempLen - 1) + lastReplacePos; + //tempLen -= lastReplacePos; + //temp = strncpy(temp, replacement, tempLen - 1) + replaceLen; + //tempLen -= replaceLen; text += lastReplacePos + searchLen; // Move to next "end of replace" } // Copy remaind text part after replacement to result (pointed by moving temp) - strncpy(temp, text, tempLen - 1); + strcpy(temp, text); // OK + //strncpy(temp, text, tempLen - 1); // WRONG } return result; From eb4ad50d9904ff0359e303708127d3d9ba68dab2 Mon Sep 17 00:00:00 2001 From: Jeffery Myers Date: Wed, 31 Dec 2025 14:52:08 -0800 Subject: [PATCH 060/232] make sure that our up vector really is up in an axis before picking a world plane (#5459) --- src/rcamera.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rcamera.h b/src/rcamera.h index 12f3a9e09..72552ec15 100644 --- a/src/rcamera.h +++ b/src/rcamera.h @@ -255,8 +255,8 @@ void CameraMoveForward(Camera *camera, float distance, bool moveInWorldPlane) if (moveInWorldPlane) { // Project vector onto world plane (the plane defined by the up vector) - if (fabsf(camera->up.z) > 0) forward.z = 0; - else if (fabsf(camera->up.x) > 0) forward.x = 0; + if (fabsf(camera->up.z) > 0.7071f) forward.z = 0; + else if (fabsf(camera->up.x) > 0.7071f) forward.x = 0; else forward.y = 0; forward = Vector3Normalize(forward); @@ -291,8 +291,8 @@ void CameraMoveRight(Camera *camera, float distance, bool moveInWorldPlane) if (moveInWorldPlane) { // Project vector onto world plane (the plane defined by the up vector) - if (fabsf(camera->up.z) > 0) right.z = 0; - else if (fabsf(camera->up.x) > 0) right.x = 0; + if (fabsf(camera->up.z) > 0.7071f) right.z = 0; + else if (fabsf(camera->up.x) > 0.7071f) right.x = 0; else right.y = 0; right = Vector3Normalize(right); From 909f040dc5038fdb7b275481d8766bf8c7239346 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 1 Jan 2026 16:33:34 +0100 Subject: [PATCH 061/232] Remove trailing spaces --- src/platforms/rcore_android.c | 2 +- src/platforms/rcore_desktop_glfw.c | 20 +++++----- src/platforms/rcore_desktop_rgfw.c | 2 +- src/platforms/rcore_desktop_sdl.c | 6 +-- src/platforms/rcore_desktop_win32.c | 12 +++--- src/platforms/rcore_drm.c | 48 ++++++++++++------------ src/platforms/rcore_memory.c | 4 +- src/platforms/rcore_web.c | 16 ++++---- src/platforms/rcore_web_emscripten.c | 56 ++++++++++++++-------------- src/raudio.c | 4 +- src/rcore.c | 20 +++++----- src/rlgl.h | 2 +- src/rmodels.c | 4 +- src/rtext.c | 16 ++++---- src/rtextures.c | 4 +- 15 files changed, 108 insertions(+), 108 deletions(-) diff --git a/src/platforms/rcore_android.c b/src/platforms/rcore_android.c index e1dba72c8..4f36f0a5b 100644 --- a/src/platforms/rcore_android.c +++ b/src/platforms/rcore_android.c @@ -360,7 +360,7 @@ void RestoreWindow(void) void SetWindowState(unsigned int flags) { 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); } diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index a1c0024aa..24b6d8d18 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -188,7 +188,7 @@ void ToggleFullscreen(void) GLFWmonitor **monitors = glfwGetMonitors(&monitorCount); GLFWmonitor *monitor = (monitorIndex < monitorCount)? monitors[monitorIndex] : NULL; - if (monitor != NULL) + if (monitor != NULL) { // Get current monitor video mode const GLFWvidmode *mode = glfwGetVideoMode(monitors[monitorIndex]); @@ -233,7 +233,7 @@ void ToggleFullscreen(void) #endif // WARNING: This function launches FramebufferSizeCallback() - glfwSetWindowMonitor(platform.handle, NULL, CORE.Window.position.x, CORE.Window.position.y, + glfwSetWindowMonitor(platform.handle, NULL, CORE.Window.position.x, CORE.Window.position.y, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE); #if defined(_GLFW_X11) || defined(_GLFW_WAYLAND) @@ -283,7 +283,7 @@ void ToggleBorderlessWindowed(void) CORE.Window.screen.height = mode->height; // Set screen position and size - glfwSetWindowMonitor(platform.handle, monitors[monitor], CORE.Window.position.x, CORE.Window.position.y, + glfwSetWindowMonitor(platform.handle, monitors[monitor], CORE.Window.position.x, CORE.Window.position.y, CORE.Window.screen.width, CORE.Window.screen.height, mode->refreshRate); // Refocus window @@ -312,7 +312,7 @@ void ToggleBorderlessWindowed(void) #endif // Return to previous screen size and position - glfwSetWindowMonitor(platform.handle, NULL, CORE.Window.position.x, CORE.Window.position.y, + glfwSetWindowMonitor(platform.handle, NULL, CORE.Window.position.x, CORE.Window.position.y, CORE.Window.screen.width, CORE.Window.screen.height, mode->refreshRate); // Refocus window @@ -908,7 +908,7 @@ Vector2 GetMonitorPosition(int monitor) if ((monitor >= 0) && (monitor < monitorCount)) { - int x = 0; + int x = 0; int y = 0; glfwGetMonitorPos(monitors[monitor], &x, &y); @@ -1026,7 +1026,7 @@ Vector2 GetWindowPosition(void) Vector2 GetWindowScaleDPI(void) { Vector2 scale = { 1.0f, 1.0f }; - if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI) && !FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI) && !FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) glfwGetWindowContentScale(platform.handle, &scale.x, &scale.y); return scale; } @@ -1275,7 +1275,7 @@ void PollInputEvents(void) state.axes[GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f; state.axes[GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f; } - + const unsigned char *buttons = state.buttons; for (int k = 0; (buttons != NULL) && (k < MAX_GAMEPAD_BUTTONS); k++) @@ -1345,7 +1345,7 @@ void PollInputEvents(void) CORE.Window.resizedLastFrame = false; - if ((CORE.Window.eventWaiting) || + 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) @@ -1455,7 +1455,7 @@ int InitPlatform(void) 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 + // 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); @@ -1463,7 +1463,7 @@ int InitPlatform(void) glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_TRUE); #endif } - else + else { glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_FALSE); #if defined(__APPLE__) diff --git a/src/platforms/rcore_desktop_rgfw.c b/src/platforms/rcore_desktop_rgfw.c index 558b6de55..b906fd103 100644 --- a/src/platforms/rcore_desktop_rgfw.c +++ b/src/platforms/rcore_desktop_rgfw.c @@ -330,7 +330,7 @@ void ToggleFullscreen(void) void ToggleBorderlessWindowed(void) { if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) ToggleFullscreen(); - + if (FLAG_IS_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE)) { CORE.Window.previousPosition = CORE.Window.position; diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index 952268ca6..cc3f7c6ae 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -1425,8 +1425,8 @@ void PollInputEvents(void) #if defined(USING_VERSION_SDL3) // const char *data; // The text for SDL_EVENT_DROP_TEXT and the file name for SDL_EVENT_DROP_FILE, NULL for other events - // Event memory is now managed by SDL, so you should not free the data in SDL_EVENT_DROP_FILE, - // and if you want to hold onto the text in SDL_EVENT_TEXT_EDITING and SDL_EVENT_TEXT_INPUT events, + // Event memory is now managed by SDL, so you should not free the data in SDL_EVENT_DROP_FILE, + // and if you want to hold onto the text in SDL_EVENT_TEXT_EDITING and SDL_EVENT_TEXT_INPUT events, // you should make a copy of it. SDL_TEXTINPUTEVENT_TEXT_SIZE is no longer necessary and has been removed strncpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.data, MAX_FILEPATH_LENGTH - 1); #else @@ -1487,7 +1487,7 @@ 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) + // 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)) { diff --git a/src/platforms/rcore_desktop_win32.c b/src/platforms/rcore_desktop_win32.c index 973fafa68..8d9bc6c8b 100644 --- a/src/platforms/rcore_desktop_win32.c +++ b/src/platforms/rcore_desktop_win32.c @@ -263,7 +263,7 @@ static bool DecoratedFromStyle(DWORD style) static DWORD MakeWindowStyle(unsigned flags) { // Flag is not needed because there are no child windows, - // but supposedly it improves efficiency, plus, windows adds this + // but supposedly it improves efficiency, plus, windows adds this // flag automatically anyway so it keeps flags in sync with the OS DWORD style = WS_CLIPSIBLINGS; @@ -1880,19 +1880,19 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara // Get current dpi scale factor float scalex = HIWORD(wParam)/96.0f; float scaley = LOWORD(wParam)/96.0f; - + RECT *suggestedRect = (RECT *)lparam; // Never set the window size to anything other than the suggested rect here // Doing so can cause a window to stutter between monitors when transitioning between them - int result = (int)SetWindowPos(hwnd, NULL, + int result = (int)SetWindowPos(hwnd, NULL, suggestedRect->left, suggestedRect->top, - suggestedRect->right - suggestedRect->left, - suggestedRect->bottom - suggestedRect->top, + suggestedRect->right - suggestedRect->left, + suggestedRect->bottom - suggestedRect->top, SWP_NOZORDER | SWP_NOACTIVATE); if (result == 0) TRACELOG(LOG_ERROR, "Failed to set window position [ERROR: %lu]", GetLastError()); - + // TODO: Update screen data, render size, screen scaling, viewport... } break; diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index c5b74b956..8db332b06 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -1606,10 +1606,10 @@ int InitPlatform(void) if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)) MinimizeWindow(); // If graphic device is no properly initialized, we end program - if (!CORE.Window.ready) - { - TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); - return -1; + if (!CORE.Window.ready) + { + TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); + return -1; } else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor())/2 - CORE.Window.screen.width/2, GetMonitorHeight(GetCurrentMonitor())/2 - CORE.Window.screen.height/2); @@ -1933,7 +1933,7 @@ static void InitEvdevInput(void) platform.touchPosition[i].y = -1; platform.touchId[i] = -1; } - + // Initialize touch slot platform.touchSlot = 0; @@ -2116,13 +2116,13 @@ static void ConfigureEvdevDevice(char *device) if (prioritize) { deviceKindStr = isTouch? "touchscreen" : "mouse"; - - if (platform.mouseFd != -1) + + if (platform.mouseFd != -1) { TRACELOG(LOG_INFO, "INPUT: Overwriting previous input device with new %s", deviceKindStr); close(platform.mouseFd); } - + platform.mouseFd = fd; platform.mouseIsTouch = isTouch; @@ -2134,7 +2134,7 @@ static void ConfigureEvdevDevice(char *device) platform.absRange.y = absinfo[ABS_Y].info.minimum; platform.absRange.height = absinfo[ABS_Y].info.maximum - absinfo[ABS_Y].info.minimum; } - + TRACELOG(LOG_INFO, "INPUT: Initialized input device %s as %s", device, deviceKindStr); } else @@ -2357,9 +2357,9 @@ static void PollMouseEvents(void) if (event.code == ABS_X) { CORE.Input.Mouse.currentPosition.x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange - + // Update single touch position only if it's active and no MT events are being used - if (platform.touchActive[0] && !isMultitouch) + if (platform.touchActive[0] && !isMultitouch) { platform.touchPosition[0].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; if (touchAction == -1) touchAction = 2; // TOUCH_ACTION_MOVE @@ -2369,9 +2369,9 @@ static void PollMouseEvents(void) if (event.code == ABS_Y) { CORE.Input.Mouse.currentPosition.y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange - + // Update single touch position only if it's active and no MT events are being used - if (platform.touchActive[0] && !isMultitouch) + if (platform.touchActive[0] && !isMultitouch) { platform.touchPosition[0].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; if (touchAction == -1) touchAction = 2; // TOUCH_ACTION_MOVE @@ -2379,9 +2379,9 @@ static void PollMouseEvents(void) } // Multitouch movement - if (event.code == ABS_MT_SLOT) + if (event.code == ABS_MT_SLOT) { - platform.touchSlot = event.value; + platform.touchSlot = event.value; isMultitouch = true; } @@ -2391,7 +2391,7 @@ static void PollMouseEvents(void) if (platform.touchSlot < MAX_TOUCH_POINTS) { platform.touchPosition[platform.touchSlot].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; - + // If this slot is active, it's a move. If not, we are just updating the buffer for when it becomes active. // Only set to MOVE if we haven't already detected a DOWN or UP event this frame if (platform.touchActive[platform.touchSlot] && touchAction == -1) touchAction = 2; // TOUCH_ACTION_MOVE @@ -2403,7 +2403,7 @@ static void PollMouseEvents(void) if (platform.touchSlot < MAX_TOUCH_POINTS) { platform.touchPosition[platform.touchSlot].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; - + // If this slot is active, it's a move. If not, we are just updating the buffer for when it becomes active. // Only set to MOVE if we haven't already detected a DOWN or UP event this frame if (platform.touchActive[platform.touchSlot] && touchAction == -1) touchAction = 2; // TOUCH_ACTION_MOVE @@ -2419,7 +2419,7 @@ static void PollMouseEvents(void) platform.touchActive[platform.touchSlot] = true; platform.touchId[platform.touchSlot] = event.value; // Use Tracking ID for unique IDs - + touchAction = 1; // TOUCH_ACTION_DOWN } else @@ -2429,7 +2429,7 @@ static void PollMouseEvents(void) platform.touchPosition[platform.touchSlot].x = -1; platform.touchPosition[platform.touchSlot].y = -1; platform.touchId[platform.touchSlot] = -1; - + // Force UP action if we haven't already set a DOWN action // (DOWN takes priority over UP if both happen in one frame, though rare) if (touchAction != 1) touchAction = 0; // TOUCH_ACTION_UP @@ -2486,7 +2486,7 @@ static void PollMouseEvents(void) if (event.value > 0) { bool activateSlot0 = false; - + if (event.code == BTN_LEFT) activateSlot0 = true; // Mouse click always activates else if (event.code == BTN_TOUCH) { @@ -2534,11 +2534,11 @@ static void PollMouseEvents(void) if (!CORE.Input.Mouse.cursorLocked) { if (CORE.Input.Mouse.currentPosition.x < 0) CORE.Input.Mouse.currentPosition.x = 0; - if (CORE.Input.Mouse.currentPosition.x > CORE.Window.screen.width/CORE.Input.Mouse.scale.x) + if (CORE.Input.Mouse.currentPosition.x > CORE.Window.screen.width/CORE.Input.Mouse.scale.x) CORE.Input.Mouse.currentPosition.x = CORE.Window.screen.width/CORE.Input.Mouse.scale.x; if (CORE.Input.Mouse.currentPosition.y < 0) CORE.Input.Mouse.currentPosition.y = 0; - if (CORE.Input.Mouse.currentPosition.y > CORE.Window.screen.height/CORE.Input.Mouse.scale.y) + if (CORE.Input.Mouse.currentPosition.y > CORE.Window.screen.height/CORE.Input.Mouse.scale.y) CORE.Input.Mouse.currentPosition.y = CORE.Window.screen.height/CORE.Input.Mouse.scale.y; } @@ -2553,9 +2553,9 @@ static void PollMouseEvents(void) k++; } } - + CORE.Input.Touch.pointCount = k; - + // Clear remaining slots for (int i = k; i < MAX_TOUCH_POINTS; i++) { diff --git a/src/platforms/rcore_memory.c b/src/platforms/rcore_memory.c index 1b7a55fd8..fda3fe774 100644 --- a/src/platforms/rcore_memory.c +++ b/src/platforms/rcore_memory.c @@ -472,7 +472,7 @@ void PollInputEvents(void) } // TODO: Poll input events for current platform - + // Check for key pressed to exit if (kbhit()) { @@ -513,7 +513,7 @@ int InitPlatform(void) TRACELOG(LOG_INFO, " > Screen size: %i x %i", CORE.Window.screen.width, CORE.Window.screen.height); TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height); TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y); - + CORE.Window.ready = true; // TODO: Load OpenGL extensions diff --git a/src/platforms/rcore_web.c b/src/platforms/rcore_web.c index b52ca1bf0..244a53dd7 100644 --- a/src/platforms/rcore_web.c +++ b/src/platforms/rcore_web.c @@ -76,10 +76,10 @@ 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 @@ -885,7 +885,7 @@ 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; @@ -1128,7 +1128,7 @@ void PollInputEvents(void) int InitPlatform(void) { SetCanvasIdJs(platform.canvasId, 64); // Get the current canvas id - + glfwSetErrorCallback(ErrorCallback); // Initialize GLFW internal global state @@ -1200,8 +1200,8 @@ int InitPlatform(void) glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // Choose OpenGL minor version (just hint) // Profiles Hint, only OpenGL 3.3 and above // Possible values: GLFW_OPENGL_CORE_PROFILE, GLFW_OPENGL_ANY_PROFILE, GLFW_OPENGL_COMPAT_PROFILE - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_FALSE); // Forward Compatibility Hint: Only 3.3 and above! // glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); // Request OpenGL DEBUG context } @@ -1236,7 +1236,7 @@ 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); @@ -1244,7 +1244,7 @@ int InitPlatform(void) 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 diff --git a/src/platforms/rcore_web_emscripten.c b/src/platforms/rcore_web_emscripten.c index aeead6d9b..71dcdc2e7 100644 --- a/src/platforms/rcore_web_emscripten.c +++ b/src/platforms/rcore_web_emscripten.c @@ -636,25 +636,25 @@ void SetWindowSize(int width, int height) // - CSS canvas size: Web layout size, logical pixels // - Canvas contained framebuffer resolution // * Browser monitor, device pixel ratio (HighDPI) - - double canvasCssWidth = 0.0; + + double canvasCssWidth = 0.0; double canvasCssHeight = 0.0; emscripten_get_element_css_size(platform.canvasId, &canvasCssWidth, &canvasCssHeight); - + // NOTE: emscripten_get_canvas_element_size() returns canvas framebuffer size, not CSS canvas size - + // Get device pixel ratio // TODO: Should DPI be considered at this point? double dpr = emscripten_get_device_pixel_ratio(); // Set canvas framebuffer size emscripten_set_canvas_element_size(platform.canvasId, width*dpr, height*dpr); - + // Set canvas CSS size // TODO: Consider canvas CSS style if already scaled 100% EM_ASM({ Module.canvas.style.width = $0; }, width*dpr); EM_ASM({ Module.canvas.style.height = $0; }, height*dpr); - + SetupViewport(width*dpr, height*dpr); // Reset viewport and projection matrix for new size } @@ -704,7 +704,7 @@ Vector2 GetMonitorPosition(int monitor) // Get selected monitor width (currently used by monitor) int GetMonitorWidth(int monitor) { - // Get the width of the user's entire screen in CSS logical pixels, + // Get the width of the user's entire screen in CSS logical pixels, // no physical pixels, it would require multiplying by device pixel ratio // NOTE: Returned value is limited to the current monitor where the browser window is located int width = 0; @@ -715,7 +715,7 @@ int GetMonitorWidth(int monitor) // Get selected monitor height (currently used by monitor) int GetMonitorHeight(int monitor) { - // Get the height of the user's entire screen in CSS logical pixels, + // Get the height of the user's entire screen in CSS logical pixels, // no physical pixels, it would require multiplying by device pixel ratio // NOTE: Returned value is limited to the current monitor where the browser window is located int height = 0; @@ -865,7 +865,7 @@ 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; @@ -904,7 +904,7 @@ double GetTime(void) time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer() */ time = emscripten_get_now()*1000.0; - + return time; } @@ -1137,7 +1137,7 @@ int InitPlatform(void) const canvas = document.getElementById(platform.canvasId); Module.canvas = canvas; }); - + // Load memory framebuffer with desired screen size platform.pixels = (unsigned int *)RL_CALLOC(CORE.Window.screen.width*CORE.Window.screen.height, sizeof(unsigned int)); } @@ -1145,7 +1145,7 @@ int InitPlatform(void) { attribs.majorVersion = 1; // WebGL 1.0 requested attribs.minorVersion = 0; - + // Create WebGL context platform.glContext = emscripten_webgl_create_context(platform.canvasId, &attribs); if (platform.glContext == 0) return 0; @@ -1156,7 +1156,7 @@ int InitPlatform(void) { attribs.majorVersion = 2; // WebGL 2.0 requested attribs.minorVersion = 0; - + // Create WebGL context platform.glContext = emscripten_webgl_create_context(platform.canvasId, &attribs); if (platform.glContext == 0) return 0; @@ -1216,7 +1216,7 @@ int InitPlatform(void) emscripten_set_keypress_callback(platform.canvasId, NULL, 1, EmscriptenKeyboardCallback); emscripten_set_keydown_callback(platform.canvasId, NULL, 1, EmscriptenKeyboardCallback); emscripten_set_keyup_callback(platform.canvasId, NULL, 1, EmscriptenKeyboardCallback); - + emscripten_set_click_callback(platform.canvasId, NULL, 1, EmscriptenMouseCallback); //emscripten_set_dblclick_callback(platform.canvasId, NULL, 1, EmscriptenMouseCallback); emscripten_set_mousedown_callback(platform.canvasId, NULL, 1, EmscriptenMouseCallback); @@ -1225,15 +1225,15 @@ int InitPlatform(void) emscripten_set_mousemove_callback(platform.canvasId, NULL, 1, EmscriptenMouseMoveCallback); emscripten_set_wheel_callback(platform.canvasId, NULL, 1, EmscriptenMouseWheelCallback); emscripten_set_pointerlockchange_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenPointerlockCallback); - + 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); - + // Trigger resize callback to force initial size EmscriptenResizeCallback(EMSCRIPTEN_EVENT_RESIZE, NULL, NULL); //---------------------------------------------------------------------------- @@ -1256,7 +1256,7 @@ int InitPlatform(void) // Close platform // NOTE: Platform closing is managed by browser, so, // this function is actually not required, but still -// implementing some logic behaviour +// implementing some logic behaviour void ClosePlatform(void) { if (platform.pixels != NULL) RL_FREE(platform.pixels); @@ -1319,14 +1319,14 @@ static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent * static EM_BOOL EmscriptenFocusCallback(int eventType, const EmscriptenFocusEvent *focusEvent, void *userData) { EM_BOOL consumed = 1; - + switch (eventType) { case EMSCRIPTEN_EVENT_BLUR: FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); break; // The canvas lost focus case EMSCRIPTEN_EVENT_FOCUS: FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); break; default: consumed = 0; break; } - + return consumed; } @@ -1335,7 +1335,7 @@ static EM_BOOL EmscriptenVisibilityChangeCallback(int eventType, const Emscripte { if (visibilityChangeEvent->hidden) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN); // The window was hidden else FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_HIDDEN); // The window was restored - + return 1; // The event was consumed by the callback handler } @@ -1405,7 +1405,7 @@ static EM_BOOL EmscriptenKeyboardCallback(int eventType, const EmscriptenKeyboar } break; default: break; } - + // TODO: Add char codes //unsigned int charCode // Check if there is space available in the queue for characters to be added @@ -1457,7 +1457,7 @@ static EM_BOOL EmscriptenMouseCallback(int eventType, const EmscriptenMouseEvent } break; default: break; } - + #if defined(SUPPORT_GESTURES_SYSTEM) && defined(SUPPORT_MOUSE_GESTURES) // Process mouse events as touches to be able to use mouse-gestures GestureEvent gestureEvent = { 0 }; @@ -1508,7 +1508,7 @@ static EM_BOOL EmscriptenMouseMoveCallback(int eventType, const EmscriptenMouseE double cssHeight = 0.0; emscripten_get_element_css_size(platform.canvasId, &cssWidth, &cssHeight); - int fbWidth = 0; + int fbWidth = 0; int fbHeight = 0; emscripten_get_canvas_element_size(platform.canvasId, &fbWidth, &fbHeight); @@ -1518,15 +1518,15 @@ static EM_BOOL EmscriptenMouseMoveCallback(int eventType, const EmscriptenMouseE int mouseX = (int)(mouseCssX*scaleX); int mouseY = (int)(mouseCssY*scaleY); - + CORE.Input.Mouse.currentPosition.x = mouseX;//(float)mouseEvent->canvasX; CORE.Input.Mouse.currentPosition.y = mouseY;//(float)mouseEvent->canvasY; - + // Shorter alternative: //double dpr = emscripten_get_device_pixel_ratio(); //int mouseX = (int)(e->canvasX*dpr); //int mouseY = (int)(e->canvasY*dpr); - + CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; } @@ -1564,7 +1564,7 @@ static EM_BOOL EmscriptenMouseWheelCallback(int eventType, const EmscriptenWheel CORE.Input.Mouse.currentWheelMove.x = (float)wheelEvent->deltaX; CORE.Input.Mouse.currentWheelMove.y = (float)wheelEvent->deltaY; } - + return 1; // The event was consumed by the callback handler } diff --git a/src/raudio.c b/src/raudio.c index c65aaa134..e022447d7 100644 --- a/src/raudio.c +++ b/src/raudio.c @@ -2743,9 +2743,9 @@ static const char *GetFileExtension(const char *fileName) static const char *strprbrk(const char *text, const char *charset) { const char *latestMatch = NULL; - + for (; (text != NULL) && (text = strpbrk(text, charset)); latestMatch = text++) { } - + return latestMatch; } diff --git a/src/rcore.c b/src/rcore.c index af761cbb2..38bee25bf 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -320,7 +320,7 @@ typedef struct CoreData { char currentKeyState[MAX_KEYBOARD_KEYS]; // Registers current frame key state char previousKeyState[MAX_KEYBOARD_KEYS]; // Registers previous frame key state - // NOTE: Since key press logic involves comparing previous vs currrent key state, + // NOTE: Since key press logic involves comparing previous vs currrent key state, // key repeats needs to be handled specially char keyRepeatInFrame[MAX_KEYBOARD_KEYS]; // Registers key repeats for current frame @@ -817,7 +817,7 @@ int GetScreenHeight(void) int GetRenderWidth(void) { int width = 0; - + if (CORE.Window.usingFbo) return CORE.Window.currentFbo.width; else width = CORE.Window.render.width; @@ -1735,7 +1735,7 @@ 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 @@ -2257,7 +2257,7 @@ const char *GetApplicationDirectory(void) #if defined(_WIN32) int len = 0; - + #if defined(UNICODE) unsigned short widePath[MAX_PATH]; len = GetModuleFileNameW(NULL, (wchar_t *)widePath, MAX_PATH); @@ -2265,7 +2265,7 @@ const char *GetApplicationDirectory(void) #else len = GetModuleFileNameA(NULL, appDir, MAX_PATH); #endif - + if (len > 0) { for (int i = len; i >= 0; --i) @@ -2282,7 +2282,7 @@ const char *GetApplicationDirectory(void) appDir[0] = '.'; appDir[1] = '\\'; } - + #elif defined(__linux__) unsigned int size = sizeof(appDir); @@ -2304,7 +2304,7 @@ const char *GetApplicationDirectory(void) appDir[0] = '.'; appDir[1] = '/'; } - + #elif defined(__APPLE__) uint32_t size = sizeof(appDir); @@ -2326,7 +2326,7 @@ const char *GetApplicationDirectory(void) appDir[0] = '.'; appDir[1] = '/'; } - + #elif defined(__FreeBSD__) size_t size = sizeof(appDir); @@ -2697,7 +2697,7 @@ 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; @@ -4241,7 +4241,7 @@ const char *TextFormat(const char *text, ...) char *currentBuffer = buffers[index]; memset(currentBuffer, 0, MAX_TEXT_BUFFER_LENGTH); // Clear buffer before using - + if (text != NULL) { va_list args; diff --git a/src/rlgl.h b/src/rlgl.h index cda64896c..b10942d88 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -3391,7 +3391,7 @@ unsigned int rlLoadTexture(const void *data, int width, int height, int format, // 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); - + // 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); diff --git a/src/rmodels.c b/src/rmodels.c index 665b94147..da26a15f1 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -132,7 +132,7 @@ #ifndef MAX_MESH_VERTEX_BUFFERS #define MAX_MESH_VERTEX_BUFFERS 9 // Maximum vertex buffers (VBO) per mesh #endif -#ifndef MAX_FILEPATH_LENGTH +#ifndef MAX_FILEPATH_LENGTH #define MAX_FILEPATH_LENGTH 4096 // Maximum length for filepaths (Linux PATH_MAX default value) #endif @@ -4153,7 +4153,7 @@ RayCollision GetRayCollisionMesh(Ray ray, Mesh mesh, Matrix transform) // Test against all triangles in mesh for (int i = 0; i < triangleCount; i++) { - Vector3 a = { 0 }; + Vector3 a = { 0 }; Vector3 b = { 0 }; Vector3 c = { 0 }; Vector3 *vertdata = (Vector3 *)mesh.vertices; diff --git a/src/rtext.c b/src/rtext.c index b0f77a767..9c22b0993 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -700,9 +700,9 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz switch (type) { case FONT_DEFAULT: - case FONT_BITMAP: + case FONT_BITMAP: { - glyphs[k].image.data = stbtt_GetCodepointBitmap(&fontInfo, scaleFactor, scaleFactor, cp, + glyphs[k].image.data = stbtt_GetCodepointBitmap(&fontInfo, scaleFactor, scaleFactor, cp, &cpWidth, &cpHeight, &glyphs[k].offsetX, &glyphs[k].offsetY); } break; case FONT_SDF: @@ -1518,7 +1518,7 @@ const char *TextFormat(const char *text, ...) char *currentBuffer = buffers[index]; memset(currentBuffer, 0, MAX_TEXT_BUFFER_LENGTH); // Clear buffer before using - + if (text != NULL) { va_list args; @@ -1756,7 +1756,7 @@ char *TextReplace(const char *text, const char *search, const char *replacement) //tempLen -= lastReplacePos; //temp = strncpy(temp, replacement, tempLen - 1) + replaceLen; //tempLen -= replaceLen; - + text += lastReplacePos + searchLen; // Move to next "end of replace" } @@ -2059,7 +2059,7 @@ char *TextToCamel(const char *text) char *LoadUTF8(const int *codepoints, int length) { char *text = NULL; - + if ((codepoints != NULL) && (length > 0)) { // We allocate enough memory to fit all possible codepoints @@ -2096,7 +2096,7 @@ int *LoadCodepoints(const char *text, int *count) { int *codepoints = NULL; int codepointCount = 0; - + if (text != NULL) { int textLength = TextLength(text); @@ -2209,7 +2209,7 @@ int GetCodepoint(const char *text, int *codepointSize) 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ - + int codepoint = 0x3f; // Codepoint (defaults to '?') *codepointSize = 1; if (text == NULL) return codepoint; @@ -2504,7 +2504,7 @@ static Font LoadBMFont(const char *fileName) int charId = 0; int charX = 0; int charY = 0; - int charWidth = 0; + int charWidth = 0; int charHeight = 0; int charOffsetX = 0; int charOffsetY = 0; diff --git a/src/rtextures.c b/src/rtextures.c index 4208b40bd..37c04c439 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -1125,7 +1125,7 @@ Image GenImageCellular(int width, int height, int tileSize) Image GenImageText(int width, int height, const char *text) { Image image = { 0 }; - + int imageSize = width*height; image.width = width; image.height = height; @@ -1487,7 +1487,7 @@ Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Co Image imText = { 0 }; #if defined(SUPPORT_MODULE_RTEXT) 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') From 5a3391fdce046bc5473e52afbd835dd2dc127146 Mon Sep 17 00:00:00 2001 From: GlitchLens <46534888+oneafter@users.noreply.github.com> Date: Thu, 1 Jan 2026 23:35:12 +0800 Subject: [PATCH 062/232] [rtext] Fix multiple security vulnerabilities in font loading (#5433, #5434, #5436) (#5450) --- src/rtext.c | 51 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/src/rtext.c b/src/rtext.c index 9c22b0993..9801bf698 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -743,8 +743,14 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz stbtt_GetCodepointHMetrics(&fontInfo, cp, &glyphs[k].advanceX, NULL); glyphs[k].advanceX = (int)((float)glyphs[k].advanceX*scaleFactor); + // [Security Fix] Prevent integer overflow/negative allocation + // Issue #5436: Malicious font files may contain negative advanceX, + // causing calloc overflow or crash + if (glyphs[k].advanceX < 0) glyphs[k].advanceX = 0; + Image imSpace = { - .data = RL_CALLOC(glyphs[k].advanceX*fontSize, 2), + // Only allocate memory if width > 0, otherwise set to NULL + .data = (glyphs[k].advanceX > 0) ? RL_CALLOC(glyphs[k].advanceX*fontSize, 2) : NULL, .width = glyphs[k].advanceX, .height = fontSize, .mipmaps = 1, @@ -853,7 +859,8 @@ Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyp } #endif - atlas.data = (unsigned char *)RL_CALLOC(1, atlas.width*atlas.height); // Create a bitmap to store characters (8 bpp) + int atlasDataSize = atlas.width * atlas.height; // Save total size for bounds checking + atlas.data = (unsigned char *)RL_CALLOC(1, atlasDataSize); // Create a bitmap to store characters (8 bpp) atlas.format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE; atlas.mipmaps = 1; @@ -898,7 +905,17 @@ Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyp { for (int x = 0; x < glyphs[i].image.width; x++) { - ((unsigned char *)atlas.data)[(offsetY + y)*atlas.width + (offsetX + x)] = ((unsigned char *)glyphs[i].image.data)[y*glyphs[i].image.width + x]; + int destX = offsetX + x; + int destY = offsetY + y; + + // Security fix: check both lower and upper bounds + // destX >= 0: prevent heap underflow (#5434) + // destX < atlas.width: prevent heap overflow (#5433) + if (destX >= 0 && destX < atlas.width && destY >= 0 && destY < atlas.height) + { + ((unsigned char *)atlas.data)[destY * atlas.width + destX] = + ((unsigned char *)glyphs[i].image.data)[y * glyphs[i].image.width + x]; + } } } @@ -946,7 +963,15 @@ Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyp { for (int x = 0; x < glyphs[i].image.width; x++) { - ((unsigned char *)atlas.data)[(rects[i].y + padding + y)*atlas.width + (rects[i].x + padding + x)] = ((unsigned char *)glyphs[i].image.data)[y*glyphs[i].image.width + x]; + int destX = rects[i].x + padding + x; + int destY = rects[i].y + padding + y; + + // Security fix: check both lower and upper bounds + if (destX >= 0 && destX < atlas.width && destY >= 0 && destY < atlas.height) + { + ((unsigned char *)atlas.data)[destY * atlas.width + destX] = + ((unsigned char *)glyphs[i].image.data)[y * glyphs[i].image.width + x]; + } } } } @@ -960,14 +985,18 @@ Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyp #if defined(SUPPORT_FONT_ATLAS_WHITE_REC) // Add a 3x3 white rectangle at the bottom-right corner of the generated atlas, - // useful to use as the white texture to draw shapes with raylib, using this rectangle - // shapes and text can be backed into a single draw call: SetShapesTexture() - for (int i = 0, k = atlas.width*atlas.height - 1; i < 3; i++) + // useful to use as the white texture to draw shapes with raylib. + // [Security Fix] Ensure the atlas is large enough to hold a 3x3 rectangle. + // This prevents heap underflow when width < 3 or height < 3 (Fixes #5434 variant) + if (atlas.width >= 3 && atlas.height >= 3) { - ((unsigned char *)atlas.data)[k - 0] = 255; - ((unsigned char *)atlas.data)[k - 1] = 255; - ((unsigned char *)atlas.data)[k - 2] = 255; - k -= atlas.width; + for (int i = 0, k = atlas.width*atlas.height - 1; i < 3; i++) + { + ((unsigned char *)atlas.data)[k - 0] = 255; + ((unsigned char *)atlas.data)[k - 1] = 255; + ((unsigned char *)atlas.data)[k - 2] = 255; + k -= atlas.width; + } } #endif From c07d075a63ec8899884841365265040ff960f9b3 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 1 Jan 2026 16:54:44 +0100 Subject: [PATCH 063/232] REVIEWED: Security checks formatting and comments --- src/rtext.c | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/src/rtext.c b/src/rtext.c index 9801bf698..9359e3ea3 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -742,21 +742,19 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz { stbtt_GetCodepointHMetrics(&fontInfo, cp, &glyphs[k].advanceX, NULL); glyphs[k].advanceX = (int)((float)glyphs[k].advanceX*scaleFactor); - - // [Security Fix] Prevent integer overflow/negative allocation - // Issue #5436: Malicious font files may contain negative advanceX, - // causing calloc overflow or crash - if (glyphs[k].advanceX < 0) glyphs[k].advanceX = 0; - + Image imSpace = { - // Only allocate memory if width > 0, otherwise set to NULL - .data = (glyphs[k].advanceX > 0) ? RL_CALLOC(glyphs[k].advanceX*fontSize, 2) : NULL, + .data = NULL, .width = glyphs[k].advanceX, .height = fontSize, .mipmaps = 1, .format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE }; + // Only allocate space image if required + if (glyphs[k].advanceX > 0) imSpace.data = RL_CALLOC(glyphs[k].advanceX*fontSize, 1); + else glyphs[k].advanceX = 0; + glyphs[k].image = imSpace; } @@ -859,8 +857,8 @@ Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyp } #endif - int atlasDataSize = atlas.width * atlas.height; // Save total size for bounds checking - atlas.data = (unsigned char *)RL_CALLOC(1, atlasDataSize); // Create a bitmap to store characters (8 bpp) + int atlasDataSize = atlas.width*atlas.height; // Save total size for bounds checking + atlas.data = (unsigned char *)RL_CALLOC(atlasDataSize, 1); // Create a bitmap to store characters (8 bpp) atlas.format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE; atlas.mipmaps = 1; @@ -908,13 +906,11 @@ Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyp int destX = offsetX + x; int destY = offsetY + y; - // Security fix: check both lower and upper bounds - // destX >= 0: prevent heap underflow (#5434) - // destX < atlas.width: prevent heap overflow (#5433) - if (destX >= 0 && destX < atlas.width && destY >= 0 && destY < atlas.height) + // Security: check both lower and upper bounds + if ((destX >= 0) && (destX < atlas.width) && (destY >= 0) && (destY < atlas.height)) { - ((unsigned char *)atlas.data)[destY * atlas.width + destX] = - ((unsigned char *)glyphs[i].image.data)[y * glyphs[i].image.width + x]; + ((unsigned char *)atlas.data)[destY*atlas.width + destX] = + ((unsigned char *)glyphs[i].image.data)[y*glyphs[i].image.width + x]; } } } @@ -985,10 +981,9 @@ Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyp #if defined(SUPPORT_FONT_ATLAS_WHITE_REC) // Add a 3x3 white rectangle at the bottom-right corner of the generated atlas, - // useful to use as the white texture to draw shapes with raylib. - // [Security Fix] Ensure the atlas is large enough to hold a 3x3 rectangle. - // This prevents heap underflow when width < 3 or height < 3 (Fixes #5434 variant) - if (atlas.width >= 3 && atlas.height >= 3) + // useful to use as the white texture to draw shapes with raylib + // Security: ensure the atlas is large enough to hold a 3x3 rectangle + if ((atlas.width >= 3) && (atlas.height >= 3)) { for (int i = 0, k = atlas.width*atlas.height - 1; i < 3; i++) { From c9a456e273e9fb0581ebce4046ada7afb26a679e Mon Sep 17 00:00:00 2001 From: Jeremiah Donley <108106416+JJLDonley@users.noreply.github.com> Date: Fri, 2 Jan 2026 07:14:25 -0500 Subject: [PATCH 064/232] Add DenoRaylib550 binding to BINDINGS.md (#5462) --- BINDINGS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/BINDINGS.md b/BINDINGS.md index 37274b3be..6ef57035f 100644 --- a/BINDINGS.md +++ b/BINDINGS.md @@ -29,6 +29,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers | [bindbc-raylib3](https://github.com/o3o/bindbc-raylib3) | **5.0** | [D](https://dlang.org) | BSL-1.0 | | [dray](https://github.com/redthing1/dray) | **5.0** | [D](https://dlang.org) | Apache-2.0 | | [raylib-d](https://github.com/schveiguy/raylib-d) | **5.5** | [D](https://dlang.org) | Zlib | +| [DenoRaylib550](https://github.com/JJLDonley/DenoRaylib550) | **5.5** | [Deno](https://deno.land) | MIT | | [rayex](https://github.com/shiryel/rayex) | 3.7 | [elixir](https://elixir-lang.org) | Apache-2.0 | | [raylib-elle](https://github.com/acquitelol/elle/blob/rewrite/std/raylib.le) | **5.5** | [Elle](https://github.com/acquitelol/elle) | GPL-3.0 | | [raylib-factor](https://github.com/factor/factor/blob/master/extra/raylib/raylib.factor) | 4.5 | [Factor](https://factorcode.org) | BSD | From 980e4d0ad3ea5fa32bb53c0de770b3ae3e4db2e2 Mon Sep 17 00:00:00 2001 From: Jeffery Myers Date: Fri, 2 Jan 2026 04:15:25 -0800 Subject: [PATCH 065/232] Use the size of the texture as the V scale so repeatable textures work well (#5463) --- examples/textures/textures_textured_curve.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/textures/textures_textured_curve.c b/examples/textures/textures_textured_curve.c index abf78c88a..f8d207d83 100644 --- a/examples/textures/textures_textured_curve.c +++ b/examples/textures/textures_textured_curve.c @@ -190,7 +190,7 @@ static void DrawTexturedCurve(void) Vector2 normal = Vector2Normalize((Vector2){ -delta.y, delta.x }); // The v texture coordinate of the segment (add up the length of all the segments so far) - float v = previousV + Vector2Length(delta); + float v = previousV + Vector2Length(delta) / (float)(texRoad.height * 2); // Make sure the start point has a normal if (!tangentSet) From 416af51a93772d1736b6dedc0d273a8079cf3381 Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 2 Jan 2026 13:40:15 +0100 Subject: [PATCH 066/232] Update year to 2026 --- LICENSE | 2 +- examples/Makefile | 8 +++++--- examples/Makefile.Web | 4 ++-- projects/VSCode/main.c | 2 +- src/Makefile | 2 +- src/config.h | 2 +- src/external/rl_gputex.h | 2 +- src/platforms/rcore_android.c | 2 +- src/platforms/rcore_desktop_glfw.c | 2 +- src/platforms/rcore_desktop_rgfw.c | 2 +- src/platforms/rcore_desktop_sdl.c | 2 +- src/platforms/rcore_desktop_win32.c | 2 +- src/platforms/rcore_drm.c | 2 +- src/platforms/rcore_template.c | 2 +- src/platforms/rcore_web.c | 2 +- src/raudio.c | 4 ++-- src/raylib.h | 2 +- src/raymath.h | 2 +- src/rcamera.h | 2 +- src/rcore.c | 4 ++-- src/rgestures.h | 2 +- src/rglfw.c | 2 +- src/rlgl.h | 2 +- src/rmodels.c | 4 ++-- src/rshapes.c | 2 +- src/rtext.c | 4 ++-- src/rtextures.c | 4 ++-- src/utils.c | 4 ++-- src/utils.h | 2 +- tools/rexm/README.md | 2 +- tools/rexm/rexm.c | 2 +- tools/rlparser/LICENSE | 2 +- tools/rlparser/README.md | 2 +- tools/rlparser/rlparser.c | 4 ++-- 34 files changed, 46 insertions(+), 44 deletions(-) diff --git a/LICENSE b/LICENSE index e96f876a2..bc6f4b851 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) +Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) This software is provided "as-is", without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/examples/Makefile b/examples/Makefile index 9983d8705..b85a448c8 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -30,7 +30,7 @@ # > PLATFORM_ANDROID: # - Android (ARM, ARM64) # -# Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) +# Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) # # This software is provided "as-is", without any express or implied warranty. In no event # will the authors be held liable for any damages arising from the use of this software. @@ -205,10 +205,12 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW) endif endif ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID) - MAKE = mingw32-make + ifeq ($(PLATFORM_OS),WINDOWS) + MAKE = mingw32-make + endif endif ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) - ifeq ($(OS),Windows_NT) + ifeq ($(PLATFORM_OS),WINDOWS) MAKE = mingw32-make else EMMAKE != type emmake diff --git a/examples/Makefile.Web b/examples/Makefile.Web index 5718088ac..56d5bd83c 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -30,7 +30,7 @@ # > PLATFORM_ANDROID: # - Android (ARM, ARM64) # -# Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) +# Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) # # This software is provided "as-is", without any express or implied warranty. In no event # will the authors be held liable for any damages arising from the use of this software. @@ -208,7 +208,7 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID) MAKE = mingw32-make endif ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) - ifeq ($(OS),Windows_NT) + ifeq ($(PLATFORM_OS),WINDOWS) MAKE = mingw32-make else EMMAKE != type emmake diff --git a/projects/VSCode/main.c b/projects/VSCode/main.c index ea394de58..7a5d89000 100644 --- a/projects/VSCode/main.c +++ b/projects/VSCode/main.c @@ -15,7 +15,7 @@ * This example has been created using raylib 1.0 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) +* Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) * ********************************************************************************************/ diff --git a/src/Makefile b/src/Makefile index bc84abece..89dd759aa 100644 --- a/src/Makefile +++ b/src/Makefile @@ -33,7 +33,7 @@ # Many thanks to Milan Nikolic (@gen2brain) for implementing Android platform pipeline. # Many thanks to Emanuele Petriglia for his contribution on GNU/Linux pipeline. # -# Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) +# Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) # # This software is provided "as-is", without any express or implied warranty. In no event # will the authors be held liable for any damages arising from the use of this software. diff --git a/src/config.h b/src/config.h index 9f54edd23..9a1d22de3 100644 --- a/src/config.h +++ b/src/config.h @@ -6,7 +6,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2018-2025 Ahmad Fatoum & Ramon Santamaria (@raysan5) +* Copyright (c) 2018-2026 Ahmad Fatoum and Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. diff --git a/src/external/rl_gputex.h b/src/external/rl_gputex.h index 9c1092695..033045bc8 100644 --- a/src/external/rl_gputex.h +++ b/src/external/rl_gputex.h @@ -62,7 +62,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) +* Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. diff --git a/src/platforms/rcore_android.c b/src/platforms/rcore_android.c index 4f36f0a5b..6d3d68f24 100644 --- a/src/platforms/rcore_android.c +++ b/src/platforms/rcore_android.c @@ -27,7 +27,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) and contributors +* Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) and contributors * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index 24b6d8d18..20b7449b8 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -30,7 +30,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) and contributors +* Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) and contributors * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. diff --git a/src/platforms/rcore_desktop_rgfw.c b/src/platforms/rcore_desktop_rgfw.c index b906fd103..05960c14b 100644 --- a/src/platforms/rcore_desktop_rgfw.c +++ b/src/platforms/rcore_desktop_rgfw.c @@ -29,7 +29,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5), Colleague Riley and contributors +* Copyright (c) 2013-2026 Ramon Santamaria (@raysan5), Colleague Riley and contributors * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index cc3f7c6ae..0279c0c28 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -29,7 +29,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) and contributors +* Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) and contributors * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. diff --git a/src/platforms/rcore_desktop_win32.c b/src/platforms/rcore_desktop_win32.c index 8d9bc6c8b..7ef01a1a0 100644 --- a/src/platforms/rcore_desktop_win32.c +++ b/src/platforms/rcore_desktop_win32.c @@ -26,7 +26,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) and contributors +* Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) and contributors * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index 8db332b06..eedb915e2 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -29,7 +29,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) and contributors +* Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) and contributors * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. diff --git a/src/platforms/rcore_template.c b/src/platforms/rcore_template.c index b22d3f2f5..87cd2e21e 100644 --- a/src/platforms/rcore_template.c +++ b/src/platforms/rcore_template.c @@ -27,7 +27,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) and contributors +* Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) and contributors * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. diff --git a/src/platforms/rcore_web.c b/src/platforms/rcore_web.c index 244a53dd7..0056849dd 100644 --- a/src/platforms/rcore_web.c +++ b/src/platforms/rcore_web.c @@ -26,7 +26,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) and contributors +* Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) and contributors * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. diff --git a/src/raudio.c b/src/raudio.c index e022447d7..98326727f 100644 --- a/src/raudio.c +++ b/src/raudio.c @@ -50,7 +50,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) +* Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -1134,7 +1134,7 @@ bool ExportWaveAsCode(Wave wave, const char *fileName) byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n"); byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n"); byteCount += sprintf(txtData + byteCount, "// //\n"); - byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2018-2025 Ramon Santamaria (@raysan5) //\n"); + byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2018-2026 Ramon Santamaria (@raysan5) //\n"); byteCount += sprintf(txtData + byteCount, "// //\n"); byteCount += sprintf(txtData + byteCount, "//////////////////////////////////////////////////////////////////////////////////\n\n"); diff --git a/src/raylib.h b/src/raylib.h index ba80e40c7..2d411f896 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -62,7 +62,7 @@ * raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software: * -* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) +* Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. diff --git a/src/raymath.h b/src/raymath.h index 8d5b1b2a9..6ab5e2b4c 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -37,7 +37,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2015-2025 Ramon Santamaria (@raysan5) +* Copyright (c) 2015-2026 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. diff --git a/src/rcamera.h b/src/rcamera.h index 72552ec15..82f14fecd 100644 --- a/src/rcamera.h +++ b/src/rcamera.h @@ -20,7 +20,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2022-2025 Christoph Wagner (@Crydsch) & Ramon Santamaria (@raysan5) +* Copyright (c) 2022-2026 Christoph Wagner (@Crydsch) and Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. diff --git a/src/rcore.c b/src/rcore.c index 38bee25bf..e16c6412a 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -70,7 +70,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) and contributors +* Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) and contributors * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -3253,7 +3253,7 @@ bool ExportAutomationEventList(AutomationEventList list, const char *fileName) byteCount += sprintf(txtData + byteCount, "# more info and bugs-report: github.com/raysan5/raylib\n"); byteCount += sprintf(txtData + byteCount, "# feedback and support: ray[at]raylib.com\n"); byteCount += sprintf(txtData + byteCount, "#\n"); - byteCount += sprintf(txtData + byteCount, "# Copyright (c) 2023-2025 Ramon Santamaria (@raysan5)\n"); + byteCount += sprintf(txtData + byteCount, "# Copyright (c) 2023-2026 Ramon Santamaria (@raysan5)\n"); byteCount += sprintf(txtData + byteCount, "#\n\n"); // Add events data diff --git a/src/rgestures.h b/src/rgestures.h index f601a4790..e6cb86300 100644 --- a/src/rgestures.h +++ b/src/rgestures.h @@ -21,7 +21,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2014-2025 Ramon Santamaria (@raysan5) +* Copyright (c) 2014-2026 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. diff --git a/src/rglfw.c b/src/rglfw.c index b167955bc..53399aa13 100644 --- a/src/rglfw.c +++ b/src/rglfw.c @@ -7,7 +7,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2017-2025 Ramon Santamaria (@raysan5) +* Copyright (c) 2017-2026 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. diff --git a/src/rlgl.h b/src/rlgl.h index b10942d88..ab85569bb 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -89,7 +89,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2014-2025 Ramon Santamaria (@raysan5) +* Copyright (c) 2014-2026 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. diff --git a/src/rmodels.c b/src/rmodels.c index da26a15f1..3ee429900 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -21,7 +21,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) +* Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -1987,7 +1987,7 @@ bool ExportMesh(Mesh mesh, const char *fileName) byteCount += sprintf(txtData + byteCount, "# // more info and bugs-report: github.com/raysan5/raylib //\n"); byteCount += sprintf(txtData + byteCount, "# // feedback and support: ray[at]raylib.com //\n"); byteCount += sprintf(txtData + byteCount, "# // //\n"); - byteCount += sprintf(txtData + byteCount, "# // Copyright (c) 2018-2025 Ramon Santamaria (@raysan5) //\n"); + byteCount += sprintf(txtData + byteCount, "# // Copyright (c) 2018-2026 Ramon Santamaria (@raysan5) //\n"); byteCount += sprintf(txtData + byteCount, "# // //\n"); byteCount += sprintf(txtData + byteCount, "# //////////////////////////////////////////////////////////////////////////////////\n\n"); byteCount += sprintf(txtData + byteCount, "# Vertex Count: %i\n", mesh.vertexCount); diff --git a/src/rshapes.c b/src/rshapes.c index 528a362d5..e828b98bc 100644 --- a/src/rshapes.c +++ b/src/rshapes.c @@ -25,7 +25,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) +* Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. diff --git a/src/rtext.c b/src/rtext.c index 9359e3ea3..1fd9a306d 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -34,7 +34,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) +* Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -1066,7 +1066,7 @@ bool ExportFontAsCode(Font font, const char *fileName) byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n"); byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n"); byteCount += sprintf(txtData + byteCount, "// //\n"); - byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2018-2025 Ramon Santamaria (@raysan5) //\n"); + byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2018-2026 Ramon Santamaria (@raysan5) //\n"); byteCount += sprintf(txtData + byteCount, "// //\n"); byteCount += sprintf(txtData + byteCount, "// ---------------------------------------------------------------------------------- //\n"); byteCount += sprintf(txtData + byteCount, "// //\n"); diff --git a/src/rtextures.c b/src/rtextures.c index 37c04c439..59000940e 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -42,7 +42,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5) +* Copyright (c) 2013-2026 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -765,7 +765,7 @@ bool ExportImageAsCode(Image image, const char *fileName) byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n"); byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n"); byteCount += sprintf(txtData + byteCount, "// //\n"); - byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2018-2025 Ramon Santamaria (@raysan5) //\n"); + byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2018-2026 Ramon Santamaria (@raysan5) //\n"); byteCount += sprintf(txtData + byteCount, "// //\n"); byteCount += sprintf(txtData + byteCount, "////////////////////////////////////////////////////////////////////////////////////////\n\n"); diff --git a/src/utils.c b/src/utils.c index 09158893a..82d7d0aa2 100644 --- a/src/utils.c +++ b/src/utils.c @@ -10,7 +10,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2014-2025 Ramon Santamaria (@raysan5) +* Copyright (c) 2014-2026 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -307,7 +307,7 @@ bool ExportDataAsCode(const unsigned char *data, int dataSize, const char *fileN byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n"); byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n"); byteCount += sprintf(txtData + byteCount, "// //\n"); - byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2022-2025 Ramon Santamaria (@raysan5) //\n"); + byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2022-2026 Ramon Santamaria (@raysan5) //\n"); byteCount += sprintf(txtData + byteCount, "// //\n"); byteCount += sprintf(txtData + byteCount, "////////////////////////////////////////////////////////////////////////////////////////\n\n"); diff --git a/src/utils.h b/src/utils.h index 271d0d2c7..7d79c2188 100644 --- a/src/utils.h +++ b/src/utils.h @@ -5,7 +5,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2014-2025 Ramon Santamaria (@raysan5) +* Copyright (c) 2014-2026 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. diff --git a/tools/rexm/README.md b/tools/rexm/README.md index 232ef51d6..14704b5ea 100644 --- a/tools/rexm/README.md +++ b/tools/rexm/README.md @@ -102,4 +102,4 @@ char *TextReplaceBetween(const char *text, const char *begin, const char *end, c `rexm` is an **open source** project, licensed under an unmodified [zlib/libpng license](LICENSE) -*Copyright (c) 2025 Ramon Santamaria ([@raysan5](https://github.com/raysan5))* +*Copyright (c) 2025-2026 Ramon Santamaria ([@raysan5](https://github.com/raysan5))* diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 36152e560..41aa7a85c 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -2840,7 +2840,7 @@ static void UpdateSourceMetadata(const char *exSrcPath, const rlExampleInfo *inf if (exTextUpdated[2] != NULL) exTextUpdatedPtr = exTextUpdated[2]; // Update copyright message - // String: "* Copyright (c) 2019-2025 Contributor Name (@github_user) and Ramon Santamaria (@raysan5)" + // String: "* Copyright (c) 2019-2026 Contributor Name (@github_user) and Ramon Santamaria (@raysan5)" if (info->yearCreated == info->yearReviewed) { exTextUpdated[3] = TextReplaceBetween(exTextUpdatedPtr, "Copyright (c) ", ")", diff --git a/tools/rlparser/LICENSE b/tools/rlparser/LICENSE index 7ed4b8722..4ce3bbb8d 100644 --- a/tools/rlparser/LICENSE +++ b/tools/rlparser/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021-2025 Ramon Santamaria (@raysan5) +Copyright (c) 2021-2026 Ramon Santamaria (@raysan5) This software is provided "as-is", without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/tools/rlparser/README.md b/tools/rlparser/README.md index 0e4f9b739..cf009a891 100644 --- a/tools/rlparser/README.md +++ b/tools/rlparser/README.md @@ -19,7 +19,7 @@ Check `rlparser.c` for details about those structs. // // // more info and bugs-report: github.com/raysan5/raylib/tools/rlparser // // // -// Copyright (c) 2021-2025 Ramon Santamaria (@raysan5) // +// Copyright (c) 2021-2026 Ramon Santamaria (@raysan5) // // // ////////////////////////////////////////////////////////////////////////////////// diff --git a/tools/rlparser/rlparser.c b/tools/rlparser/rlparser.c index d5b03fa01..c291c3038 100644 --- a/tools/rlparser/rlparser.c +++ b/tools/rlparser/rlparser.c @@ -52,7 +52,7 @@ raylib-parser is licensed under an unmodified zlib/libpng license, which is an OSI-certified, BSD-like license that allows static linking with closed source software: - Copyright (c) 2021-2025 Ramon Santamaria (@raysan5) + Copyright (c) 2021-2026 Ramon Santamaria (@raysan5) **********************************************************************************************/ @@ -1084,7 +1084,7 @@ static void ShowCommandLineInfo(void) printf("// //\n"); printf("// more info and bugs-report: github.com/raysan5/raylib/tools/rlparser //\n"); printf("// //\n"); - printf("// Copyright (c) 2021-2025 Ramon Santamaria (@raysan5) //\n"); + printf("// Copyright (c) 2021-2026 Ramon Santamaria (@raysan5) //\n"); printf("// //\n"); printf("//////////////////////////////////////////////////////////////////////////////////\n\n"); From ca89934ed5af9161f781a9b35b808b765dc40f3a Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 2 Jan 2026 13:53:20 +0100 Subject: [PATCH 067/232] Update year to 2026 --- src/platforms/rcore_memory.c | 2 +- src/platforms/rcore_web_emscripten.c | 2 +- tools/rexm/rexm.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/platforms/rcore_memory.c b/src/platforms/rcore_memory.c index fda3fe774..04d343164 100644 --- a/src/platforms/rcore_memory.c +++ b/src/platforms/rcore_memory.c @@ -27,7 +27,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2025 Ramon Santamaria (@raysan5) and contributors +* Copyright (c) 2025-2026 Ramon Santamaria (@raysan5) and contributors * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. diff --git a/src/platforms/rcore_web_emscripten.c b/src/platforms/rcore_web_emscripten.c index 71dcdc2e7..28d530e97 100644 --- a/src/platforms/rcore_web_emscripten.c +++ b/src/platforms/rcore_web_emscripten.c @@ -25,7 +25,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2025 Ramon Santamaria (@raysan5) and contributors +* Copyright (c) 2025-2026 Ramon Santamaria (@raysan5) and contributors * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 41aa7a85c..d3ff18289 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -30,7 +30,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2025 Ramon Santamaria (@raysan5) +* Copyright (c) 2025-2026 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -1881,7 +1881,7 @@ int main(int argc, char *argv[]) printf("// rexm [raylib examples manager] - A simple command-line tool to manage raylib examples //\n"); printf("// powered by raylib v5.6-dev //\n"); printf("// //\n"); - printf("// Copyright (c) 2025 Ramon Santamaria (@raysan5) //\n"); + printf("// Copyright (c) 2025-2026 Ramon Santamaria (@raysan5) //\n"); printf("// //\n"); printf("////////////////////////////////////////////////////////////////////////////////////////////\n\n"); From 942f93db55105495fd39acfc0666997b4efb4c98 Mon Sep 17 00:00:00 2001 From: sleeptightAnsiC <91839286+sleeptightAnsiC@users.noreply.github.com> Date: Fri, 2 Jan 2026 18:36:22 +0100 Subject: [PATCH 068/232] fix(build): do not use != assignment in Makefiles (#5464) GNU Make 3.81 that ships with MacOSX does not understand '!= ...' assignment so we use ':= $(shell ...)' instead which have the same behavior here. Additionally, I have changed the use of 'type' to 'command -v' because assigning the result of 'type' to variable named 'EMMAKE' does not make much sense. I also reused this variable. For more detailed information read the linked issue. Fixes: https://github.com/raysan5/raylib/issues/5460 --- examples/Makefile | 4 ++-- examples/Makefile.Web | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/Makefile b/examples/Makefile index b85a448c8..3cbc2ffc1 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -213,9 +213,9 @@ ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_R ifeq ($(PLATFORM_OS),WINDOWS) MAKE = mingw32-make else - EMMAKE != type emmake + EMMAKE := $(shell command -v emmake) ifneq (, $(EMMAKE)) - MAKE = emmake make + MAKE = $(EMMAKE) make else MAKE = mingw32-make endif diff --git a/examples/Makefile.Web b/examples/Makefile.Web index 56d5bd83c..fe4de1330 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -211,9 +211,9 @@ ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_R ifeq ($(PLATFORM_OS),WINDOWS) MAKE = mingw32-make else - EMMAKE != type emmake + EMMAKE := $(shell command -v emmake) ifneq (, $(EMMAKE)) - MAKE = emmake make + MAKE = $(EMMAKE) make else MAKE = mingw32-make endif From c92de5f108850b91f140a932ca25aa3508336d58 Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 2 Jan 2026 18:43:28 +0100 Subject: [PATCH 069/232] REVIEWED: Comments about intrinsics support #5316 --- src/raymath.h | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/raymath.h b/src/raymath.h index 6ab5e2b4c..57e3dac51 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -177,26 +177,24 @@ typedef struct float16 { #if defined(RAYMATH_USE_SIMD_INTRINSICS) // SIMD is used on the most costly raymath function MatrixMultiply() // NOTE: Only SSE intrinsics support implemented - // TODO: Consider support for other SIMD instrinsics + // TODO: Consider support for other SIMD instrinsics: + // - SSEx, AVX, AVX2, FMA, NEON, RVV /* #if defined(__SSE4_2__) - #define SW_HAS_SSE42 #include + #define RAYMATH_SSE42_ENABLED #elif defined(__SSE4_1__) - #define SW_HAS_SSE41 #include + #define RAYMATH_SSE41_ENABLED #elif defined(__SSSE3__) - #define SW_HAS_SSSE3 #include + #define RAYMATH_SSSE3_ENABLED #elif defined(__SSE3__) - #define SW_HAS_SSE3 #include + #define RAYMATH_SSE3_ENABLED #elif defined(__SSE2__) || (defined(_M_AMD64) || defined(_M_X64)) // SSE2 x64 - #define SW_HAS_SSE2 #include - #elif defined(__SSE__) - #define SW_HAS_SSE - #include + #define RAYMATH_SSE2_ENABLED #endif */ #if defined(__SSE__) || defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP >= 1)) From f67e70bb4763635740cf5a3f7e334f7e0a1f2854 Mon Sep 17 00:00:00 2001 From: Jeffery Myers Date: Fri, 2 Jan 2026 23:59:34 -0800 Subject: [PATCH 070/232] Fix typecast warnings in rcore (#5466) --- src/platforms/rcore_desktop_glfw.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index 20b7449b8..84b021573 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -227,8 +227,8 @@ void ToggleFullscreen(void) if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) { Vector2 scaleDpi = GetWindowScaleDPI(); - CORE.Window.screen.width *= scaleDpi.x; - CORE.Window.screen.height *= scaleDpi.y; + CORE.Window.screen.width = (unsigned int)(CORE.Window.screen.width * scaleDpi.x); + CORE.Window.screen.height = (unsigned int)(CORE.Window.screen.height * scaleDpi.y); } #endif @@ -306,8 +306,8 @@ void ToggleBorderlessWindowed(void) if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) { Vector2 scaleDpi = GetWindowScaleDPI(); - CORE.Window.screen.width *= scaleDpi.x; - CORE.Window.screen.height *= scaleDpi.y; + CORE.Window.screen.width = (unsigned int)(CORE.Window.screen.width * scaleDpi.x); + CORE.Window.screen.height = (unsigned int)(CORE.Window.screen.height * scaleDpi.y); } #endif From b00cbdaf49a7140db890d4c5621c422c83872eab Mon Sep 17 00:00:00 2001 From: Jeffery Myers Date: Sat, 3 Jan 2026 13:38:51 -0800 Subject: [PATCH 071/232] Cleanup warnings in examples (#5467) --- examples/audio/audio_music_stream.c | 4 +- examples/core/core_input_gamepad.c | 4 +- examples/core/core_viewport_scaling.c | 12 +++--- examples/models/models_decals.c | 39 ++++++++++--------- examples/shapes/shapes_ball_physics.c | 16 ++++---- examples/shapes/shapes_kaleidoscope.c | 6 +-- examples/shapes/shapes_penrose_tile.c | 10 ++--- examples/text/text_inline_styling.c | 6 +-- examples/text/text_strings_management.c | 16 ++++---- examples/textures/textures_screen_buffer.c | 2 +- .../examples/shapes_hilbert_curve.vcxproj | 16 ++++---- .../examples/shapes_penrose_tile.vcxproj | 16 ++++---- .../examples/shapes_rlgl_color_wheel.vcxproj | 16 ++++---- 13 files changed, 83 insertions(+), 80 deletions(-) diff --git a/examples/audio/audio_music_stream.c b/examples/audio/audio_music_stream.c index 05ec1c2d6..6e1dfc8c5 100644 --- a/examples/audio/audio_music_stream.c +++ b/examples/audio/audio_music_stream.c @@ -113,7 +113,7 @@ int main(void) DrawText("LEFT-RIGHT for PAN CONTROL", 320, 74, 10, DARKBLUE); DrawRectangle(300, 100, 200, 12, LIGHTGRAY); DrawRectangleLines(300, 100, 200, 12, GRAY); - DrawRectangle(300 + (pan + 1.0)/2.0f*200 - 5, 92, 10, 28, DARKGRAY); + DrawRectangle((int)(300 + (pan + 1.0f)/2.0f*200 - 5), 92, 10, 28, DARKGRAY); DrawRectangle(200, 200, 400, 12, LIGHTGRAY); DrawRectangle(200, 200, (int)(timePlayed*400.0f), 12, MAROON); @@ -125,7 +125,7 @@ int main(void) DrawText("UP-DOWN for VOLUME CONTROL", 320, 334, 10, DARKGREEN); DrawRectangle(300, 360, 200, 12, LIGHTGRAY); DrawRectangleLines(300, 360, 200, 12, GRAY); - DrawRectangle(300 + volume*200 - 5, 352, 10, 28, DARKGRAY); + DrawRectangle((int)(300 + volume*200 - 5), 352, 10, 28, DARKGRAY); EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/examples/core/core_input_gamepad.c b/examples/core/core_input_gamepad.c index 3c9454318..a9e0660e0 100644 --- a/examples/core/core_input_gamepad.c +++ b/examples/core/core_input_gamepad.c @@ -67,7 +67,7 @@ int main(void) if (IsKeyPressed(KEY_RIGHT)) gamepad++; Vector2 mousePosition = GetMousePosition(); - vibrateButton = (Rectangle){ 10, 70 + 20*GetGamepadAxisCount(gamepad) + 20, 75, 24 }; + vibrateButton = (Rectangle){ 10, 70.0f + 20*GetGamepadAxisCount(gamepad) + 20, 75, 24 }; if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && CheckCollisionPointRec(mousePosition, vibrateButton)) SetGamepadVibration(gamepad, 1.0, 1.0, 1.0); //---------------------------------------------------------------------------------- @@ -262,7 +262,7 @@ int main(void) // Draw vibrate button DrawRectangleRec(vibrateButton, SKYBLUE); - DrawText("VIBRATE", vibrateButton.x + 14, vibrateButton.y + 1, 10, DARKGRAY); + DrawText("VIBRATE", (int)(vibrateButton.x + 14), (int)(vibrateButton.y + 1), 10, DARKGRAY); if (GetGamepadButtonPressed() != GAMEPAD_BUTTON_UNKNOWN) DrawText(TextFormat("DETECTED BUTTON: %i", GetGamepadButtonPressed()), 10, 430, 10, RED); else DrawText("DETECTED BUTTON: NONE", 10, 430, 10, GRAY); diff --git a/examples/core/core_viewport_scaling.c b/examples/core/core_viewport_scaling.c index adcd51ea3..6ff5ac9c4 100644 --- a/examples/core/core_viewport_scaling.c +++ b/examples/core/core_viewport_scaling.c @@ -112,16 +112,16 @@ int main(void) if (CheckCollisionPointRec(mousePosition, decreaseResolutionButton) && mousePressed) { resolutionIndex = (resolutionIndex + RESOLUTION_COUNT - 1)%RESOLUTION_COUNT; - gameWidth = resolutionList[resolutionIndex].x; - gameHeight = resolutionList[resolutionIndex].y; + gameWidth = (int)resolutionList[resolutionIndex].x; + gameHeight = (int)resolutionList[resolutionIndex].y; ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target); } if (CheckCollisionPointRec(mousePosition, increaseResolutionButton) && mousePressed) { resolutionIndex = (resolutionIndex + 1)%RESOLUTION_COUNT; - gameWidth = resolutionList[resolutionIndex].x; - gameHeight = resolutionList[resolutionIndex].y; + gameWidth = (int)resolutionList[resolutionIndex].x; + gameHeight = (int)resolutionList[resolutionIndex].y; ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target); } @@ -145,7 +145,7 @@ int main(void) // Draw our scene to the render texture BeginTextureMode(target); ClearBackground(WHITE); - DrawCircle(textureMousePosition.x, textureMousePosition.y, 20.0f, LIME); + DrawCircleV(textureMousePosition, 20.0f, LIME); EndTextureMode(); // Draw render texture to main framebuffer @@ -159,7 +159,7 @@ int main(void) // Draw info box Rectangle infoRect = (Rectangle){5, 5, 330, 105}; DrawRectangleRec(infoRect, Fade(LIGHTGRAY, 0.7f)); - DrawRectangleLines(infoRect.x, infoRect.y, infoRect.width, infoRect.height, BLUE); + DrawRectangleLinesEx(infoRect, 1, BLUE); DrawText(TextFormat("Window Resolution: %d x %d", screenWidth, screenHeight), 15, 15, 10, BLACK); DrawText(TextFormat("Game Resolution: %d x %d", gameWidth, gameHeight), 15, 30, 10, BLACK); diff --git a/examples/models/models_decals.c b/examples/models/models_decals.c index f556139e1..f35794daa 100644 --- a/examples/models/models_decals.c +++ b/examples/models/models_decals.c @@ -45,7 +45,10 @@ static void FreeMeshBuilder(MeshBuilder *mb); static Mesh BuildMesh(MeshBuilder *mb); static Mesh GenMeshDecal(Model inputModel, Matrix projection, float decalSize, float decalOffset); static Vector3 ClipSegment(Vector3 v0, Vector3 v1, Vector3 p, float s); -#define FreeDecalMeshData() GenMeshDecal((Model){ .meshCount = -1.0f }, (Matrix){ 0 }, 0.0f, 0.0f) +inline void FreeDecalMeshData() +{ + GenMeshDecal((Model) { .meshCount = -1 }, (Matrix) { 0 }, 0.0f, 0.0f); +} static bool GuiButton(Rectangle rec, const char *label); //------------------------------------------------------------------------------------ @@ -198,12 +201,12 @@ int main(void) EndMode3D(); float yPos = 10; - float x0 = GetScreenWidth() - 300; + float x0 = GetScreenWidth() - 300.0f; float x1 = x0 + 100; float x2 = x1 + 100; - DrawText("Vertices", x1, yPos, 10, LIME); - DrawText("Triangles", x2, yPos, 10, LIME); + DrawText("Vertices", (int)x1, (int)yPos, 10, LIME); + DrawText("Triangles", (int)x2, (int)yPos, 10, LIME); yPos += 15; int vertexCount = 0; @@ -215,24 +218,24 @@ int main(void) triangleCount += model.meshes[i].triangleCount; } - DrawText("Main model", x0, yPos, 10, LIME); - DrawText(TextFormat("%d", vertexCount), x1, yPos, 10, LIME); - DrawText(TextFormat("%d", triangleCount), x2, yPos, 10, LIME); + DrawText("Main model", (int)x0, (int)yPos, 10, LIME); + DrawText(TextFormat("%d", vertexCount), (int)x1, (int)yPos, 10, LIME); + DrawText(TextFormat("%d", triangleCount), (int)x2, (int)yPos, 10, LIME); yPos += 15; for (int i = 0; i < decalCount; i++) { if (i == 20) { - DrawText("...", x0, yPos, 10, LIME); + DrawText("...", (int)x0, (int)yPos, 10, LIME); yPos += 15; } if (i < 20) { - DrawText(TextFormat("Decal #%d", i+1), x0, yPos, 10, LIME); - DrawText(TextFormat("%d", decalModels[i].meshes[0].vertexCount), x1, yPos, 10, LIME); - DrawText(TextFormat("%d", decalModels[i].meshes[0].triangleCount), x2, yPos, 10, LIME); + DrawText(TextFormat("Decal #%d", i+1), (int)x0, (int)yPos, 10, LIME); + DrawText(TextFormat("%d", decalModels[i].meshes[0].vertexCount), (int)x1, (int)yPos, 10, LIME); + DrawText(TextFormat("%d", decalModels[i].meshes[0].triangleCount), (int)x2, (int)yPos, 10, LIME); yPos += 15; } @@ -240,18 +243,18 @@ int main(void) triangleCount += decalModels[i].meshes[0].triangleCount; } - DrawText("TOTAL", x0, yPos, 10, LIME); - DrawText(TextFormat("%d", vertexCount), x1, yPos, 10, LIME); - DrawText(TextFormat("%d", triangleCount), x2, yPos, 10, LIME); + DrawText("TOTAL", (int)x0, (int)yPos, 10, LIME); + DrawText(TextFormat("%d", vertexCount), (int)x1, (int)yPos, 10, LIME); + DrawText(TextFormat("%d", triangleCount), (int)x2, (int)yPos, 10, LIME); yPos += 15; DrawText("Hold RMB to move camera", 10, 430, 10, GRAY); DrawText("(c) Character model and texture from kenney.nl", screenWidth - 260, screenHeight - 20, 10, GRAY); // UI elements - if (GuiButton((Rectangle){ 10, screenHeight - 100, 100, 60 }, showModel ? "Hide Model" : "Show Model")) showModel = !showModel; + if (GuiButton((Rectangle){ 10, screenHeight - 1000.f, 100, 60 }, showModel ? "Hide Model" : "Show Model")) showModel = !showModel; - if (GuiButton((Rectangle){ 10 + 110, screenHeight - 100, 100, 60 }, "Clear Decals")) + if (GuiButton((Rectangle){ 10 + 110, screenHeight - 100.0f, 100, 60 }, "Clear Decals")) { // Clear decals, unload all decal models for (int i = 0; i < decalCount; i++) UnloadModel(decalModels[i]); @@ -596,8 +599,8 @@ static bool GuiButton(Rectangle rec, const char *label) DrawRectangleRec(rec, bgColor); DrawRectangleLinesEx(rec, 2.0f, DARKGRAY); - float fontSize = 10.0f; - float textWidth = MeasureText(label, fontSize); + int fontSize = 10; + int textWidth = MeasureText(label, fontSize); DrawText(label, (int)(rec.x + rec.width*0.5f - textWidth*0.5f), (int)(rec.y + rec.height*0.5f - fontSize*0.5f), fontSize, DARKGRAY); diff --git a/examples/shapes/shapes_ball_physics.c b/examples/shapes/shapes_ball_physics.c index f9b620d28..0c98ccf9d 100644 --- a/examples/shapes/shapes_ball_physics.c +++ b/examples/shapes/shapes_ball_physics.c @@ -46,12 +46,12 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [shapes] example - ball physics"); Ball balls[MAX_BALLS] = {{ - .pos = { GetScreenWidth()/2, GetScreenHeight()/2 }, + .pos = { GetScreenWidth()/2.0f, GetScreenHeight()/2.0f }, .vel = { 200, 200 }, .ppos = { 0 }, .radius = 40, - .friction = 0.99, - .elasticity = 0.9, + .friction = 0.99f, + .elasticity = 0.9f, .color = BLUE, .grabbed = false }}; @@ -110,11 +110,11 @@ int main(void) { balls[ballCount++] = (Ball){ .pos = mousePos, - .vel = { GetRandomValue(-300, 300), GetRandomValue(-300, 300) }, + .vel = { (float)GetRandomValue(-300, 300), (float)GetRandomValue(-300, 300) }, .ppos = { 0 }, - .radius = 20 + GetRandomValue(0, 30), - .friction = 0.99, - .elasticity = 0.9, + .radius = 20.0f + (float)GetRandomValue(0, 30), + .friction = 0.99f, + .elasticity = 0.9f, .color = { GetRandomValue(0, 255), GetRandomValue(0, 255), GetRandomValue(0, 255), 255 }, .grabbed = false }; @@ -126,7 +126,7 @@ int main(void) { for (int i = 0; i < ballCount; i++) { - if (!balls[i].grabbed) balls[i].vel = (Vector2){ GetRandomValue(-2000, 2000), GetRandomValue(-2000, 2000) }; + if (!balls[i].grabbed) balls[i].vel = (Vector2){ (float)GetRandomValue(-2000, 2000), (float)GetRandomValue(-2000, 2000) }; } } diff --git a/examples/shapes/shapes_kaleidoscope.c b/examples/shapes/shapes_kaleidoscope.c index 119fca598..31129a54c 100644 --- a/examples/shapes/shapes_kaleidoscope.c +++ b/examples/shapes/shapes_kaleidoscope.c @@ -50,9 +50,9 @@ int main(void) int symmetry = 6; float angle = 360.0f/(float)symmetry; float thickness = 3.0f; - Rectangle resetButtonRec = { screenWidth - 55, 5, 50, 25 }; - Rectangle backButtonRec = { screenWidth - 55, screenHeight - 30, 25, 25 }; - Rectangle nextButtonRec = { screenWidth - 30, screenHeight - 30, 25, 25 }; + Rectangle resetButtonRec = { screenWidth - 55.0f, 5.0f, 50, 25 }; + Rectangle backButtonRec = { screenWidth - 55.0f, screenHeight - 30.0f, 25, 25 }; + Rectangle nextButtonRec = { screenWidth - 30.0f, screenHeight - 30.0f, 25, 25 }; Vector2 mousePos = { 0 }; Vector2 prevMousePos = { 0 }; Vector2 scaleVector = { 1.0f, -1.0f }; diff --git a/examples/shapes/shapes_penrose_tile.c b/examples/shapes/shapes_penrose_tile.c index 304dca3cc..cf41852f8 100644 --- a/examples/shapes/shapes_penrose_tile.c +++ b/examples/shapes/shapes_penrose_tile.c @@ -185,12 +185,12 @@ static void BuildProductionStep(PenroseLSystem *ls) char *newProduction = (char *)RL_MALLOC(sizeof(char)*STR_MAX_SIZE); newProduction[0] = '\0'; - int productionLength = strnlen(ls->production, STR_MAX_SIZE); + int productionLength = (int)strnlen(ls->production, STR_MAX_SIZE); for (int i = 0; i < productionLength; i++) { char step = ls->production[i]; - int remainingSpace = STR_MAX_SIZE - strnlen(newProduction, STR_MAX_SIZE) - 1; + int remainingSpace = STR_MAX_SIZE - (int)strnlen(newProduction, STR_MAX_SIZE) - 1; switch (step) { case 'W': strncat(newProduction, ls->ruleW, remainingSpace); break; @@ -201,7 +201,7 @@ static void BuildProductionStep(PenroseLSystem *ls) { if (step != 'F') { - int t = strnlen(newProduction, STR_MAX_SIZE); + int t = (int)strnlen(newProduction, STR_MAX_SIZE); newProduction[t] = step; newProduction[t + 1] = '\0'; } @@ -218,7 +218,7 @@ static void BuildProductionStep(PenroseLSystem *ls) // Draw penrose tile lines static void DrawPenroseLSystem(PenroseLSystem *ls) { - Vector2 screenCenter = { GetScreenWidth()/2, GetScreenHeight()/2 }; + Vector2 screenCenter = { GetScreenWidth()/2.0f, GetScreenHeight()/2.0f }; TurtleState turtle = { .origin = { 0 }, @@ -245,7 +245,7 @@ static void DrawPenroseLSystem(PenroseLSystem *ls) Vector2 startPosScreen = { startPosWorld.x + screenCenter.x, startPosWorld.y + screenCenter.y }; Vector2 endPosScreen = { turtle.origin.x + screenCenter.x, turtle.origin.y + screenCenter.y }; - DrawLineEx(startPosScreen, endPosScreen, 2, Fade(BLACK, 0.2)); + DrawLineEx(startPosScreen, endPosScreen, 2, Fade(BLACK, 0.2f)); } repeats = 1; diff --git a/examples/text/text_inline_styling.c b/examples/text/text_inline_styling.c index 8faef30eb..81f8156b6 100644 --- a/examples/text/text_inline_styling.c +++ b/examples/text/text_inline_styling.c @@ -178,14 +178,14 @@ static void DrawTextStyled(Font font, const char *text, Vector2 position, float // Convert hex color text into actual Color unsigned int colHexValue = strtoul(colHexText, NULL, 16); if (text[i - 1] == 'c') - { + { colFront = GetColor(colHexValue); - colFront.a *= (float)color.a/255.0f; + colFront.a = (unsigned char)(colFront.a * (float)color.a/255.0f); } else if (text[i - 1] == 'b') { colBack = GetColor(colHexValue); - colBack.a *= (float)color.a/255.0f; + colBack.a *= (unsigned char)(colFront.a * (float)color.a / 255.0f); } i += (colHexCount + 1); // Skip color value retrieved and ']' diff --git a/examples/text/text_strings_management.c b/examples/text/text_strings_management.c index d2e349279..e4a7ab2af 100644 --- a/examples/text/text_strings_management.c +++ b/examples/text/text_strings_management.c @@ -133,7 +133,7 @@ int main(void) { for (int i = 0; i < particleCount; i++) { - if (!textParticles[i].grabbed) textParticles[i].vel = (Vector2){ GetRandomValue(-2000, 2000), GetRandomValue(-2000, 2000) }; + if (!textParticles[i].grabbed) textParticles[i].vel = (Vector2){ (float)GetRandomValue(-2000, 2000), (float)GetRandomValue(-2000, 2000) }; } } @@ -233,9 +233,9 @@ int main(void) for (int i = 0; i < particleCount; i++) { TextParticle *tp = &textParticles[i]; - DrawRectangle(tp->rect.x-tp->borderWidth, tp->rect.y-tp->borderWidth, tp->rect.width+tp->borderWidth*2, tp->rect.height+tp->borderWidth*2, BLACK); + DrawRectangleRec((Rectangle) { tp->rect.x - tp->borderWidth, tp->rect.y - tp->borderWidth, tp->rect.width + tp->borderWidth * 2, tp->rect.height + tp->borderWidth * 2 }, BLACK); DrawRectangleRec(tp->rect, tp->color); - DrawText(tp->text, tp->rect.x+tp->padding, tp->rect.y+tp->padding, FONT_SIZE, BLACK); + DrawText(tp->text, (int)(tp->rect.x+tp->padding), (int)(tp->rect.y+tp->padding), FONT_SIZE, BLACK); } DrawText("grab a text particle by pressing with the mouse and throw it by releasing", 10, 10, 10, DARKGRAY); @@ -265,8 +265,8 @@ void PrepareFirstTextParticle(const char* text, TextParticle *tps, int *particle { tps[0] = CreateTextParticle( text, - GetScreenWidth()/2, - GetScreenHeight()/2, + GetScreenWidth()/2.0f, + GetScreenHeight()/2.0f, RAYWHITE ); *particleCount = 1; @@ -277,12 +277,12 @@ TextParticle CreateTextParticle(const char *text, float x, float y, Color color) TextParticle tp = { .text = "", .rect = { x, y, 30, 30 }, - .vel = { GetRandomValue(-200, 200), GetRandomValue(-200, 200) }, + .vel = { (float)GetRandomValue(-200, 200), (float)GetRandomValue(-200, 200) }, .ppos = { 0 }, .padding = 5.0f, .borderWidth = 5.0f, - .friction = 0.99, - .elasticity = 0.9, + .friction = 0.99f, + .elasticity = 0.9f, .color = color, .grabbed = false }; diff --git a/examples/textures/textures_screen_buffer.c b/examples/textures/textures_screen_buffer.c index e620aab31..503b8d249 100644 --- a/examples/textures/textures_screen_buffer.c +++ b/examples/textures/textures_screen_buffer.c @@ -66,7 +66,7 @@ int main(void) // Grow flameRoot for (int x = 2; x < flameWidth; x++) { - unsigned short flame = flameRootBuffer[x]; + unsigned char flame = flameRootBuffer[x]; if (flame == 255) continue; flame += GetRandomValue(0, 2); if (flame > 255) flame = 255; diff --git a/projects/VS2022/examples/shapes_hilbert_curve.vcxproj b/projects/VS2022/examples/shapes_hilbert_curve.vcxproj index 8fcbfab5f..6c60841fb 100644 --- a/projects/VS2022/examples/shapes_hilbert_curve.vcxproj +++ b/projects/VS2022/examples/shapes_hilbert_curve.vcxproj @@ -292,7 +292,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNIGNS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) CompileAsC $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) @@ -309,7 +309,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNIGNS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) CompileAsC $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) /FS %(AdditionalOptions) @@ -345,7 +345,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNIGNS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) CompileAsC $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) @@ -366,7 +366,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNIGNS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) CompileAsC $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) @@ -410,7 +410,7 @@ MaxSpeed true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + _CRT_SECURE_NO_WARNIGNS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) CompileAsC true @@ -432,7 +432,7 @@ MaxSpeed true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + _CRT_SECURE_NO_WARNIGNS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) CompileAsC true @@ -476,7 +476,7 @@ MaxSpeed true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + _CRT_SECURE_NO_WARNIGNS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) CompileAsC true @@ -504,7 +504,7 @@ MaxSpeed true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + _CRT_SECURE_NO_WARNIGNS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) CompileAsC true diff --git a/projects/VS2022/examples/shapes_penrose_tile.vcxproj b/projects/VS2022/examples/shapes_penrose_tile.vcxproj index bde99f8c1..389bdde36 100644 --- a/projects/VS2022/examples/shapes_penrose_tile.vcxproj +++ b/projects/VS2022/examples/shapes_penrose_tile.vcxproj @@ -292,7 +292,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) CompileAsC $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) @@ -309,7 +309,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) CompileAsC $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) /FS %(AdditionalOptions) @@ -345,7 +345,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) CompileAsC $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) @@ -366,7 +366,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) CompileAsC $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) @@ -410,7 +410,7 @@ MaxSpeed true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) CompileAsC true @@ -432,7 +432,7 @@ MaxSpeed true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) CompileAsC true @@ -476,7 +476,7 @@ MaxSpeed true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) CompileAsC true @@ -504,7 +504,7 @@ MaxSpeed true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) CompileAsC true diff --git a/projects/VS2022/examples/shapes_rlgl_color_wheel.vcxproj b/projects/VS2022/examples/shapes_rlgl_color_wheel.vcxproj index b22703577..a02a2d4e2 100644 --- a/projects/VS2022/examples/shapes_rlgl_color_wheel.vcxproj +++ b/projects/VS2022/examples/shapes_rlgl_color_wheel.vcxproj @@ -292,7 +292,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNIGNS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) CompileAsC $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) @@ -309,7 +309,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNIGNS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) CompileAsC $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) /FS %(AdditionalOptions) @@ -345,7 +345,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNIGNS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) CompileAsC $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) @@ -366,7 +366,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNIGNS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) CompileAsC $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) @@ -410,7 +410,7 @@ MaxSpeed true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + _CRT_SECURE_NO_WARNIGNS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) CompileAsC true @@ -432,7 +432,7 @@ MaxSpeed true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + _CRT_SECURE_NO_WARNIGNS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) CompileAsC true @@ -476,7 +476,7 @@ MaxSpeed true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + _CRT_SECURE_NO_WARNIGNS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) CompileAsC true @@ -504,7 +504,7 @@ MaxSpeed true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + _CRT_SECURE_NO_WARNIGNS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) CompileAsC true From a44157c2a834c4956e98afafbced96e25177b1a5 Mon Sep 17 00:00:00 2001 From: Jack Boakes <163384444+jackboakes@users.noreply.github.com> Date: Sun, 4 Jan 2026 08:41:52 +1100 Subject: [PATCH 072/232] [example] Added textures_frame_buffer_rendering (#5468) --- .../textures_frame_buffer_rendering.png | Bin 0 -> 31588 bytes .../textures/textures_framebuffer_rendering.c | 208 ++++++++++++++++++ 2 files changed, 208 insertions(+) create mode 100644 examples/textures/textures_frame_buffer_rendering.png create mode 100644 examples/textures/textures_framebuffer_rendering.c diff --git a/examples/textures/textures_frame_buffer_rendering.png b/examples/textures/textures_frame_buffer_rendering.png new file mode 100644 index 0000000000000000000000000000000000000000..e6829f0bd20ef747b29a0fb868ca5f2c4cc635e5 GIT binary patch literal 31588 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 Duq`3E literal 0 HcmV?d00001 diff --git a/examples/textures/textures_framebuffer_rendering.c b/examples/textures/textures_framebuffer_rendering.c new file mode 100644 index 000000000..a8b466187 --- /dev/null +++ b/examples/textures/textures_framebuffer_rendering.c @@ -0,0 +1,208 @@ +/******************************************************************************************* +* +* raylib [textures] example - framebuffer rendering +* +* Example complexity rating: [★★☆☆] 2/4 +* +* Example originally created with raylib 5.6, last time updated with raylib 5.6 +* +* Example contributed by Jack Boakes (@jackboakes) and reviewed by Ramon Santamaria (@raysan5) +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2026-2026 Jack Boakes (@jackboakes) +* +********************************************************************************************/ + +#include "raylib.h" +#include "raymath.h" + +//------------------------------------------------------------------------------------ +// Module Functions Declaration +//------------------------------------------------------------------------------------ +static void DrawCameraPrism(Camera3D camera, float aspect, Color color); + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + const int splitWidth = screenWidth/2; + + InitWindow(screenWidth, screenHeight, "raylib [textures] example - framebuffer rendering"); + + // Camera to look at the 3D world + Camera3D subjectCamera = { 0 }; + subjectCamera.position = (Vector3){ 5.0f, 5.0f, 5.0f }; + subjectCamera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; + subjectCamera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; + subjectCamera.fovy = 45.0f; + subjectCamera.projection = CAMERA_PERSPECTIVE; + + // Camera to observe the subject camera and 3D world + Camera3D observerCamera = { 0 }; + observerCamera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; + observerCamera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; + observerCamera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; + observerCamera.fovy = 45.0f; + observerCamera.projection = CAMERA_PERSPECTIVE; + + // Set up render textures + RenderTexture2D observerTarget = LoadRenderTexture(splitWidth, screenHeight); + Rectangle observerSource = { 0.0f, 0.0f, (float)observerTarget.texture.width, -(float)observerTarget.texture.height }; + Rectangle observerDest = { 0.0f, 0.0f, (float)splitWidth, (float)screenHeight }; + + RenderTexture2D subjectTarget = LoadRenderTexture(splitWidth, screenHeight); + Rectangle subjectSource = { 0.0f, 0.0f, (float)subjectTarget.texture.width, -(float)subjectTarget.texture.height }; + Rectangle subjectDest = { (float)splitWidth, 0.0f, (float)splitWidth, (float)screenHeight }; + const float textureAspectRatio = (float)subjectTarget.texture.width/(float)subjectTarget.texture.height; + + // Rectangles for cropping render texture + const float captureSize = 128.0f; + Rectangle cropSource = { (subjectTarget.texture.width - captureSize)/2.0f, (subjectTarget.texture.height - captureSize)/2.0f, captureSize, -captureSize }; + Rectangle cropDest = { splitWidth + 20, 20, captureSize, captureSize}; + + SetTargetFPS(60); + DisableCursor(); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + UpdateCamera(&observerCamera, CAMERA_FREE); + UpdateCamera(&subjectCamera, CAMERA_ORBITAL); + + if (IsKeyPressed(KEY_R)) observerCamera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; + + // Build LHS observer view texture + BeginTextureMode(observerTarget); + + ClearBackground(RAYWHITE); + + BeginMode3D(observerCamera); + + DrawGrid(10, 1.0f); + DrawCube((Vector3){ 0.0f, 0.0f, 0.0f }, 2.0f, 2.0f, 2.0f, GOLD); + DrawCubeWires((Vector3){ 0.0f, 0.0f, 0.0f }, 2.0f, 2.0f, 2.0f, PINK); + DrawCameraPrism(subjectCamera, textureAspectRatio, GREEN); + + EndMode3D(); + + DrawText("Observer View", 10, observerTarget.texture.height - 30, 20, BLACK); + DrawText("WASD + Mouse to Move", 10, 10, 20, DARKGRAY); + DrawText("Scroll to Zoom", 10, 30, 20, DARKGRAY); + DrawText("R to Reset Observer Target", 10, 50, 20, DARKGRAY); + + EndTextureMode(); + + // Build RHS subject view texture + BeginTextureMode(subjectTarget); + + ClearBackground(RAYWHITE); + + BeginMode3D(subjectCamera); + + DrawCube((Vector3){ 0.0f, 0.0f, 0.0f }, 2.0f, 2.0f, 2.0f, GOLD); + DrawCubeWires((Vector3){ 0.0f, 0.0f, 0.0f }, 2.0f, 2.0f, 2.0f, PINK); + DrawGrid(10, 1.0f); + + EndMode3D(); + + DrawRectangleLines((subjectTarget.texture.width - captureSize)/2, (subjectTarget.texture.height - captureSize)/2, captureSize, captureSize, GREEN); + DrawText("Subject View", 10, subjectTarget.texture.height - 30, 20, BLACK); + + EndTextureMode(); + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(BLACK); + + // Draw observer texture LHS + DrawTexturePro(observerTarget.texture, observerSource, observerDest, (Vector2){0.0f, 0.0f }, 0.0f, WHITE); + + // Draw subject texture RHS + DrawTexturePro(subjectTarget.texture, subjectSource, subjectDest, (Vector2){ 0.0f, 0.0f }, 0.0f, WHITE); + + // Draw the small crop overlay on top + DrawTexturePro(subjectTarget.texture, cropSource, cropDest, (Vector2){ 0.0f, 0.0f }, 0.0f, WHITE); + DrawRectangleLinesEx(cropDest, 2, BLACK); + + // Draw split screen divider line + DrawLine(splitWidth, 0, splitWidth, screenHeight, BLACK); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadRenderTexture(observerTarget); + UnloadRenderTexture(subjectTarget); + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} + +//---------------------------------------------------------------------------------- +// Module Functions Definition +//---------------------------------------------------------------------------------- +static void DrawCameraPrism(Camera3D camera, float aspect, Color color) +{ + float length = Vector3Distance(camera.position, camera.target); + // Define the 4 corners of the camera's prism plane sliced at the target in Normalized Device Coordinates + Vector3 planeNDC[4] = { + { -1.0f, -1.0f, 1.0f }, // Bottom Left + { 1.0f, -1.0f, 1.0f }, // Bottom Right + { 1.0f, 1.0f, 1.0f }, // Top Right + { -1.0f, 1.0f, 1.0f } // Top Left + }; + + // Build the matrices + Matrix view = GetCameraMatrix(camera); + Matrix proj = MatrixPerspective(camera.fovy * DEG2RAD, aspect, 0.05f, length); + // Combine view and projection so we can reverse the full camera transform + Matrix viewProj = MatrixMultiply(view, proj); + // Invert the view-projection matrix to unproject points from NDC space back into world space + Matrix inverseViewProj = MatrixInvert(viewProj); + + // Transform the 4 plane corners from NDC into world space + Vector3 corners[4]; + for (int i = 0; i < 4; i++) + { + float x = planeNDC[i].x; + float y = planeNDC[i].y; + float z = planeNDC[i].z; + + // Multiply NDC position by the inverse view-projection matrix + // This produces a homogeneous (x, y, z, w) position in world space + float vx = inverseViewProj.m0*x + inverseViewProj.m4*y + inverseViewProj.m8*z + inverseViewProj.m12; + float vy = inverseViewProj.m1*x + inverseViewProj.m5*y + inverseViewProj.m9*z + inverseViewProj.m13; + float vz = inverseViewProj.m2*x + inverseViewProj.m6*y + inverseViewProj.m10*z + inverseViewProj.m14; + float vw = inverseViewProj.m3*x + inverseViewProj.m7*y + inverseViewProj.m11*z + inverseViewProj.m15; + + corners[i] = (Vector3){ vx/vw, vy/vw, vz/vw }; + } + + // Draw the far plane sliced at the target + DrawLine3D(corners[0], corners[1], color); + DrawLine3D(corners[1], corners[2], color); + DrawLine3D(corners[2], corners[3], color); + DrawLine3D(corners[3], corners[0], color); + + // Draw the prism lines from the far plane to the camera position + for (int i = 0; i < 4; i++) + { + DrawLine3D(camera.position, corners[i], color); + } +} \ No newline at end of file From c4b11a30cd77d8cbcf3380cecf3f3540257caaf9 Mon Sep 17 00:00:00 2001 From: Michael Kolupaev Date: Sat, 3 Jan 2026 13:52:04 -0800 Subject: [PATCH 073/232] Fix DrawMeshInstanced breaking if instanceTransform is unused (#5469) --- src/rmodels.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/rmodels.c b/src/rmodels.c index 3ee429900..c22c0a0c9 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -1762,11 +1762,14 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i instancesVboId = rlLoadVertexBuffer(instanceTransforms, instances*sizeof(float16), false); // Instances transformation matrices are sent to shader attribute location: SHADER_LOC_VERTEX_INSTANCE_TX - for (unsigned int i = 0; i < 4; i++) + if (material.shader.locs[SHADER_LOC_VERTEX_INSTANCE_TX] != -1) { - rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_INSTANCE_TX] + i); - rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_INSTANCE_TX] + i, 4, RL_FLOAT, 0, sizeof(Matrix), i*sizeof(Vector4)); - rlSetVertexAttributeDivisor(material.shader.locs[SHADER_LOC_VERTEX_INSTANCE_TX] + i, 1); + for (unsigned int i = 0; i < 4; i++) + { + rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_INSTANCE_TX] + i); + rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_INSTANCE_TX] + i, 4, RL_FLOAT, 0, sizeof(Matrix), i*sizeof(Vector4)); + rlSetVertexAttributeDivisor(material.shader.locs[SHADER_LOC_VERTEX_INSTANCE_TX] + i, 1); + } } rlDisableVertexBuffer(); From af544c24b9751a4b2972e22e472578cfc30ff339 Mon Sep 17 00:00:00 2001 From: ssszcmawo Date: Sat, 3 Jan 2026 22:57:22 +0100 Subject: [PATCH 074/232] [rcore] Fix touch position automation event handling (#5470) * fix touch position automation event handling * Fix alignment of previousPosition comment in rcore.c --- src/rcore.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/rcore.c b/src/rcore.c index e16c6412a..59563537d 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -350,11 +350,12 @@ typedef struct CoreData { } Mouse; struct { - int pointCount; // Number of touch points active - int pointId[MAX_TOUCH_POINTS]; // Point identifiers - Vector2 position[MAX_TOUCH_POINTS]; // Touch position on screen - char currentTouchState[MAX_TOUCH_POINTS]; // Registers current touch state - char previousTouchState[MAX_TOUCH_POINTS]; // Registers previous touch state + int pointCount; // Number of touch points active + int pointId[MAX_TOUCH_POINTS]; // Point identifiers + Vector2 position[MAX_TOUCH_POINTS]; // Touch position on screen + Vector2 previousPosition[MAX_TOUCH_POINTS]; // Previous touch position on screen + char currentTouchState[MAX_TOUCH_POINTS]; // Registers current touch state + char previousTouchState[MAX_TOUCH_POINTS]; // Registers previous touch state } Touch; struct { @@ -4104,22 +4105,20 @@ static void RecordAutomationEvent(void) if (currentEventList->count == currentEventList->capacity) return; // Security check - // Event type: INPUT_TOUCH_POSITION - // TODO: It requires the id! - /* - if (((int)CORE.Input.Touch.currentPosition[id].x != (int)CORE.Input.Touch.previousPosition[id].x) || - ((int)CORE.Input.Touch.currentPosition[id].y != (int)CORE.Input.Touch.previousPosition[id].y)) + // Event type: INPUT_TOUCH_POSITION + if (((int)CORE.Input.Touch.position[id].x != (int)CORE.Input.Touch.previousPosition[id].x) || + ((int)CORE.Input.Touch.position[id].y != (int)CORE.Input.Touch.previousPosition[id].y)) { currentEventList->events[currentEventList->count].frame = CORE.Time.frameCounter; currentEventList->events[currentEventList->count].type = INPUT_TOUCH_POSITION; currentEventList->events[currentEventList->count].params[0] = id; - currentEventList->events[currentEventList->count].params[1] = (int)CORE.Input.Touch.currentPosition[id].x; - currentEventList->events[currentEventList->count].params[2] = (int)CORE.Input.Touch.currentPosition[id].y; + currentEventList->events[currentEventList->count].params[1] = (int)CORE.Input.Touch.position[id].x; + currentEventList->events[currentEventList->count].params[2] = (int)CORE.Input.Touch.position[id].y; TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_TOUCH_POSITION | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]); currentEventList->count++; } - */ + if (currentEventList->count == currentEventList->capacity) return; // Security check } From 35fc8ece44f899b420c7a227b2f307ba48ff48d2 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 3 Jan 2026 23:01:37 +0100 Subject: [PATCH 075/232] Update models_decals.c --- examples/models/models_decals.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/examples/models/models_decals.c b/examples/models/models_decals.c index f35794daa..71122dd68 100644 --- a/examples/models/models_decals.c +++ b/examples/models/models_decals.c @@ -45,10 +45,7 @@ static void FreeMeshBuilder(MeshBuilder *mb); static Mesh BuildMesh(MeshBuilder *mb); static Mesh GenMeshDecal(Model inputModel, Matrix projection, float decalSize, float decalOffset); static Vector3 ClipSegment(Vector3 v0, Vector3 v1, Vector3 p, float s); -inline void FreeDecalMeshData() -{ - GenMeshDecal((Model) { .meshCount = -1 }, (Matrix) { 0 }, 0.0f, 0.0f); -} +static void FreeDecalMeshData(void) { GenMeshDecal((Model){ .meshCount = -1 }, (Matrix){ 0 }, 0.0f, 0.0f); } static bool GuiButton(Rectangle rec, const char *label); //------------------------------------------------------------------------------------ From 3678c2d15763c4ec906506ba9f9e790ede8d0b94 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 5 Jan 2026 20:47:25 +0100 Subject: [PATCH 076/232] REMOVE: `TRACELOGD()`, hardly ever used --- src/config.h | 2 -- src/platforms/rcore_web.c | 8 ++++---- src/platforms/rcore_web_emscripten.c | 8 ++++---- src/rlgl.h | 5 ++--- src/rtext.c | 2 +- src/rtextures.c | 4 ++-- src/utils.h | 7 ------- 7 files changed, 13 insertions(+), 23 deletions(-) diff --git a/src/config.h b/src/config.h index 9a1d22de3..1286e5082 100644 --- a/src/config.h +++ b/src/config.h @@ -287,9 +287,7 @@ // Standard file io library (stdio.h) included #define SUPPORT_STANDARD_FILEIO 1 // Show TRACELOG() output messages -// NOTE: By default LOG_DEBUG traces not shown #define SUPPORT_TRACELOG 1 -//#define SUPPORT_TRACELOG_DEBUG 1 // utils: Configuration values //------------------------------------------------------------------------------------ diff --git a/src/platforms/rcore_web.c b/src/platforms/rcore_web.c index 0056849dd..2b51804ef 100644 --- a/src/platforms/rcore_web.c +++ b/src/platforms/rcore_web.c @@ -1104,7 +1104,7 @@ void PollInputEvents(void) else CORE.Input.Gamepad.currentButtonState[i][button] = 0; } - //TRACELOGD("INPUT: Gamepad %d, button %d: Digital: %d, Analog: %g", gamepadState.index, j, gamepadState.digitalButton[j], gamepadState.analogButton[j]); + //TRACELOG(LOG_DEBUG, "INPUT: Gamepad %d, button %d: Digital: %d, Analog: %g", gamepadState.index, j, gamepadState.digitalButton[j], gamepadState.analogButton[j]); } // Register axis data for every connected gamepad @@ -1695,12 +1695,12 @@ static EM_BOOL EmscriptenPointerlockCallback(int eventType, const EmscriptenPoin static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData) { /* - TRACELOGD("%s: timeStamp: %g, connected: %d, index: %ld, numAxes: %d, numButtons: %d, id: \"%s\", mapping: \"%s\"", + TRACELOG(LOG_DEBUG, "%s: timeStamp: %g, connected: %d, index: %ld, numAxes: %d, numButtons: %d, id: \"%s\", mapping: \"%s\"", eventType != 0? emscripten_event_type_to_string(eventType) : "Gamepad state", gamepadEvent->timestamp, gamepadEvent->connected, gamepadEvent->index, gamepadEvent->numAxes, gamepadEvent->numButtons, gamepadEvent->id, gamepadEvent->mapping); - for (int i = 0; i < gamepadEvent->numAxes; i++) TRACELOGD("Axis %d: %g", i, gamepadEvent->axis[i]); - for (int i = 0; i < gamepadEvent->numButtons; i++) TRACELOGD("Button %d: Digital: %d, Analog: %g", i, gamepadEvent->digitalButton[i], gamepadEvent->analogButton[i]); + for (int i = 0; i < gamepadEvent->numAxes; i++) TRACELOG(LOG_DEBUG, "Axis %d: %g", i, gamepadEvent->axis[i]); + for (int i = 0; i < gamepadEvent->numButtons; i++) TRACELOG(LOG_DEBUG, "Button %d: Digital: %d, Analog: %g", i, gamepadEvent->digitalButton[i], gamepadEvent->analogButton[i]); */ if (gamepadEvent->connected && (gamepadEvent->index < MAX_GAMEPADS)) diff --git a/src/platforms/rcore_web_emscripten.c b/src/platforms/rcore_web_emscripten.c index 28d530e97..5fdcdbefc 100644 --- a/src/platforms/rcore_web_emscripten.c +++ b/src/platforms/rcore_web_emscripten.c @@ -1076,7 +1076,7 @@ void PollInputEvents(void) else CORE.Input.Gamepad.currentButtonState[i][button] = 0; } - //TRACELOGD("INPUT: Gamepad %d, button %d: Digital: %d, Analog: %g", gamepadState.index, j, gamepadState.digitalButton[j], gamepadState.analogButton[j]); + //TRACELOG(LOG_DEBUG, "INPUT: Gamepad %d, button %d: Digital: %d, Analog: %g", gamepadState.index, j, gamepadState.digitalButton[j], gamepadState.analogButton[j]); } // Register axis data for every connected gamepad @@ -1586,12 +1586,12 @@ static EM_BOOL EmscriptenPointerlockCallback(int eventType, const EmscriptenPoin static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData) { /* - TRACELOGD("%s: timeStamp: %g, connected: %d, index: %ld, numAxes: %d, numButtons: %d, id: \"%s\", mapping: \"%s\"", + TRACELOG(LOG_DEBUG, "%s: timeStamp: %g, connected: %d, index: %ld, numAxes: %d, numButtons: %d, id: \"%s\", mapping: \"%s\"", eventType != 0? emscripten_event_type_to_string(eventType) : "Gamepad state", gamepadEvent->timestamp, gamepadEvent->connected, gamepadEvent->index, gamepadEvent->numAxes, gamepadEvent->numButtons, gamepadEvent->id, gamepadEvent->mapping); - for (int i = 0; i < gamepadEvent->numAxes; i++) TRACELOGD("Axis %d: %g", i, gamepadEvent->axis[i]); - for (int i = 0; i < gamepadEvent->numButtons; i++) TRACELOGD("Button %d: Digital: %d, Analog: %g", i, gamepadEvent->digitalButton[i], gamepadEvent->analogButton[i]); + for (int i = 0; i < gamepadEvent->numAxes; i++) TRACELOG(LOG_DEBUG, "Axis %d: %g", i, gamepadEvent->axis[i]); + for (int i = 0; i < gamepadEvent->numButtons; i++) TRACELOG(LOG_DEBUG, "Button %d: Digital: %d, Analog: %g", i, gamepadEvent->digitalButton[i], gamepadEvent->analogButton[i]); */ if (gamepadEvent->connected && (gamepadEvent->index < MAX_GAMEPADS)) diff --git a/src/rlgl.h b/src/rlgl.h index ab85569bb..7fa22f9cc 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -132,7 +132,6 @@ // Support TRACELOG macros #ifndef TRACELOG #define TRACELOG(level, ...) (void)0 - #define TRACELOGD(...) (void)0 #endif // Allow custom memory allocators @@ -3324,7 +3323,7 @@ unsigned int rlLoadTexture(const void *data, int width, int height, int format, unsigned int glInternalFormat, glFormat, glType; rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType); - TRACELOGD("TEXTURE: Load mipmap level %i (%i x %i), size: %i, offset: %i", i, mipWidth, mipHeight, mipSize, mipOffset); + TRACELOG(RL_LOG_DEBUG, "TEXTURE: Load mipmap level %i (%i x %i), size: %i, offset: %i", i, mipWidth, mipHeight, mipSize, mipOffset); if (glInternalFormat != 0) { @@ -4246,7 +4245,7 @@ unsigned int rlLoadShaderCode(const char *vsCode, const char *fsCode) glGetActiveUniform(id, i, sizeof(name) - 1, &namelen, &num, &type, name); name[namelen] = 0; - TRACELOGD("SHADER: [ID %i] Active uniform (%s) set at location: %i", id, name, glGetUniformLocation(id, name)); + TRACELOG(RL_LOG_DEBUG, "SHADER: [ID %i] Active uniform (%s) set at location: %i", id, name, glGetUniformLocation(id, name)); } } */ diff --git a/src/rtext.c b/src/rtext.c index 1fd9a306d..8413d62bf 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -1035,7 +1035,7 @@ void UnloadFont(Font font) UnloadTexture(font.texture); RL_FREE(font.recs); - TRACELOGD("FONT: Unloaded font data from RAM and VRAM"); + TRACELOG(LOG_DEBUG, "FONT: Unloaded font data from RAM and VRAM"); } } diff --git a/src/rtextures.c b/src/rtextures.c index 59000940e..8d4128d4e 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -2395,7 +2395,7 @@ void ImageMipmaps(Image *image) if (mipWidth < 1) mipWidth = 1; if (mipHeight < 1) mipHeight = 1; - TRACELOGD("IMAGE: Next mipmap level: %i x %i - current size %i", mipWidth, mipHeight, mipSize); + TRACELOG(LOG_DEBUG, "IMAGE: Next mipmap level: %i x %i - current size %i", mipWidth, mipHeight, mipSize); mipCount++; mipSize += GetPixelDataSize(mipWidth, mipHeight, image->format); // Add mipmap size (in bytes) @@ -2432,7 +2432,7 @@ void ImageMipmaps(Image *image) if (i < image->mipmaps) continue; - TRACELOGD("IMAGE: Generating mipmap level: %i (%i x %i) - size: %i - offset: 0x%x", i, mipWidth, mipHeight, mipSize, nextmip); + TRACELOG(LOG_DEBUG, "IMAGE: Generating mipmap level: %i (%i x %i) - size: %i - offset: 0x%x", i, mipWidth, mipHeight, mipSize, nextmip); ImageResize(&imCopy, mipWidth, mipHeight); // Uses internally Mitchell cubic downscale filter memcpy(nextmip, imCopy.data, mipSize); } diff --git a/src/utils.h b/src/utils.h index 7d79c2188..9c15ac285 100644 --- a/src/utils.h +++ b/src/utils.h @@ -34,15 +34,8 @@ #if defined(SUPPORT_TRACELOG) #define TRACELOG(level, ...) TraceLog(level, __VA_ARGS__) - - #if defined(SUPPORT_TRACELOG_DEBUG) - #define TRACELOGD(...) TraceLog(LOG_DEBUG, __VA_ARGS__) - #else - #define TRACELOGD(...) (void)0 - #endif #else #define TRACELOG(level, ...) (void)0 - #define TRACELOGD(...) (void)0 #endif //---------------------------------------------------------------------------------- From c78ac657862e13898b4bc3a3b8a200a61667042c Mon Sep 17 00:00:00 2001 From: Jeffery Myers Date: Tue, 6 Jan 2026 13:32:42 -0800 Subject: [PATCH 077/232] Don't require a M3d animation only file to have a mesh. There are valid use cases for animation only files that can be applied to N other meshes. (#5475) --- src/rmodels.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rmodels.c b/src/rmodels.c index c22c0a0c9..20287a935 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -7045,8 +7045,8 @@ static ModelAnimation *LoadModelAnimationsM3D(const char *fileName, int *animCou else TRACELOG(LOG_INFO, "MODEL: [%s] M3D data loaded successfully: %i animations, %i bones, %i skins", fileName, m3d->numaction, m3d->numbone, m3d->numskin); - // No animation or bone+skin? - if (!m3d->numaction || !m3d->numbone || !m3d->numskin) + // No animation or bones, exit out. skins are not required because some people use one animation for N models + if (!m3d->numaction || !m3d->numbone) { m3d_free(m3d); UnloadFileData(fileData); From 23bc037c37545d6bcbf31231d00503339234fabf Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 7 Jan 2026 22:32:09 +0100 Subject: [PATCH 078/232] Revert change, trying to follow DRM implementation but not needed on Android #5477 --- src/platforms/rcore_android.c | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/src/platforms/rcore_android.c b/src/platforms/rcore_android.c index 6d3d68f24..19b686cef 100644 --- a/src/platforms/rcore_android.c +++ b/src/platforms/rcore_android.c @@ -919,26 +919,7 @@ static int InitGraphicsDevice(void) EGLint numConfigs = 0; // Get an EGL device connection - // NOTE: eglGetPlatformDisplay() is preferred over eglGetDisplay() legacy call - platform.device = EGL_NO_DISPLAY; -#if defined(EGL_VERSION_1_5) - platform.device = eglGetPlatformDisplay(EGL_PLATFORM_GBM_KHR, platform.gbmDevice, NULL); -#else - // Check if extension is available for eglGetPlatformDisplayEXT() - // NOTE: Better compatibility with some drivers (e.g. Mali Midgard) - const char *eglClientExtensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); - if (eglClientExtensions != NULL) - { - if (strstr(eglClientExtensions, "EGL_EXT_platform_base") != NULL) - { - PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT"); - if (eglGetPlatformDisplayEXT != NULL) platform.device = eglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_KHR, platform.gbmDevice, NULL); - } - } - - // In case extension not found or display could not be retrieved, try useing legacy version - if (platform.device == EGL_NO_DISPLAY) platform.device = eglGetDisplay(EGL_DEFAULT_DISPLAY); -#endif + platform.device = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (platform.device == EGL_NO_DISPLAY) { From c256f146b4c4e6b2f796bcb9e86197be44ec57e8 Mon Sep 17 00:00:00 2001 From: ssszcmawo Date: Wed, 7 Jan 2026 22:32:58 +0100 Subject: [PATCH 079/232] added saving to memory buffer and SaveFileData for binary files (#5476) --- src/rcore.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/rcore.c b/src/rcore.c index 59563537d..52ca0e2b6 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -3230,15 +3230,25 @@ bool ExportAutomationEventList(AutomationEventList list, const char *fileName) #if defined(SUPPORT_AUTOMATION_EVENTS) // Export events as binary file - // TODO: Save to memory buffer and SaveFileData() - /* - unsigned char fileId[4] = "rAE "; - FILE *raeFile = fopen(fileName, "wb"); - fwrite(fileId, sizeof(unsigned char), 4, raeFile); - fwrite(&eventCount, sizeof(int), 1, raeFile); - fwrite(events, sizeof(AutomationEvent), eventCount, raeFile); - fclose(raeFile); - */ + + // Binary buffer size = header (file id + count) + events data + int binarySize = 4 + sizeof(int) + sizeof(AutomationEvent)*list.count; + unsigned char *binBuffer = (unsigned char* )RL_MALLOC(binarySize); + if(!binBuffer) return false; + + int offset = 0; + memcpy(binBuffer + offset, "rAE ", 4); offset += 4; + memcpy(binBuffer + offset, &list.count, sizeof(int)); offset += sizeof(int); + + if(list.count > 0) + { + memcpy(binBuffer + offset, list.events,sizeof(AutomationEvent)*list.count); + offset += sizeof(AutomationEvent)*list.count; + } + + success = SaveFileData(TextFormat("%s.rae",fileName), binBuffer, binarySize); + + RL_FREE(binBuffer); // Export events as text // NOTE: Save to memory buffer and SaveFileText() From 229f82699ba311f8ca71c977d1eb6ae3ca2b6597 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 7 Jan 2026 22:36:40 +0100 Subject: [PATCH 080/232] Reviewed change #5476 --- src/rcore.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/rcore.c b/src/rcore.c index 52ca0e2b6..b7fcbf4a0 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -3230,25 +3230,24 @@ bool ExportAutomationEventList(AutomationEventList list, const char *fileName) #if defined(SUPPORT_AUTOMATION_EVENTS) // Export events as binary file - - // Binary buffer size = header (file id + count) + events data - int binarySize = 4 + sizeof(int) + sizeof(AutomationEvent)*list.count; - unsigned char *binBuffer = (unsigned char* )RL_MALLOC(binarySize); - if(!binBuffer) return false; - - int offset = 0; - memcpy(binBuffer + offset, "rAE ", 4); offset += 4; - memcpy(binBuffer + offset, &list.count, sizeof(int)); offset += sizeof(int); - - if(list.count > 0) + // NOTE: Code not used, only for reference if required in the future + /* + if (list.count > 0) { - memcpy(binBuffer + offset, list.events,sizeof(AutomationEvent)*list.count); + int binarySize = 4 + sizeof(int) + sizeof(AutomationEvent)*list.count; + unsigned char *binBuffer = (unsigned char *)RL_CALLOC(binarySize, 1); + int offset = 0; + memcpy(binBuffer + offset, "rAE ", 4); + offset += 4; + memcpy(binBuffer + offset, &list.count, sizeof(int)); + offset += sizeof(int); + memcpy(binBuffer + offset, list.events, sizeof(AutomationEvent)*list.count); offset += sizeof(AutomationEvent)*list.count; + + success = SaveFileData(TextFormat("%s.rae",fileName), binBuffer, binarySize); + RL_FREE(binBuffer); } - - success = SaveFileData(TextFormat("%s.rae",fileName), binBuffer, binarySize); - - RL_FREE(binBuffer); + */ // Export events as text // NOTE: Save to memory buffer and SaveFileText() From 5e1f5d5b7429bb7d1dae2be9a99266b73de954d4 Mon Sep 17 00:00:00 2001 From: Paul de Mascarel Date: Wed, 7 Jan 2026 22:38:04 +0100 Subject: [PATCH 081/232] examples/models: optimize collision check in first_person_maze (#5478) Limit collision detection to the player surrounding cells instead of iterating the full cubicmap each frame. --- examples/models/models_first_person_maze.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/models/models_first_person_maze.c b/examples/models/models_first_person_maze.c index 43020974f..eb0db6024 100644 --- a/examples/models/models_first_person_maze.c +++ b/examples/models/models_first_person_maze.c @@ -80,12 +80,13 @@ int main(void) if (playerCellY < 0) playerCellY = 0; else if (playerCellY >= cubicmap.height) playerCellY = cubicmap.height - 1; - // Check map collisions using image data and player position - // TODO: Improvement: Just check player surrounding cells for collision - for (int y = 0; y < cubicmap.height; y++) + // Check map collisions using image data and player position against surrounding cells only + for (int y = playerCellY - 1; y <= playerCellY + 1; y++) { - for (int x = 0; x < cubicmap.width; x++) + if (y < 0 || y >= cubicmap.height) continue; + for (int x = playerCellX - 1; x <= playerCellX + 1; x++) { + if (x < 0 || x >= cubicmap.width) continue; if ((mapPixels[y*cubicmap.width + x].r == 255) && // Collision: white pixel, only check R channel (CheckCollisionCircleRec(playerPos, playerRadius, (Rectangle){ mapPosition.x - 0.5f + x*1.0f, mapPosition.z - 0.5f + y*1.0f, 1.0f, 1.0f }))) From c814625c009f7bdbca47352a5951236558937e7e Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 7 Jan 2026 22:40:28 +0100 Subject: [PATCH 082/232] Update models_first_person_maze.c --- examples/models/models_first_person_maze.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/models/models_first_person_maze.c b/examples/models/models_first_person_maze.c index eb0db6024..4c77d6121 100644 --- a/examples/models/models_first_person_maze.c +++ b/examples/models/models_first_person_maze.c @@ -83,10 +83,14 @@ int main(void) // Check map collisions using image data and player position against surrounding cells only for (int y = playerCellY - 1; y <= playerCellY + 1; y++) { - if (y < 0 || y >= cubicmap.height) continue; + // Avoid map accessing out of bounds + if ((y < 0) || (y >= cubicmap.height)) continue; + for (int x = playerCellX - 1; x <= playerCellX + 1; x++) { - if (x < 0 || x >= cubicmap.width) continue; + // Avoid map accessing out of bounds + if ((x < 0) || (x >= cubicmap.width)) continue; + if ((mapPixels[y*cubicmap.width + x].r == 255) && // Collision: white pixel, only check R channel (CheckCollisionCircleRec(playerPos, playerRadius, (Rectangle){ mapPosition.x - 0.5f + x*1.0f, mapPosition.z - 0.5f + y*1.0f, 1.0f, 1.0f }))) From 5398b8c9b06589ee3897f6c17c8739a4260d3f86 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 7 Jan 2026 23:09:51 +0100 Subject: [PATCH 083/232] Update rexm.c --- tools/rexm/rexm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index d3ff18289..9914733f0 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -2894,8 +2894,8 @@ static void UpdateWebMetadata(const char *exHtmlPath, const char *exFilePath) // Get example name: replace underscore by spaces 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] = ' '; } + strcpy(exTitle, exName); + for (int i = 0; (i < 64) && (exTitle[i] != '\0'); i++) { if (exTitle[i] == '_') exTitle[i] = ' '; } // Get example category from exName: copy until first underscore for (int i = 0; (exName[i] != '_'); i++) exCategory[i] = exName[i]; From 0bcf79ce287d6180cedf7422c8a947e61247e81e Mon Sep 17 00:00:00 2001 From: Krzysztof Szenk Date: Thu, 8 Jan 2026 17:26:56 +0100 Subject: [PATCH 084/232] [#5455] Fix for: Fix window width calculation by adding wOffset (#5480) --- src/external/RGFW.h | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/external/RGFW.h b/src/external/RGFW.h index 0ab3858cf..c01ce1177 100644 --- a/src/external/RGFW.h +++ b/src/external/RGFW.h @@ -669,7 +669,8 @@ typedef struct RGFW_event { typedef struct RGFW_window_src { HWND window; /*!< source window */ HDC hdc; /*!< source HDC */ - u32 hOffset; /*!< height offset for window */ + i32 wOffset; /*!< width offset for window */ + i32 hOffset; /*!< height offset for window */ HICON hIconSmall, hIconBig; /*!< source window icons */ #if (defined(RGFW_OPENGL)) && !defined(RGFW_OSMESA) && !defined(RGFW_EGL) HGLRC ctx; /*!< source graphics context */ @@ -6537,11 +6538,11 @@ LRESULT CALLBACK WndProcW(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) else windowRect.bottom = windowRect.top + newHeight; } - RGFW_window_resize(win, RGFW_AREA((windowRect.right - windowRect.left), + RGFW_window_resize(win, RGFW_AREA((u32)(windowRect.right - windowRect.left) - (u32)win->src.wOffset, (u32)(windowRect.bottom - windowRect.top) - (u32)win->src.hOffset)); } - win->r.w = windowRect.right - windowRect.left; + win->r.w = (windowRect.right - windowRect.left) - (i32)win->src.wOffset; win->r.h = (windowRect.bottom - windowRect.top) - (i32)win->src.hOffset; RGFW_eventQueuePushEx(e.type = RGFW_windowResized; e._win = win); RGFW_windowResizedCallback(win, win->r); @@ -6561,12 +6562,12 @@ LRESULT CALLBACK WndProcW(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) #endif case WM_GETMINMAXINFO: { MINMAXINFO* mmi = (MINMAXINFO*) lParam; - mmi->ptMinTrackSize.x = (LONG)win->src.minSize.w; + mmi->ptMinTrackSize.x = (LONG)(win->src.minSize.w + win->src.wOffset); mmi->ptMinTrackSize.y = (LONG)(win->src.minSize.h + win->src.hOffset); if (win->src.maxSize.w == 0 && win->src.maxSize.h == 0) return DefWindowProcW(hWnd, message, wParam, lParam); - mmi->ptMaxTrackSize.x = (LONG)win->src.maxSize.w; + mmi->ptMaxTrackSize.x = (LONG)(win->src.maxSize.w + win->src.wOffset); mmi->ptMaxTrackSize.y = (LONG)(win->src.maxSize.h + win->src.hOffset); return DefWindowProcW(hWnd, message, wParam, lParam); } @@ -6969,7 +6970,7 @@ RGFW_window* RGFW_createWindowPtr(const char* name, RGFW_rect rect, RGFW_windowF win->src.hOffset = (u32)(windowRect.bottom - windowRect.top) - (u32)(clientRect.bottom - clientRect.top); win->src.wOffset = (u32)(windowRect.right - windowRect.left) - (u32)(clientRect.right - clientRect.left); - win->src.window = CreateWindowW(Class.lpszClassName, (wchar_t*)wide_name, window_style, win->r.x, win->r.y, win->r.w, win->r.h + (i32)win->src.hOffset, 0, 0, inh, 0); + win->src.window = CreateWindowW(Class.lpszClassName, (wchar_t*)wide_name, window_style, win->r.x, win->r.y, win->r.w + (i32)win->src.wOffset, win->r.h + (i32)win->src.hOffset, 0, 0, inh, 0); SetPropW(win->src.window, L"RGFW", win); RGFW_window_resize(win, RGFW_AREA(win->r.w, win->r.h)); /* so WM_GETMINMAXINFO gets called again */ @@ -7065,7 +7066,7 @@ void RGFW_window_setFullscreen(RGFW_window* win, RGFW_bool fullscreen) { if (fullscreen == RGFW_FALSE) { RGFW_window_setBorder(win, 1); - SetWindowPos(win->src.window, HWND_NOTOPMOST, win->_oldRect.x, win->_oldRect.y, win->_oldRect.w, win->_oldRect.h + (i32)win->src.hOffset, + SetWindowPos(win->src.window, HWND_NOTOPMOST, win->_oldRect.x, win->_oldRect.y, win->_oldRect.w + (i32)win->src.wOffset, win->_oldRect.h + (i32)win->src.hOffset, SWP_NOOWNERZORDER | SWP_FRAMECHANGED); win->_flags &= ~(u32)RGFW_windowFullscreen; @@ -7899,7 +7900,7 @@ void RGFW_window_resize(RGFW_window* win, RGFW_area a) { win->r.w = (i32)a.w; win->r.h = (i32)a.h; - SetWindowPos(win->src.window, HWND_TOP, 0, 0, win->r.w, win->r.h + (i32)win->src.hOffset, SWP_NOMOVE); + SetWindowPos(win->src.window, HWND_TOP, 0, 0, win->r.w + (i32)win->src.wOffset, win->r.h + (i32)win->src.hOffset, SWP_NOMOVE); } From 16e6d325b9f787bb99dc11c6504f8b73d37706ac Mon Sep 17 00:00:00 2001 From: Marcos Paccor Date: Thu, 8 Jan 2026 18:04:09 -0300 Subject: [PATCH 085/232] [raudio] Fix freeing the wrong memory (#5481) --- src/raudio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/raudio.c b/src/raudio.c index 98326727f..cfb86cdbd 100644 --- a/src/raudio.c +++ b/src/raudio.c @@ -1249,7 +1249,7 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels) frameCount = (ma_uint32)ma_convert_frames(data, frameCount, formatOut, channels, sampleRate, wave->data, frameCountIn, formatIn, wave->channels, wave->sampleRate); if (frameCount == 0) { - RL_FREE(wave->data); + RL_FREE(data); TRACELOG(LOG_WARNING, "WAVE: Failed format conversion"); return; } From 5cc42c1b805cd07227d48ee73c9c21c35fb528aa Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 9 Jan 2026 19:55:26 +0100 Subject: [PATCH 086/232] Updated file name --- examples/textures/textures_framebuffer_rendering.c | 2 +- ...ering.png => textures_framebuffer_rendering.png} | Bin 2 files changed, 1 insertion(+), 1 deletion(-) rename examples/textures/{textures_frame_buffer_rendering.png => textures_framebuffer_rendering.png} (100%) diff --git a/examples/textures/textures_framebuffer_rendering.c b/examples/textures/textures_framebuffer_rendering.c index a8b466187..484192739 100644 --- a/examples/textures/textures_framebuffer_rendering.c +++ b/examples/textures/textures_framebuffer_rendering.c @@ -11,7 +11,7 @@ * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software * -* Copyright (c) 2026-2026 Jack Boakes (@jackboakes) +* Copyright (c) 2026 Jack Boakes (@jackboakes) * ********************************************************************************************/ diff --git a/examples/textures/textures_frame_buffer_rendering.png b/examples/textures/textures_framebuffer_rendering.png similarity index 100% rename from examples/textures/textures_frame_buffer_rendering.png rename to examples/textures/textures_framebuffer_rendering.png From 4cf844b74ea9a3c5e5ab6cd57b4b7ff1eafe275b Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 9 Jan 2026 19:55:31 +0100 Subject: [PATCH 087/232] Update raylib.h --- src/raylib.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/raylib.h b/src/raylib.h index 2d411f896..6eae8411e 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -570,8 +570,7 @@ typedef enum { } TraceLogLevel; // Keyboard keys (US keyboard layout) -// NOTE: Use GetKeyPressed() to allow redefining -// required keys for alternative layouts +// NOTE: Use GetKeyPressed() to allow redefining required keys for alternative layouts typedef enum { KEY_NULL = 0, // Key: NULL, used for no key pressed // Alphanumeric keys From b365d23f49d352019eb29f2f4e52d481c48c70dd Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 9 Jan 2026 19:59:38 +0100 Subject: [PATCH 088/232] Update examples_list.txt --- examples/examples_list.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/examples_list.txt b/examples/examples_list.txt index 96d64ca84..ba3a16d08 100644 --- a/examples/examples_list.txt +++ b/examples/examples_list.txt @@ -124,6 +124,7 @@ textures;textures_screen_buffer;★★☆☆;5.5;5.5;2025;2025;"Agnis Aldiņš"; textures;textures_textured_curve;★★★☆;4.5;4.5;2022;2025;"Jeffery Myers";@JeffM2501 textures;textures_sprite_stacking;★★☆☆;5.6-dev;6.0;2025;2025;"Robin";@RobinsAviary textures;textures_cellular_automata;★★☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant +texture;textures_framebuffer_rendering;★★☆☆;5.6;5.6;2026;2026;"Jack Boakes";@jackboakes text;text_sprite_fonts;★☆☆☆;1.7;3.7;2017;2025;"Ramon Santamaria";@raysan5 text;text_font_spritefont;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5 text;text_font_filters;★★☆☆;1.3;4.2;2015;2025;"Ramon Santamaria";@raysan5 From cfd5c3f2abe2a54cfa5cc60806601455feafc769 Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 9 Jan 2026 20:02:29 +0100 Subject: [PATCH 089/232] Update examples_list.txt --- examples/examples_list.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/examples_list.txt b/examples/examples_list.txt index ba3a16d08..c825e137d 100644 --- a/examples/examples_list.txt +++ b/examples/examples_list.txt @@ -124,7 +124,7 @@ textures;textures_screen_buffer;★★☆☆;5.5;5.5;2025;2025;"Agnis Aldiņš"; textures;textures_textured_curve;★★★☆;4.5;4.5;2022;2025;"Jeffery Myers";@JeffM2501 textures;textures_sprite_stacking;★★☆☆;5.6-dev;6.0;2025;2025;"Robin";@RobinsAviary textures;textures_cellular_automata;★★☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant -texture;textures_framebuffer_rendering;★★☆☆;5.6;5.6;2026;2026;"Jack Boakes";@jackboakes +textures;textures_framebuffer_rendering;★★☆☆;5.6;5.6;2026;2026;"Jack Boakes";@jackboakes text;text_sprite_fonts;★☆☆☆;1.7;3.7;2017;2025;"Ramon Santamaria";@raysan5 text;text_font_spritefont;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5 text;text_font_filters;★★☆☆;1.3;4.2;2015;2025;"Ramon Santamaria";@raysan5 From 7218b674e5cab56a89ffad8e4f9ec5cea1e1c06e Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 9 Jan 2026 20:05:46 +0100 Subject: [PATCH 090/232] REXM: Updated: `textures_framebuffer_rendering` --- examples/Makefile | 1 + examples/Makefile.Web | 4 + .../textures_framebuffer_rendering.vcxproj | 569 ++++++++++++++++++ tools/rexm/reports/examples_issues.md | 1 + tools/rexm/reports/examples_validation.md | 3 +- 5 files changed, 577 insertions(+), 1 deletion(-) create mode 100644 projects/VS2022/examples/textures_framebuffer_rendering.vcxproj diff --git a/examples/Makefile b/examples/Makefile index 3cbc2ffc1..a402ae692 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -608,6 +608,7 @@ TEXTURES = \ textures/textures_bunnymark \ textures/textures_cellular_automata \ textures/textures_fog_of_war \ + textures/textures_framebuffer_rendering \ textures/textures_gif_player \ textures/textures_image_channel \ textures/textures_image_drawing \ diff --git a/examples/Makefile.Web b/examples/Makefile.Web index fe4de1330..556900a76 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -594,6 +594,7 @@ TEXTURES = \ textures/textures_bunnymark \ textures/textures_cellular_automata \ textures/textures_fog_of_war \ + textures/textures_framebuffer_rendering \ textures/textures_gif_player \ textures/textures_image_channel \ textures/textures_image_drawing \ @@ -1009,6 +1010,9 @@ textures/textures_cellular_automata: textures/textures_cellular_automata.c textures/textures_fog_of_war: textures/textures_fog_of_war.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) +textures/textures_framebuffer_rendering: textures/textures_framebuffer_rendering.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + textures/textures_gif_player: textures/textures_gif_player.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file textures/resources/scarfy_run.gif@resources/scarfy_run.gif diff --git a/projects/VS2022/examples/textures_framebuffer_rendering.vcxproj b/projects/VS2022/examples/textures_framebuffer_rendering.vcxproj new file mode 100644 index 000000000..3a7eeeb35 --- /dev/null +++ b/projects/VS2022/examples/textures_framebuffer_rendering.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 + + + + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E} + Win32Proj + textures_framebuffer_rendering + 10.0 + textures_framebuffer_rendering + + + + 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/tools/rexm/reports/examples_issues.md b/tools/rexm/reports/examples_issues.md index 081170806..7b39c7a0b 100644 --- a/tools/rexm/reports/examples_issues.md +++ b/tools/rexm/reports/examples_issues.md @@ -21,6 +21,7 @@ Example elements validated: | **EXAMPLE NAME** | [C] | [CAT]| [INFO]|[PNG]|[WPNG]| [RES]| [MK] |[MKWEB]| [VCX]| [SOL]|[RDME]|[JS] | [WOUT]|[WMETA]| |:---------------------------------|:---:|:----:|:-----:|:---:|:----:|:----:|:----:|:-----:|:----:|:----:|:----:|:---:|:-----:|:-----:| | core_highdpi_testbed | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| core_keyboard_testbed | ✔ | ✔ | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | rlgl_standalone | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | rlgl_compute_shader | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | easings_testbed | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | diff --git a/tools/rexm/reports/examples_validation.md b/tools/rexm/reports/examples_validation.md index 6770f3c37..8d3f699ca 100644 --- a/tools/rexm/reports/examples_validation.md +++ b/tools/rexm/reports/examples_validation.md @@ -105,6 +105,7 @@ Example elements validated: | shapes_rlgl_triangle | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_ball_physics | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_penrose_tile | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_hilbert_curve | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_logo_raylib | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_srcrec_dstrec | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_image_drawing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | @@ -134,6 +135,7 @@ Example elements validated: | textures_textured_curve | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_sprite_stacking | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_cellular_automata | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| textures_framebuffer_rendering | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_sprite_fonts | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_font_spritefont | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_font_filters | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | @@ -225,4 +227,3 @@ Example elements validated: | raylib_opengl_interop | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | | embedded_files_loading | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | web_basic_window | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_hilbert_curve | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | From 11f7db2dd8c00b397980fab82372ef17c4b9a709 Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 9 Jan 2026 20:06:53 +0100 Subject: [PATCH 091/232] REXM: ADDED: `core_keyboard_testbed` --- examples/Makefile | 1 + examples/Makefile.Web | 4 + examples/README.md | 8 +- examples/core/core_keyboard_testbed.c | 333 ++++++++++ examples/core/core_keyboard_testbed.png | Bin 0 -> 17631 bytes examples/examples_list.txt | 1 + .../examples/core_keyboard_testbed.vcxproj | 569 ++++++++++++++++++ projects/VS2022/raylib.sln | 54 ++ tools/rexm/reports/examples_issues.md | 1 - tools/rexm/reports/examples_validation.md | 1 + 10 files changed, 968 insertions(+), 4 deletions(-) create mode 100644 examples/core/core_keyboard_testbed.c create mode 100644 examples/core/core_keyboard_testbed.png create mode 100644 projects/VS2022/examples/core_keyboard_testbed.vcxproj diff --git a/examples/Makefile b/examples/Makefile index a402ae692..acfcb0857 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -544,6 +544,7 @@ CORE = \ core/core_input_mouse_wheel \ core/core_input_multitouch \ core/core_input_virtual_controls \ + core/core_keyboard_testbed \ core/core_monitor_detector \ core/core_random_sequence \ core/core_random_values \ diff --git a/examples/Makefile.Web b/examples/Makefile.Web index 556900a76..3841dff29 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -530,6 +530,7 @@ CORE = \ core/core_input_mouse_wheel \ core/core_input_multitouch \ core/core_input_virtual_controls \ + core/core_keyboard_testbed \ core/core_monitor_detector \ core/core_random_sequence \ core/core_random_values \ @@ -820,6 +821,9 @@ core/core_input_multitouch: core/core_input_multitouch.c core/core_input_virtual_controls: core/core_input_virtual_controls.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) +core/core_keyboard_testbed: core/core_keyboard_testbed.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + core/core_monitor_detector: core/core_monitor_detector.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) diff --git a/examples/README.md b/examples/README.md index d9b03669d..6b2c1950b 100644 --- a/examples/README.md +++ b/examples/README.md @@ -17,9 +17,9 @@ You may find it easier to use than other toolchains, especially when it comes to - `zig build [module]` to compile all examples for a module (e.g. `zig build core`) - `zig build [example]` to compile _and run_ a particular example (e.g. `zig build core_basic_window`) -## EXAMPLES COLLECTION [TOTAL: 206] +## EXAMPLES COLLECTION [TOTAL: 208] -### category: core [47] +### category: core [48] Examples using raylib [core](../src/rcore.c) module platform functionality: window creation, inputs, drawing modes and system functionality. @@ -72,6 +72,7 @@ Examples using raylib [core](../src/rcore.c) module platform functionality: wind | [core_clipboard_text](core/core_clipboard_text.c) | core_clipboard_text | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Ananth S](https://github.com/Ananth1839) | | [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) | +| [core_keyboard_testbed](core/core_keyboard_testbed.c) | core_keyboard_testbed | ⭐⭐☆☆ | 5.6 | 5.6 | [Ramon Santamaria](https://github.com/raysan5) | ### category: shapes [39] @@ -119,7 +120,7 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes]( | [shapes_penrose_tile](shapes/shapes_penrose_tile.c) | shapes_penrose_tile | ⭐⭐⭐⭐️ | 5.5 | 5.6-dev | [David Buzatto](https://github.com/davidbuzatto) | | [shapes_hilbert_curve](shapes/shapes_hilbert_curve.c) | shapes_hilbert_curve | ⭐⭐⭐☆ | 5.6 | 5.6 | [Hamza RAHAL](https://github.com/hmz-rhl) | -### category: textures [29] +### category: textures [30] Examples using raylib textures functionality, including image/textures loading/generation and drawing, provided by raylib [textures](../src/rtextures.c) module. @@ -154,6 +155,7 @@ Examples using raylib textures functionality, including image/textures loading/g | [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) | +| [textures_framebuffer_rendering](textures/textures_framebuffer_rendering.c) | textures_framebuffer_rendering | ⭐⭐☆☆ | 5.6 | 5.6 | [Jack Boakes](https://github.com/jackboakes) | ### category: text [16] diff --git a/examples/core/core_keyboard_testbed.c b/examples/core/core_keyboard_testbed.c new file mode 100644 index 000000000..904e9c90a --- /dev/null +++ b/examples/core/core_keyboard_testbed.c @@ -0,0 +1,333 @@ +/******************************************************************************************* +* +* raylib [core] example - keyboard testbed +* +* Example complexity rating: [★★☆☆] 2/4 +* +* NOTE: raylib defined keys refer to ENG-US Keyboard layout, +* mapping to other layouts is up to the user +* +* Example originally created with raylib 5.6, last time updated with raylib 5.6 +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2026 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#define KEY_REC_SPACING 4 // Space in pixels between key rectangles + +//------------------------------------------------------------------------------------ +// Module Functions Declaration +//------------------------------------------------------------------------------------ +static const char *GetKeyText(int key); +static void GuiKeyboardKey(Rectangle bounds, int key); + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [core] example - keyboard testbed"); + SetExitKey(KEY_NULL); // Avoid exit on KEY_ESCAPE + + // Keyboard line 01 + int line01KeyWidths[15] = { 0 }; + for (int i = 0; i < 15; i++) line01KeyWidths[i] = 45; + line01KeyWidths[13] = 62; // PRINTSCREEN + int line01Keys[15] = { + KEY_ESCAPE, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, + KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11, + KEY_F12, KEY_PRINT_SCREEN, KEY_PAUSE + }; + + // Keyboard line 02 + int line02KeyWidths[15] = { 0 }; + for (int i = 0; i < 15; i++) line02KeyWidths[i] = 45; + line02KeyWidths[0] = 25; // GRAVE + line02KeyWidths[13] = 82; // BACKSPACE + int line02Keys[15] = { + KEY_GRAVE, KEY_ONE, KEY_TWO, KEY_THREE, KEY_FOUR, + KEY_FIVE, KEY_SIX, KEY_SEVEN, KEY_EIGHT, KEY_NINE, + KEY_ZERO, KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_DELETE }; + + // Keyboard line 03 + int line03KeyWidths[15] = { 0 }; + for (int i = 0; i < 15; i++) line03KeyWidths[i] = 45; + line03KeyWidths[0] = 50; // TAB + line03KeyWidths[13] = 57; // BACKSLASH + int line03Keys[15] = { + KEY_TAB, KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y, + KEY_U, KEY_I, KEY_O, KEY_P, KEY_LEFT_BRACKET, + KEY_RIGHT_BRACKET, KEY_BACKSLASH, KEY_INSERT + }; + + // Keyboard line 04 + int line04KeyWidths[14] = { 0 }; + for (int i = 0; i < 14; i++) line04KeyWidths[i] = 45; + line04KeyWidths[0] = 68; // CAPS + line04KeyWidths[12] = 88; // ENTER + int line04Keys[14] = { + KEY_CAPS_LOCK, KEY_A, KEY_S, KEY_D, KEY_F, KEY_G, + KEY_H, KEY_J, KEY_K, KEY_L, KEY_SEMICOLON, + KEY_APOSTROPHE, KEY_ENTER, KEY_PAGE_UP + }; + + // Keyboard line 05 + int line05KeyWidths[14] = { 0 }; + for (int i = 0; i < 14; i++) line05KeyWidths[i] = 45; + line05KeyWidths[0] = 80; // LSHIFT + line05KeyWidths[11] = 76; // RSHIFT + int line05Keys[14] = { + KEY_LEFT_SHIFT, KEY_Z, KEY_X, KEY_C, KEY_V, KEY_B, + KEY_N, KEY_M, KEY_COMMA, KEY_PERIOD, /*KEY_MINUS*/ + KEY_SLASH, KEY_RIGHT_SHIFT, KEY_UP, KEY_PAGE_DOWN + }; + + // Keyboard line 06 + int line06KeyWidths[11] = { 0 }; + for (int i = 0; i < 11; i++) line06KeyWidths[i] = 45; + line06KeyWidths[0] = 80; // LCTRL + line06KeyWidths[3] = 208; // SPACE + line06KeyWidths[7] = 60; // RCTRL + int line06Keys[11] = { + KEY_LEFT_CONTROL, KEY_LEFT_SUPER, KEY_LEFT_ALT, + KEY_SPACE, KEY_RIGHT_ALT, 162, KEY_NULL, + KEY_RIGHT_CONTROL, KEY_LEFT, KEY_DOWN, KEY_RIGHT + }; + + Vector2 keyboardOffset = { 26, 80 }; + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + int key = GetKeyPressed(); // Get pressed keycode + if (key > 0) TraceLog(LOG_INFO, "KEYBOARD TESTBED: KEY PRESSED: %d", key); + + int ch = GetCharPressed(); // Get pressed char for text input, using OS mapping + if (ch > 0) TraceLog(LOG_INFO, "KEYBOARD TESTBED: CHAR PRESSED: %c (%d)", ch, ch); + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + DrawText("KEYBOARD LAYOUT: ENG-US", 26, 38, 20, LIGHTGRAY); + + // Keyboard line 01 - 15 keys + // ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, IMP, CLOSE + for (int i = 0, recOffsetX = 0; i < 15; i++) + { + GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y, line01KeyWidths[i], 30 }, line01Keys[i]); + recOffsetX += line01KeyWidths[i] + KEY_REC_SPACING; + } + + // Keyboard line 02 - 15 keys + // `, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, -, =, BACKSPACE, DEL + for (int i = 0, recOffsetX = 0; i < 15; i++) + { + GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + KEY_REC_SPACING, line02KeyWidths[i], 38 }, line02Keys[i]); + recOffsetX += line02KeyWidths[i] + KEY_REC_SPACING; + } + + // Keyboard line 03 - 15 keys + // TAB, Q, W, E, R, T, Y, U, I, O, P, [, ], \, INS + for (int i = 0, recOffsetX = 0; i < 15; i++) + { + GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38 + KEY_REC_SPACING*2, line03KeyWidths[i], 38 }, line03Keys[i]); + recOffsetX += line03KeyWidths[i] + KEY_REC_SPACING; + } + + // Keyboard line 04 - 14 keys + // MAYUS, A, S, D, F, G, H, J, K, L, ;, ', ENTER, REPAG + for (int i = 0, recOffsetX = 0; i < 14; i++) + { + GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38*2 + KEY_REC_SPACING*3, line04KeyWidths[i], 38 }, line04Keys[i]); + recOffsetX += line04KeyWidths[i] + KEY_REC_SPACING; + } + + // Keyboard line 05 - 14 keys + // LSHIFT, Z, X, C, V, B, N, M, ,, ., /, RSHIFT, UP, AVPAG + for (int i = 0, recOffsetX = 0; i < 14; i++) + { + GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38*3 + KEY_REC_SPACING*4, line05KeyWidths[i], 38 }, line05Keys[i]); + recOffsetX += line05KeyWidths[i] + KEY_REC_SPACING; + } + + // Keyboard line 06 - 11 keys + // LCTRL, WIN, LALT, SPACE, ALTGR, \, FN, RCTRL, LEFT, DOWN, RIGHT + for (int i = 0, recOffsetX = 0; i < 11; i++) + { + GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38*4 + KEY_REC_SPACING*5, line06KeyWidths[i], 38 }, line06Keys[i]); + recOffsetX += line06KeyWidths[i] + KEY_REC_SPACING; + } + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} + +//------------------------------------------------------------------------------------ +// Module Functions Definition +//------------------------------------------------------------------------------------ +// Get keyboard keycode as text (US keyboard) +// NOTE: Mapping for other keyboard layouts can be done here +static const char *GetKeyText(int key) +{ + switch (key) + { + case KEY_APOSTROPHE : return "'"; // Key: ' + case KEY_COMMA : return ","; // Key: , + case KEY_MINUS : return "-"; // Key: - + case KEY_PERIOD : return "."; // Key: . + case KEY_SLASH : return "/"; // Key: / + case KEY_ZERO : return "0"; // Key: 0 + case KEY_ONE : return "1"; // Key: 1 + case KEY_TWO : return "2"; // Key: 2 + case KEY_THREE : return "3"; // Key: 3 + case KEY_FOUR : return "4"; // Key: 4 + case KEY_FIVE : return "5"; // Key: 5 + case KEY_SIX : return "6"; // Key: 6 + case KEY_SEVEN : return "7"; // Key: 7 + case KEY_EIGHT : return "8"; // Key: 8 + case KEY_NINE : return "9"; // Key: 9 + case KEY_SEMICOLON : return ";"; // Key: ; + case KEY_EQUAL : return "="; // Key: = + case KEY_A : return "A"; // Key: A | a + case KEY_B : return "B"; // Key: B | b + case KEY_C : return "C"; // Key: C | c + case KEY_D : return "D"; // Key: D | d + case KEY_E : return "E"; // Key: E | e + case KEY_F : return "F"; // Key: F | f + case KEY_G : return "G"; // Key: G | g + case KEY_H : return "H"; // Key: H | h + case KEY_I : return "I"; // Key: I | i + case KEY_J : return "J"; // Key: J | j + case KEY_K : return "K"; // Key: K | k + case KEY_L : return "L"; // Key: L | l + case KEY_M : return "M"; // Key: M | m + case KEY_N : return "N"; // Key: N | n + case KEY_O : return "O"; // Key: O | o + case KEY_P : return "P"; // Key: P | p + case KEY_Q : return "Q"; // Key: Q | q + case KEY_R : return "R"; // Key: R | r + case KEY_S : return "S"; // Key: S | s + case KEY_T : return "T"; // Key: T | t + case KEY_U : return "U"; // Key: U | u + case KEY_V : return "V"; // Key: V | v + case KEY_W : return "W"; // Key: W | w + case KEY_X : return "X"; // Key: X | x + case KEY_Y : return "Y"; // Key: Y | y + case KEY_Z : return "Z"; // Key: Z | z + case KEY_LEFT_BRACKET : return "["; // Key: [ + case KEY_BACKSLASH : return "\\"; // Key: '\' + case KEY_RIGHT_BRACKET : return "]"; // Key: ] + case KEY_GRAVE : return "`"; // Key: ` + case KEY_SPACE : return "SPACE"; // Key: Space + case KEY_ESCAPE : return "ESC"; // Key: Esc + case KEY_ENTER : return "ENTER"; // Key: Enter + case KEY_TAB : return "TAB"; // Key: Tab + case KEY_BACKSPACE : return "BACK"; // Key: Backspace + case KEY_INSERT : return "INS"; // Key: Ins + case KEY_DELETE : return "DEL"; // Key: Del + case KEY_RIGHT : return "RIGHT"; // Key: Cursor right + case KEY_LEFT : return "LEFT"; // Key: Cursor left + case KEY_DOWN : return "DOWN"; // Key: Cursor down + case KEY_UP : return "UP"; // Key: Cursor up + case KEY_PAGE_UP : return "PGUP"; // Key: Page up + case KEY_PAGE_DOWN : return "PGDOWN"; // Key: Page down + case KEY_HOME : return "HOME"; // Key: Home + case KEY_END : return "END"; // Key: End + case KEY_CAPS_LOCK : return "CAPS"; // Key: Caps lock + case KEY_SCROLL_LOCK : return "LOCK"; // Key: Scroll down + case KEY_NUM_LOCK : return "NUMLOCK"; // Key: Num lock + case KEY_PRINT_SCREEN : return "PRINTSCR"; // Key: Print screen + case KEY_PAUSE : return "PAUSE"; // Key: Pause + case KEY_F1 : return "F1"; // Key: F1 + case KEY_F2 : return "F2"; // Key: F2 + case KEY_F3 : return "F3"; // Key: F3 + case KEY_F4 : return "F4"; // Key: F4 + case KEY_F5 : return "F5"; // Key: F5 + case KEY_F6 : return "F6"; // Key: F6 + case KEY_F7 : return "F7"; // Key: F7 + case KEY_F8 : return "F8"; // Key: F8 + case KEY_F9 : return "F9"; // Key: F9 + case KEY_F10 : return "F10"; // Key: F10 + case KEY_F11 : return "F11"; // Key: F11 + case KEY_F12 : return "F12"; // Key: F12 + case KEY_LEFT_SHIFT : return "LSHIFT"; // Key: Shift left + case KEY_LEFT_CONTROL : return "LCTRL"; // Key: Control left + case KEY_LEFT_ALT : return "LALT"; // Key: Alt left + case KEY_LEFT_SUPER : return "WIN"; // Key: Super left + case KEY_RIGHT_SHIFT : return "RSHIFT"; // Key: Shift right + case KEY_RIGHT_CONTROL : return "RCTRL"; // Key: Control right + case KEY_RIGHT_ALT : return "ALTGR"; // Key: Alt right + case KEY_RIGHT_SUPER : return "RSUPER"; // Key: Super right + case KEY_KB_MENU : return "KBMENU"; // Key: KB menu + case KEY_KP_0 : return "KP0"; // Key: Keypad 0 + case KEY_KP_1 : return "KP1"; // Key: Keypad 1 + case KEY_KP_2 : return "KP2"; // Key: Keypad 2 + case KEY_KP_3 : return "KP3"; // Key: Keypad 3 + case KEY_KP_4 : return "KP4"; // Key: Keypad 4 + case KEY_KP_5 : return "KP5"; // Key: Keypad 5 + case KEY_KP_6 : return "KP6"; // Key: Keypad 6 + case KEY_KP_7 : return "KP7"; // Key: Keypad 7 + case KEY_KP_8 : return "KP8"; // Key: Keypad 8 + case KEY_KP_9 : return "KP9"; // Key: Keypad 9 + case KEY_KP_DECIMAL : return "KPDEC"; // Key: Keypad . + case KEY_KP_DIVIDE : return "KPDIV"; // Key: Keypad / + case KEY_KP_MULTIPLY : return "KPMUL"; // Key: Keypad * + case KEY_KP_SUBTRACT : return "KPSUB"; // Key: Keypad - + case KEY_KP_ADD : return "KPADD"; // Key: Keypad + + case KEY_KP_ENTER : return "KPENTER"; // Key: Keypad Enter + case KEY_KP_EQUAL : return "KPEQU"; // Key: Keypad = + default: return ""; + } +} + +// Draw keyboard key +static void GuiKeyboardKey(Rectangle bounds, int key) +{ + if (key == KEY_NULL) DrawRectangleLinesEx(bounds, 2.0f, LIGHTGRAY); + else + { + if (IsKeyDown(key)) + { + DrawRectangleLinesEx(bounds, 2.0f, MAROON); + DrawText(GetKeyText(key), bounds.x + 4, bounds.y + 4, 10, MAROON); + } + else + { + DrawRectangleLinesEx(bounds, 2.0f, DARKGRAY); + DrawText(GetKeyText(key), bounds.x + 4, bounds.y + 4, 10, DARKGRAY); + } + } + + if (CheckCollisionPointRec(GetMousePosition(), bounds)) + { + DrawRectangleRec(bounds, Fade(RED, 0.2f)); + DrawRectangleLinesEx(bounds, 3.0f, RED); + } +} \ No newline at end of file diff --git a/examples/core/core_keyboard_testbed.png b/examples/core/core_keyboard_testbed.png new file mode 100644 index 0000000000000000000000000000000000000000..bac0fc29ac41ee31592622b54bf65af602427995 GIT binary patch literal 17631 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 literal 0 HcmV?d00001 diff --git a/examples/examples_list.txt b/examples/examples_list.txt index c825e137d..eda62ee13 100644 --- a/examples/examples_list.txt +++ b/examples/examples_list.txt @@ -56,6 +56,7 @@ core;core_screen_recording;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santama core;core_clipboard_text;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ananth S";@Ananth1839 core;core_text_file_loading;★☆☆☆;5.5;5.6;0;0;"Aanjishnu Bhattacharyya";@NimComPoo-04 core;core_compute_hash;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5 +core;core_keyboard_testbed;★★☆☆;5.6;5.6;2026;2026;"Ramon Santamaria";@raysan5 shapes;shapes_basic_shapes;★☆☆☆;1.0;4.2;2014;2025;"Ramon Santamaria";@raysan5 shapes;shapes_bouncing_ball;★☆☆☆;2.5;2.5;2013;2025;"Ramon Santamaria";@raysan5 shapes;shapes_bullet_hell;★☆☆☆;5.6;5.6;2025;2025;"Zero";@zerohorsepower diff --git a/projects/VS2022/examples/core_keyboard_testbed.vcxproj b/projects/VS2022/examples/core_keyboard_testbed.vcxproj new file mode 100644 index 000000000..3a146b762 --- /dev/null +++ b/projects/VS2022/examples/core_keyboard_testbed.vcxproj @@ -0,0 +1,569 @@ + + + + + Debug.DLL + ARM64 + + + Debug.DLL + Win32 + + + Debug.DLL + x64 + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + Release.DLL + ARM64 + + + Release.DLL + Win32 + + + Release.DLL + x64 + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + {6B1A933E-71B8-4C1F-9E79-02D98830E671} + Win32Proj + core_keyboard_testbed + 10.0 + core_keyboard_testbed + + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;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 df2633843..93c4efaf1 100644 --- a/projects/VS2022/raylib.sln +++ b/projects/VS2022/raylib.sln @@ -433,6 +433,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_cellular_automata" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_hilbert_curve", "examples\shapes_hilbert_curve.vcxproj", "{DC163251-16C3-4B72-B965-ACDBA0F02BD1}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_keyboard_testbed", "examples\core_keyboard_testbed.vcxproj", "{6B1A933E-71B8-4C1F-9E79-02D98830E671}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_framebuffer_rendering", "examples\textures_framebuffer_rendering.vcxproj", "{2CCCD9E4-9058-4291-BD89-39C979F0CA1E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug.DLL|ARM64 = Debug.DLL|ARM64 @@ -5391,6 +5395,54 @@ Global {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|x64.Build.0 = Release|x64 {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|x86.ActiveCfg = Release|Win32 {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|x86.Build.0 = Release|Win32 + {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|ARM64.Build.0 = Debug|ARM64 + {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x64.ActiveCfg = Debug|x64 + {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x64.Build.0 = Debug|x64 + {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x86.ActiveCfg = Debug|Win32 + {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x86.Build.0 = Debug|Win32 + {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|ARM64.ActiveCfg = Release|ARM64 + {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|ARM64.Build.0 = Release|ARM64 + {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x64.ActiveCfg = Release|x64 + {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x64.Build.0 = Release|x64 + {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x86.ActiveCfg = Release|Win32 + {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x86.Build.0 = Release|Win32 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|ARM64.Build.0 = Debug|ARM64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|x64.ActiveCfg = Debug|x64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|x64.Build.0 = Debug|x64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|x86.ActiveCfg = Debug|Win32 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|x86.Build.0 = Debug|Win32 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|ARM64.ActiveCfg = Release|ARM64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|ARM64.Build.0 = Release|ARM64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|x64.ActiveCfg = Release|x64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|x64.Build.0 = Release|x64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|x86.ActiveCfg = Release|Win32 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -5609,6 +5661,8 @@ Global {1F4722E7-F78E-413F-A106-D3490211EA57} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} {0A0FC982-6E31-401F-BA77-3C5E8AB02C68} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} {DC163251-16C3-4B72-B965-ACDBA0F02BD1} = {278D8859-20B1-428F-8448-064F46E1F021} + {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29} diff --git a/tools/rexm/reports/examples_issues.md b/tools/rexm/reports/examples_issues.md index 7b39c7a0b..081170806 100644 --- a/tools/rexm/reports/examples_issues.md +++ b/tools/rexm/reports/examples_issues.md @@ -21,7 +21,6 @@ Example elements validated: | **EXAMPLE NAME** | [C] | [CAT]| [INFO]|[PNG]|[WPNG]| [RES]| [MK] |[MKWEB]| [VCX]| [SOL]|[RDME]|[JS] | [WOUT]|[WMETA]| |:---------------------------------|:---:|:----:|:-----:|:---:|:----:|:----:|:----:|:-----:|:----:|:----:|:----:|:---:|:-----:|:-----:| | core_highdpi_testbed | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| core_keyboard_testbed | ✔ | ✔ | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | rlgl_standalone | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | rlgl_compute_shader | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | easings_testbed | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | diff --git a/tools/rexm/reports/examples_validation.md b/tools/rexm/reports/examples_validation.md index 8d3f699ca..d8f4a9521 100644 --- a/tools/rexm/reports/examples_validation.md +++ b/tools/rexm/reports/examples_validation.md @@ -67,6 +67,7 @@ Example elements validated: | core_clipboard_text | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_text_file_loading | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_compute_hash | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| core_keyboard_testbed | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_basic_shapes | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_bouncing_ball | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_bullet_hell | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | From a6dd2af9e993a3a1d22696324e01f5b4f446c890 Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 9 Jan 2026 20:06:57 +0100 Subject: [PATCH 092/232] Update rexm.c --- tools/rexm/rexm.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 9914733f0..95ed13739 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -570,7 +570,7 @@ int main(int argc, char *argv[]) // ----------------------------------------------------------------------------------------- // Add example to the collection list, if not already there - // NOTE: Required format: shapes;shapes_basic_shapes;★☆☆☆;1.0;4.2;2014;2025;"Ray";@raysan5 + // NOTE: Required format: shapes;shapes_basic_shapes;★☆☆☆;1.0;4.2;2014;2026;"Ray";@raysan5 //------------------------------------------------------------------------------------------------ char *exCollectionList = LoadFileText(exCollectionFilePath); if (TextFindIndex(exCollectionList, exName) == -1) // Example not found @@ -2440,7 +2440,7 @@ static void UnloadExampleInfo(rlExampleInfo *exInfo) } // raylib example line info parser -// Parses following line format: core;core_basic_window;★☆☆☆;1.0;1.0;2013;2025;"Ray";@raysan5 +// Parses following line format: core;core_basic_window;★☆☆☆;1.0;1.0;2013;2026;"Ray";@raysan5 static int ParseExampleInfoLine(const char *line, rlExampleInfo *entry) { #define MAX_EXAMPLE_INFO_LINE_LEN 512 @@ -2452,7 +2452,10 @@ static int ParseExampleInfoLine(const char *line, rlExampleInfo *entry) int tokenCount = 0; char **tokens = TextSplit(line, ';', &tokenCount); - if (tokenCount != 9) LOG("REXM: WARNING: Example collection line contains invalid number of tokens: %i\n", tokenCount); + if (tokenCount != 9) + { + LOG("REXM: WARNING: Example collection line contains invalid number of tokens: %i\n", tokenCount); + } // Get category and name strcpy(entry->category, tokens[0]); From 1284d687213ae53313cf69f283e04a0e6c200c17 Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 9 Jan 2026 20:18:45 +0100 Subject: [PATCH 093/232] Update core_highdpi_testbed.png --- examples/core/core_highdpi_testbed.png | Bin 17323 -> 18560 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/examples/core/core_highdpi_testbed.png b/examples/core/core_highdpi_testbed.png index da99bbb0d97118eef3ca41c16b62182acced63f9..a37c821304b22cc7cbcb463de52eb95d0b5c2a90 100644 GIT binary patch literal 18560 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 literal 17323 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 aXx{Fh`%kLYY!czW3FF=h-xU_U{Qm(sHl%3) From 5b0a799769da9a2ebc662d4aab1f31cf85882c56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=AErvu=20Mihai=20Cristian?= Date: Sat, 10 Jan 2026 00:09:06 +0200 Subject: [PATCH 094/232] fix (#5482) --- src/shell.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shell.html b/src/shell.html index e6c80a39b..e5e26a3b1 100644 --- a/src/shell.html +++ b/src/shell.html @@ -179,7 +179,7 @@ jwE50AGjLCVuS8Yt4H7OgZLKK5EKOsLviEWJSL/+0uMi7gLUSBseYwqEbXvSHCec1CJvZPyHCmYQffaB - + From 8de88c71daa21b943daef1b08b2c39013a868d74 Mon Sep 17 00:00:00 2001 From: lucas150670 Date: Sat, 10 Jan 2026 17:54:54 +0800 Subject: [PATCH 095/232] fix: fall back on dirent filename when all route fails on Android (#5484) --- src/utils.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/utils.c b/src/utils.c index 82d7d0aa2..28939b4f8 100644 --- a/src/utils.c +++ b/src/utils.c @@ -473,7 +473,9 @@ FILE *android_fopen(const char *fileName, const char *mode) { #undef fopen // Just do a regular open if file is not found in the assets - return fopen(TextFormat("%s/%s", internalDataPath, fileName), mode); + if(fopen(TextFormat("%s/%s", internalDataPath, fileName), mode) == NULL) { + return fopen(fileName, mode); + } #define fopen(name, mode) android_fopen(name, mode) } } From 683330582679397f225212bfcf925684e351954b Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 10 Jan 2026 10:59:22 +0100 Subject: [PATCH 096/232] REVIEWED: `android_fopen()` --- src/utils.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/utils.c b/src/utils.c index 28939b4f8..80c8dec55 100644 --- a/src/utils.c +++ b/src/utils.c @@ -449,6 +449,8 @@ void InitAssetManager(AAssetManager *manager, const char *dataPath) // REF: https://developer.android.com/ndk/reference/group/asset FILE *android_fopen(const char *fileName, const char *mode) { + FILE *file = NULL; + if (mode[0] == 'w') { // NOTE: fopen() is mapped to android_fopen() that only grants read access to @@ -456,7 +458,7 @@ FILE *android_fopen(const char *fileName, const char *mode) // write data when required using the standard stdio FILE access functions // REF: https://stackoverflow.com/questions/11294487/android-writing-saving-files-from-native-code-only #undef fopen - return fopen(TextFormat("%s/%s", internalDataPath, fileName), mode); + file = fopen(TextFormat("%s/%s", internalDataPath, fileName), mode); #define fopen(name, mode) android_fopen(name, mode) } else @@ -467,18 +469,19 @@ FILE *android_fopen(const char *fileName, const char *mode) if (asset != NULL) { // Get pointer to file in the assets - return funopen(asset, android_read, android_write, android_seek, android_close); + file = funopen(asset, android_read, android_write, android_seek, android_close); } else { #undef fopen // Just do a regular open if file is not found in the assets - if(fopen(TextFormat("%s/%s", internalDataPath, fileName), mode) == NULL) { - return fopen(fileName, mode); - } + file = fopen(TextFormat("%s/%s", internalDataPath, fileName), mode); + if (file == NULL) file = fopen(fileName, mode); #define fopen(name, mode) android_fopen(name, mode) } } + + return file; } #endif // PLATFORM_ANDROID From c7de5c9d4b2f0ec0ba049db5ffa4036fa63d5fff Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 10 Jan 2026 11:53:29 +0100 Subject: [PATCH 097/232] Updated examples VCXPROJ UUID, not correctly calculated by REXM --- projects/VS2022/examples/core_keyboard_testbed.vcxproj | 2 +- projects/VS2022/examples/textures_framebuffer_rendering.vcxproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/VS2022/examples/core_keyboard_testbed.vcxproj b/projects/VS2022/examples/core_keyboard_testbed.vcxproj index 3a146b762..2278f4ec5 100644 --- a/projects/VS2022/examples/core_keyboard_testbed.vcxproj +++ b/projects/VS2022/examples/core_keyboard_testbed.vcxproj @@ -51,7 +51,7 @@ - {6B1A933E-71B8-4C1F-9E79-02D98830E671} + {D35D2FDA-B53F-4F70-81CA-24D95812B89C} Win32Proj core_keyboard_testbed 10.0 diff --git a/projects/VS2022/examples/textures_framebuffer_rendering.vcxproj b/projects/VS2022/examples/textures_framebuffer_rendering.vcxproj index 3a7eeeb35..3e845545e 100644 --- a/projects/VS2022/examples/textures_framebuffer_rendering.vcxproj +++ b/projects/VS2022/examples/textures_framebuffer_rendering.vcxproj @@ -51,7 +51,7 @@ - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E} + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C} Win32Proj textures_framebuffer_rendering 10.0 From 2f6feb74d49eab6b3384440c51aff46c40326e44 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 10 Jan 2026 11:53:46 +0100 Subject: [PATCH 098/232] Update raylib.sln --- projects/VS2022/raylib.sln | 106 ++++++++++++++++++------------------- 1 file changed, 52 insertions(+), 54 deletions(-) diff --git a/projects/VS2022/raylib.sln b/projects/VS2022/raylib.sln index 93c4efaf1..9b088f52d 100644 --- a/projects/VS2022/raylib.sln +++ b/projects/VS2022/raylib.sln @@ -433,9 +433,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_cellular_automata" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_hilbert_curve", "examples\shapes_hilbert_curve.vcxproj", "{DC163251-16C3-4B72-B965-ACDBA0F02BD1}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_keyboard_testbed", "examples\core_keyboard_testbed.vcxproj", "{6B1A933E-71B8-4C1F-9E79-02D98830E671}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_keyboard_testbed", "examples\core_keyboard_testbed.vcxproj", "{D35D2FDA-B53F-4F70-81CA-24D95812B89C}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_framebuffer_rendering", "examples\textures_framebuffer_rendering.vcxproj", "{2CCCD9E4-9058-4291-BD89-39C979F0CA1E}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_framebuffer_rendering", "examples\textures_framebuffer_rendering.vcxproj", "{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -5395,54 +5395,54 @@ Global {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|x64.Build.0 = Release|x64 {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|x86.ActiveCfg = Release|Win32 {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|x86.Build.0 = Release|Win32 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|ARM64.Build.0 = Debug|ARM64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x64.ActiveCfg = Debug|x64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x64.Build.0 = Debug|x64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x86.ActiveCfg = Debug|Win32 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x86.Build.0 = Debug|Win32 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|ARM64.ActiveCfg = Release|ARM64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|ARM64.Build.0 = Release|ARM64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x64.ActiveCfg = Release|x64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x64.Build.0 = Release|x64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x86.ActiveCfg = Release|Win32 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x86.Build.0 = Release|Win32 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|ARM64.Build.0 = Debug|ARM64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|x64.ActiveCfg = Debug|x64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|x64.Build.0 = Debug|x64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|x86.ActiveCfg = Debug|Win32 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|x86.Build.0 = Debug|Win32 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|ARM64.ActiveCfg = Release|ARM64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|ARM64.Build.0 = Release|ARM64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|x64.ActiveCfg = Release|x64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|x64.Build.0 = Release|x64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|x86.ActiveCfg = Release|Win32 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|x86.Build.0 = Release|Win32 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|ARM64.Build.0 = Debug|ARM64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|x64.ActiveCfg = Debug|x64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|x64.Build.0 = Debug|x64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|x86.ActiveCfg = Debug|Win32 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|x86.Build.0 = Debug|Win32 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|ARM64.ActiveCfg = Release|ARM64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|ARM64.Build.0 = Release|ARM64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|x64.ActiveCfg = Release|x64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|x64.Build.0 = Release|x64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|x86.ActiveCfg = Release|Win32 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|x86.Build.0 = Release|Win32 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|ARM64.Build.0 = Debug|ARM64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|x64.ActiveCfg = Debug|x64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|x64.Build.0 = Debug|x64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|x86.ActiveCfg = Debug|Win32 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|x86.Build.0 = Debug|Win32 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|ARM64.ActiveCfg = Release|ARM64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|ARM64.Build.0 = Release|ARM64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|x64.ActiveCfg = Release|x64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|x64.Build.0 = Release|x64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|x86.ActiveCfg = Release|Win32 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -5610,7 +5610,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} = {278D8859-20B1-428F-8448-064F46E1F021} + {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} {6777EC3C-077C-42FC-B4AD-B799CE55CCE4} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} {A61DAD9C-271C-4E95-81AA-DB4CD58564D4} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} @@ -5619,7 +5619,7 @@ 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} = {278D8859-20B1-428F-8448-064F46E1F021} + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} {9DB1F875-6E65-4195-B23F-ED8095C0B99C} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} {8E132D5A-2C00-48D0-8747-97E41356F26F} = {278D8859-20B1-428F-8448-064F46E1F021} @@ -5661,8 +5661,6 @@ Global {1F4722E7-F78E-413F-A106-D3490211EA57} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} {0A0FC982-6E31-401F-BA77-3C5E8AB02C68} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} {DC163251-16C3-4B72-B965-ACDBA0F02BD1} = {278D8859-20B1-428F-8448-064F46E1F021} - {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29} From dd7a1948f1c5b97b6e6e4c80cc0ae17d99ded8c6 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 10 Jan 2026 12:13:07 +0100 Subject: [PATCH 099/232] WARNING: REDESIGN: REMOVED: `utils` module, functionality moved to `rcore` module: logging and file-system #4551 [utils] was created long time ago, when [rcore] contained all the platforms code, the purpose of the file was exposing basic filesystem functionality across modules and also logging mechanism but many things have changed since then and there is no need to keep using this module. - Logging system has been move to [rcore] module and macros are exposed through `config.h` to other modules - File system functionality has also been centralized in [rcore] module that along the years it was already adding more and more file-system functions, now they are all in the same module - Android specific code has been moved to `rcore_android.c`, it had no sense to have specific platform code in `utils`, [rcore] is responsible of all platform code. --- build.zig | 2 +- projects/VS2022/raylib/raylib.vcxproj | 1 - projects/VS2022/raylib/raylib.vcxproj.filters | 3 - src/Makefile | 13 +- src/config.h | 27 +- src/platforms/rcore_android.c | 82 ++- src/platforms/rcore_desktop_glfw.c | 4 - src/platforms/rcore_desktop_rgfw.c | 5 +- src/platforms/rcore_desktop_sdl.c | 3 - src/platforms/rcore_desktop_win32.c | 3 - src/platforms/rcore_drm.c | 3 - src/platforms/rcore_memory.c | 3 - src/platforms/rcore_web.c | 3 - src/platforms/rcore_web_emscripten.c | 3 - src/raudio.c | 2 +- src/raylib.h | 59 +- src/rcore.c | 407 +++++++++++++- src/rmodels.c | 1 - src/rtext.c | 1 - src/rtextures.c | 1 - src/utils.c | 514 ------------------ src/utils.h | 74 --- 22 files changed, 525 insertions(+), 689 deletions(-) delete mode 100644 src/utils.c delete mode 100644 src/utils.h diff --git a/build.zig b/build.zig index 239b10f9e..2e53bfbdc 100644 --- a/build.zig +++ b/build.zig @@ -197,7 +197,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std. } var c_source_files: std.ArrayList([]const u8) = try .initCapacity(b.allocator, 2); - c_source_files.appendSliceAssumeCapacity(&.{ "src/rcore.c", "src/utils.c" }); + c_source_files.appendSliceAssumeCapacity(&.{ "src/rcore.c" }); if (options.rshapes) { try c_source_files.append(b.allocator, "src/rshapes.c"); diff --git a/projects/VS2022/raylib/raylib.vcxproj b/projects/VS2022/raylib/raylib.vcxproj index 3a7082d77..287410f06 100644 --- a/projects/VS2022/raylib/raylib.vcxproj +++ b/projects/VS2022/raylib/raylib.vcxproj @@ -582,7 +582,6 @@ - diff --git a/projects/VS2022/raylib/raylib.vcxproj.filters b/projects/VS2022/raylib/raylib.vcxproj.filters index 33030fc9c..75cc28a7e 100644 --- a/projects/VS2022/raylib/raylib.vcxproj.filters +++ b/projects/VS2022/raylib/raylib.vcxproj.filters @@ -22,9 +22,6 @@ Source Files - - Source Files - Source Files\Platform Files diff --git a/src/Makefile b/src/Makefile index 89dd759aa..459b79f83 100644 --- a/src/Makefile +++ b/src/Makefile @@ -658,8 +658,7 @@ endif OBJS = rcore.o \ rshapes.o \ rtextures.o \ - rtext.o \ - utils.o + rtext.o ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW) ifeq ($(USE_EXTERNAL_GLFW),FALSE) @@ -758,7 +757,7 @@ endif rcore.o : platforms/*.c # Compile core module -rcore.o : rcore.c raylib.h rlgl.h utils.h raymath.h rcamera.h rgestures.h +rcore.o : rcore.c raylib.h rlgl.h raymath.h rcamera.h rgestures.h $(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) # Compile rglfw module @@ -770,15 +769,11 @@ rshapes.o : rshapes.c raylib.h rlgl.h $(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) # Compile textures module -rtextures.o : rtextures.c raylib.h rlgl.h utils.h +rtextures.o : rtextures.c raylib.h rlgl.h $(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) # Compile text module -rtext.o : rtext.c raylib.h utils.h - $(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) - -# Compile utils module -utils.o : utils.c utils.h +rtext.o : rtext.c raylib.h $(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS) # Compile models module diff --git a/src/config.h b/src/config.h index 1286e5082..68b42cc0e 100644 --- a/src/config.h +++ b/src/config.h @@ -30,7 +30,7 @@ //------------------------------------------------------------------------------------ // Module selection - Some modules could be avoided -// Mandatory modules: rcore, rlgl, utils +// Mandatory modules: rcore, rlgl //------------------------------------------------------------------------------------ #define SUPPORT_MODULE_RSHAPES 1 #define SUPPORT_MODULE_RTEXTURES 1 @@ -41,6 +41,16 @@ //------------------------------------------------------------------------------------ // Module: rcore - Configuration Flags //------------------------------------------------------------------------------------ +// Standard file io library (stdio.h) included +#define SUPPORT_STANDARD_FILEIO 1 +// Show TRACELOG() output messages +#define SUPPORT_TRACELOG 1 +#if defined(SUPPORT_TRACELOG) + #define TRACELOG(level, ...) TraceLog(level, __VA_ARGS__) +#else + #define TRACELOG(level, ...) (void)0 +#endif + // Camera module is included (rcamera.h) and multiple predefined cameras are available: free, 1st/3rd person, orbital #define SUPPORT_CAMERA_SYSTEM 1 // Gestures module is included (rgestures.h) to support gestures detection: tap, hold, swipe, drag @@ -72,7 +82,7 @@ // Support for clipboard image loading // NOTE: Only working on SDL3, GLFW (Windows) and RGFW (Windows) -#define SUPPORT_CLIPBOARD_IMAGE 1 +#define SUPPORT_CLIPBOARD_IMAGE 1 // NOTE: Clipboard image loading requires support for some image file formats // TODO: Those defines should probably be removed from here, letting the user manage them @@ -96,6 +106,7 @@ // rcore: Configuration values //------------------------------------------------------------------------------------ +#define MAX_TRACELOG_MSG_LENGTH 256 // Max length of one trace-log message #define MAX_FILEPATH_CAPACITY 8192 // Maximum file paths capacity #define MAX_FILEPATH_LENGTH 4096 // Maximum length for filepaths (Linux PATH_MAX default value) @@ -281,16 +292,4 @@ #define MAX_AUDIO_BUFFER_POOL_CHANNELS 16 // Maximum number of audio pool channels -//------------------------------------------------------------------------------------ -// Module: utils - Configuration Flags -//------------------------------------------------------------------------------------ -// Standard file io library (stdio.h) included -#define SUPPORT_STANDARD_FILEIO 1 -// Show TRACELOG() output messages -#define SUPPORT_TRACELOG 1 - -// utils: Configuration values -//------------------------------------------------------------------------------------ -#define MAX_TRACELOG_MSG_LENGTH 256 // Max length of one trace-log message - #endif // CONFIG_H diff --git a/src/platforms/rcore_android.c b/src/platforms/rcore_android.c index 19b686cef..6122f9a74 100644 --- a/src/platforms/rcore_android.c +++ b/src/platforms/rcore_android.c @@ -13,9 +13,6 @@ * - Improvement 01 * - Improvement 02 * -* ADDITIONAL NOTES: -* - TRACELOG() function is located in raylib [utils] module -* * CONFIGURATION: * #define RCORE_PLATFORM_CUSTOM_FLAG * Custom flag for rcore on target platform -not used- @@ -48,7 +45,11 @@ #include // Required for: android_app struct and activity management #include // Required for: AWINDOW_FLAG_FULLSCREEN definition and others +#include // Required for: Android log system: __android_log_vprint() +#include // Required for: AAssetManager //#include // Required for: Android sensors functions (accelerometer, gyroscope, light...) + +#include // Required for: error types #include // Required for: JNIEnv and JavaVM [Used in OpenURL() and GetCurrentMonitor()] #include // Native platform windowing system interface @@ -269,6 +270,17 @@ static GamepadButton AndroidTranslateGamepadButton(int button); static void SetupFramebuffer(int width, int height); // Setup main framebuffer (required by InitPlatform()) +static int android_read(void *cookie, char *buf, int size); +static int android_write(void *cookie, const char *buf, int size); +static fpos_t android_seek(void *cookie, fpos_t offset, int whence); +static int android_close(void *cookie); + +FILE *android_fopen(const char *fileName, const char *mode); // Replacement for fopen() -> Read-only! +FILE *funopen(const void *cookie, int (*readfn)(void *, char *, int), int (*writefn)(void *, const char *, int), + fpos_t (*seekfn)(void *, fpos_t, int), int (*closefn)(void *)); + +#define fopen(name, mode) android_fopen(name, mode) + //---------------------------------------------------------------------------------- // Module Functions Declaration //---------------------------------------------------------------------------------- @@ -819,8 +831,6 @@ int InitPlatform(void) // Initialize storage system //---------------------------------------------------------------------------- - InitAssetManager(platform.app->activity->assetManager, platform.app->activity->internalDataPath); // Initialize assets manager - CORE.Storage.basePath = platform.app->activity->internalDataPath; // Define base path for storage //---------------------------------------------------------------------------- @@ -1514,4 +1524,66 @@ static void SetupFramebuffer(int width, int height) } } +// Replacement for fopen() +// REF: https://developer.android.com/ndk/reference/group/asset +FILE *android_fopen(const char *fileName, const char *mode) +{ + FILE *file = NULL; + + if (mode[0] == 'w') + { + // NOTE: fopen() is mapped to android_fopen() that only grants read access to + // assets directory through AAssetManager but we want to also be able to + // write data when required using the standard stdio FILE access functions + // REF: https://stackoverflow.com/questions/11294487/android-writing-saving-files-from-native-code-only + #undef fopen + file = fopen(TextFormat("%s/%s", platform.app->activity->internalDataPath, fileName), mode); + #define fopen(name, mode) android_fopen(name, mode) + } + else + { + // NOTE: AAsset provides access to read-only asset + AAsset *asset = AAssetManager_open(platform.app->activity->assetManager, fileName, AASSET_MODE_UNKNOWN); + + if (asset != NULL) + { + // Get pointer to file in the assets + file = funopen(asset, android_read, android_write, android_seek, android_close); + } + else + { + #undef fopen + // Just do a regular open if file is not found in the assets + file = fopen(TextFormat("%s/%s", platform.app->activity->internalDataPath, fileName), mode); + if (file == NULL) file = fopen(fileName, mode); + #define fopen(name, mode) android_fopen(name, mode) + } + } + + return file; +} + +static int android_read(void *cookie, char *data, int dataSize) +{ + return AAsset_read((AAsset *)cookie, data, dataSize); +} + +static int android_write(void *cookie, const char *data, int dataSize) +{ + TRACELOG(LOG_WARNING, "ANDROID: Failed to provide write access to APK"); + + return EACCES; +} + +static fpos_t android_seek(void *cookie, fpos_t offset, int whence) +{ + return AAsset_seek((AAsset *)cookie, offset, whence); +} + +static int android_close(void *cookie) +{ + AAsset_close((AAsset *)cookie); + return 0; +} + // EOF diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index 84b021573..f39e256aa 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -16,9 +16,6 @@ * - Improvement 01 * - Improvement 02 * -* ADDITIONAL NOTES: -* - TRACELOG() function is located in raylib [utils] module -* * CONFIGURATION: * #define RCORE_PLATFORM_CUSTOM_FLAG * Custom flag for rcore on target platform -not used- @@ -1364,7 +1361,6 @@ 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 static void *AllocateWrapper(size_t size, void *user) { diff --git a/src/platforms/rcore_desktop_rgfw.c b/src/platforms/rcore_desktop_rgfw.c index 05960c14b..d1518b909 100644 --- a/src/platforms/rcore_desktop_rgfw.c +++ b/src/platforms/rcore_desktop_rgfw.c @@ -13,10 +13,7 @@ * - TODO * * POSSIBLE IMPROVEMENTS: -* - TODO -* -* ADDITIONAL NOTES: -* - TRACELOG() function is located in raylib [utils] module +* - TBD * * CONFIGURATION: * #define RCORE_PLATFORM_RGFW diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index 0279c0c28..eabea6bfe 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -15,9 +15,6 @@ * - Improvement 01 * - Improvement 02 * -* ADDITIONAL NOTES: -* - TRACELOG() function is located in raylib [utils] module -* * CONFIGURATION: * #define RCORE_PLATFORM_CUSTOM_FLAG * Custom flag for rcore on target platform -not used- diff --git a/src/platforms/rcore_desktop_win32.c b/src/platforms/rcore_desktop_win32.c index 7ef01a1a0..9f33dce1b 100644 --- a/src/platforms/rcore_desktop_win32.c +++ b/src/platforms/rcore_desktop_win32.c @@ -13,9 +13,6 @@ * - Improvement 01 * - Improvement 02 * -* ADDITIONAL NOTES: -* - TRACELOG() function is located in raylib [utils] module -* * CONFIGURATION: * #define RCORE_PLATFORM_CUSTOM_FLAG * Custom flag for rcore on target platform -not used- diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index eedb915e2..2e224ad92 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -13,9 +13,6 @@ * - Improvement 01 * - Improvement 02 * -* ADDITIONAL NOTES: -* - TRACELOG() function is located in raylib [utils] module -* * CONFIGURATION: * #define SUPPORT_SSH_KEYBOARD_RPI (Raspberry Pi only) * Reconfigure standard input to receive key inputs, works with SSH connection diff --git a/src/platforms/rcore_memory.c b/src/platforms/rcore_memory.c index 04d343164..c9409a750 100644 --- a/src/platforms/rcore_memory.c +++ b/src/platforms/rcore_memory.c @@ -13,9 +13,6 @@ * - Improvement 01 * - Improvement 02 * -* ADDITIONAL NOTES: -* - TRACELOG() function is located in raylib [utils] module -* * CONFIGURATION: * #define RCORE_PLATFORM_CUSTOM_FLAG * Custom flag for rcore on target platform -not used- diff --git a/src/platforms/rcore_web.c b/src/platforms/rcore_web.c index 2b51804ef..f1922600f 100644 --- a/src/platforms/rcore_web.c +++ b/src/platforms/rcore_web.c @@ -12,9 +12,6 @@ * POSSIBLE IMPROVEMENTS: * - Replace glfw3 dependency by direct browser API calls (same as library_glfw3.js) * -* ADDITIONAL NOTES: -* - TRACELOG() function is located in raylib [utils] module -* * CONFIGURATION: * #define RCORE_PLATFORM_CUSTOM_FLAG * Custom flag for rcore on target platform -not used- diff --git a/src/platforms/rcore_web_emscripten.c b/src/platforms/rcore_web_emscripten.c index 5fdcdbefc..36b8e964a 100644 --- a/src/platforms/rcore_web_emscripten.c +++ b/src/platforms/rcore_web_emscripten.c @@ -11,9 +11,6 @@ * POSSIBLE IMPROVEMENTS: * - TBD * -* ADDITIONAL NOTES: -* - TRACELOG() function is located in raylib [utils] module -* * CONFIGURATION: * #define RCORE_PLATFORM_CUSTOM_FLAG * Custom flag for rcore on target platform -not used- diff --git a/src/raudio.c b/src/raudio.c index cfb86cdbd..c25ad1f02 100644 --- a/src/raudio.c +++ b/src/raudio.c @@ -78,7 +78,7 @@ #if !defined(EXTERNAL_CONFIG_FLAGS) #include "config.h" // Defines module configuration flags #endif - #include "utils.h" // Required for: fopen() Android mapping + //#include "utils.h" // Required for: fopen() Android mapping #endif #if defined(SUPPORT_MODULE_RAUDIO) || defined(RAUDIO_STANDALONE) diff --git a/src/raylib.h b/src/raylib.h index 6eae8411e..177138dc9 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1074,47 +1074,41 @@ RLAPI Matrix GetCameraMatrix(Camera camera); // Get c RLAPI Matrix GetCameraMatrix2D(Camera2D camera); // Get camera 2d transform matrix // Timing-related functions -RLAPI void SetTargetFPS(int fps); // Set target FPS (maximum) -RLAPI float GetFrameTime(void); // Get time in seconds for last frame drawn (delta time) -RLAPI double GetTime(void); // Get elapsed time in seconds since InitWindow() -RLAPI int GetFPS(void); // Get current FPS +RLAPI void SetTargetFPS(int fps); // Set target FPS (maximum) +RLAPI float GetFrameTime(void); // Get time in seconds for last frame drawn (delta time) +RLAPI double GetTime(void); // Get elapsed time in seconds since InitWindow() +RLAPI int GetFPS(void); // Get current FPS // Custom frame control functions // NOTE: Those functions are intended for advanced users that want full control over the frame processing // By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timing + PollInputEvents() // To avoid that behaviour and control frame processes manually, enable in config.h: SUPPORT_CUSTOM_FRAME_CONTROL -RLAPI void SwapScreenBuffer(void); // Swap back buffer with front buffer (screen drawing) -RLAPI void PollInputEvents(void); // Register all input events -RLAPI void WaitTime(double seconds); // Wait for some time (halt program execution) +RLAPI void SwapScreenBuffer(void); // Swap back buffer with front buffer (screen drawing) +RLAPI void PollInputEvents(void); // Register all input events +RLAPI void WaitTime(double seconds); // Wait for some time (halt program execution) // Random values generation functions -RLAPI void SetRandomSeed(unsigned int seed); // Set the seed for the random number generator -RLAPI int GetRandomValue(int min, int max); // Get a random value between min and max (both included) +RLAPI void SetRandomSeed(unsigned int seed); // Set the seed for the random number generator +RLAPI int GetRandomValue(int min, int max); // Get a random value between min and max (both included) RLAPI int *LoadRandomSequence(unsigned int count, int min, int max); // Load random values sequence, no values repeated -RLAPI void UnloadRandomSequence(int *sequence); // Unload random values sequence +RLAPI void UnloadRandomSequence(int *sequence); // Unload random values sequence // Misc. functions -RLAPI void TakeScreenshot(const char *fileName); // Takes a screenshot of current screen (filename extension defines format) -RLAPI void SetConfigFlags(unsigned int flags); // Setup init configuration flags (view FLAGS) -RLAPI void OpenURL(const char *url); // Open URL with default system browser (if available) +RLAPI void TakeScreenshot(const char *fileName); // Takes a screenshot of current screen (filename extension defines format) +RLAPI void SetConfigFlags(unsigned int flags); // Setup init configuration flags (view FLAGS) +RLAPI void OpenURL(const char *url); // Open URL with default system browser (if available) -// NOTE: Following functions implemented in module [utils] -//------------------------------------------------------------------ -RLAPI void TraceLog(int logLevel, const char *text, ...); // Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...) -RLAPI void SetTraceLogLevel(int logLevel); // Set the current threshold (minimum) log level -RLAPI void *MemAlloc(unsigned int size); // Internal memory allocator -RLAPI void *MemRealloc(void *ptr, unsigned int size); // Internal memory reallocator -RLAPI void MemFree(void *ptr); // Internal memory free +// Logging system +RLAPI void SetTraceLogLevel(int logLevel); // Set the current threshold (minimum) log level +RLAPI void TraceLog(int logLevel, const char *text, ...); // Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...) +RLAPI void SetTraceLogCallback(TraceLogCallback callback); // Set custom trace log -// Set custom callbacks -// WARNING: Callbacks setup is intended for advanced users -RLAPI void SetTraceLogCallback(TraceLogCallback callback); // Set custom trace log -RLAPI void SetLoadFileDataCallback(LoadFileDataCallback callback); // Set custom file binary data loader -RLAPI void SetSaveFileDataCallback(SaveFileDataCallback callback); // Set custom file binary data saver -RLAPI void SetLoadFileTextCallback(LoadFileTextCallback callback); // Set custom file text data loader -RLAPI void SetSaveFileTextCallback(SaveFileTextCallback callback); // Set custom file text data saver +// Memory management, using internal allocators +RLAPI void *MemAlloc(unsigned int size); // Internal memory allocator +RLAPI void *MemRealloc(void *ptr, unsigned int size); // Internal memory reallocator +RLAPI void MemFree(void *ptr); // Internal memory free -// Files management functions +// File system management functions RLAPI unsigned char *LoadFileData(const char *fileName, int *dataSize); // Load file data as byte array (read) RLAPI void UnloadFileData(unsigned char *data); // Unload file data allocated by LoadFileData() RLAPI bool SaveFileData(const char *fileName, void *data, int dataSize); // Save data to file from byte array (write), returns true on success @@ -1122,9 +1116,14 @@ RLAPI bool ExportDataAsCode(const unsigned char *data, int dataSize, const char RLAPI char *LoadFileText(const char *fileName); // Load text data from file (read), returns a '\0' terminated string RLAPI void UnloadFileText(char *text); // Unload file text data allocated by LoadFileText() RLAPI bool SaveFileText(const char *fileName, const char *text); // Save text data to file (write), string must be '\0' terminated, returns true on success -//------------------------------------------------------------------ -// File system functions +// File access custom callbacks +// WARNING: Callbacks setup is intended for advanced users +RLAPI void SetLoadFileDataCallback(LoadFileDataCallback callback); // Set custom file binary data loader +RLAPI void SetSaveFileDataCallback(SaveFileDataCallback callback); // Set custom file binary data saver +RLAPI void SetLoadFileTextCallback(LoadFileTextCallback callback); // Set custom file text data loader +RLAPI void SetSaveFileTextCallback(SaveFileTextCallback callback); // Set custom file text data saver + RLAPI int FileRename(const char *fileName, const char *fileRename); // Rename file (if exists) RLAPI int FileRemove(const char *fileName); // Remove file (if exists) RLAPI int FileCopy(const char *srcPath, const char *dstPath); // Copy file from one path to another, dstPath created if it doesn't exist diff --git a/src/rcore.c b/src/rcore.c index b7fcbf4a0..7837f8c4e 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -109,11 +109,10 @@ #include "config.h" // Defines module configuration flags #endif -#include "utils.h" // Required for: TRACELOG() macros - -#include // Required for: srand(), rand(), atexit() -#include // Required for: sprintf() [Used in OpenURL()] -#include // Required for: strlen(), strncpy(), strcmp(), strrchr(), memset() +#include // Required for: srand(), rand(), atexit(), exit() +#include // Required for: FILE, fopen(), fseek(), ftell(), fread(), fwrite(), fprintf(), vprintf(), fclose(), sprintf() [Used in OpenURL()] +#include // Required for: strlen(), strncpy(), strcmp(), strrchr(), memset(), strcat() +#include // Required for: va_list, va_start(), va_end() [Used in TraceLog()] #include // Required for: time() [Used in InitTimer()] #include // Required for: tan() [Used in BeginMode3D()], atan2f() [Used in LoadVrStereoConfig()] @@ -217,6 +216,10 @@ //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- +#ifndef MAX_TRACELOG_MSG_LENGTH + #define MAX_TRACELOG_MSG_LENGTH 256 // Max length of one trace-log message +#endif + #ifndef MAX_FILEPATH_CAPACITY #define MAX_FILEPATH_CAPACITY 8192 // Maximum capacity for filepath #endif @@ -387,10 +390,18 @@ typedef struct CoreData { //---------------------------------------------------------------------------------- RLAPI const char *raylib_version = RAYLIB_VERSION; // raylib version exported symbol, required for some bindings -CoreData CORE = { 0 }; // Global CORE state context +CoreData CORE = { 0 }; // Global CORE state context + +static int logTypeLevel = LOG_INFO; // Minimum log type level + +static TraceLogCallback traceLog = NULL; // TraceLog callback function pointer +static LoadFileDataCallback loadFileData = NULL; // LoadFileData callback function pointer +static SaveFileDataCallback saveFileData = NULL; // SaveFileText callback function pointer +static LoadFileTextCallback loadFileText = NULL; // LoadFileText callback function pointer +static SaveFileTextCallback saveFileText = NULL; // SaveFileText callback function pointer #if defined(SUPPORT_SCREEN_CAPTURE) -static int screenshotCounter = 0; // Screenshots counter +static int screenshotCounter = 0; // Screenshots counter #endif #if defined(SUPPORT_AUTOMATION_EVENTS) @@ -1857,9 +1868,389 @@ void SetConfigFlags(unsigned int flags) FLAG_SET(CORE.Window.flags, flags); } +// void OpenURL(const char *url); // Defined per platform + //---------------------------------------------------------------------------------- -// Module Functions Definition: File system +// Module Functions Definition: Logging system //---------------------------------------------------------------------------------- +// Set the current threshold (minimum) log level +void SetTraceLogLevel(int logType) { logTypeLevel = logType; } + +// Show trace log messages (LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_DEBUG) +void TraceLog(int logType, const char *text, ...) +{ +#if defined(SUPPORT_TRACELOG) + // Message has level below current threshold, don't emit + if ((logType < logTypeLevel) || (text == NULL)) return; + + va_list args; + va_start(args, text); + + if (traceLog) + { + traceLog(logType, text, args); + va_end(args); + return; + } + +#if defined(PLATFORM_ANDROID) + switch (logType) + { + case LOG_TRACE: __android_log_vprint(ANDROID_LOG_VERBOSE, "raylib", text, args); break; + case LOG_DEBUG: __android_log_vprint(ANDROID_LOG_DEBUG, "raylib", text, args); break; + case LOG_INFO: __android_log_vprint(ANDROID_LOG_INFO, "raylib", text, args); break; + case LOG_WARNING: __android_log_vprint(ANDROID_LOG_WARN, "raylib", text, args); break; + case LOG_ERROR: __android_log_vprint(ANDROID_LOG_ERROR, "raylib", text, args); break; + case LOG_FATAL: __android_log_vprint(ANDROID_LOG_FATAL, "raylib", text, args); break; + default: break; + } +#else + char buffer[MAX_TRACELOG_MSG_LENGTH] = { 0 }; + + switch (logType) + { + case LOG_TRACE: strncpy(buffer, "TRACE: ", 8); break; + case LOG_DEBUG: strncpy(buffer, "DEBUG: ", 8); break; + case LOG_INFO: strncpy(buffer, "INFO: ", 7); break; + case LOG_WARNING: strncpy(buffer, "WARNING: ", 10); break; + case LOG_ERROR: strncpy(buffer, "ERROR: ", 8); break; + case LOG_FATAL: strncpy(buffer, "FATAL: ", 8); break; + default: break; + } + + unsigned int textLength = (unsigned int)strlen(text); + memcpy(buffer + strlen(buffer), text, (textLength < (MAX_TRACELOG_MSG_LENGTH - 12))? textLength : (MAX_TRACELOG_MSG_LENGTH - 12)); + strcat(buffer, "\n"); + vprintf(buffer, args); + fflush(stdout); +#endif + + va_end(args); + + if (logType == LOG_FATAL) exit(EXIT_FAILURE); // If fatal logging, exit program + +#endif // SUPPORT_TRACELOG +} + +// Set custom trace log +void SetTraceLogCallback(TraceLogCallback callback) +{ + traceLog = callback; +} + +//---------------------------------------------------------------------------------- +// Module Functions Definition: Memory management +//---------------------------------------------------------------------------------- +// Internal memory allocator +// NOTE: Initializes to zero by default +void *MemAlloc(unsigned int size) +{ + void *ptr = RL_CALLOC(size, 1); + return ptr; +} + +// Internal memory reallocator +void *MemRealloc(void *ptr, unsigned int size) +{ + void *ret = RL_REALLOC(ptr, size); + return ret; +} + +// Internal memory free +void MemFree(void *ptr) +{ + RL_FREE(ptr); +} + +//---------------------------------------------------------------------------------- +// Module Functions Definition: File System management +//---------------------------------------------------------------------------------- +// Load data from file into a buffer +unsigned char *LoadFileData(const char *fileName, int *dataSize) +{ + unsigned char *data = NULL; + *dataSize = 0; + + if (fileName != NULL) + { + if (loadFileData) + { + data = loadFileData(fileName, dataSize); + return data; + } +#if defined(SUPPORT_STANDARD_FILEIO) + FILE *file = fopen(fileName, "rb"); + + if (file != NULL) + { + // WARNING: On binary streams SEEK_END could not be found, + // using fseek() and ftell() could not work in some (rare) cases + fseek(file, 0, SEEK_END); + int size = ftell(file); // WARNING: ftell() returns 'long int', maximum size returned is INT_MAX (2147483647 bytes) + fseek(file, 0, SEEK_SET); + + if (size > 0) + { + data = (unsigned char *)RL_CALLOC(size, sizeof(unsigned char)); + + if (data != NULL) + { + // NOTE: fread() returns number of read elements instead of bytes, so we read [1 byte, size elements] + size_t count = fread(data, sizeof(unsigned char), size, file); + + // WARNING: fread() returns a size_t value, usually 'unsigned int' (32bit compilation) and 'unsigned long long' (64bit compilation) + // dataSize is unified along raylib as a 'int' type, so, for file-sizes > INT_MAX (2147483647 bytes) we have a limitation + if (count > 2147483647) + { + TRACELOG(LOG_WARNING, "FILEIO: [%s] File is bigger than 2147483647 bytes, avoid using LoadFileData()", fileName); + + RL_FREE(data); + data = NULL; + } + else + { + *dataSize = (int)count; + + if ((*dataSize) != size) TRACELOG(LOG_WARNING, "FILEIO: [%s] File partially loaded (%i bytes out of %i)", fileName, dataSize, count); + else TRACELOG(LOG_INFO, "FILEIO: [%s] File loaded successfully", fileName); + } + } + else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to allocated memory for file reading", fileName); + } + else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to read file", fileName); + + fclose(file); + } + else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open file", fileName); +#else + TRACELOG(LOG_WARNING, "FILEIO: Standard file io not supported, use custom file callback"); +#endif + } + else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid"); + + return data; +} + +// Unload file data allocated by LoadFileData() +void UnloadFileData(unsigned char *data) +{ + RL_FREE(data); +} + +// Save data to file from buffer +bool SaveFileData(const char *fileName, void *data, int dataSize) +{ + bool success = false; + + if (fileName != NULL) + { + if (saveFileData) + { + return saveFileData(fileName, data, dataSize); + } +#if defined(SUPPORT_STANDARD_FILEIO) + FILE *file = fopen(fileName, "wb"); + + if (file != NULL) + { + // WARNING: fwrite() returns a size_t value, usually 'unsigned int' (32bit compilation) and 'unsigned long long' (64bit compilation) + // and expects a size_t input value but as dataSize is limited to INT_MAX (2147483647 bytes), there shouldn't be a problem + int count = (int)fwrite(data, sizeof(unsigned char), dataSize, file); + + if (count == 0) TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to write file", fileName); + else if (count != dataSize) TRACELOG(LOG_WARNING, "FILEIO: [%s] File partially written", fileName); + else TRACELOG(LOG_INFO, "FILEIO: [%s] File saved successfully", fileName); + + int result = fclose(file); + if (result == 0) success = true; + } + else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open file", fileName); +#else + TRACELOG(LOG_WARNING, "FILEIO: Standard file io not supported, use custom file callback"); +#endif + } + else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid"); + + return success; +} + +// Export data to code (.h), returns true on success +bool ExportDataAsCode(const unsigned char *data, int dataSize, const char *fileName) +{ + bool success = false; + +#ifndef TEXT_BYTES_PER_LINE + #define TEXT_BYTES_PER_LINE 20 +#endif + + // NOTE: Text data buffer size is estimated considering raw data size in bytes + // and requiring 6 char bytes for every byte: "0x00, " + char *txtData = (char *)RL_CALLOC(dataSize*6 + 2000, sizeof(char)); + + int byteCount = 0; + byteCount += sprintf(txtData + byteCount, "////////////////////////////////////////////////////////////////////////////////////////\n"); + byteCount += sprintf(txtData + byteCount, "// //\n"); + byteCount += sprintf(txtData + byteCount, "// DataAsCode exporter v1.0 - Raw data exported as an array of bytes //\n"); + byteCount += sprintf(txtData + byteCount, "// //\n"); + byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n"); + byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n"); + byteCount += sprintf(txtData + byteCount, "// //\n"); + byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2022-2026 Ramon Santamaria (@raysan5) //\n"); + byteCount += sprintf(txtData + byteCount, "// //\n"); + byteCount += sprintf(txtData + byteCount, "////////////////////////////////////////////////////////////////////////////////////////\n\n"); + + // Get file name from path + char varFileName[256] = { 0 }; + strncpy(varFileName, GetFileNameWithoutExt(fileName), 256 - 1); + for (int i = 0; varFileName[i] != '\0'; i++) + { + // Convert variable name to uppercase + if ((varFileName[i] >= 'a') && (varFileName[i] <= 'z')) { varFileName[i] = varFileName[i] - 32; } + // Replace non valid character for C identifier with '_' + else if (varFileName[i] == '.' || varFileName[i] == '-' || varFileName[i] == '?' || varFileName[i] == '!' || varFileName[i] == '+') { varFileName[i] = '_'; } + } + + byteCount += sprintf(txtData + byteCount, "#define %s_DATA_SIZE %i\n\n", varFileName, dataSize); + + byteCount += sprintf(txtData + byteCount, "static unsigned char %s_DATA[%s_DATA_SIZE] = { ", varFileName, varFileName); + for (int i = 0; i < (dataSize - 1); i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "0x%x,\n" : "0x%x, "), data[i]); + byteCount += sprintf(txtData + byteCount, "0x%x };\n", data[dataSize - 1]); + + // NOTE: Text data size exported is determined by '\0' (NULL) character + success = SaveFileText(fileName, txtData); + + RL_FREE(txtData); + + if (success != 0) TRACELOG(LOG_INFO, "FILEIO: [%s] Data as code exported successfully", fileName); + else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to export data as code", fileName); + + return success; +} + +// Load text data from file, returns a '\0' terminated string +// NOTE: text chars array should be freed manually +char *LoadFileText(const char *fileName) +{ + char *text = NULL; + + if (fileName != NULL) + { + if (loadFileText) + { + text = loadFileText(fileName); + return text; + } +#if defined(SUPPORT_STANDARD_FILEIO) + FILE *file = fopen(fileName, "rt"); + + if (file != NULL) + { + // WARNING: When reading a file as 'text' file, + // text mode causes carriage return-linefeed translation... + // ...but using fseek() should return correct byte-offset + fseek(file, 0, SEEK_END); + unsigned int size = (unsigned int)ftell(file); + fseek(file, 0, SEEK_SET); + + if (size > 0) + { + text = (char *)RL_CALLOC(size + 1, sizeof(char)); + + if (text != NULL) + { + unsigned int count = (unsigned int)fread(text, sizeof(char), size, file); + + // WARNING: \r\n is converted to \n on reading, so, + // read bytes count gets reduced by the number of lines + if (count < size) text = (char *)RL_REALLOC(text, count + 1); + + // Zero-terminate the string + text[count] = '\0'; + + TRACELOG(LOG_INFO, "FILEIO: [%s] Text file loaded successfully", fileName); + } + else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to allocated memory for file reading", fileName); + } + else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to read text file", fileName); + + fclose(file); + } + else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open text file", fileName); +#else + TRACELOG(LOG_WARNING, "FILEIO: Standard file io not supported, use custom file callback"); +#endif + } + else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid"); + + return text; +} + +// Unload file text data allocated by LoadFileText() +void UnloadFileText(char *text) +{ + RL_FREE(text); +} + +// Save text data to file (write), string must be '\0' terminated +bool SaveFileText(const char *fileName, const char *text) +{ + bool success = false; + + if (fileName != NULL) + { + if (saveFileText) + { + return saveFileText(fileName, text); + } +#if defined(SUPPORT_STANDARD_FILEIO) + FILE *file = fopen(fileName, "wt"); + + if (file != NULL) + { + int count = fprintf(file, "%s", text); + + if (count < 0) TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to write text file", fileName); + else TRACELOG(LOG_INFO, "FILEIO: [%s] Text file saved successfully", fileName); + + int result = fclose(file); + if (result == 0) success = true; + } + else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open text file", fileName); +#else + TRACELOG(LOG_WARNING, "FILEIO: Standard file io not supported, use custom file callback"); +#endif + } + else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid"); + + return success; +} + +// File access custom callbacks +// WARNING: Callbacks setup is intended for advanced users + +// Set custom file binary data loader +void SetLoadFileDataCallback(LoadFileDataCallback callback) +{ + loadFileData = callback; +} + +// Set custom file binary data saver +void SetSaveFileDataCallback(SaveFileDataCallback callback) +{ + saveFileData = callback; +} + +// Set custom file text data loader +void SetLoadFileTextCallback(LoadFileTextCallback callback) +{ + loadFileText = callback; +} + +// Set custom file text data saver +void SetSaveFileTextCallback(SaveFileTextCallback callback) +{ + saveFileText = callback; +} // Rename file (if exists) // NOTE: Only rename file name required, not full path diff --git a/src/rmodels.c b/src/rmodels.c index 20287a935..76efa3e4a 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -49,7 +49,6 @@ #if defined(SUPPORT_MODULE_RMODELS) -#include "utils.h" // Required for: TRACELOG(), LoadFileData(), LoadFileText(), SaveFileText() #include "rlgl.h" // OpenGL abstraction layer to OpenGL 1.1, 2.1, 3.3+ or ES2 #include "raymath.h" // Required for: Vector3, Quaternion and Matrix functionality diff --git a/src/rtext.c b/src/rtext.c index 8413d62bf..7a1b3c027 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -62,7 +62,6 @@ #if defined(SUPPORT_MODULE_RTEXT) -#include "utils.h" // Required for: LoadFile*() #include "rlgl.h" // OpenGL abstraction layer to OpenGL 1.1, 2.1, 3.3+ or ES2 -> Only DrawTextPro() #include // Required for: malloc(), free() diff --git a/src/rtextures.c b/src/rtextures.c index 8d4128d4e..fa03d193b 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -70,7 +70,6 @@ #if defined(SUPPORT_MODULE_RTEXTURES) -#include "utils.h" // Required for: TRACELOG() #include "rlgl.h" // OpenGL abstraction layer to multiple versions #include // Required for: malloc(), calloc(), free() diff --git a/src/utils.c b/src/utils.c deleted file mode 100644 index 80c8dec55..000000000 --- a/src/utils.c +++ /dev/null @@ -1,514 +0,0 @@ -/********************************************************************************************** -* -* raylib.utils - Some common utility functions -* -* CONFIGURATION: -* #define SUPPORT_TRACELOG -* Show TraceLog() output messages -* NOTE: By default LOG_DEBUG traces not shown -* -* -* LICENSE: zlib/libpng -* -* Copyright (c) 2014-2026 Ramon Santamaria (@raysan5) -* -* This software is provided "as-is", without any express or implied warranty. In no event -* will the authors be held liable for any damages arising from the use of this software. -* -* Permission is granted to anyone to use this software for any purpose, including commercial -* applications, and to alter it and redistribute it freely, subject to the following restrictions: -* -* 1. The origin of this software must not be misrepresented; you must not claim that you -* wrote the original software. If you use this software in a product, an acknowledgment -* in the product documentation would be appreciated but is not required. -* -* 2. Altered source versions must be plainly marked as such, and must not be misrepresented -* as being the original software. -* -* 3. This notice may not be removed or altered from any source distribution. -* -**********************************************************************************************/ - -#include "raylib.h" // WARNING: Required for: LogType enum - -// Check if config flags have been externally provided on compilation line -#if !defined(EXTERNAL_CONFIG_FLAGS) - #include "config.h" // Defines module configuration flags -#endif - -#include "utils.h" - -#if defined(PLATFORM_ANDROID) - #include // Required for: Android error types - #include // Required for: Android log system: __android_log_vprint() - #include // Required for: Android assets manager: AAsset, AAssetManager_open()... -#endif - -#include // Required for: exit() -#include // Required for: FILE, fopen(), fseek(), ftell(), fread(), fwrite(), fprintf(), vprintf(), fclose() -#include // Required for: va_list, va_start(), va_end() -#include // Required for: strcpy(), strcat() - -//---------------------------------------------------------------------------------- -// Defines and Macros -//---------------------------------------------------------------------------------- -#ifndef MAX_TRACELOG_MSG_LENGTH - #define MAX_TRACELOG_MSG_LENGTH 256 // Max length of one trace-log message -#endif - -//---------------------------------------------------------------------------------- -// Global Variables Definition -//---------------------------------------------------------------------------------- -static int logTypeLevel = LOG_INFO; // Minimum log type level - -static TraceLogCallback traceLog = NULL; // TraceLog callback function pointer -static LoadFileDataCallback loadFileData = NULL; // LoadFileData callback function pointer -static SaveFileDataCallback saveFileData = NULL; // SaveFileText callback function pointer -static LoadFileTextCallback loadFileText = NULL; // LoadFileText callback function pointer -static SaveFileTextCallback saveFileText = NULL; // SaveFileText callback function pointer - -//---------------------------------------------------------------------------------- -// Functions to set internal callbacks -//---------------------------------------------------------------------------------- -void SetTraceLogCallback(TraceLogCallback callback) { traceLog = callback; } // Set custom trace log -void SetLoadFileDataCallback(LoadFileDataCallback callback) { loadFileData = callback; } // Set custom file data loader -void SetSaveFileDataCallback(SaveFileDataCallback callback) { saveFileData = callback; } // Set custom file data saver -void SetLoadFileTextCallback(LoadFileTextCallback callback) { loadFileText = callback; } // Set custom file text loader -void SetSaveFileTextCallback(SaveFileTextCallback callback) { saveFileText = callback; } // Set custom file text saver - -#if defined(PLATFORM_ANDROID) -static AAssetManager *assetManager = NULL; // Android assets manager pointer -static const char *internalDataPath = NULL; // Android internal data path -#endif - -//---------------------------------------------------------------------------------- -// Module Internal Functions Declaration -//---------------------------------------------------------------------------------- -#if defined(PLATFORM_ANDROID) -FILE *funopen(const void *cookie, int (*readfn)(void *, char *, int), int (*writefn)(void *, const char *, int), - fpos_t (*seekfn)(void *, fpos_t, int), int (*closefn)(void *)); - -static int android_read(void *cookie, char *buf, int size); -static int android_write(void *cookie, const char *buf, int size); -static fpos_t android_seek(void *cookie, fpos_t offset, int whence); -static int android_close(void *cookie); -#endif - -//---------------------------------------------------------------------------------- -// Module Functions Definition -//---------------------------------------------------------------------------------- -// Set the current threshold (minimum) log level -void SetTraceLogLevel(int logType) { logTypeLevel = logType; } - -// Show trace log messages (LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_DEBUG) -void TraceLog(int logType, const char *text, ...) -{ -#if defined(SUPPORT_TRACELOG) - // Message has level below current threshold, don't emit - if ((logType < logTypeLevel) || (text == NULL)) return; - - va_list args; - va_start(args, text); - - if (traceLog) - { - traceLog(logType, text, args); - va_end(args); - return; - } - -#if defined(PLATFORM_ANDROID) - switch (logType) - { - case LOG_TRACE: __android_log_vprint(ANDROID_LOG_VERBOSE, "raylib", text, args); break; - case LOG_DEBUG: __android_log_vprint(ANDROID_LOG_DEBUG, "raylib", text, args); break; - case LOG_INFO: __android_log_vprint(ANDROID_LOG_INFO, "raylib", text, args); break; - case LOG_WARNING: __android_log_vprint(ANDROID_LOG_WARN, "raylib", text, args); break; - case LOG_ERROR: __android_log_vprint(ANDROID_LOG_ERROR, "raylib", text, args); break; - case LOG_FATAL: __android_log_vprint(ANDROID_LOG_FATAL, "raylib", text, args); break; - default: break; - } -#else - char buffer[MAX_TRACELOG_MSG_LENGTH] = { 0 }; - - switch (logType) - { - case LOG_TRACE: strcpy(buffer, "TRACE: "); break; - case LOG_DEBUG: strcpy(buffer, "DEBUG: "); break; - case LOG_INFO: strcpy(buffer, "INFO: "); break; - case LOG_WARNING: strcpy(buffer, "WARNING: "); break; - case LOG_ERROR: strcpy(buffer, "ERROR: "); break; - case LOG_FATAL: strcpy(buffer, "FATAL: "); break; - default: break; - } - - unsigned int textLength = (unsigned int)strlen(text); - memcpy(buffer + strlen(buffer), text, (textLength < (MAX_TRACELOG_MSG_LENGTH - 12))? textLength : (MAX_TRACELOG_MSG_LENGTH - 12)); - strcat(buffer, "\n"); - vprintf(buffer, args); - fflush(stdout); -#endif - - va_end(args); - - if (logType == LOG_FATAL) exit(EXIT_FAILURE); // If fatal logging, exit program - -#endif // SUPPORT_TRACELOG -} - -// Internal memory allocator -// NOTE: Initializes to zero by default -void *MemAlloc(unsigned int size) -{ - void *ptr = RL_CALLOC(size, 1); - return ptr; -} - -// Internal memory reallocator -void *MemRealloc(void *ptr, unsigned int size) -{ - void *ret = RL_REALLOC(ptr, size); - return ret; -} - -// Internal memory free -void MemFree(void *ptr) -{ - RL_FREE(ptr); -} - -// Load data from file into a buffer -unsigned char *LoadFileData(const char *fileName, int *dataSize) -{ - unsigned char *data = NULL; - *dataSize = 0; - - if (fileName != NULL) - { - if (loadFileData) - { - data = loadFileData(fileName, dataSize); - return data; - } -#if defined(SUPPORT_STANDARD_FILEIO) - FILE *file = fopen(fileName, "rb"); - - if (file != NULL) - { - // WARNING: On binary streams SEEK_END could not be found, - // using fseek() and ftell() could not work in some (rare) cases - fseek(file, 0, SEEK_END); - int size = ftell(file); // WARNING: ftell() returns 'long int', maximum size returned is INT_MAX (2147483647 bytes) - fseek(file, 0, SEEK_SET); - - if (size > 0) - { - data = (unsigned char *)RL_CALLOC(size, sizeof(unsigned char)); - - if (data != NULL) - { - // NOTE: fread() returns number of read elements instead of bytes, so we read [1 byte, size elements] - size_t count = fread(data, sizeof(unsigned char), size, file); - - // WARNING: fread() returns a size_t value, usually 'unsigned int' (32bit compilation) and 'unsigned long long' (64bit compilation) - // dataSize is unified along raylib as a 'int' type, so, for file-sizes > INT_MAX (2147483647 bytes) we have a limitation - if (count > 2147483647) - { - TRACELOG(LOG_WARNING, "FILEIO: [%s] File is bigger than 2147483647 bytes, avoid using LoadFileData()", fileName); - - RL_FREE(data); - data = NULL; - } - else - { - *dataSize = (int)count; - - if ((*dataSize) != size) TRACELOG(LOG_WARNING, "FILEIO: [%s] File partially loaded (%i bytes out of %i)", fileName, dataSize, count); - else TRACELOG(LOG_INFO, "FILEIO: [%s] File loaded successfully", fileName); - } - } - else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to allocated memory for file reading", fileName); - } - else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to read file", fileName); - - fclose(file); - } - else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open file", fileName); -#else - TRACELOG(LOG_WARNING, "FILEIO: Standard file io not supported, use custom file callback"); -#endif - } - else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid"); - - return data; -} - -// Unload file data allocated by LoadFileData() -void UnloadFileData(unsigned char *data) -{ - RL_FREE(data); -} - -// Save data to file from buffer -bool SaveFileData(const char *fileName, void *data, int dataSize) -{ - bool success = false; - - if (fileName != NULL) - { - if (saveFileData) - { - return saveFileData(fileName, data, dataSize); - } -#if defined(SUPPORT_STANDARD_FILEIO) - FILE *file = fopen(fileName, "wb"); - - if (file != NULL) - { - // WARNING: fwrite() returns a size_t value, usually 'unsigned int' (32bit compilation) and 'unsigned long long' (64bit compilation) - // and expects a size_t input value but as dataSize is limited to INT_MAX (2147483647 bytes), there shouldn't be a problem - int count = (int)fwrite(data, sizeof(unsigned char), dataSize, file); - - if (count == 0) TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to write file", fileName); - else if (count != dataSize) TRACELOG(LOG_WARNING, "FILEIO: [%s] File partially written", fileName); - else TRACELOG(LOG_INFO, "FILEIO: [%s] File saved successfully", fileName); - - int result = fclose(file); - if (result == 0) success = true; - } - else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open file", fileName); -#else - TRACELOG(LOG_WARNING, "FILEIO: Standard file io not supported, use custom file callback"); -#endif - } - else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid"); - - return success; -} - -// Export data to code (.h), returns true on success -bool ExportDataAsCode(const unsigned char *data, int dataSize, const char *fileName) -{ - bool success = false; - -#ifndef TEXT_BYTES_PER_LINE - #define TEXT_BYTES_PER_LINE 20 -#endif - - // NOTE: Text data buffer size is estimated considering raw data size in bytes - // and requiring 6 char bytes for every byte: "0x00, " - char *txtData = (char *)RL_CALLOC(dataSize*6 + 2000, sizeof(char)); - - int byteCount = 0; - byteCount += sprintf(txtData + byteCount, "////////////////////////////////////////////////////////////////////////////////////////\n"); - byteCount += sprintf(txtData + byteCount, "// //\n"); - byteCount += sprintf(txtData + byteCount, "// DataAsCode exporter v1.0 - Raw data exported as an array of bytes //\n"); - byteCount += sprintf(txtData + byteCount, "// //\n"); - byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n"); - byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n"); - byteCount += sprintf(txtData + byteCount, "// //\n"); - byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2022-2026 Ramon Santamaria (@raysan5) //\n"); - byteCount += sprintf(txtData + byteCount, "// //\n"); - byteCount += sprintf(txtData + byteCount, "////////////////////////////////////////////////////////////////////////////////////////\n\n"); - - // Get file name from path - char varFileName[256] = { 0 }; - strncpy(varFileName, GetFileNameWithoutExt(fileName), 256 - 1); - for (int i = 0; varFileName[i] != '\0'; i++) - { - // Convert variable name to uppercase - if ((varFileName[i] >= 'a') && (varFileName[i] <= 'z')) { varFileName[i] = varFileName[i] - 32; } - // Replace non valid character for C identifier with '_' - else if (varFileName[i] == '.' || varFileName[i] == '-' || varFileName[i] == '?' || varFileName[i] == '!' || varFileName[i] == '+') { varFileName[i] = '_'; } - } - - byteCount += sprintf(txtData + byteCount, "#define %s_DATA_SIZE %i\n\n", varFileName, dataSize); - - byteCount += sprintf(txtData + byteCount, "static unsigned char %s_DATA[%s_DATA_SIZE] = { ", varFileName, varFileName); - for (int i = 0; i < (dataSize - 1); i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "0x%x,\n" : "0x%x, "), data[i]); - byteCount += sprintf(txtData + byteCount, "0x%x };\n", data[dataSize - 1]); - - // NOTE: Text data size exported is determined by '\0' (NULL) character - success = SaveFileText(fileName, txtData); - - RL_FREE(txtData); - - if (success != 0) TRACELOG(LOG_INFO, "FILEIO: [%s] Data as code exported successfully", fileName); - else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to export data as code", fileName); - - return success; -} - -// Load text data from file, returns a '\0' terminated string -// NOTE: text chars array should be freed manually -char *LoadFileText(const char *fileName) -{ - char *text = NULL; - - if (fileName != NULL) - { - if (loadFileText) - { - text = loadFileText(fileName); - return text; - } -#if defined(SUPPORT_STANDARD_FILEIO) - FILE *file = fopen(fileName, "rt"); - - if (file != NULL) - { - // WARNING: When reading a file as 'text' file, - // text mode causes carriage return-linefeed translation... - // ...but using fseek() should return correct byte-offset - fseek(file, 0, SEEK_END); - unsigned int size = (unsigned int)ftell(file); - fseek(file, 0, SEEK_SET); - - if (size > 0) - { - text = (char *)RL_CALLOC(size + 1, sizeof(char)); - - if (text != NULL) - { - unsigned int count = (unsigned int)fread(text, sizeof(char), size, file); - - // WARNING: \r\n is converted to \n on reading, so, - // read bytes count gets reduced by the number of lines - if (count < size) text = (char *)RL_REALLOC(text, count + 1); - - // Zero-terminate the string - text[count] = '\0'; - - TRACELOG(LOG_INFO, "FILEIO: [%s] Text file loaded successfully", fileName); - } - else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to allocated memory for file reading", fileName); - } - else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to read text file", fileName); - - fclose(file); - } - else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open text file", fileName); -#else - TRACELOG(LOG_WARNING, "FILEIO: Standard file io not supported, use custom file callback"); -#endif - } - else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid"); - - return text; -} - -// Unload file text data allocated by LoadFileText() -void UnloadFileText(char *text) -{ - RL_FREE(text); -} - -// Save text data to file (write), string must be '\0' terminated -bool SaveFileText(const char *fileName, const char *text) -{ - bool success = false; - - if (fileName != NULL) - { - if (saveFileText) - { - return saveFileText(fileName, text); - } -#if defined(SUPPORT_STANDARD_FILEIO) - FILE *file = fopen(fileName, "wt"); - - if (file != NULL) - { - int count = fprintf(file, "%s", text); - - if (count < 0) TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to write text file", fileName); - else TRACELOG(LOG_INFO, "FILEIO: [%s] Text file saved successfully", fileName); - - int result = fclose(file); - if (result == 0) success = true; - } - else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open text file", fileName); -#else - TRACELOG(LOG_WARNING, "FILEIO: Standard file io not supported, use custom file callback"); -#endif - } - else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid"); - - return success; -} - -#if defined(PLATFORM_ANDROID) -// Initialize asset manager from android app -void InitAssetManager(AAssetManager *manager, const char *dataPath) -{ - assetManager = manager; - internalDataPath = dataPath; -} - -// Replacement for fopen() -// REF: https://developer.android.com/ndk/reference/group/asset -FILE *android_fopen(const char *fileName, const char *mode) -{ - FILE *file = NULL; - - if (mode[0] == 'w') - { - // NOTE: fopen() is mapped to android_fopen() that only grants read access to - // assets directory through AAssetManager but we want to also be able to - // write data when required using the standard stdio FILE access functions - // REF: https://stackoverflow.com/questions/11294487/android-writing-saving-files-from-native-code-only - #undef fopen - file = fopen(TextFormat("%s/%s", internalDataPath, fileName), mode); - #define fopen(name, mode) android_fopen(name, mode) - } - else - { - // NOTE: AAsset provides access to read-only asset - AAsset *asset = AAssetManager_open(assetManager, fileName, AASSET_MODE_UNKNOWN); - - if (asset != NULL) - { - // Get pointer to file in the assets - file = funopen(asset, android_read, android_write, android_seek, android_close); - } - else - { - #undef fopen - // Just do a regular open if file is not found in the assets - file = fopen(TextFormat("%s/%s", internalDataPath, fileName), mode); - if (file == NULL) file = fopen(fileName, mode); - #define fopen(name, mode) android_fopen(name, mode) - } - } - - return file; -} -#endif // PLATFORM_ANDROID - -//---------------------------------------------------------------------------------- -// Module Internal Functions Definition -//---------------------------------------------------------------------------------- -#if defined(PLATFORM_ANDROID) -static int android_read(void *cookie, char *data, int dataSize) -{ - return AAsset_read((AAsset *)cookie, data, dataSize); -} - -static int android_write(void *cookie, const char *data, int dataSize) -{ - TRACELOG(LOG_WARNING, "ANDROID: Failed to provide write access to APK"); - - return EACCES; -} - -static fpos_t android_seek(void *cookie, fpos_t offset, int whence) -{ - return AAsset_seek((AAsset *)cookie, offset, whence); -} - -static int android_close(void *cookie) -{ - AAsset_close((AAsset *)cookie); - return 0; -} -#endif // PLATFORM_ANDROID diff --git a/src/utils.h b/src/utils.h deleted file mode 100644 index 9c15ac285..000000000 --- a/src/utils.h +++ /dev/null @@ -1,74 +0,0 @@ -/********************************************************************************************** -* -* raylib.utils - Some common utility functions -* -* -* LICENSE: zlib/libpng -* -* Copyright (c) 2014-2026 Ramon Santamaria (@raysan5) -* -* This software is provided "as-is", without any express or implied warranty. In no event -* will the authors be held liable for any damages arising from the use of this software. -* -* Permission is granted to anyone to use this software for any purpose, including commercial -* applications, and to alter it and redistribute it freely, subject to the following restrictions: -* -* 1. The origin of this software must not be misrepresented; you must not claim that you -* wrote the original software. If you use this software in a product, an acknowledgment -* in the product documentation would be appreciated but is not required. -* -* 2. Altered source versions must be plainly marked as such, and must not be misrepresented -* as being the original software. -* -* 3. This notice may not be removed or altered from any source distribution. -* -**********************************************************************************************/ - -#ifndef UTILS_H -#define UTILS_H - -#if defined(PLATFORM_ANDROID) - #include // Required for: FILE - #include // Required for: AAssetManager -#endif - -#if defined(SUPPORT_TRACELOG) - #define TRACELOG(level, ...) TraceLog(level, __VA_ARGS__) -#else - #define TRACELOG(level, ...) (void)0 -#endif - -//---------------------------------------------------------------------------------- -// Some basic Defines -//---------------------------------------------------------------------------------- -#if defined(PLATFORM_ANDROID) - #define fopen(name, mode) android_fopen(name, mode) -#endif - -//---------------------------------------------------------------------------------- -// Types and Structures Definition -//---------------------------------------------------------------------------------- -//... - -//---------------------------------------------------------------------------------- -// Global Variables Definition -//---------------------------------------------------------------------------------- -// Nop... - -//---------------------------------------------------------------------------------- -// Module Functions Declaration -//---------------------------------------------------------------------------------- -#if defined(__cplusplus) -extern "C" { // Prevents name mangling of functions -#endif - -#if defined(PLATFORM_ANDROID) -void InitAssetManager(AAssetManager *manager, const char *dataPath); // Initialize asset manager from android app -FILE *android_fopen(const char *fileName, const char *mode); // Replacement for fopen() -> Read-only! -#endif - -#if defined(__cplusplus) -} -#endif - -#endif // UTILS_H From 21f026a48492a649f74a53519f82809cd5ba0119 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 10 Jan 2026 11:13:29 +0000 Subject: [PATCH 100/232] rlparser: update raylib_api.* by CI --- tools/rlparser/output/raylib_api.json | 118 +++++++++++++------------- tools/rlparser/output/raylib_api.lua | 86 +++++++++---------- tools/rlparser/output/raylib_api.txt | 80 ++++++++--------- tools/rlparser/output/raylib_api.xml | 34 ++++---- 4 files changed, 159 insertions(+), 159 deletions(-) diff --git a/tools/rlparser/output/raylib_api.json b/tools/rlparser/output/raylib_api.json index 66d8e9f30..185516563 100644 --- a/tools/rlparser/output/raylib_api.json +++ b/tools/rlparser/output/raylib_api.json @@ -4191,6 +4191,17 @@ } ] }, + { + "name": "SetTraceLogLevel", + "description": "Set the current threshold (minimum) log level", + "returnType": "void", + "params": [ + { + "type": "int", + "name": "logLevel" + } + ] + }, { "name": "TraceLog", "description": "Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...)", @@ -4211,13 +4222,13 @@ ] }, { - "name": "SetTraceLogLevel", - "description": "Set the current threshold (minimum) log level", + "name": "SetTraceLogCallback", + "description": "Set custom trace log", "returnType": "void", "params": [ { - "type": "int", - "name": "logLevel" + "type": "TraceLogCallback", + "name": "callback" } ] }, @@ -4258,61 +4269,6 @@ } ] }, - { - "name": "SetTraceLogCallback", - "description": "Set custom trace log", - "returnType": "void", - "params": [ - { - "type": "TraceLogCallback", - "name": "callback" - } - ] - }, - { - "name": "SetLoadFileDataCallback", - "description": "Set custom file binary data loader", - "returnType": "void", - "params": [ - { - "type": "LoadFileDataCallback", - "name": "callback" - } - ] - }, - { - "name": "SetSaveFileDataCallback", - "description": "Set custom file binary data saver", - "returnType": "void", - "params": [ - { - "type": "SaveFileDataCallback", - "name": "callback" - } - ] - }, - { - "name": "SetLoadFileTextCallback", - "description": "Set custom file text data loader", - "returnType": "void", - "params": [ - { - "type": "LoadFileTextCallback", - "name": "callback" - } - ] - }, - { - "name": "SetSaveFileTextCallback", - "description": "Set custom file text data saver", - "returnType": "void", - "params": [ - { - "type": "SaveFileTextCallback", - "name": "callback" - } - ] - }, { "name": "LoadFileData", "description": "Load file data as byte array (read)", @@ -4414,6 +4370,50 @@ } ] }, + { + "name": "SetLoadFileDataCallback", + "description": "Set custom file binary data loader", + "returnType": "void", + "params": [ + { + "type": "LoadFileDataCallback", + "name": "callback" + } + ] + }, + { + "name": "SetSaveFileDataCallback", + "description": "Set custom file binary data saver", + "returnType": "void", + "params": [ + { + "type": "SaveFileDataCallback", + "name": "callback" + } + ] + }, + { + "name": "SetLoadFileTextCallback", + "description": "Set custom file text data loader", + "returnType": "void", + "params": [ + { + "type": "LoadFileTextCallback", + "name": "callback" + } + ] + }, + { + "name": "SetSaveFileTextCallback", + "description": "Set custom file text data saver", + "returnType": "void", + "params": [ + { + "type": "SaveFileTextCallback", + "name": "callback" + } + ] + }, { "name": "FileRename", "description": "Rename file (if exists)", diff --git a/tools/rlparser/output/raylib_api.lua b/tools/rlparser/output/raylib_api.lua index 192ad963a..f2836e1ff 100644 --- a/tools/rlparser/output/raylib_api.lua +++ b/tools/rlparser/output/raylib_api.lua @@ -3864,6 +3864,14 @@ return { {type = "const char *", name = "url"} } }, + { + name = "SetTraceLogLevel", + description = "Set the current threshold (minimum) log level", + returnType = "void", + params = { + {type = "int", name = "logLevel"} + } + }, { name = "TraceLog", description = "Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...)", @@ -3875,11 +3883,11 @@ return { } }, { - name = "SetTraceLogLevel", - description = "Set the current threshold (minimum) log level", + name = "SetTraceLogCallback", + description = "Set custom trace log", returnType = "void", params = { - {type = "int", name = "logLevel"} + {type = "TraceLogCallback", name = "callback"} } }, { @@ -3907,46 +3915,6 @@ return { {type = "void *", name = "ptr"} } }, - { - name = "SetTraceLogCallback", - description = "Set custom trace log", - returnType = "void", - params = { - {type = "TraceLogCallback", name = "callback"} - } - }, - { - name = "SetLoadFileDataCallback", - description = "Set custom file binary data loader", - returnType = "void", - params = { - {type = "LoadFileDataCallback", name = "callback"} - } - }, - { - name = "SetSaveFileDataCallback", - description = "Set custom file binary data saver", - returnType = "void", - params = { - {type = "SaveFileDataCallback", name = "callback"} - } - }, - { - name = "SetLoadFileTextCallback", - description = "Set custom file text data loader", - returnType = "void", - params = { - {type = "LoadFileTextCallback", name = "callback"} - } - }, - { - name = "SetSaveFileTextCallback", - description = "Set custom file text data saver", - returnType = "void", - params = { - {type = "SaveFileTextCallback", name = "callback"} - } - }, { name = "LoadFileData", description = "Load file data as byte array (read)", @@ -4009,6 +3977,38 @@ return { {type = "const char *", name = "text"} } }, + { + name = "SetLoadFileDataCallback", + description = "Set custom file binary data loader", + returnType = "void", + params = { + {type = "LoadFileDataCallback", name = "callback"} + } + }, + { + name = "SetSaveFileDataCallback", + description = "Set custom file binary data saver", + returnType = "void", + params = { + {type = "SaveFileDataCallback", name = "callback"} + } + }, + { + name = "SetLoadFileTextCallback", + description = "Set custom file text data loader", + returnType = "void", + params = { + {type = "LoadFileTextCallback", name = "callback"} + } + }, + { + name = "SetSaveFileTextCallback", + description = "Set custom file text data saver", + returnType = "void", + params = { + {type = "SaveFileTextCallback", name = "callback"} + } + }, { name = "FileRename", description = "Rename file (if exists)", diff --git a/tools/rlparser/output/raylib_api.txt b/tools/rlparser/output/raylib_api.txt index f60f8fc81..0676b8138 100644 --- a/tools/rlparser/output/raylib_api.txt +++ b/tools/rlparser/output/raylib_api.txt @@ -1563,100 +1563,100 @@ Function 106: OpenURL() (1 input parameters) Return type: void Description: Open URL with default system browser (if available) Param[1]: url (type: const char *) -Function 107: TraceLog() (3 input parameters) +Function 107: SetTraceLogLevel() (1 input parameters) + Name: SetTraceLogLevel + Return type: void + Description: Set the current threshold (minimum) log level + Param[1]: logLevel (type: int) +Function 108: TraceLog() (3 input parameters) Name: TraceLog Return type: void Description: Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...) Param[1]: logLevel (type: int) Param[2]: text (type: const char *) Param[3]: args (type: ...) -Function 108: SetTraceLogLevel() (1 input parameters) - Name: SetTraceLogLevel +Function 109: SetTraceLogCallback() (1 input parameters) + Name: SetTraceLogCallback Return type: void - Description: Set the current threshold (minimum) log level - Param[1]: logLevel (type: int) -Function 109: MemAlloc() (1 input parameters) + Description: Set custom trace log + Param[1]: callback (type: TraceLogCallback) +Function 110: MemAlloc() (1 input parameters) Name: MemAlloc Return type: void * Description: Internal memory allocator Param[1]: size (type: unsigned int) -Function 110: MemRealloc() (2 input parameters) +Function 111: MemRealloc() (2 input parameters) Name: MemRealloc Return type: void * Description: Internal memory reallocator Param[1]: ptr (type: void *) Param[2]: size (type: unsigned int) -Function 111: MemFree() (1 input parameters) +Function 112: MemFree() (1 input parameters) Name: MemFree Return type: void Description: Internal memory free Param[1]: ptr (type: void *) -Function 112: SetTraceLogCallback() (1 input parameters) - Name: SetTraceLogCallback - Return type: void - Description: Set custom trace log - Param[1]: callback (type: TraceLogCallback) -Function 113: SetLoadFileDataCallback() (1 input parameters) - Name: SetLoadFileDataCallback - Return type: void - Description: Set custom file binary data loader - Param[1]: callback (type: LoadFileDataCallback) -Function 114: SetSaveFileDataCallback() (1 input parameters) - Name: SetSaveFileDataCallback - Return type: void - Description: Set custom file binary data saver - Param[1]: callback (type: SaveFileDataCallback) -Function 115: SetLoadFileTextCallback() (1 input parameters) - Name: SetLoadFileTextCallback - Return type: void - Description: Set custom file text data loader - Param[1]: callback (type: LoadFileTextCallback) -Function 116: SetSaveFileTextCallback() (1 input parameters) - Name: SetSaveFileTextCallback - Return type: void - Description: Set custom file text data saver - Param[1]: callback (type: SaveFileTextCallback) -Function 117: LoadFileData() (2 input parameters) +Function 113: LoadFileData() (2 input parameters) Name: LoadFileData Return type: unsigned char * Description: Load file data as byte array (read) Param[1]: fileName (type: const char *) Param[2]: dataSize (type: int *) -Function 118: UnloadFileData() (1 input parameters) +Function 114: UnloadFileData() (1 input parameters) Name: UnloadFileData Return type: void Description: Unload file data allocated by LoadFileData() Param[1]: data (type: unsigned char *) -Function 119: SaveFileData() (3 input parameters) +Function 115: SaveFileData() (3 input parameters) Name: SaveFileData Return type: bool Description: Save data to file from byte array (write), returns true on success Param[1]: fileName (type: const char *) Param[2]: data (type: void *) Param[3]: dataSize (type: int) -Function 120: ExportDataAsCode() (3 input parameters) +Function 116: ExportDataAsCode() (3 input parameters) Name: ExportDataAsCode Return type: bool Description: Export data to code (.h), returns true on success Param[1]: data (type: const unsigned char *) Param[2]: dataSize (type: int) Param[3]: fileName (type: const char *) -Function 121: LoadFileText() (1 input parameters) +Function 117: LoadFileText() (1 input parameters) Name: LoadFileText Return type: char * Description: Load text data from file (read), returns a '\0' terminated string Param[1]: fileName (type: const char *) -Function 122: UnloadFileText() (1 input parameters) +Function 118: UnloadFileText() (1 input parameters) Name: UnloadFileText Return type: void Description: Unload file text data allocated by LoadFileText() Param[1]: text (type: char *) -Function 123: SaveFileText() (2 input parameters) +Function 119: SaveFileText() (2 input parameters) Name: SaveFileText Return type: bool Description: Save text data to file (write), string must be '\0' terminated, returns true on success Param[1]: fileName (type: const char *) Param[2]: text (type: const char *) +Function 120: SetLoadFileDataCallback() (1 input parameters) + Name: SetLoadFileDataCallback + Return type: void + Description: Set custom file binary data loader + Param[1]: callback (type: LoadFileDataCallback) +Function 121: SetSaveFileDataCallback() (1 input parameters) + Name: SetSaveFileDataCallback + Return type: void + Description: Set custom file binary data saver + Param[1]: callback (type: SaveFileDataCallback) +Function 122: SetLoadFileTextCallback() (1 input parameters) + Name: SetLoadFileTextCallback + Return type: void + Description: Set custom file text data loader + Param[1]: callback (type: LoadFileTextCallback) +Function 123: SetSaveFileTextCallback() (1 input parameters) + Name: SetSaveFileTextCallback + Return type: void + Description: Set custom file text data saver + Param[1]: callback (type: SaveFileTextCallback) Function 124: FileRename() (2 input parameters) Name: FileRename Return type: int diff --git a/tools/rlparser/output/raylib_api.xml b/tools/rlparser/output/raylib_api.xml index 1bbeb175c..3853ac74f 100644 --- a/tools/rlparser/output/raylib_api.xml +++ b/tools/rlparser/output/raylib_api.xml @@ -988,13 +988,16 @@ + + + - - + + @@ -1006,21 +1009,6 @@ - - - - - - - - - - - - - - - @@ -1048,6 +1036,18 @@ + + + + + + + + + + + + From 1606dca0cbece4ffc7769bf664a86e05b1866fbb Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 10 Jan 2026 12:20:26 +0100 Subject: [PATCH 101/232] Update CMakeLists.txt --- src/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 087141447..76c985969 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -36,7 +36,6 @@ set(raylib_sources rshapes.c rtext.c rtextures.c - utils.c ) # /cmake/GlfwImport.cmake handles the details around the inclusion of glfw From d94ea00a9782ce7f9dc451a0f9afc9fa313b6954 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 11 Jan 2026 00:27:24 +0100 Subject: [PATCH 102/232] Update raylib.sln --- projects/VS2022/raylib.sln | 2 ++ 1 file changed, 2 insertions(+) diff --git a/projects/VS2022/raylib.sln b/projects/VS2022/raylib.sln index 9b088f52d..47e83ef4c 100644 --- a/projects/VS2022/raylib.sln +++ b/projects/VS2022/raylib.sln @@ -5661,6 +5661,8 @@ Global {1F4722E7-F78E-413F-A106-D3490211EA57} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} {0A0FC982-6E31-401F-BA77-3C5E8AB02C68} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} {DC163251-16C3-4B72-B965-ACDBA0F02BD1} = {278D8859-20B1-428F-8448-064F46E1F021} + {D35D2FDA-B53F-4F70-81CA-24D95812B89C} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29} From 972d6f0775f1d51199654dcc14e4285bec746770 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 11 Jan 2026 00:32:16 +0100 Subject: [PATCH 103/232] REXM: Fix raylib building --- tools/rexm/VS2022/raylib/raylib.vcxproj | 2 -- tools/rexm/VS2022/raylib/raylib.vcxproj.filters | 2 -- 2 files changed, 4 deletions(-) diff --git a/tools/rexm/VS2022/raylib/raylib.vcxproj b/tools/rexm/VS2022/raylib/raylib.vcxproj index df2831b33..dbc6272ed 100644 --- a/tools/rexm/VS2022/raylib/raylib.vcxproj +++ b/tools/rexm/VS2022/raylib/raylib.vcxproj @@ -312,7 +312,6 @@ - @@ -320,7 +319,6 @@ - diff --git a/tools/rexm/VS2022/raylib/raylib.vcxproj.filters b/tools/rexm/VS2022/raylib/raylib.vcxproj.filters index b5f5536dc..5914ba240 100644 --- a/tools/rexm/VS2022/raylib/raylib.vcxproj.filters +++ b/tools/rexm/VS2022/raylib/raylib.vcxproj.filters @@ -8,7 +8,6 @@ - @@ -16,7 +15,6 @@ - external From 483b26ef843cff0cda5f939033c9bc4bca73d879 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 11 Jan 2026 01:04:32 +0100 Subject: [PATCH 104/232] Update rexm.c --- tools/rexm/rexm.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 95ed13739..ad9bcbed0 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -660,7 +660,8 @@ int main(int argc, char *argv[]) // we must store provided file paths because pointers will be overwriten // TODO: It seems projects are added to solution BUT not to required solution folder, // that process still requires to be done manually - LOG("INFO: [%s] Adding project to raylib solution (.sln)\n", TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exName)); + LOG("INFO: [%s] Adding project to raylib solution (.sln)\n", + TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exName)); AddVSProjectToSolution(exVSProjectSolutionFile, TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exName), exCategory); //------------------------------------------------------------------------------------------------ @@ -2613,7 +2614,7 @@ static int AddVSProjectToSolution(const char *slnFile, const char *projFile, con int result = 0; // WARNING: Function uses extensively TextFormat(), - // *projFile ptr will be overwriten after a while + // *projFile ptr could be overwriten after a while -> Use copied string // Generate unique UUID const char *uuid = GenerateUUIDv4(); @@ -2697,14 +2698,22 @@ static int AddVSProjectToSolution(const char *slnFile, const char *projFile, con // Add project folder line // NOTE: Folder uuid depends on category - if (strcmp(category, "core") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}\n", uuid)); - else if (strcmp(category, "shapes") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s} = {278D8859-20B1-428F-8448-064F46E1F021}\n", uuid)); - else if (strcmp(category, "textures") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE}\n", uuid)); - else if (strcmp(category, "text") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A}\n", uuid)); - else if (strcmp(category, "models") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}\n", uuid)); - else if (strcmp(category, "shaders") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9}\n", uuid)); - else if (strcmp(category, "audio") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s} = {CC132A4D-D081-4C26-BFB9-AB11984054F8}\n", uuid)); - else if (strcmp(category, "other") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s} = {E9D708A5-9C1F-4B84-A795-C5F191801762}\n", uuid)); + if (strcmp(category, "core") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, + TextFormat("\t\t{%s} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}\n", uuid)); + else if (strcmp(category, "shapes") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, + TextFormat("\t\t{%s} = {278D8859-20B1-428F-8448-064F46E1F021}\n", uuid)); + else if (strcmp(category, "textures") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, + TextFormat("\t\t{%s} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE}\n", uuid)); + else if (strcmp(category, "text") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, + TextFormat("\t\t{%s} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A}\n", uuid)); + else if (strcmp(category, "models") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, + TextFormat("\t\t{%s} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}\n", uuid)); + else if (strcmp(category, "shaders") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, + TextFormat("\t\t{%s} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9}\n", uuid)); + else if (strcmp(category, "audio") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, + TextFormat("\t\t{%s} = {CC132A4D-D081-4C26-BFB9-AB11984054F8}\n", uuid)); + else if (strcmp(category, "other") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, + TextFormat("\t\t{%s} = {E9D708A5-9C1F-4B84-A795-C5F191801762}\n", uuid)); else LOG("WARNING: Provided category is not valid: %s\n", category); //---------------------------------------------------------------------------------------- From 51bdaa34fa2f84063d643d999e44f54d52cc38d1 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 11 Jan 2026 16:56:47 +0100 Subject: [PATCH 105/232] Update raylib.vcxproj --- projects/VS2022/raylib/raylib.vcxproj | 1 - 1 file changed, 1 deletion(-) diff --git a/projects/VS2022/raylib/raylib.vcxproj b/projects/VS2022/raylib/raylib.vcxproj index 287410f06..8cc3fae7a 100644 --- a/projects/VS2022/raylib/raylib.vcxproj +++ b/projects/VS2022/raylib/raylib.vcxproj @@ -601,7 +601,6 @@ - From 4badbe2b1751b88a813c5f2cfe7ac94d2a979078 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 11 Jan 2026 21:02:59 +0100 Subject: [PATCH 106/232] REVIEWED: Variable scope #5485 --- src/platforms/rcore_drm.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index 2e224ad92..a0ae1fa37 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -1415,6 +1415,7 @@ int InitPlatform(void) }; EGLint numConfigs = 0; + const char *eglClientExtensions = NULL; // Get an EGL device connection // NOTE: eglGetPlatformDisplay() is preferred over eglGetDisplay() legacy call @@ -1424,14 +1425,12 @@ int InitPlatform(void) #else // Check if extension is available for eglGetPlatformDisplayEXT() // NOTE: Better compatibility with some drivers (e.g. Mali Midgard) - const char *eglClientExtensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); - if (eglClientExtensions != NULL) + eglClientExtensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); + if ((eglClientExtensions != NULL) && (strstr(eglClientExtensions, "EGL_EXT_platform_base") != NULL)) { - if (strstr(eglClientExtensions, "EGL_EXT_platform_base") != NULL) - { - PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT"); - if (eglGetPlatformDisplayEXT != NULL) platform.device = eglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_KHR, platform.gbmDevice, NULL); - } + PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT"); + + if (eglGetPlatformDisplayEXT != NULL) platform.device = eglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_KHR, platform.gbmDevice, NULL); } // In case extension not found or display could not be retrieved, try useing legacy version @@ -1520,13 +1519,9 @@ int InitPlatform(void) if ((eglClientExtensions != NULL) && (strstr(eglClientExtensions, "EGL_EXT_platform_base") != NULL)) { - PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC eglCreatePlatformWindowSurfaceEXT = - (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT"); + PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC eglCreatePlatformWindowSurfaceEXT = (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT"); - if (eglCreatePlatformWindowSurfaceEXT != NULL) - { - platform.surface = eglCreatePlatformWindowSurfaceEXT(platform.device, platform.config, platform.gbmSurface, NULL); - } + if (eglCreatePlatformWindowSurfaceEXT != NULL) platform.surface = eglCreatePlatformWindowSurfaceEXT(platform.device, platform.config, platform.gbmSurface, NULL); } if (platform.surface == EGL_NO_SURFACE) From d7c38cfbe43dc9f053eacb219cf9523e9c2372b0 Mon Sep 17 00:00:00 2001 From: James Mintram Date: Sun, 11 Jan 2026 21:01:14 +0000 Subject: [PATCH 107/232] fix rglfw.c path in build.zig for bsd platforms (#5486) --- build.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.zig b/build.zig index 2e53bfbdc..ab98bbe98 100644 --- a/build.zig +++ b/build.zig @@ -348,7 +348,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std. } }, .freebsd, .openbsd, .netbsd, .dragonfly => { - try c_source_files.append(b.allocator, "rglfw.c"); + try c_source_files.append(b.allocator, "src/rglfw.c"); raylib.root_module.linkSystemLibrary("GL", .{}); raylib.root_module.linkSystemLibrary("rt", .{}); raylib.root_module.linkSystemLibrary("dl", .{}); From 32e7732061ec425aa261e7eede3b483fa33adbef Mon Sep 17 00:00:00 2001 From: Morgan Moore Date: Sun, 11 Jan 2026 17:43:38 -0500 Subject: [PATCH 108/232] Update build.zig to work with 0.16 (#5487) --- build.zig | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/build.zig b/build.zig index ab98bbe98..111a1bcb1 100644 --- a/build.zig +++ b/build.zig @@ -522,12 +522,13 @@ fn addExamples( raylib: *std.Build.Step.Compile, ) !*std.Build.Step { const all = b.step(module, "All " ++ module ++ " examples"); + const io = all.owner.graph.io; const module_subpath = b.pathJoin(&.{ "examples", module }); - var dir = try std.fs.cwd().openDir(b.pathFromRoot(module_subpath), .{ .iterate = true }); - defer dir.close(); + var dir = try std.Io.Dir.cwd().openDir(io, b.pathFromRoot(module_subpath), .{ .iterate = true }); + defer dir.close(io); var iter = dir.iterate(); - while (try iter.next()) |entry| { + while (try iter.next(io)) |entry| { if (entry.kind != .file) continue; const extension_idx = std.mem.lastIndexOf(u8, entry.name, ".c") orelse continue; const name = entry.name[0..extension_idx]; From 0c33c603f4d7244b652fd6d133fa8a1ed8ae583f Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 12 Jan 2026 13:04:38 +0100 Subject: [PATCH 109/232] REVIEWED: `EXTERNAL_CONFIG_FLAGS` usage, check moved to `config.h` Due to `utils` module removal, `EXTERNAL_CONFIG_FLAGS` was not working, so the system was redesigned. This change is independent of #4411 --- src/config.h | 40 +++++++++++++++++++++++++++------------- src/raudio.c | 6 +----- src/rcore.c | 5 +---- src/rmodels.c | 5 +---- src/rshapes.c | 5 +---- src/rtext.c | 5 +---- src/rtextures.c | 5 +---- 7 files changed, 33 insertions(+), 38 deletions(-) diff --git a/src/config.h b/src/config.h index 68b42cc0e..5e7c6f1d2 100644 --- a/src/config.h +++ b/src/config.h @@ -32,25 +32,22 @@ // Module selection - Some modules could be avoided // Mandatory modules: rcore, rlgl //------------------------------------------------------------------------------------ -#define SUPPORT_MODULE_RSHAPES 1 -#define SUPPORT_MODULE_RTEXTURES 1 -#define SUPPORT_MODULE_RTEXT 1 // WARNING: It requires SUPPORT_MODULE_RTEXTURES to load sprite font textures -#define SUPPORT_MODULE_RMODELS 1 -#define SUPPORT_MODULE_RAUDIO 1 +#if !defined(EXTERNAL_CONFIG_FLAGS) + #define SUPPORT_MODULE_RSHAPES 1 + #define SUPPORT_MODULE_RTEXTURES 1 + #define SUPPORT_MODULE_RTEXT 1 // WARNING: It requires SUPPORT_MODULE_RTEXTURES to load sprite font textures + #define SUPPORT_MODULE_RMODELS 1 + #define SUPPORT_MODULE_RAUDIO 1 +#endif //------------------------------------------------------------------------------------ // Module: rcore - Configuration Flags //------------------------------------------------------------------------------------ +#if !defined(EXTERNAL_CONFIG_FLAGS) // Standard file io library (stdio.h) included #define SUPPORT_STANDARD_FILEIO 1 // Show TRACELOG() output messages #define SUPPORT_TRACELOG 1 -#if defined(SUPPORT_TRACELOG) - #define TRACELOG(level, ...) TraceLog(level, __VA_ARGS__) -#else - #define TRACELOG(level, ...) (void)0 -#endif - // Camera module is included (rcamera.h) and multiple predefined cameras are available: free, 1st/3rd person, orbital #define SUPPORT_CAMERA_SYSTEM 1 // Gestures module is included (rgestures.h) to support gestures detection: tap, hold, swipe, drag @@ -79,10 +76,10 @@ // By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timing + PollInputEvents() // Enabling this flag allows manual control of the frame processes, use at your own risk //#define SUPPORT_CUSTOM_FRAME_CONTROL 1 - // Support for clipboard image loading // NOTE: Only working on SDL3, GLFW (Windows) and RGFW (Windows) #define SUPPORT_CLIPBOARD_IMAGE 1 +#endif // NOTE: Clipboard image loading requires support for some image file formats // TODO: Those defines should probably be removed from here, letting the user manage them @@ -104,6 +101,12 @@ #endif #endif +#if defined(SUPPORT_TRACELOG) + #define TRACELOG(level, ...) TraceLog(level, __VA_ARGS__) +#else + #define TRACELOG(level, ...) (void)0 +#endif + // rcore: Configuration values //------------------------------------------------------------------------------------ #define MAX_TRACELOG_MSG_LENGTH 256 // Max length of one trace-log message @@ -127,7 +130,7 @@ //------------------------------------------------------------------------------------ // Module: rlgl - Configuration values //------------------------------------------------------------------------------------ - +#if !defined(EXTERNAL_CONFIG_FLAGS) // Enable OpenGL Debug Context (only available on OpenGL 4.3) //#define RLGL_ENABLE_OPENGL_DEBUG_CONTEXT 1 @@ -135,6 +138,7 @@ //#define RLGL_SHOW_GL_DETAILS_INFO 1 #define RL_SUPPORT_MESH_GPU_SKINNING 1 // GPU skinning, comment if your GPU does not support more than 8 VBOs +#endif //#define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 4096 // Default internal render batch elements limits #define RL_DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering) @@ -184,9 +188,11 @@ //------------------------------------------------------------------------------------ // Module: rshapes - Configuration Flags //------------------------------------------------------------------------------------ +#if !defined(EXTERNAL_CONFIG_FLAGS) // Use QUADS instead of TRIANGLES for drawing when possible // Some lines-based shapes could still use lines #define SUPPORT_QUADS_DRAW_MODE 1 +#endif // rshapes: Configuration values //------------------------------------------------------------------------------------ @@ -195,6 +201,7 @@ //------------------------------------------------------------------------------------ // Module: rtextures - Configuration Flags //------------------------------------------------------------------------------------ +#if !defined(EXTERNAL_CONFIG_FLAGS) // Selected desired fileformats to be supported for image data loading #define SUPPORT_FILEFORMAT_PNG 1 //#define SUPPORT_FILEFORMAT_BMP 1 @@ -218,10 +225,12 @@ // Support multiple image editing functions to scale, adjust colors, flip, draw on images, crop... // If not defined, still some functions are supported: ImageFormat(), ImageCrop(), ImageToPOT() #define SUPPORT_IMAGE_MANIPULATION 1 +#endif //------------------------------------------------------------------------------------ // Module: rtext - Configuration Flags //------------------------------------------------------------------------------------ +#if !defined(EXTERNAL_CONFIG_FLAGS) // Default font is loaded on window initialization to be available for the user to render simple text // NOTE: If enabled, uses external module functions to load default raylib font #define SUPPORT_DEFAULT_FONT 1 @@ -241,6 +250,7 @@ // Support conservative font atlas size estimation //#define SUPPORT_FONT_ATLAS_SIZE_CONSERVATIVE 1 +#endif // rtext: Configuration values //------------------------------------------------------------------------------------ @@ -251,6 +261,7 @@ //------------------------------------------------------------------------------------ // Module: rmodels - Configuration Flags //------------------------------------------------------------------------------------ +#if !defined(EXTERNAL_CONFIG_FLAGS) // Selected desired model fileformats to be supported for loading #define SUPPORT_FILEFORMAT_OBJ 1 #define SUPPORT_FILEFORMAT_MTL 1 @@ -261,6 +272,7 @@ // Support procedural mesh generation functions, uses external par_shapes.h library // NOTE: Some generated meshes DO NOT include generated texture coordinates #define SUPPORT_MESH_GENERATION 1 +#endif // rmodels: Configuration values //------------------------------------------------------------------------------------ @@ -275,6 +287,7 @@ //------------------------------------------------------------------------------------ // Module: raudio - Configuration Flags //------------------------------------------------------------------------------------ +#if !defined(EXTERNAL_CONFIG_FLAGS) // Desired audio fileformats to be supported for loading #define SUPPORT_FILEFORMAT_WAV 1 #define SUPPORT_FILEFORMAT_OGG 1 @@ -283,6 +296,7 @@ //#define SUPPORT_FILEFORMAT_FLAC 1 #define SUPPORT_FILEFORMAT_XM 1 #define SUPPORT_FILEFORMAT_MOD 1 +#endif // raudio: Configuration values //------------------------------------------------------------------------------------ diff --git a/src/raudio.c b/src/raudio.c index c25ad1f02..18f9e0aad 100644 --- a/src/raudio.c +++ b/src/raudio.c @@ -74,11 +74,7 @@ #else #include "raylib.h" // Declares module functions - // Check if config flags have been externally provided on compilation line - #if !defined(EXTERNAL_CONFIG_FLAGS) - #include "config.h" // Defines module configuration flags - #endif - //#include "utils.h" // Required for: fopen() Android mapping + #include "config.h" // Defines module configuration flags #endif #if defined(SUPPORT_MODULE_RAUDIO) || defined(RAUDIO_STANDALONE) diff --git a/src/rcore.c b/src/rcore.c index 7837f8c4e..dd4123a3b 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -104,10 +104,7 @@ #include "raylib.h" // Declares module functions -// Check if config flags have been externally provided on compilation line -#if !defined(EXTERNAL_CONFIG_FLAGS) - #include "config.h" // Defines module configuration flags -#endif +#include "config.h" // Defines module configuration flags #include // Required for: srand(), rand(), atexit(), exit() #include // Required for: FILE, fopen(), fseek(), ftell(), fread(), fwrite(), fprintf(), vprintf(), fclose(), sprintf() [Used in OpenURL()] diff --git a/src/rmodels.c b/src/rmodels.c index 76efa3e4a..58b08350d 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -42,10 +42,7 @@ #include "raylib.h" // Declares module functions -// Check if config flags have been externally provided on compilation line -#if !defined(EXTERNAL_CONFIG_FLAGS) - #include "config.h" // Defines module configuration flags -#endif +#include "config.h" // Defines module configuration flags #if defined(SUPPORT_MODULE_RMODELS) diff --git a/src/rshapes.c b/src/rshapes.c index e828b98bc..3f686f21a 100644 --- a/src/rshapes.c +++ b/src/rshapes.c @@ -46,10 +46,7 @@ #include "raylib.h" // Declares module functions -// Check if config flags have been externally provided on compilation line -#if !defined(EXTERNAL_CONFIG_FLAGS) - #include "config.h" // Defines module configuration flags -#endif +#include "config.h" // Defines module configuration flags #if defined(SUPPORT_MODULE_RSHAPES) diff --git a/src/rtext.c b/src/rtext.c index 7a1b3c027..8085e81c8 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -55,10 +55,7 @@ #include "raylib.h" // Declares module functions -// Check if config flags have been externally provided on compilation line -#if !defined(EXTERNAL_CONFIG_FLAGS) - #include "config.h" // Defines module configuration flags -#endif +#include "config.h" // Defines module configuration flags #if defined(SUPPORT_MODULE_RTEXT) diff --git a/src/rtextures.c b/src/rtextures.c index fa03d193b..a20b5e516 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -63,10 +63,7 @@ #include "raylib.h" // Declares module functions -// Check if config flags have been externally provided on compilation line -#if !defined(EXTERNAL_CONFIG_FLAGS) - #include "config.h" // Defines module configuration flags -#endif +#include "config.h" // Defines module configuration flags #if defined(SUPPORT_MODULE_RTEXTURES) From 28b9411e9d8d14ba2bf991a5d2ce95f3498d0cde Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 12 Jan 2026 13:23:27 +0100 Subject: [PATCH 110/232] REMOVED: `RLGL_RENDER_TEXTURES_HINT`, enabled by default and no complaints of anyone having issues #5479 --- src/rlgl.h | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/src/rlgl.h b/src/rlgl.h index 7fa22f9cc..8b264343a 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -37,10 +37,6 @@ * If not defined, the library is in header only mode and can be included in other headers * or source files without problems. But only ONE file should hold the implementation * -* #define RLGL_RENDER_TEXTURES_HINT -* Enable framebuffer objects (fbo) support (enabled by default) -* Some GPUs could not support them despite the OpenGL version -* * #define RLGL_SHOW_GL_DETAILS_INFO * Show OpenGL extensions and capabilities detailed logs on init * @@ -196,10 +192,6 @@ #define GRAPHICS_API_OPENGL_ES2 #endif -// Support framebuffer objects by default -// NOTE: Some driver implementation do not support it, despite they should -#define RLGL_RENDER_TEXTURES_HINT - //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- @@ -1863,7 +1855,7 @@ void rlDisableShader(void) // Enable rendering to texture (fbo) void rlEnableFramebuffer(unsigned int id) { -#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) +#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) glBindFramebuffer(GL_FRAMEBUFFER, id); #endif } @@ -1872,7 +1864,7 @@ void rlEnableFramebuffer(unsigned int id) unsigned int rlGetActiveFramebuffer(void) { GLint fboId = 0; -#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES3)) && defined(RLGL_RENDER_TEXTURES_HINT) +#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES3)) glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &fboId); #endif return fboId; @@ -1881,7 +1873,7 @@ unsigned int rlGetActiveFramebuffer(void) // Disable rendering to texture void rlDisableFramebuffer(void) { -#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) +#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) glBindFramebuffer(GL_FRAMEBUFFER, 0); #endif } @@ -1889,7 +1881,7 @@ void rlDisableFramebuffer(void) // Blit active framebuffer to main framebuffer void rlBlitFramebuffer(int srcX, int srcY, int srcWidth, int srcHeight, int dstX, int dstY, int dstWidth, int dstHeight, int bufferMask) { -#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES3)) && defined(RLGL_RENDER_TEXTURES_HINT) +#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES3)) glBlitFramebuffer(srcX, srcY, srcWidth, srcHeight, dstX, dstY, dstWidth, dstHeight, bufferMask, GL_NEAREST); #endif } @@ -1897,7 +1889,7 @@ void rlBlitFramebuffer(int srcX, int srcY, int srcWidth, int srcHeight, int dstX // Bind framebuffer object (fbo) void rlBindFramebuffer(unsigned int target, unsigned int framebuffer) { -#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) +#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) glBindFramebuffer(target, framebuffer); #endif } @@ -1906,7 +1898,7 @@ void rlBindFramebuffer(unsigned int target, unsigned int framebuffer) // NOTE: One color buffer is always active by default void rlActiveDrawBuffers(int count) { -#if ((defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES3)) && defined(RLGL_RENDER_TEXTURES_HINT)) +#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES3)) // NOTE: Maximum number of draw buffers supported is implementation dependant, // it can be queried with glGet*() but it must be at least 8 //GLint maxDrawBuffers = 0; @@ -3826,7 +3818,7 @@ 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) +#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) glGenFramebuffers(1, &fboId); // Create the framebuffer object glBindFramebuffer(GL_FRAMEBUFFER, 0); // Unbind any framebuffer #endif @@ -3838,7 +3830,7 @@ unsigned int rlLoadFramebuffer(void) // NOTE: Attach type: 0-Color, 1-Depth renderbuffer, 2-Depth texture void rlFramebufferAttach(unsigned int fboId, unsigned int texId, int attachType, int texType, int mipLevel) { -#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) +#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) glBindFramebuffer(GL_FRAMEBUFFER, fboId); switch (attachType) @@ -3878,7 +3870,7 @@ bool rlFramebufferComplete(unsigned int id) { bool result = false; -#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) +#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) glBindFramebuffer(GL_FRAMEBUFFER, id); GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); @@ -3909,7 +3901,7 @@ bool rlFramebufferComplete(unsigned int id) // NOTE: All attached textures/cubemaps/renderbuffers are also deleted void rlUnloadFramebuffer(unsigned int id) { -#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) +#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) // Query depth attachment to automatically delete texture/renderbuffer int depthType = 0, depthId = 0; glBindFramebuffer(GL_FRAMEBUFFER, id); // Bind framebuffer to query depth texture type From 644ff28f87055e84289684036b67bc7149e38ac3 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 12 Jan 2026 13:36:40 +0100 Subject: [PATCH 111/232] Update shaders_deferred_rendering.c --- examples/shaders/shaders_deferred_rendering.c | 110 ++++++++---------- 1 file changed, 51 insertions(+), 59 deletions(-) diff --git a/examples/shaders/shaders_deferred_rendering.c b/examples/shaders/shaders_deferred_rendering.c index 811566917..4b03b69a4 100644 --- a/examples/shaders/shaders_deferred_rendering.c +++ b/examples/shaders/shaders_deferred_rendering.c @@ -40,13 +40,13 @@ //---------------------------------------------------------------------------------- // GBuffer data typedef struct GBuffer { - unsigned int framebuffer; + unsigned int framebufferId; - unsigned int positionTexture; - unsigned int normalTexture; - unsigned int albedoSpecTexture; + unsigned int positionTextureId; + unsigned int normalTextureId; + unsigned int albedoSpecTextureId; - unsigned int depthRenderbuffer; + unsigned int depthRenderbufferId; } GBuffer; // Deferred mode passes @@ -90,15 +90,10 @@ int main(void) // Initialize the G-buffer GBuffer gBuffer = { 0 }; - gBuffer.framebuffer = rlLoadFramebuffer(); + gBuffer.framebufferId = rlLoadFramebuffer(); + if (gBuffer.framebufferId == 0) TraceLog(LOG_WARNING, "Failed to create framebufferId"); - if (!gBuffer.framebuffer) - { - TraceLog(LOG_WARNING, "Failed to create framebuffer"); - exit(1); - } - - rlEnableFramebuffer(gBuffer.framebuffer); + rlEnableFramebuffer(gBuffer.framebufferId); // NOTE: Vertex positions are stored in a texture for simplicity. A better approach would use a depth texture // (instead of a detph renderbuffer) to reconstruct world positions in the final render shader via clip-space position, @@ -107,46 +102,42 @@ int main(void) // 16-bit precision ensures OpenGL ES 3 compatibility, though it may lack precision for real scenarios // But as mentioned above, the positions could be reconstructed instead of stored. If not targeting OpenGL ES // and you wish to maintain this approach, consider using `RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32` - gBuffer.positionTexture = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16, 1); + gBuffer.positionTextureId = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16, 1); // Similarly, 16-bit precision is used for normals ensures OpenGL ES 3 compatibility // This is generally sufficient, but a 16-bit fixed-point format offer a better uniform precision in all orientations - gBuffer.normalTexture = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16, 1); + gBuffer.normalTextureId = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16, 1); // Albedo (diffuse color) and specular strength can be combined into one texture // The color in RGB, and the specular strength in the alpha channel - gBuffer.albedoSpecTexture = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, 1); + gBuffer.albedoSpecTextureId = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, 1); - // Activate the draw buffers for our framebuffer + // Activate the draw buffers for our framebufferId rlActiveDrawBuffers(3); - // Now we attach our textures to the framebuffer - rlFramebufferAttach(gBuffer.framebuffer, gBuffer.positionTexture, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_TEXTURE2D, 0); - rlFramebufferAttach(gBuffer.framebuffer, gBuffer.normalTexture, RL_ATTACHMENT_COLOR_CHANNEL1, RL_ATTACHMENT_TEXTURE2D, 0); - rlFramebufferAttach(gBuffer.framebuffer, gBuffer.albedoSpecTexture, RL_ATTACHMENT_COLOR_CHANNEL2, RL_ATTACHMENT_TEXTURE2D, 0); + // Now we attach our textures to the framebufferId + rlFramebufferAttach(gBuffer.framebufferId, gBuffer.positionTextureId, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_TEXTURE2D, 0); + rlFramebufferAttach(gBuffer.framebufferId, gBuffer.normalTextureId, RL_ATTACHMENT_COLOR_CHANNEL1, RL_ATTACHMENT_TEXTURE2D, 0); + rlFramebufferAttach(gBuffer.framebufferId, gBuffer.albedoSpecTextureId, RL_ATTACHMENT_COLOR_CHANNEL2, RL_ATTACHMENT_TEXTURE2D, 0); // Finally we attach the depth buffer - gBuffer.depthRenderbuffer = rlLoadTextureDepth(screenWidth, screenHeight, true); - rlFramebufferAttach(gBuffer.framebuffer, gBuffer.depthRenderbuffer, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_RENDERBUFFER, 0); + gBuffer.depthRenderbufferId = rlLoadTextureDepth(screenWidth, screenHeight, true); + rlFramebufferAttach(gBuffer.framebufferId, gBuffer.depthRenderbufferId, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_RENDERBUFFER, 0); - // Make sure our framebuffer is complete - // NOTE: rlFramebufferComplete() automatically unbinds the framebuffer, so we don't have - // to rlDisableFramebuffer() here - if (!rlFramebufferComplete(gBuffer.framebuffer)) - { - TraceLog(LOG_WARNING, "Framebuffer is not complete"); - } + // Make sure our framebufferId is complete + // NOTE: rlFramebufferComplete() automatically unbinds the framebufferId, so we don't have to rlDisableFramebuffer() here + if (!rlFramebufferComplete(gBuffer.framebufferId)) TraceLog(LOG_WARNING, "Framebuffer is not complete"); // Now we initialize the sampler2D uniform's in the deferred shader // We do this by setting the uniform's values to the texture units that // we later bind our g-buffer textures to rlEnableShader(deferredShader.id); - int texUnitPosition = 0; - int texUnitNormal = 1; - int texUnitAlbedoSpec = 2; - SetShaderValue(deferredShader, rlGetLocationUniform(deferredShader.id, "gPosition"), &texUnitPosition, RL_SHADER_UNIFORM_SAMPLER2D); - SetShaderValue(deferredShader, rlGetLocationUniform(deferredShader.id, "gNormal"), &texUnitNormal, RL_SHADER_UNIFORM_SAMPLER2D); - SetShaderValue(deferredShader, rlGetLocationUniform(deferredShader.id, "gAlbedoSpec"), &texUnitAlbedoSpec, RL_SHADER_UNIFORM_SAMPLER2D); + int texUnitPosition = 0; + int texUnitNormal = 1; + int texUnitAlbedoSpec = 2; + SetShaderValue(deferredShader, rlGetLocationUniform(deferredShader.id, "gPosition"), &texUnitPosition, RL_SHADER_UNIFORM_SAMPLER2D); + SetShaderValue(deferredShader, rlGetLocationUniform(deferredShader.id, "gNormal"), &texUnitNormal, RL_SHADER_UNIFORM_SAMPLER2D); + SetShaderValue(deferredShader, rlGetLocationUniform(deferredShader.id, "gAlbedoSpec"), &texUnitAlbedoSpec, RL_SHADER_UNIFORM_SAMPLER2D); rlDisableShader(); // Assign out lighting shader to model @@ -176,7 +167,7 @@ int main(void) cubeRotations[i] = (float)(rand()%360); } - DeferredMode mode = DEFERRED_SHADING; + int mode = DEFERRED_SHADING; rlEnableDepthTest(); @@ -215,17 +206,16 @@ int main(void) BeginDrawing(); // Draw to the geometry buffer by first activating it - rlEnableFramebuffer(gBuffer.framebuffer); + rlEnableFramebuffer(gBuffer.framebufferId); rlClearColor(0, 0, 0, 0); rlClearScreenBuffers(); // Clear color and depth buffer - rlDisableColorBlend(); + BeginMode3D(camera); // NOTE: We have to use rlEnableShader here. `BeginShaderMode` or thus `rlSetShader` // will not work, as they won't immediately load the shader program rlEnableShader(gbufferShader.id); - // When drawing a model here, make sure that the material's shaders - // are set to the gbuffer shader! + // When drawing a model here, make sure that the material's shaders are set to the gbuffer shader! DrawModel(model, Vector3Zero(), 1.0f, WHITE); DrawModel(cube, (Vector3) { 0.0, 1.0f, 0.0 }, 1.0f, WHITE); @@ -234,12 +224,12 @@ int main(void) Vector3 position = cubePositions[i]; DrawModelEx(cube, position, (Vector3) { 1, 1, 1 }, cubeRotations[i], (Vector3) { CUBE_SCALE, CUBE_SCALE, CUBE_SCALE }, WHITE); } - rlDisableShader(); EndMode3D(); + rlEnableColorBlend(); - // Go back to the default framebuffer (0) and draw our deferred shading + // Go back to the default framebufferId (0) and draw our deferred shading rlDisableFramebuffer(); rlClearScreenBuffers(); // Clear color & depth buffer @@ -254,21 +244,21 @@ int main(void) // We are binding them to locations that we earlier set in sampler2D uniforms `gPosition`, `gNormal`, // and `gAlbedoSpec` rlActiveTextureSlot(texUnitPosition); - rlEnableTexture(gBuffer.positionTexture); + rlEnableTexture(gBuffer.positionTextureId); rlActiveTextureSlot(texUnitNormal); - rlEnableTexture(gBuffer.normalTexture); + rlEnableTexture(gBuffer.normalTextureId); rlActiveTextureSlot(texUnitAlbedoSpec); - rlEnableTexture(gBuffer.albedoSpecTexture); + rlEnableTexture(gBuffer.albedoSpecTextureId); - // Finally, we draw a fullscreen quad to our default framebuffer + // Finally, we draw a fullscreen quad to our default framebufferId // This will now be shaded using our deferred shader rlLoadDrawQuad(); rlDisableShader(); rlEnableColorBlend(); EndMode3D(); - // As a last step, we now copy over the depth buffer from our g-buffer to the default framebuffer - rlBindFramebuffer(RL_READ_FRAMEBUFFER, gBuffer.framebuffer); + // As a last step, we now copy over the depth buffer from our g-buffer to the default framebufferId + rlBindFramebuffer(RL_READ_FRAMEBUFFER, gBuffer.framebufferId); rlBindFramebuffer(RL_DRAW_FRAMEBUFFER, 0); rlBlitFramebuffer(0, 0, screenWidth, screenHeight, 0, 0, screenWidth, screenHeight, 0x00000100); // GL_DEPTH_BUFFER_BIT rlDisableFramebuffer(); @@ -290,7 +280,7 @@ int main(void) case DEFERRED_POSITION: { DrawTextureRec((Texture2D){ - .id = gBuffer.positionTexture, + .id = gBuffer.positionTextureId, .width = screenWidth, .height = screenHeight, }, (Rectangle) { 0, 0, (float)screenWidth, (float)-screenHeight }, Vector2Zero(), RAYWHITE); @@ -300,7 +290,7 @@ int main(void) case DEFERRED_NORMAL: { DrawTextureRec((Texture2D){ - .id = gBuffer.normalTexture, + .id = gBuffer.normalTextureId, .width = screenWidth, .height = screenHeight, }, (Rectangle) { 0, 0, (float)screenWidth, (float)-screenHeight }, Vector2Zero(), RAYWHITE); @@ -310,7 +300,7 @@ int main(void) case DEFERRED_ALBEDO: { DrawTextureRec((Texture2D){ - .id = gBuffer.albedoSpecTexture, + .id = gBuffer.albedoSpecTextureId, .width = screenWidth, .height = screenHeight, }, (Rectangle) { 0, 0, (float)screenWidth, (float)-screenHeight }, Vector2Zero(), RAYWHITE); @@ -331,18 +321,20 @@ int main(void) // De-Initialization //-------------------------------------------------------------------------------------- - UnloadModel(model); // Unload the models + // Unload the models + UnloadModel(model); UnloadModel(cube); - UnloadShader(deferredShader); // Unload shaders + // Unload shaders + UnloadShader(deferredShader); UnloadShader(gbufferShader); // Unload geometry buffer and all attached textures - rlUnloadFramebuffer(gBuffer.framebuffer); - rlUnloadTexture(gBuffer.positionTexture); - rlUnloadTexture(gBuffer.normalTexture); - rlUnloadTexture(gBuffer.albedoSpecTexture); - rlUnloadTexture(gBuffer.depthRenderbuffer); + rlUnloadFramebuffer(gBuffer.framebufferId); + rlUnloadTexture(gBuffer.positionTextureId); + rlUnloadTexture(gBuffer.normalTextureId); + rlUnloadTexture(gBuffer.albedoSpecTextureId); + rlUnloadTexture(gBuffer.depthRenderbufferId); CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- From cfb81e4a0000b1ad1bd5726a697aaa66c82ba73d Mon Sep 17 00:00:00 2001 From: Iisakki Rotko Date: Mon, 12 Jan 2026 22:58:41 +0100 Subject: [PATCH 112/232] fix zig build accessing env vars (#5490) --- build.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.zig b/build.zig index 111a1bcb1..c62e48642 100644 --- a/build.zig +++ b/build.zig @@ -448,7 +448,7 @@ pub const Options = struct { .linux_display_backend = b.option(LinuxDisplayBackend, "linux_display_backend", "Linux display backend to use") orelse defaults.linux_display_backend, .opengl_version = b.option(OpenglVersion, "opengl_version", "OpenGL version to use") orelse defaults.opengl_version, .config = b.option([]const u8, "config", "Compile with custom define macros overriding config.h") orelse &.{}, - .android_ndk = b.option([]const u8, "android_ndk", "specify path to android ndk") orelse std.process.getEnvVarOwned(b.allocator, "ANDROID_NDK_HOME") catch "", + .android_ndk = b.option([]const u8, "android_ndk", "specify path to android ndk") orelse "", .android_api_version = b.option([]const u8, "android_api_version", "specify target android API level") orelse defaults.android_api_version, }; } From 132151cf280b738c2a0e8b1fb0c5e081a1366478 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 13 Jan 2026 16:27:16 +0100 Subject: [PATCH 113/232] Revert "Update build.zig to work with 0.16 (#5487)" This reverts commit 32e7732061ec425aa261e7eede3b483fa33adbef. --- build.zig | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/build.zig b/build.zig index 111a1bcb1..ab98bbe98 100644 --- a/build.zig +++ b/build.zig @@ -522,13 +522,12 @@ fn addExamples( raylib: *std.Build.Step.Compile, ) !*std.Build.Step { const all = b.step(module, "All " ++ module ++ " examples"); - const io = all.owner.graph.io; const module_subpath = b.pathJoin(&.{ "examples", module }); - var dir = try std.Io.Dir.cwd().openDir(io, b.pathFromRoot(module_subpath), .{ .iterate = true }); - defer dir.close(io); + var dir = try std.fs.cwd().openDir(b.pathFromRoot(module_subpath), .{ .iterate = true }); + defer dir.close(); var iter = dir.iterate(); - while (try iter.next(io)) |entry| { + while (try iter.next()) |entry| { if (entry.kind != .file) continue; const extension_idx = std.mem.lastIndexOf(u8, entry.name, ".c") orelse continue; const name = entry.name[0..extension_idx]; From 4be6815b3b15e6ec9b37c12bc111fab7ab340394 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 13 Jan 2026 16:27:51 +0100 Subject: [PATCH 114/232] Revert "fix zig build accessing env vars (#5490)" This reverts commit cfb81e4a0000b1ad1bd5726a697aaa66c82ba73d. --- build.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.zig b/build.zig index 50222a109..ab98bbe98 100644 --- a/build.zig +++ b/build.zig @@ -448,7 +448,7 @@ pub const Options = struct { .linux_display_backend = b.option(LinuxDisplayBackend, "linux_display_backend", "Linux display backend to use") orelse defaults.linux_display_backend, .opengl_version = b.option(OpenglVersion, "opengl_version", "OpenGL version to use") orelse defaults.opengl_version, .config = b.option([]const u8, "config", "Compile with custom define macros overriding config.h") orelse &.{}, - .android_ndk = b.option([]const u8, "android_ndk", "specify path to android ndk") orelse "", + .android_ndk = b.option([]const u8, "android_ndk", "specify path to android ndk") orelse std.process.getEnvVarOwned(b.allocator, "ANDROID_NDK_HOME") catch "", .android_api_version = b.option([]const u8, "android_api_version", "specify target android API level") orelse defaults.android_api_version, }; } From 4b74312860e16de6272803e1ae7abfde006c31c9 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 13 Jan 2026 20:03:30 +0100 Subject: [PATCH 115/232] Update ROADMAP.md --- ROADMAP.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 9a8111133..a49cdbfd7 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -15,13 +15,13 @@ _Current version of raylib is complete and functional but there is always room f **raylib 5.x** - [ ] `rcore`: Support additional platforms: iOS, consoles? - - [ ] `rcore_web`: Avoid GLFW dependency, functionality can be directly implemented using emscripten SDK + - [x] `rcore_web`: Avoid GLFW dependency, functionality can be directly implemented using emscripten SDK - [ ] `rlgl`: Review GLSL shaders naming conventions for consistency - [ ] `textures`: Improve compressed textures support, loading and saving - [ ] `rmodels`: Improve 3d objects loading, specially animations (obj, gltf) - [ ] `raudio`: Implement miniaudio high-level provided features - - [ ] `examples`: Review all examples, add more and better code explanations - - [ ] Software renderer backend? Maybe using `Image` provided API + - [x] `examples`: Review all examples, add more and better code explanations + - [x] Software renderer backend? Maybe using `Image` provided API **raylib 4.x** - [x] Split core module into separate platforms? From 026b7e808a6b30c2948b1b1c4e666c9cbaf4322c Mon Sep 17 00:00:00 2001 From: Matthew Kennedy Date: Thu, 15 Jan 2026 01:03:54 -0800 Subject: [PATCH 116/232] fix drm resources leak (#5494) --- src/platforms/rcore_drm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index a0ae1fa37..b296e0042 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -1161,7 +1161,8 @@ int InitPlatform(void) platform.fd = open("/dev/dri/by-path/platform-gpu-card", O_RDWR); // VideoCore VI (Raspberry Pi 4) if (platform.fd != -1) TRACELOG(LOG_INFO, "DISPLAY: platform-gpu-card opened successfully"); - if ((platform.fd == -1) || (drmModeGetResources(platform.fd) == NULL)) + drmModeRes *res = NULL; + if ((platform.fd == -1) || ((res = drmModeGetResources(platform.fd)) == NULL)) { if (platform.fd != -1) close(platform.fd); TRACELOG(LOG_WARNING, "DISPLAY: Failed to open platform-gpu-card, trying card1"); @@ -1169,7 +1170,7 @@ int InitPlatform(void) if (platform.fd != -1) TRACELOG(LOG_INFO, "DISPLAY: card1 opened successfully"); } - if ((platform.fd == -1) || (drmModeGetResources(platform.fd) == NULL)) + if ((platform.fd == -1) || ((res = drmModeGetResources(platform.fd)) == NULL)) { if (platform.fd != -1) close(platform.fd); TRACELOG(LOG_WARNING, "DISPLAY: Failed to open graphic card1, trying card0"); @@ -1177,7 +1178,7 @@ int InitPlatform(void) if (platform.fd != -1) TRACELOG(LOG_INFO, "DISPLAY: card0 opened successfully"); } - if ((platform.fd == -1) || (drmModeGetResources(platform.fd) == NULL)) + if ((platform.fd == -1) || ((res = drmModeGetResources(platform.fd)) == NULL)) { if (platform.fd != -1) close(platform.fd); TRACELOG(LOG_WARNING, "DISPLAY: Failed to open graphic card0, trying card2"); @@ -1192,7 +1193,6 @@ int InitPlatform(void) return -1; } - drmModeRes *res = drmModeGetResources(platform.fd); if (!res) { TRACELOG(LOG_WARNING, "DISPLAY: Failed get DRM resources"); From a938a7c97a8372e0d4a84addbb1cd1bc3673c44c Mon Sep 17 00:00:00 2001 From: base Date: Thu, 15 Jan 2026 06:08:03 -0300 Subject: [PATCH 117/232] chore: add GetAppDir for wasm returning root VFS (#5495) --- src/rcore.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/rcore.c b/src/rcore.c index dd4123a3b..a393264af 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -2738,6 +2738,9 @@ const char *GetApplicationDirectory(void) appDir[0] = '.'; appDir[1] = '/'; } + +#elif defined(__wasm__) + appDir[0] = '/'; #endif return appDir; From 0df2fe981b8173db9074688a1f612a3263f96052 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 15 Jan 2026 10:42:58 +0100 Subject: [PATCH 118/232] REVIEWED: `ExportFontAsCode()` #5497 --- src/rtext.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/rtext.c b/src/rtext.c index 8085e81c8..45aa19b13 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -1044,15 +1044,26 @@ bool ExportFontAsCode(Font font, const char *fileName) #define TEXT_BYTES_PER_LINE 20 #endif - #define MAX_FONT_DATA_SIZE 1024*1024 // 1 MB - // Get file name from path char fileNamePascal[256] = { 0 }; strncpy(fileNamePascal, TextToPascal(GetFileNameWithoutExt(fileName)), 256 - 1); + + // Get font atlas image and size, required to estimate code file size + // NOTE: This mechanism is highly coupled to raylib + Image image = LoadImageFromTexture(font.texture); + if (image.format != PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA) TRACELOG(LOG_WARNING, "Font export as code: Font image format is not GRAY+ALPHA!"); + int imageDataSize = GetPixelDataSize(image.width, image.height, image.format); - // NOTE: Text data buffer size is estimated considering image data size in bytes - // and requiring 6 char bytes for every byte: "0x00, " - char *txtData = (char *)RL_CALLOC(MAX_FONT_DATA_SIZE, sizeof(char)); + // Image data is usually GRAYSCALE + ALPHA and can be reduced to GRAYSCALE + //ImageFormat(&image, PIXELFORMAT_UNCOMPRESSED_GRAYSCALE); + + // Estimate text code size + // - Image data is stored as "0x%02x", so it requires at least 4 char per byte, let's use 6 + // - font.recs[] data is stored as "{ %1.0f, %1.0f, %1.0f , %1.0f }", let's reserve 64 per rec + // - font.glyphs[] data is stored as "{ %i, %i, %i, %i, { 0 }},\n", let's reserve 64 per glyph + // - Comments and additional code, let's reserve 32KB + int txtDataSize = imageDataSize*6 + font.glyphCount*64 + font.glyphCount*64 + 32768; + char *txtData = (char *)RL_CALLOC(txtDataSize, sizeof(char)); int byteCount = 0; byteCount += sprintf(txtData + byteCount, "////////////////////////////////////////////////////////////////////////////////////////\n"); @@ -1074,15 +1085,6 @@ bool ExportFontAsCode(Font font, const char *fileName) byteCount += sprintf(txtData + byteCount, "// //\n"); byteCount += sprintf(txtData + byteCount, "////////////////////////////////////////////////////////////////////////////////////////\n\n"); - // Support font export and initialization - // NOTE: This mechanism is highly coupled to raylib - Image image = LoadImageFromTexture(font.texture); - if (image.format != PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA) TRACELOG(LOG_WARNING, "Font export as code: Font image format is not GRAY+ALPHA!"); - int imageDataSize = GetPixelDataSize(image.width, image.height, image.format); - - // Image data is usually GRAYSCALE + ALPHA and can be reduced to GRAYSCALE - //ImageFormat(&image, PIXELFORMAT_UNCOMPRESSED_GRAYSCALE); - #define SUPPORT_COMPRESSED_FONT_ATLAS #if defined(SUPPORT_COMPRESSED_FONT_ATLAS) // WARNING: Data is compressed using raylib CompressData() DEFLATE, @@ -1120,8 +1122,7 @@ bool ExportFontAsCode(Font font, const char *fileName) byteCount += sprintf(txtData + byteCount, "};\n\n"); // Save font glyphs data - // NOTE: Glyphs image data not saved (grayscale pixels), - // it could be generated from image and recs + // NOTE: Glyphs image data not saved (grayscale pixels), it could be generated from image and recs byteCount += sprintf(txtData + byteCount, "// Font glyphs info data\n"); byteCount += sprintf(txtData + byteCount, "// NOTE: No glyphs.image data provided\n"); byteCount += sprintf(txtData + byteCount, "static GlyphInfo fontGlyphs_%s[%i] = {\n", fileNamePascal, font.glyphCount); @@ -1152,8 +1153,8 @@ bool ExportFontAsCode(Font font, const char *fileName) #if defined(SUPPORT_COMPRESSED_FONT_ATLAS) byteCount += sprintf(txtData + byteCount, " UnloadImage(imFont); // Uncompressed data can be unloaded from memory\n\n"); #endif - // We have two possible mechanisms to assign font.recs and font.glyphs data, - // that data is already available as global arrays, we two options to assign that data: + // There are two possible mechanisms to assign font.recs and font.glyphs data, + // that data is already available as global arrays, two options to assign that data: // - 1. Data copy. This option consumes more memory and Font MUST be unloaded by user, requiring additional code // - 2. Data assignment. This option consumes less memory and Font MUST NOT be unloaded by user because data is on protected DATA segment //#define SUPPORT_FONT_DATA_COPY From 439448ad7ccfadd2adb15502e17564d873e4dc92 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 15 Jan 2026 10:43:08 +0100 Subject: [PATCH 119/232] Update rcore.c --- src/rcore.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rcore.c b/src/rcore.c index a393264af..1794637bd 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -2740,6 +2740,7 @@ const char *GetApplicationDirectory(void) } #elif defined(__wasm__) + appDir[0] = '/'; #endif From 10b94b02adb469e7ce9af169c2d21c13124a82ce Mon Sep 17 00:00:00 2001 From: jscaff Date: Thu, 15 Jan 2026 17:30:13 -0500 Subject: [PATCH 120/232] Fix opengl interop single header library not having it's implementation loaded (#5498) --- examples/others/raylib_opengl_interop.c | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/others/raylib_opengl_interop.c b/examples/others/raylib_opengl_interop.c index 540a623ab..935eb87f8 100644 --- a/examples/others/raylib_opengl_interop.c +++ b/examples/others/raylib_opengl_interop.c @@ -30,6 +30,7 @@ #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_DESKTOP_SDL) #if defined(GRAPHICS_API_OPENGL_ES2) + #define GLAD_GLES2_IMPLEMENTATION #include "glad_gles2.h" // Required for: OpenGL functionality #define glGenVertexArrays glGenVertexArraysOES #define glBindVertexArray glBindVertexArrayOES From 9621c3d395859382f856389c54d81b1c2f9abeee Mon Sep 17 00:00:00 2001 From: jscaff Date: Fri, 16 Jan 2026 03:42:15 -0500 Subject: [PATCH 121/232] Add QNX EGL2.0 Library configuration (#5499) --- cmake/LibraryConfigurations.cmake | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cmake/LibraryConfigurations.cmake b/cmake/LibraryConfigurations.cmake index 96abeea93..9b8fbdb25 100644 --- a/cmake/LibraryConfigurations.cmake +++ b/cmake/LibraryConfigurations.cmake @@ -27,6 +27,12 @@ if (${PLATFORM} MATCHES "Desktop") add_definitions(-D_CRT_SECURE_NO_WARNINGS) find_package(OpenGL QUIET) set(LIBS_PRIVATE ${OPENGL_LIBRARIES} winmm) + elseif("${CMAKE_SYSTEM_NAME}" MATCHES "QNX") + set(GRAPHICS "GRAPHICS_API_OPENGL_ES2") + find_library(GLESV2 GLESv2) + find_library(EGL EGL) + set(LIBS_PUBLIC m) + set(LIBS_PRIVATE ${GLESV2} ${EGL} atomic pthread dl) elseif (UNIX) find_library(pthread NAMES pthread) find_package(OpenGL QUIET) From fbed591a6ff2da8b953ac201943799ea6129b6aa Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 17 Jan 2026 20:15:45 +0100 Subject: [PATCH 122/232] Reviewed example --- examples/audio/audio_spectrum_visualizer.c | 2 +- examples/audio/audio_spectrum_visualizer.png | Bin 15580 -> 15477 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/audio/audio_spectrum_visualizer.c b/examples/audio/audio_spectrum_visualizer.c index f5334c9cc..5cde7e9bd 100644 --- a/examples/audio/audio_spectrum_visualizer.c +++ b/examples/audio/audio_spectrum_visualizer.c @@ -115,7 +115,7 @@ int main(void) .tapbackPos = 0.01f }; - size_t wavCursor = 0; + int wavCursor = 0; const short *wavPCM16 = wav.data; short chunkSamples[AUDIO_STREAM_RING_BUFFER_SIZE] = { 0 }; diff --git a/examples/audio/audio_spectrum_visualizer.png b/examples/audio/audio_spectrum_visualizer.png index c3f1bc8b0acfbc066c241358f06922dcc8133e86..f885927b1b8bbc124c7ac52f0fb41a8f5d958cc2 100644 GIT binary patch literal 15477 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 literal 15580 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 XmXUW`GFsuSWx Date: Sat, 17 Jan 2026 20:15:48 +0100 Subject: [PATCH 123/232] Update models_first_person_maze.c --- examples/models/models_first_person_maze.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/models/models_first_person_maze.c b/examples/models/models_first_person_maze.c index 4c77d6121..13b56f4cd 100644 --- a/examples/models/models_first_person_maze.c +++ b/examples/models/models_first_person_maze.c @@ -84,19 +84,19 @@ int main(void) for (int y = playerCellY - 1; y <= playerCellY + 1; y++) { // Avoid map accessing out of bounds - if ((y < 0) || (y >= cubicmap.height)) continue; - - for (int x = playerCellX - 1; x <= playerCellX + 1; x++) + if ((y >= 0) && (y < cubicmap.height)) { - // Avoid map accessing out of bounds - if ((x < 0) || (x >= cubicmap.width)) continue; - - if ((mapPixels[y*cubicmap.width + x].r == 255) && // Collision: white pixel, only check R channel - (CheckCollisionCircleRec(playerPos, playerRadius, - (Rectangle){ mapPosition.x - 0.5f + x*1.0f, mapPosition.z - 0.5f + y*1.0f, 1.0f, 1.0f }))) + for (int x = playerCellX - 1; x <= playerCellX + 1; x++) { - // Collision detected, reset camera position - camera.position = oldCamPos; + // NOTE: Collision: Only checking R channel for white pixel + if (((x >= 0) && (x < cubicmap.width)) && + (mapPixels[y*cubicmap.width + x].r == 255) && + (CheckCollisionCircleRec(playerPos, playerRadius, + (Rectangle){ mapPosition.x - 0.5f + x*1.0f, mapPosition.z - 0.5f + y*1.0f, 1.0f, 1.0f }))) + { + // Collision detected, reset camera position + camera.position = oldCamPos; + } } } } From 29896a24039fb687d6ede44c63a78dd3b5829f8b Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 19 Jan 2026 12:40:32 +0100 Subject: [PATCH 124/232] REVIEWED: Some comments (Code Gardening) --- src/external/rlsw.h | 50 ++++++++++++++-------------- src/platforms/rcore_android.c | 4 +-- src/platforms/rcore_desktop_glfw.c | 28 ++++++++-------- src/platforms/rcore_desktop_sdl.c | 45 ++++++++++++------------- src/platforms/rcore_desktop_win32.c | 32 +++++++++--------- src/platforms/rcore_memory.c | 2 +- src/platforms/rcore_web.c | 8 ++--- src/platforms/rcore_web_emscripten.c | 10 +++--- src/raudio.c | 18 +++++----- src/raylib.h | 2 +- src/raymath.h | 26 +++++++-------- src/rcore.c | 4 +-- src/rlgl.h | 8 ++--- src/rmodels.c | 4 +-- src/rshapes.c | 20 +++++------ 15 files changed, 130 insertions(+), 131 deletions(-) diff --git a/src/external/rlsw.h b/src/external/rlsw.h index 80fb02c4f..aad99f937 100644 --- a/src/external/rlsw.h +++ b/src/external/rlsw.h @@ -1177,7 +1177,7 @@ static inline void sw_float_to_unorm8_simd(uint8_t dst[4], const float src[4]) static inline void sw_float_from_unorm8_simd(float dst[4], const uint8_t src[4]) { #if defined(SW_HAS_NEON) - uint8x8_t bytes8 = vld1_u8(src); //< Read 8 bytes, faster, but let's hope we're not at the end of the page (unlikely)... + uint8x8_t bytes8 = vld1_u8(src); // Reading 8 bytes, faster, but let's hope not hitting the end of the page (unlikely)... uint16x8_t bytes16 = vmovl_u8(bytes8); uint32x4_t ints = vmovl_u16(vget_low_u16(bytes16)); float32x4_t floats = vcvtq_f32_u32(ints); @@ -1224,8 +1224,8 @@ static inline uint32_t sw_half_to_float_ui(uint16_t h) // denormal: flush to zero r = (em < (1 << 10))? 0 : r; - // infinity/NaN; note that we preserve NaN payload as a byproduct of unifying inf/nan cases - // 112 is an exponent bias fixup; since we already applied it once, applying it twice converts 31 to 255 + // NOTE: infinity/NaN; NaN payload is preserved as a byproduct of unifying inf/nan cases + // 112 is an exponent bias fixup; since it is already applied once, applying it twice converts 31 to 255 r += (em >= (31 << 10))? (112 << 23) : 0; return s | r; @@ -1252,7 +1252,7 @@ static inline uint16_t sw_half_from_float_ui(uint32_t ui) // Overflow: infinity; 143 encodes exponent 16 h = (em >= (143 << 23))? 0x7c00 : h; - // NaN; note that we convert all types of NaN to qNaN + // NOTE: NaN; all types of NaN aree converted to qNaN h = (em > (255 << 23))? 0x7e00 : h; return (uint16_t)(s | h); @@ -1918,8 +1918,8 @@ static inline void sw_texture_sample_nearest(float *color, const sw_texture_t *t static inline void sw_texture_sample_linear(float *color, const sw_texture_t *tex, float u, float v) { - // TODO: With a bit more cleverness we could clearly reduce the - // number of operations here, but for now it works fine + // TODO: With a bit more cleverness thee number of operations can + // be clearly reduced, but for now it works fine float xf = (u*tex->width) - 0.5f; float yf = (v*tex->height) - 0.5f; @@ -1933,7 +1933,7 @@ static inline void sw_texture_sample_linear(float *color, const sw_texture_t *te int x1 = x0 + 1; int y1 = y0 + 1; - // NOTE: If the textures are POT we could avoid the division for SW_REPEAT + // NOTE: If the textures are POT, avoid the division for SW_REPEAT if (tex->sWrap == SW_CLAMP) { @@ -1974,7 +1974,7 @@ static inline void sw_texture_sample_linear(float *color, const sw_texture_t *te static inline void sw_texture_sample(float *color, const sw_texture_t *tex, float u, float v, float dUdx, float dUdy, float dVdx, float dVdy) { // Previous method: There is no need to compute the square root - // because using the squared value, the comparison remains `L2 > 1.0f*1.0f` + // because using the squared value, the comparison remains (L2 > 1.0f*1.0f) //float du = sqrtf(dUdx*dUdx + dUdy*dUdy); //float dv = sqrtf(dVdx*dVdx + dVdy*dVdy); //float L = (du > dv)? du : dv; @@ -2204,12 +2204,12 @@ static inline bool sw_polygon_clip(sw_vertex_t polygon[SW_MAX_CLIPPED_POLYGON_VE static inline bool sw_triangle_face_culling(void) { // NOTE: Face culling is done before clipping to avoid unnecessary computations - // To handle triangles crossing the w=0 plane correctly, - // we perform the winding order test in homogeneous coordinates directly, - // before the perspective division (division by w) - // This test determines the orientation of the triangle in the (x,y,w) plane, - // which corresponds to the projected 2D winding order sign, - // even with negative w values + // To handle triangles crossing the w=0 plane correctly, + // the winding order test is performeed in homogeneous coordinates directly, + // before the perspective division (division by w) + // This test determines the orientation of the triangle in the (x,y,w) plane, + // which corresponds to the projected 2D winding order sign, + // even with negative w values // Preload homogeneous coordinates into local variables const float *h0 = RLSW.vertexBuffer[0].homogeneous; @@ -2558,13 +2558,13 @@ static inline void sw_triangle_render(void) static inline bool sw_quad_face_culling(void) { // NOTE: Face culling is done before clipping to avoid unnecessary computations - // To handle quads crossing the w=0 plane correctly, - // we perform the winding order test in homogeneous coordinates directly, - // before the perspective division (division by w) - // For a convex quad with vertices P0, P1, P2, P3 in sequential order, - // the winding order of the quad is the same as the winding order - // of the triangle P0 P1 P2. We use the homogeneous triangle - // winding test on this first triangle + // To handle quads crossing the w=0 plane correctly, + // the winding order test is performed in homogeneous coordinates directly, + // before the perspective division (division by w) + // For a convex quad with vertices P0, P1, P2, P3 in sequential order, + // the winding order of the quad is the same as the winding order + // of the triangle P0 P1 P2. The homogeneous triangle is used on + // winding test on this first triangle // Preload homogeneous coordinates into local variables const float *h0 = RLSW.vertexBuffer[0].homogeneous; @@ -2649,7 +2649,7 @@ static inline bool sw_quad_is_axis_aligned(void) { // Reject quads with perspective projection // The fast path assumes affine (non-perspective) quads, - // so we require all vertices to have homogeneous w = 1.0 + // so it's required for all vertices to have homogeneous w = 1.0 for (int i = 0; i < 4; i++) { if (RLSW.vertexBuffer[i].homogeneous[3] != 1.0f) return false; @@ -2721,7 +2721,7 @@ static inline void sw_quad_sort_cw(const sw_vertex_t* *output) // TODO: REVIEW: Could a perfectly aligned quad, where one of the four points has a different depth, // still appear perfectly aligned from a certain point of view? -// Because in that case, we would still need to perform perspective division for textures and colors... +// Because in that case, it's still needed to perform perspective division for textures and colors... #define DEFINE_QUAD_RASTER_AXIS_ALIGNED(FUNC_NAME, ENABLE_TEXTURE, ENABLE_DEPTH_TEST, ENABLE_COLOR_BLEND) \ static inline void FUNC_NAME(void) \ { \ @@ -3090,7 +3090,7 @@ static inline void FUNC_NAME(const sw_vertex_t *v0, const sw_vertex_t *v1) \ \ for (int i = 0; i < numPixels; i++) \ { \ - /* REVIEW: May require reviewing projection details */ \ + /* TODO: REVIEW: May require reviewing projection details */ \ int px = (int)(x - 0.5f); \ int py = (int)(y - 0.5f); \ \ @@ -3721,7 +3721,7 @@ void swBlitFramebuffer(int xDst, int yDst, int wDst, int hDst, int xSrc, int ySr ySrc = sw_clampi(ySrc, 0, hSrc); // Check if the sizes are identical after clamping the source to avoid unexpected issues - // REVIEW: This repeats the operations if true, so we could make a copy function without these checks + // TODO: REVIEW: This repeats the operations if true, so a copy function can be made without these checks if (xDst == xSrc && yDst == ySrc && wDst == wSrc && hDst == hSrc) { swCopyFramebuffer(xSrc, ySrc, wSrc, hSrc, format, type, pixels); diff --git a/src/platforms/rcore_android.c b/src/platforms/rcore_android.c index 6122f9a74..65d1c2ddf 100644 --- a/src/platforms/rcore_android.c +++ b/src/platforms/rcore_android.c @@ -1189,7 +1189,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) if (FLAG_IS_SET(source, AINPUT_SOURCE_JOYSTICK) || FLAG_IS_SET(source, AINPUT_SOURCE_GAMEPAD)) { - // For now we'll assume a single gamepad which we "detect" on its input event + // Assuming a single gamepad, "detected" on its input event CORE.Input.Gamepad.ready[0] = true; CORE.Input.Gamepad.axisState[0][GAMEPAD_AXIS_LEFT_X] = AMotionEvent_getAxisValue( @@ -1256,7 +1256,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) FLAG_IS_SET(source, AINPUT_SOURCE_GAMEPAD)) && !FLAG_IS_SET(source, AINPUT_SOURCE_KEYBOARD)) { - // For now we'll assume a single gamepad which we "detect" on its input event + // Assuming a single gamepad, "detected" on its input event CORE.Input.Gamepad.ready[0] = true; GamepadButton button = AndroidTranslateGamepadButton(keycode); diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index f39e256aa..fd9632700 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -602,7 +602,7 @@ void SetWindowIcon(Image image) icon[0].height = image.height; icon[0].pixels = (unsigned char *)image.data; - // NOTE 1: We only support one image icon + // NOTE 1: Only one image icon supported // NOTE 2: The specified image data is copied before this function returns glfwSetWindowIcon(platform.handle, 1, icon); } @@ -833,7 +833,7 @@ int GetCurrentMonitor(void) } else { - // In case the window is between two monitors, we use below logic + // In case the window is between two monitors, below logic is used // to try to detect the "current monitor" for that window, note that // this is probably an overengineered solution for a very side case // trying to match SDL behaviour @@ -1186,7 +1186,7 @@ void SetMouseCursor(int cursor) if (cursor == MOUSE_CURSOR_DEFAULT) glfwSetCursor(platform.handle, NULL); else { - // NOTE: We are relating internal GLFW enum values to our MouseCursor enum values + // NOTE: Mapping internal GLFW enum values to MouseCursor enum values glfwSetCursor(platform.handle, glfwCreateStandardCursor(0x00036000 + cursor)); } } @@ -1247,7 +1247,7 @@ void PollInputEvents(void) CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; // Check if gamepads are ready - // NOTE: We do it here in case of disconnection + // NOTE: Doing it here in case of disconnection for (int i = 0; i < MAX_GAMEPADS; i++) { if (glfwJoystickPresent(i)) CORE.Input.Gamepad.ready[i] = true; @@ -1263,7 +1263,7 @@ void PollInputEvents(void) for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) CORE.Input.Gamepad.previousButtonState[i][k] = CORE.Input.Gamepad.currentButtonState[i][k]; // Get current gamepad state - // NOTE: There is no callback available, so we get it manually + // NOTE: There is no callback available, getting it manually GLFWgamepadstate state = { 0 }; int result = glfwGetGamepadState(i, &state); // This remaps all gamepads so they have their buttons mapped like an xbox controller if (result == GLFW_FALSE) // No joystick is connected, no gamepad mapping or an error occurred @@ -1359,8 +1359,8 @@ void PollInputEvents(void) //---------------------------------------------------------------------------------- // Module Internal Functions Definition //---------------------------------------------------------------------------------- -// 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 +// Function wrappers around RL_*ALLOC macros, used by glfwInitAllocator() inside of InitPlatform() +// GLFWallocator expects function pointers with specific signatures to be provided // REF: https://www.glfw.org/docs/latest/intro_guide.html#init_allocator static void *AllocateWrapper(size_t size, void *user) { @@ -1742,7 +1742,7 @@ int InitPlatform(void) for (int i = 0; i < MAX_GAMEPADS; i++) { // WARNING: If glfwGetJoystickName() is longer than MAX_GAMEPAD_NAME_LENGTH, - // we can get a not-NULL terminated string, so, we only copy up to (MAX_GAMEPAD_NAME_LENGTH - 1) + // only copying up to (MAX_GAMEPAD_NAME_LENGTH - 1) if (glfwJoystickPresent(i)) { CORE.Input.Gamepad.ready[i] = true; @@ -1819,8 +1819,8 @@ 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 + // WARNING: On window minimization, callback is called with 0 values, + // but internal screen values should not be changed, it breaks things if ((width == 0) || (height == 0)) return; // Reset viewport and projection matrix for new size @@ -1926,7 +1926,7 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths { if (count > 0) { - // In case previous dropped filepaths have not been freed, we free them + // In case previous dropped filepaths have not been freed, free them if (CORE.Window.dropFileCount > 0) { for (unsigned int i = 0; i < CORE.Window.dropFileCount; i++) RL_FREE(CORE.Window.dropFilepaths[i]); @@ -1937,7 +1937,7 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths CORE.Window.dropFilepaths = NULL; } - // WARNING: Paths are freed by GLFW when the callback returns, we must keep an internal copy + // WARNING: Paths are freed by GLFW when the callback returns, keeping an internal copy CORE.Window.dropFileCount = count; CORE.Window.dropFilepaths = (char **)RL_CALLOC(CORE.Window.dropFileCount, sizeof(char *)); @@ -1954,7 +1954,7 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i { if (key < 0) return; // Security check, macOS fn key generates -1 - // WARNING: GLFW could return GLFW_REPEAT, we need to consider it as 1 + // WARNING: GLFW could return GLFW_REPEAT, it needs to be considered as 1 // to work properly with our implementation (IsKeyDown/IsKeyUp checks) if (action == GLFW_RELEASE) CORE.Input.Keyboard.currentKeyState[key] = 0; else if (action == GLFW_PRESS) CORE.Input.Keyboard.currentKeyState[key] = 1; @@ -2079,7 +2079,7 @@ static void JoystickCallback(int jid, int event) if (event == GLFW_CONNECTED) { // WARNING: If glfwGetJoystickName() is longer than MAX_GAMEPAD_NAME_LENGTH, - // we can get a not-NULL terminated string, so, we clean destination and only copy up to -1 + // only copy up to (MAX_GAMEPAD_NAME_LENGTH -1) to destination string memset(CORE.Input.Gamepad.name[jid], 0, MAX_GAMEPAD_NAME_LENGTH); strncpy(CORE.Input.Gamepad.name[jid], glfwGetJoystickName(jid), MAX_GAMEPAD_NAME_LENGTH - 1); } diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index eabea6bfe..45bb30c65 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -49,7 +49,7 @@ #define USING_SDL3_PROJECT #endif #ifndef SDL_ENABLE_OLD_NAMES - #define SDL_ENABLE_OLD_NAMES // Just in case we're on SDL3, we need some in-between compatibily + #define SDL_ENABLE_OLD_NAMES // Just in case on SDL3, some in-between compatibily is needed #endif // SDL base library (window/rendered, input, timing... functionality) #ifdef USING_SDL3_PROJECT @@ -254,10 +254,10 @@ static const int CursorsLUT[] = { #if defined(USING_VERSION_SDL3) // SDL3 Migration: -// SDL_WINDOW_FULLSCREEN_DESKTOP has been removed, -// and you can call SDL_GetWindowFullscreenMode() -// to see whether an exclusive fullscreen mode will be used -// or the borderless fullscreen desktop mode will be used +// SDL_WINDOW_FULLSCREEN_DESKTOP has been removed, +// and you can call SDL_GetWindowFullscreenMode() +// to see whether an exclusive fullscreen mode will be used +// or the borderless fullscreen desktop mode will be used #define SDL_WINDOW_FULLSCREEN_DESKTOP SDL_WINDOW_FULLSCREEN #define SDL_IGNORE false @@ -340,9 +340,8 @@ SDL_Surface *SDL_CreateRGBSurface(Uint32 flags, int width, int height, int depth } // SDL3 Migration: -// SDL_GetDisplayDPI() - -// not reliable across platforms, approximately replaced by multiplying -// SDL_GetWindowDisplayScale() times 160 on iPhone and Android, and 96 on other platforms +// SDL_GetDisplayDPI() not reliable across platforms, approximately replaced by multiplying +// SDL_GetWindowDisplayScale() times 160 on iPhone and Android, and 96 on other platforms // returns 0 on success or a negative error code on failure int SDL_GetDisplayDPI(int displayIndex, float *ddpi, float *hdpi, float *vdpi) { @@ -413,7 +412,7 @@ int SDL_GetNumTouchFingers(SDL_TouchID touchID) return count; } -#else // We're on SDL2 +#else // SDL2 fallback // Since SDL2 doesn't have this function we leave a stub // SDL_GetClipboardData function is available since SDL 3.1.3. (e.g. SDL3) @@ -833,10 +832,9 @@ void SetWindowMonitor(int monitor) if ((monitor >= 0) && (monitor < monitorCount)) #endif { - // NOTE: - // 1. SDL started supporting moving exclusive fullscreen windows between displays on SDL3, - // see commit https://github.com/libsdl-org/SDL/commit/3f5ef7dd422057edbcf3e736107e34be4b75d9ba - // 2. A workaround for SDL2 is leaving fullscreen, moving the window, then entering full screen again + // NOTE 1: SDL started supporting moving exclusive fullscreen windows between displays on SDL3, + // see commit https://github.com/libsdl-org/SDL/commit/3f5ef7dd422057edbcf3e736107e34be4b75d9ba + // NOTE 2: A workaround for SDL2 is leaving fullscreen, moving the window, then entering full screen again const bool wasFullscreen = (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE))? true : false; const int screenWidth = CORE.Window.screen.width; @@ -854,14 +852,13 @@ void SetWindowMonitor(int monitor) // If the screen size is larger than the monitor usable area, anchor it on the top left corner, otherwise, center it if ((screenWidth >= usableBounds.w) || (screenHeight >= usableBounds.h)) { - // NOTE: - // 1. There's a known issue where if the window larger than the target display bounds, - // when moving the windows to that display, the window could be clipped back - // ending up positioned partly outside the target display - // 2. The workaround for that is, previously to moving the window, - // setting the window size to the target display size, so they match - // 3. It wasn't done here because we can't assume changing the window size automatically - // is acceptable behavior by the user + // NOTE 1: There's a known issue where if the window larger than the target display bounds, + // when moving the windows to that display, the window could be clipped back + // ending up positioned partly outside the target display + // NOTE 2: The workaround for that is, previously to moving the window, + // setting the window size to the target display size, so they match + // NOTE 3: It wasn't done here because we can't assume changing the window size automatically + // is acceptable behavior by the user SDL_SetWindowPosition(platform.window, usableBounds.x, usableBounds.y); CORE.Window.position.x = usableBounds.x; CORE.Window.position.y = usableBounds.y; @@ -1250,7 +1247,7 @@ void DisableCursor(void) void SwapScreenBuffer(void) { #if defined(GRAPHICS_API_OPENGL_11_SOFTWARE) - // NOTE: We use a preprocessor condition here because `rlCopyFramebuffer` is only declared for software rendering + // NOTE: We use a preprocessor condition here because rlCopyFramebuffer() is only declared for software rendering SDL_Surface *surface = SDL_GetWindowSurface(platform.window); rlCopyFramebuffer(0, 0, CORE.Window.render.width, CORE.Window.render.height, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, surface->pixels); SDL_UpdateWindowSurface(platform.window); @@ -1617,7 +1614,7 @@ void PollInputEvents(void) case SDL_MOUSEBUTTONDOWN: { // NOTE: SDL2 mouse button order is LEFT, MIDDLE, RIGHT, but raylib uses LEFT, RIGHT, MIDDLE like GLFW - // The following conditions align SDL with raylib.h MouseButton enum order + // The following conditions align SDL with raylib.h MouseButton enum order int btn = event.button.button - 1; if (btn == 2) btn = 1; else if (btn == 1) btn = 2; @@ -1630,7 +1627,7 @@ void PollInputEvents(void) case SDL_MOUSEBUTTONUP: { // NOTE: SDL2 mouse button order is LEFT, MIDDLE, RIGHT, but raylib uses LEFT, RIGHT, MIDDLE like GLFW - // The following conditions align SDL with raylib.h MouseButton enum order + // The following conditions align SDL with raylib.h MouseButton enum order int btn = event.button.button - 1; if (btn == 2) btn = 1; else if (btn == 1) btn = 2; diff --git a/src/platforms/rcore_desktop_win32.c b/src/platforms/rcore_desktop_win32.c index 9f33dce1b..28094b53f 100644 --- a/src/platforms/rcore_desktop_win32.c +++ b/src/platforms/rcore_desktop_win32.c @@ -433,7 +433,7 @@ static bool UpdateWindowSize(int mode, HWND hwnd, int width, int height, unsigne return true; } -// Verify if we are running in Windows 10 version 1703 (Creators Update) +// Check if running in Windows 10 version 1703 (Creators Update) static BOOL IsWindows10Version1703OrGreaterWin32(void) { HMODULE ntdll = LoadLibraryW(L"ntdll.dll"); @@ -1138,7 +1138,7 @@ void ShowCursor(void) // Hides mouse cursor void HideCursor(void) { - // NOTE: We use SetCursor() instead of ShowCursor() because + // NOTE: Using SetCursor() instead of ShowCursor() because // it makes it easy to only hide the cursor while it's inside the client area SetCursor(NULL); CORE.Input.Mouse.cursorHidden = true; @@ -1345,7 +1345,7 @@ void PollInputEvents(void) //---------------------------------------------------------------------------------- // Initialize modern OpenGL context -// NOTE: We need to create a dummy context first to query required extensions +// NOTE: Creating a dummy context first to query required extensions HGLRC InitOpenGL(HWND hwnd, HDC hdc) { // First, create a dummy context to get WGL extensions @@ -1460,7 +1460,7 @@ HGLRC InitOpenGL(HWND hwnd, HDC hdc) 0 // Terminator }; - // NOTE: We are not sharing context resources so, second parameters is NULL + // NOTE: Not sharing context resources so, second parameters is NULL realContext = wglCreateContextAttribsARB(hdc, NULL, contextAttribs); // Check for error context creation errors @@ -1476,8 +1476,8 @@ HGLRC InitOpenGL(HWND hwnd, HDC hdc) // Activate real context if (realContext) wglMakeCurrent(hdc, realContext); - // Once we got a real modern OpenGL context, - // we can load required extensions (function pointers) + // Once a real modern OpenGL context is created, + // required extensions can be loaded (function pointers) rlLoadExtensions(WglGetProcAddress); return realContext; @@ -1521,7 +1521,7 @@ int InitPlatform(void) .lpfnWndProc = WndProc, // Custom procedure assigned .cbWndExtra = sizeof(LONG_PTR), // extra space for the Tuple object ptr .hInstance = hInstance, - .hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW), // TODO: Audit if we want to set this since we're implementing WM_SETCURSOR + .hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW), // TODO: Check if this is really required, since WM_SETCURSOR event is processed .lpszClassName = CLASS_NAME // Class name: L"raylibWindow" }; @@ -1854,8 +1854,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara SIZE *inoutSize = (SIZE *)lparam; UINT newDpi = (UINT)wparam; // TODO: WARNING: Converting from WPARAM = UINT_PTR - // for any of these other cases, we might want to post a window - // resize event after the dpi changes? + // For the following flag changes, a window resize event should be posted, + // TODO: Should it be done after dpi changes? if (CORE.Window.flags & FLAG_WINDOW_MINIMIZED) return TRUE; if (CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) return TRUE; if (CORE.Window.flags & FLAG_BORDERLESS_WINDOWED_MODE) return TRUE; @@ -2025,8 +2025,8 @@ static void HandleRawInput(LPARAM lparam) if (input.data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP) TRACELOG(LOG_ERROR, "TODO: handle virtual desktop mouse inputs!"); - // Trick to keep the mouse position at 0,0 and instead move - // the previous position so we can still get a proper mouse delta + // Trick to keep the mouse position at (0,0) and instead move + // the previous position so a proper mouse delta can still be retrieved //CORE.Input.Mouse.previousPosition.x -= input.data.mouse.lLastX; //CORE.Input.Mouse.previousPosition.y -= input.data.mouse.lLastY; //if (CORE.Input.Mouse.currentPosition.x != 0) abort(); @@ -2138,12 +2138,12 @@ static unsigned SanitizeFlags(int mode, unsigned flags) // This design takes care of many odd corner cases. For example, if you want to restore // a window that was previously maximized AND minimized and you want to remove both these // flags, you actually need to call ShowWindow with SW_RESTORE twice. Another example is -// if you have a maximized window, if the undecorated flag is modified then we'd need to -// update the window style, but updating the style would mean the window size would change -// causing the window to lose its Maximized state which would mean we'd need to update the -// window size and then update the window style a second time to restore that maximized +// if you have a maximized window, if the undecorated flag is modified then the window style +// needs to be updated, but updating the style would mean the window size would change +// causing the window to lose its Maximized state which would mean the window size +// needs to be updated, followed by the update of window style, a second time, to restore that maximized // state. This implementation is able to handle any/all of these special situations with a -// retry loop that continues until we either reach the desired state or the state stops changing +// retry loop that continues until either the desired state is reached or the state stops changing static void UpdateFlags(HWND hwnd, unsigned desiredFlags, int width, int height) { // Flags that just apply immediately without needing any operations diff --git a/src/platforms/rcore_memory.c b/src/platforms/rcore_memory.c index c9409a750..1d69f5ed3 100644 --- a/src/platforms/rcore_memory.c +++ b/src/platforms/rcore_memory.c @@ -499,7 +499,7 @@ int InitPlatform(void) } //---------------------------------------------------------------------------- - // If everything work as expected, we can continue + // If everything worked as expected, continue CORE.Window.render.width = CORE.Window.screen.width; CORE.Window.render.height = CORE.Window.screen.height; CORE.Window.currentFbo.width = CORE.Window.render.width; diff --git a/src/platforms/rcore_web.c b/src/platforms/rcore_web.c index f1922600f..b0a145f67 100644 --- a/src/platforms/rcore_web.c +++ b/src/platforms/rcore_web.c @@ -953,8 +953,8 @@ void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float d if (duration > MAX_GAMEPAD_VIBRATION_TIME) duration = MAX_GAMEPAD_VIBRATION_TIME; duration *= 1000.0f; // Convert duration to ms - // Note: At the moment (2024.10.21) Chrome, Edge, Opera, Safari, Android Chrome, Android Webview only support the vibrationActuator API, - // and Firefox only supports the hapticActuators API + // NOTE: At the moment (2024.10.21) Chrome, Edge, Opera, Safari, Android Chrome, Android Webview only support the vibrationActuator API, + // and Firefox only supports the hapticActuators API EM_ASM({ try { @@ -1798,8 +1798,8 @@ static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent // Emscripten: Called on fullscreen change events static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const EmscriptenFullscreenChangeEvent *event, void *userData) { - // NOTE: 1. Reset the fullscreen flags if the user left fullscreen manually by pressing the Escape key - // 2. Which is a necessary safeguard because that case will bypass the toggles CORE.Window.flags resets + // NOTE 1: Reset the fullscreen flags if the user left fullscreen manually by pressing the Escape key + // NOTE 2: Which is a necessary safeguard because that case will bypass the toggles CORE.Window.flags resets if (platform.ourFullscreen) platform.ourFullscreen = false; else { diff --git a/src/platforms/rcore_web_emscripten.c b/src/platforms/rcore_web_emscripten.c index 36b8e964a..ad26077f4 100644 --- a/src/platforms/rcore_web_emscripten.c +++ b/src/platforms/rcore_web_emscripten.c @@ -137,7 +137,7 @@ bool WindowShouldClose(void) // and encapsulating one frame execution on a UpdateDrawFrame() function, // allowing the browser to manage execution asynchronously - // Optionally we can manage the time we give-control-back-to-browser if required, + // NOTE: Optionally, time can be managed, giving control back-to-browser as required, // but it seems below line could generate stuttering on some browsers emscripten_sleep(12); @@ -1358,7 +1358,7 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths { if (count > 0) { - // In case previous dropped filepaths have not been freed, we free them + // In case previous dropped filepaths have not been freed, free them if (CORE.Window.dropFileCount > 0) { for (unsigned int i = 0; i < CORE.Window.dropFileCount; i++) RL_FREE(CORE.Window.dropFilepaths[i]); @@ -1369,7 +1369,7 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths CORE.Window.dropFilepaths = NULL; } - // WARNING: Paths are freed by GLFW when the callback returns, we must keep an internal copy + // WARNING: Paths are freed by GLFW when the callback returns, an internal copy should be kept CORE.Window.dropFileCount = count; CORE.Window.dropFilepaths = (char **)RL_CALLOC(CORE.Window.dropFileCount, sizeof(char *)); @@ -1610,7 +1610,7 @@ static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent double canvasWidth = 0.0; double canvasHeight = 0.0; // 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 + // 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(platform.canvasId, &canvasWidth, &canvasHeight); @@ -1630,7 +1630,7 @@ static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent else if (eventType == EMSCRIPTEN_EVENT_TOUCHEND) CORE.Input.Touch.currentTouchState[i] = 0; } - // Update mouse position if we detect a single touch + // Update mouse position if a single touch is detected if (CORE.Input.Touch.pointCount == 1) { CORE.Input.Mouse.currentPosition.x = CORE.Input.Touch.position[0].x; diff --git a/src/raudio.c b/src/raudio.c index 18f9e0aad..2e087205e 100644 --- a/src/raudio.c +++ b/src/raudio.c @@ -2418,7 +2418,7 @@ static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer, audioBuffer->frameCursorPos = (audioBuffer->frameCursorPos + framesToRead)%audioBuffer->sizeInFrames; framesRead += framesToRead; - // If we've read to the end of the buffer, mark it as processed + // If the end of the buffer is read, mark it as processed if (framesToRead == framesRemainingInOutputBuffer) { audioBuffer->isSubBufferProcessed[currentSubBufferIndex] = true; @@ -2426,7 +2426,7 @@ static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer, currentSubBufferIndex = (currentSubBufferIndex + 1)%2; - // We need to break from this loop if we're not looping + // Break from this loop if looping not enabled if (!audioBuffer->looping) { StopAudioBufferInLockedState(audioBuffer); @@ -2453,10 +2453,12 @@ static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer, // Reads audio data from an AudioBuffer object in device format, returned data will be in a format appropriate for mixing static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, float *framesOut, ma_uint32 frameCount) { - // What's going on here is that we're continuously converting data from the AudioBuffer's internal format to the mixing format, which - // should be defined by the output format of the data converter. We do this until frameCount frames have been output. The important - // detail to remember here is that we never, ever attempt to read more input data than is required for the specified number of output - // frames. This can be achieved with ma_data_converter_get_required_input_frame_count() + // NOTE: Continuously converting data from the AudioBuffer's internal format to the mixing format, + // which should be defined by the output format of the data converter. + // This is done until frameCount frames have been output. + // The important detail to remember is that more data than required should neeveer be read, + // for the specified number of output frames. + // This can be achieved with ma_data_converter_get_required_input_frame_count() ma_uint8 inputBuffer[4096] = { 0 }; ma_uint32 inputBufferFrameCap = sizeof(inputBuffer)/ma_get_bytes_per_frame(audioBuffer->converter.formatIn, audioBuffer->converter.channelsIn); @@ -2573,8 +2575,8 @@ static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const } } - // If for some reason we weren't able to read every frame we'll need to break from the loop - // Not doing this could theoretically put us into an infinite loop + // If for some reason is not possible to read every frame, the loop needs to be broken + // Not doing this could theoretically eend up into an infinite loop if (framesToRead > 0) break; } } diff --git a/src/raylib.h b/src/raylib.h index 177138dc9..9a68b80ce 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -336,7 +336,7 @@ typedef Camera3D Camera; // Camera type fallback, defaults to Camera3D typedef struct Camera2D { 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 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; diff --git a/src/raymath.h b/src/raymath.h index 57e3dac51..7b58d410e 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -66,11 +66,11 @@ // Function specifiers definition #if defined(RAYMATH_IMPLEMENTATION) #if defined(_WIN32) && defined(BUILD_LIBTYPE_SHARED) - #define RMAPI __declspec(dllexport) extern inline // We are building raylib as a Win32 shared library (.dll) + #define RMAPI __declspec(dllexport) extern inline // Building raylib as a Win32 shared library (.dll) #elif defined(BUILD_LIBTYPE_SHARED) - #define RMAPI __attribute__((visibility("default"))) // We are building raylib as a Unix shared library (.so/.dylib) + #define RMAPI __attribute__((visibility("default"))) // Building raylib as a Unix shared library (.so/.dylib) #elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED) - #define RMAPI __declspec(dllimport) // We are using raylib as a Win32 shared library (.dll) + #define RMAPI __declspec(dllimport) // Using raylib as a Win32 shared library (.dll) #else #define RMAPI extern inline // Provide external definition #endif @@ -595,7 +595,7 @@ RMAPI int Vector2Equals(Vector2 p, Vector2 q) // v: normalized direction of the incoming ray // n: normalized normal vector of the interface of two optical media // r: ratio of the refractive index of the medium from where the ray comes -// to the refractive index of the medium on the other side of the surface +// to the refractive index of the medium on the other side of the surface RMAPI Vector2 Vector2Refract(Vector2 v, Vector2 n, float r) { Vector2 result = { 0 }; @@ -1083,7 +1083,7 @@ RMAPI Vector3 Vector3Barycenter(Vector3 p, Vector3 a, Vector3 b, Vector3 c) } // Projects a Vector3 from screen space into object space -// NOTE: We are avoiding calling other raymath functions despite available +// NOTE: Self-contained function, no other raymath functions are called RMAPI Vector3 Vector3Unproject(Vector3 source, Matrix projection, Matrix view) { Vector3 result = { 0 }; @@ -1245,7 +1245,7 @@ RMAPI int Vector3Equals(Vector3 p, Vector3 q) // v: normalized direction of the incoming ray // n: normalized normal vector of the interface of two optical media // r: ratio of the refractive index of the medium from where the ray comes -// to the refractive index of the medium on the other side of the surface +// to the refractive index of the medium on the other side of the surface RMAPI Vector3 Vector3Refract(Vector3 v, Vector3 n, float r) { Vector3 result = { 0 }; @@ -2663,14 +2663,14 @@ RMAPI Matrix MatrixCompose(Vector3 translation, Quaternion rotation, Vector3 sca forward = Vector3RotateByQuaternion(forward, rotation); // Set result matrix output - Matrix result = { - right.x, up.x, forward.x, translation.x, - right.y, up.y, forward.y, translation.y, - right.z, up.z, forward.z, translation.z, - 0.0f, 0.0f, 0.0f, 1.0f - }; + Matrix result = { + right.x, up.x, forward.x, translation.x, + right.y, up.y, forward.y, translation.y, + right.z, up.z, forward.z, translation.z, + 0.0f, 0.0f, 0.0f, 1.0f + }; - return result; + return result; } // Decompose a transformation matrix into its rotational, translational and scaling components and remove shear diff --git a/src/rcore.c b/src/rcore.c index 1794637bd..d07334b28 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -525,7 +525,7 @@ const char *TextFormat(const char *text, ...); // Formatting of text with variab #define PLATFORM_DESKTOP_GLFW #endif -// We're using '#pragma message' because '#warning' is not adopted by MSVC +// Using '#pragma message' because '#warning' is not adopted by MSVC #if defined(SUPPORT_CLIPBOARD_IMAGE) #if !defined(SUPPORT_MODULE_RTEXTURES) #pragma message ("WARNING: Enabling SUPPORT_CLIPBOARD_IMAGE requires SUPPORT_MODULE_RTEXTURES to work properly") @@ -1499,7 +1499,7 @@ Matrix GetCameraMatrix2D(Camera2D camera) // When setting higher scale, it's more intuitive for the world to become bigger (= camera become smaller), // not for the camera getting bigger, hence the invert. Same deal with rotation // 3. Move it by (-offset); - // Offset defines target transform relative to screen, but since we're effectively "moving" screen (camera) + // Offset defines target transform relative to screen, but since effectively "moving" screen (camera) // we need to do it into opposite direction (inverse transform) // Having camera transform in world-space, inverse of it gives the modelview transform diff --git a/src/rlgl.h b/src/rlgl.h index 8b264343a..c604553ee 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -113,11 +113,11 @@ // NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll // NOTE: visibility(default) attribute makes symbols "visible" when compiled with -fvisibility=hidden #if defined(_WIN32) && defined(BUILD_LIBTYPE_SHARED) - #define RLAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll) + #define RLAPI __declspec(dllexport) // Building the library as a Win32 shared library (.dll) #elif defined(BUILD_LIBTYPE_SHARED) - #define RLAPI __attribute__((visibility("default"))) // We are building the library as a Unix shared library (.so/.dylib) + #define RLAPI __attribute__((visibility("default"))) // Building the library as a Unix shared library (.so/.dylib) #elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED) - #define RLAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll) + #define RLAPI __declspec(dllimport) // Using the library as a Win32 shared library (.dll) #endif // Function specifiers definition @@ -3731,7 +3731,7 @@ void *rlReadTexturePixels(unsigned int id, int width, int height, int format) // Two possible Options: // 1 - Bind texture to color fbo attachment and glReadPixels() // 2 - Create an fbo, activate it, render quad with texture, glReadPixels() - // We are using Option 1, just need to care for texture format on retrieval + // Using Option 1, just need to care for texture format on retrieval // NOTE: This behaviour could be conditioned by graphic driver... unsigned int fboId = rlLoadFramebuffer(); diff --git a/src/rmodels.c b/src/rmodels.c index 58b08350d..26fc7bcf8 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -1754,7 +1754,7 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i // This could alternatively use a static VBO and either glMapBuffer() or glBufferSubData() // It isn't clear which would be reliably faster in all cases and on all platforms, // anecdotally glMapBuffer() seems very slow (syncs) while glBufferSubData() seems - // no faster, since we're transferring all the transform matrices anyway + // no faster, since all the transform matrices are transferred anyway instancesVboId = rlLoadVertexBuffer(instanceTransforms, instances*sizeof(float16), false); // Instances transformation matrices are sent to shader attribute location: SHADER_LOC_VERTEX_INSTANCE_TX @@ -4084,7 +4084,7 @@ RayCollision GetRayCollisionBox(Ray ray, BoundingBox box) { RayCollision collision = { 0 }; - // Note: If ray.position is inside the box, the distance is negative (as if the ray was reversed) + // NOTE: If ray.position is inside the box, the distance is negative (as if the ray was reversed) // Reversing ray.direction will give use the correct result bool insideBox = (ray.position.x > box.min.x) && (ray.position.x < box.max.x) && (ray.position.y > box.min.y) && (ray.position.y < box.max.y) && diff --git a/src/rshapes.c b/src/rshapes.c index 3f686f21a..7487e6296 100644 --- a/src/rshapes.c +++ b/src/rshapes.c @@ -59,9 +59,9 @@ //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- -// Error rate to calculate how many segments we need to draw a smooth circle, -// taken from https://stackoverflow.com/a/2244088 #ifndef SMOOTH_CIRCLE_ERROR_RATE + // Define error rate to calculate how many segments are needed to draw a smooth circle + // REF: https://stackoverflow.com/a/2244088 #define SMOOTH_CIRCLE_ERROR_RATE 0.5f // Circle error rate #endif #ifndef SPLINE_SEGMENT_DIVISIONS @@ -318,7 +318,7 @@ void DrawCircle(int centerX, int centerY, float radius, Color color) } // Draw a color-filled circle (Vector version) -// NOTE: On OpenGL 3.3 and ES2 we use QUADS to avoid drawing order issues +// NOTE: On OpenGL 3.3 and ES2 using QUADS to avoid drawing order issues void DrawCircleV(Vector2 center, float radius, Color color) { DrawCircleSector(center, radius, 0, 360, 36, color); @@ -379,7 +379,7 @@ void DrawCircleSector(Vector2 center, float radius, float startAngle, float endA angle += (stepLength*2.0f); } - // NOTE: In case number of segments is odd, we add one last piece to the cake + // NOTE: In case number of segments is odd, adding one last piece to the cake if ((((unsigned int)segments)%2) == 1) { rlColor4ub(color.r, color.g, color.b, color.a); @@ -722,7 +722,7 @@ void DrawRectangle(int posX, int posY, int width, int height, Color color) } // Draw a color-filled rectangle (Vector version) -// NOTE: On OpenGL 3.3 and ES2 we use QUADS to avoid drawing order issues +// NOTE: On OpenGL 3.3 and ES2 using QUADS to avoid drawing order issues void DrawRectangleV(Vector2 position, Vector2 size, Color color) { DrawRectanglePro((Rectangle){ position.x, position.y, size.x, size.y }, (Vector2){ 0.0f, 0.0f }, 0.0f, color); @@ -968,7 +968,7 @@ void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color co /* Quick sketch to make sense of all of this, - there are 9 parts to draw, also mark the 12 points we'll use + there are 9 parts to draw, also mark the 12 points used P0____________________P1 /| |\ @@ -1024,7 +1024,7 @@ void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color co angle += (stepLength*2); } - // NOTE: In case number of segments is odd, we add one last piece to the cake + // NOTE: In case number of segments is odd, adding one last piece to the cake if (segments%2) { rlColor4ub(color.r, color.g, color.b, color.a); @@ -1168,7 +1168,7 @@ void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color co // Draw rectangle with rounded edges void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, Color color) { - // NOTE: For line thicknes <=1.0f we use RL_LINES, otherwise wee use RL_QUADS/RL_TRIANGLES + // NOTE: For line thicknes <=1.0f using RL_LINES, otherwise using RL_QUADS/RL_TRIANGLES DrawRectangleRoundedLinesEx(rec, roundness, segments, 1.0f, color); } @@ -1204,7 +1204,7 @@ void DrawRectangleRoundedLinesEx(Rectangle rec, float roundness, int segments, f /* Quick sketch to make sense of all of this, - marks the 16 + 4(corner centers P16-19) points we'll use + marks the 16 + 4(corner centers P16-19) points used P0 ================== P1 // P8 P9 \\ @@ -1946,7 +1946,7 @@ void DrawSplineBezierCubic(const Vector2 *points, int pointCount, float thick, C // Draw spline segment: Linear, 2 points void DrawSplineSegmentLinear(Vector2 p1, Vector2 p2, float thick, Color color) { - // NOTE: For the linear spline we don't use subdivisions, just a single quad + // NOTE: For the linear spline no subdivisions are used, just a single quad Vector2 delta = { p2.x - p1.x, p2.y - p1.y }; float length = sqrtf(delta.x*delta.x + delta.y*delta.y); From c610d228a244f930ad53492604640f39584c66da Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 20 Jan 2026 21:01:41 +0100 Subject: [PATCH 125/232] Update text_inline_styling.c --- examples/text/text_inline_styling.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/text/text_inline_styling.c b/examples/text/text_inline_styling.c index 81f8156b6..8634ccc19 100644 --- a/examples/text/text_inline_styling.c +++ b/examples/text/text_inline_styling.c @@ -180,12 +180,12 @@ static void DrawTextStyled(Font font, const char *text, Vector2 position, float if (text[i - 1] == 'c') { colFront = GetColor(colHexValue); - colFront.a = (unsigned char)(colFront.a * (float)color.a/255.0f); + //colFront.a *= (unsigned char)(colFront.a*(float)color.a/255.0f); // TODO: Review } else if (text[i - 1] == 'b') { colBack = GetColor(colHexValue); - colBack.a *= (unsigned char)(colFront.a * (float)color.a / 255.0f); + //colBack.a *= (unsigned char)(colFront.a*(float)color.a/255.0f); } i += (colHexCount + 1); // Skip color value retrieved and ']' From 594f5429b2a5b5551f810340927321d0ee6c8a7c Mon Sep 17 00:00:00 2001 From: Catania <79325830+katanya04@users.noreply.github.com> Date: Fri, 23 Jan 2026 13:48:26 +0100 Subject: [PATCH 126/232] [rcore] `LoadDirectoryFilesEx()`, count files if not recursive (#5496) * LoadDirectoryFilesEx on not recursive loading count files * Removed FilePathList.capacity * Added security check in case of memory leak * Fix stop loading paths early on recursive loading * Fix count directories only if filter contains DIRECTORY_FILTER_TAG * rlparser: update raylib_api.* by CI * GetDirectoryFileCount() and GetDirectoryFileCountEx() made visible * rlparser: update raylib_api.* by CI * Added new file and directories filter tags * Renamed `fileCount` in `ScanDirectoryFiles()` to `expectedFileCount` --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- src/raylib.h | 3 +- src/rcore.c | 223 +++---- tools/rlparser/output/raylib_api.json | 35 +- tools/rlparser/output/raylib_api.lua | 23 +- tools/rlparser/output/raylib_api.txt | 913 +++++++++++++------------- tools/rlparser/output/raylib_api.xml | 13 +- 6 files changed, 615 insertions(+), 595 deletions(-) diff --git a/src/raylib.h b/src/raylib.h index 9a68b80ce..8a0a14dad 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -512,7 +512,6 @@ typedef struct VrStereoConfig { // File path list typedef struct FilePathList { - unsigned int capacity; // Filepaths max entries unsigned int count; // Filepaths entries count char **paths; // Filepaths entries } FilePathList; @@ -1152,6 +1151,8 @@ RLAPI void UnloadDirectoryFiles(FilePathList files); // Unload fi RLAPI bool IsFileDropped(void); // Check if a file has been dropped into window RLAPI FilePathList LoadDroppedFiles(void); // Load dropped filepaths RLAPI void UnloadDroppedFiles(FilePathList files); // Unload dropped filepaths +RLAPI unsigned int GetDirectoryFileCount(const char *dirPath); // Get the file count in a directory +RLAPI unsigned int GetDirectoryFileCountEx(const char *basePath, const char *filter, bool scanSubdirs);// Get the file count in a directory with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result // Compression/Encoding functionality RLAPI unsigned char *CompressData(const unsigned char *data, int dataSize, int *compDataSize); // Compress data (DEFLATE algorithm), memory must be MemFree() diff --git a/src/rcore.c b/src/rcore.c index d07334b28..aabf85022 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -267,9 +267,15 @@ #define MAX_AUTOMATION_EVENTS 16384 // Maximum number of automation events to record #endif -#ifndef DIRECTORY_FILTER_TAG - #define DIRECTORY_FILTER_TAG "DIR" // Name tag used to request directory inclusion on directory scan -#endif // NOTE: Used in ScanDirectoryFiles(), ScanDirectoryFilesRecursively() and LoadDirectoryFilesEx() +#ifndef FILE_FILTER_TAG_ALL + #define FILE_FILTER_TAG_ALL "*.*" // Filter to include all file types and directories on directory scan +#endif // NOTE: Used in ScanDirectoryFiles(), LoadDirectoryFilesEx() and GetDirectoryFileCountEx() +#ifndef FILE_FILTER_TAG_FILE_ONLY + #define FILE_FILTER_TAG_FILE_ONLY "FILES*" // Filter to include all file types on directory scan +#endif // NOTE: Used in ScanDirectoryFiles(), LoadDirectoryFilesEx() and GetDirectoryFileCountEx() +#ifndef FILE_FILTER_TAG_DIR_ONLY + #define FILE_FILTER_TAG_DIR_ONLY "DIR*" // Filter to include directories on directory scan +#endif // NOTE: Used in ScanDirectoryFiles(), LoadDirectoryFilesEx() and GetDirectoryFileCountEx() // Flags operation macros #define FLAG_SET(n, f) ((n) |= (f)) @@ -505,8 +511,7 @@ extern void ClosePlatform(void); // Close platform static void InitTimer(void); // Initialize timer, hi-resolution if available (required by InitPlatform()) static void SetupViewport(int width, int height); // Set viewport for a provided width and height -static void ScanDirectoryFiles(const char *basePath, FilePathList *list, const char *filter); // Scan all files and directories in a base path -static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *list, const char *filter); // Scan all files and directories recursively from a base path +static void ScanDirectoryFiles(const char *basePath, FilePathList *list, const char *filter, unsigned int expectedFileCount, bool scanSubdirs); // Scan all files and directories in a base path #if defined(SUPPORT_AUTOMATION_EVENTS) static void RecordAutomationEvent(void); // Record frame events (to internal events array) @@ -2753,53 +2758,36 @@ const char *GetApplicationDirectory(void) // No recursive scanning is done! FilePathList LoadDirectoryFiles(const char *dirPath) { - FilePathList files = { 0 }; - unsigned int fileCounter = 0; - - struct dirent *entity; - DIR *dir = opendir(dirPath); - - if (dir != NULL) // It's a directory - { - // SCAN 1: Count files - while ((entity = readdir(dir)) != NULL) - { - // NOTE: We skip '.' (current dir) and '..' (parent dir) filepaths - if ((strcmp(entity->d_name, ".") != 0) && (strcmp(entity->d_name, "..") != 0)) fileCounter++; - } - - // Memory allocation for dirFileCount - files.capacity = fileCounter; - files.paths = (char **)RL_CALLOC(files.capacity, sizeof(char *)); - for (unsigned int i = 0; i < files.capacity; i++) files.paths[i] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); - - closedir(dir); - - // SCAN 2: Read filepaths - // NOTE: Directory paths are also registered - ScanDirectoryFiles(dirPath, &files, NULL); - - // Security check: read files.count should match fileCounter - if (files.count != files.capacity) TRACELOG(LOG_WARNING, "FILEIO: Read files count do not match capacity allocated"); - } - else TRACELOG(LOG_WARNING, "FILEIO: Failed to open requested directory"); // Maybe it's a file... - - return files; + return LoadDirectoryFilesEx(dirPath, FILE_FILTER_TAG_ALL, false); } // Load directory filepaths with extension filtering and recursive directory scan -// NOTE: On recursive loading we do not pre-scan for file count, we use MAX_FILEPATH_CAPACITY +// WARNING: Directory is scanned twice, first time to get files count FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs) { FilePathList files = { 0 }; - files.capacity = MAX_FILEPATH_CAPACITY; - files.paths = (char **)RL_CALLOC(files.capacity, sizeof(char *)); - for (unsigned int i = 0; i < files.capacity; i++) files.paths[i] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); + if (DirectoryExists(basePath)) // It's a directory + { + // SCAN 1: Count files + unsigned int fileCounter = GetDirectoryFileCountEx(basePath, filter, scanSubdirs); + + // Memory allocation for dirFileCount + files.paths = (char **)RL_CALLOC(fileCounter, sizeof(char *)); + for (unsigned int i = 0; i < fileCounter; i++) files.paths[i] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); - // WARNING: basePath is always prepended to scanned paths - if (scanSubdirs) ScanDirectoryFilesRecursively(basePath, &files, filter); - else ScanDirectoryFiles(basePath, &files, filter); + // SCAN 2: Read filepaths + // WARNING: basePath is always prepended to scanned paths + ScanDirectoryFiles(basePath, &files, filter, fileCounter, scanSubdirs); + + // Security check: read files.count should match fileCounter + if (files.count != fileCounter) + { + TRACELOG(LOG_WARNING, "FILEIO: Read files count (%u) does not match capacity allocated (%u)", files.count, fileCounter); + files.count = fileCounter; // Avoid memory leak when unloading this FilePathList + } + } + else TRACELOG(LOG_WARNING, "FILEIO: Directory cannot be opened (%s)", basePath); // Maybe it's a file... return files; } @@ -2810,7 +2798,7 @@ void UnloadDirectoryFiles(FilePathList files) { if (files.paths != NULL) { - for (unsigned int i = 0; i < files.capacity; i++) RL_FREE(files.paths[i]); + for (unsigned int i = 0; i < files.count; i++) RL_FREE(files.paths[i]); RL_FREE(files.paths); } @@ -2966,6 +2954,59 @@ void UnloadDroppedFiles(FilePathList files) } } +// Get the file count in a directory +unsigned int GetDirectoryFileCount(const char *dirPath) +{ + return GetDirectoryFileCountEx(dirPath, FILE_FILTER_TAG_ALL, false); +} + +// Get the file count in a directory with extension filtering and recursive directory scan. Use 'FILE_FILTER_TAG_DIR_ONLY' in the filter string to include directories in the result +unsigned int GetDirectoryFileCountEx(const char *basePath, const char *filter, bool scanSubdirs) +{ + unsigned int fileCounter = 0; + + // WARNING: Path can not be static or it will be reused between recursive function calls! + char path[MAX_FILEPATH_LENGTH] = { 0 }; + memset(path, 0, MAX_FILEPATH_LENGTH); + + struct dirent *entity; + DIR *dir = opendir(basePath); + + if (dir != NULL) // It's a directory + { + while ((entity = readdir(dir)) != NULL) + { + // NOTE: We skip '.' (current dir) and '..' (parent dir) filepaths + if ((strcmp(entity->d_name, ".") != 0) && (strcmp(entity->d_name, "..") != 0)) + { + // Construct new path from our base path + #if defined(_WIN32) + int pathLength = snprintf(path, MAX_FILEPATH_LENGTH - 1, "%s\\%s", basePath, entity->d_name); + #else + int pathLength = snprintf(path, MAX_FILEPATH_LENGTH - 1, "%s/%s", basePath, entity->d_name); + #endif + // Don't add to count if path too long + if ((pathLength < 0) || (pathLength >= MAX_FILEPATH_LENGTH)) + { + TRACELOG(LOG_WARNING, "FILEIO: Path longer than %d characters (%s...)", MAX_FILEPATH_LENGTH, basePath); + } + else if (IsPathFile(path)) + { + if ((filter == NULL) || (strstr(filter, FILE_FILTER_TAG_ALL) != NULL) || + (strstr(filter, FILE_FILTER_TAG_FILE_ONLY) != NULL) || IsFileExtension(path, filter)) fileCounter++; + } + else + { + if ((filter != NULL) && ((strstr(filter, FILE_FILTER_TAG_ALL) != NULL) || (strstr(filter, FILE_FILTER_TAG_DIR_ONLY) != NULL))) fileCounter++; + if (scanSubdirs) fileCounter += GetDirectoryFileCountEx(path, filter, scanSubdirs); + } + } + } + } + else TRACELOG(LOG_WARNING, "FILEIO: Directory cannot be opened (%s)", basePath); // Maybe it's a file... + return fileCounter; +} + //---------------------------------------------------------------------------------- // Module Functions Definition: Compression and Encoding //---------------------------------------------------------------------------------- @@ -4229,66 +4270,7 @@ void SetupViewport(int width, int height) // Scan all files and directories in a base path // WARNING: files.paths[] must be previously allocated and // contain enough space to store all required paths -static void ScanDirectoryFiles(const char *basePath, FilePathList *files, const char *filter) -{ - static char path[MAX_FILEPATH_LENGTH] = { 0 }; - memset(path, 0, MAX_FILEPATH_LENGTH); - - struct dirent *dp = NULL; - DIR *dir = opendir(basePath); - - if (dir != NULL) - { - while ((dp = readdir(dir)) != NULL) - { - if ((strcmp(dp->d_name, ".") != 0) && - (strcmp(dp->d_name, "..") != 0)) - { - // Construct new path from our base path - #if defined(_WIN32) - int pathLength = snprintf(path, MAX_FILEPATH_LENGTH - 1, "%s\\%s", basePath, dp->d_name); - #else - int pathLength = snprintf(path, MAX_FILEPATH_LENGTH - 1, "%s/%s", basePath, dp->d_name); - #endif - - if ((pathLength < 0) || (pathLength >= MAX_FILEPATH_LENGTH)) - { - TRACELOG(LOG_WARNING, "FILEIO: Path longer than %d characters (%s...)", MAX_FILEPATH_LENGTH, basePath); - } - else if (filter != NULL) - { - if (IsPathFile(path)) - { - if (IsFileExtension(path, filter)) - { - strncpy(files->paths[files->count], path, MAX_FILEPATH_LENGTH - 1); - files->count++; - } - } - else - { - if (strstr(filter, DIRECTORY_FILTER_TAG) != NULL) - { - strncpy(files->paths[files->count], path, MAX_FILEPATH_LENGTH - 1); - files->count++; - } - } - } - else - { - strncpy(files->paths[files->count], path, MAX_FILEPATH_LENGTH - 1); - files->count++; - } - } - } - - closedir(dir); - } - else TRACELOG(LOG_WARNING, "FILEIO: Directory cannot be opened (%s)", basePath); -} - -// Scan all files and directories recursively from a base path -static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *files, const char *filter) +static void ScanDirectoryFiles(const char *basePath, FilePathList *files, const char *filter, unsigned int expectedFileCount, bool scanSubdirs) { // WARNING: Path can not be static or it will be reused between recursive function calls! char path[MAX_FILEPATH_LENGTH] = { 0 }; @@ -4299,7 +4281,7 @@ static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *fi if (dir != NULL) { - while (((dp = readdir(dir)) != NULL) && (files->count < files->capacity)) + while (((dp = readdir(dir)) != NULL) && (files->count < expectedFileCount)) { if ((strcmp(dp->d_name, ".") != 0) && (strcmp(dp->d_name, "..") != 0)) { @@ -4316,48 +4298,29 @@ static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *fi } else if (IsPathFile(path)) { - if (filter != NULL) - { - if (IsFileExtension(path, filter)) - { - strncpy(files->paths[files->count], path, MAX_FILEPATH_LENGTH - 1); - files->count++; - } - } - else + if ((filter == NULL) || (strstr(filter, FILE_FILTER_TAG_ALL) != NULL) || + (strstr(filter, FILE_FILTER_TAG_FILE_ONLY) != NULL) || IsFileExtension(path, filter)) { strncpy(files->paths[files->count], path, MAX_FILEPATH_LENGTH - 1); files->count++; } - - if (files->count >= files->capacity) - { - TRACELOG(LOG_WARNING, "FILEIO: Maximum filepath scan capacity reached (%i files)", files->capacity); - break; - } } else { - if ((filter != NULL) && (strstr(filter, DIRECTORY_FILTER_TAG) != NULL)) + if ((filter != NULL) && ((strstr(filter, FILE_FILTER_TAG_DIR_ONLY) != NULL) || (strstr(filter, FILE_FILTER_TAG_ALL) != NULL))) { strncpy(files->paths[files->count], path, MAX_FILEPATH_LENGTH - 1); files->count++; } - if (files->count >= files->capacity) - { - TRACELOG(LOG_WARNING, "FILEIO: Maximum filepath scan capacity reached (%i files)", files->capacity); - break; - } - - ScanDirectoryFilesRecursively(path, files, filter); + if (scanSubdirs) ScanDirectoryFiles(path, files, filter, expectedFileCount, scanSubdirs); } } } closedir(dir); } - else TRACELOG(LOG_WARNING, "FILEIO: Directory cannot be opened (%s)", basePath); + else TRACELOG(LOG_WARNING, "FILEIO: Directory cannot be opened (%s)", basePath); // Maybe it's a file... } #if defined(SUPPORT_AUTOMATION_EVENTS) diff --git a/tools/rlparser/output/raylib_api.json b/tools/rlparser/output/raylib_api.json index 185516563..d4c059c50 100644 --- a/tools/rlparser/output/raylib_api.json +++ b/tools/rlparser/output/raylib_api.json @@ -1324,11 +1324,6 @@ "name": "FilePathList", "description": "File path list", "fields": [ - { - "type": "unsigned int", - "name": "capacity", - "description": "Filepaths max entries" - }, { "type": "unsigned int", "name": "count", @@ -4734,6 +4729,36 @@ } ] }, + { + "name": "GetDirectoryFileCount", + "description": "Get the file count in a directory", + "returnType": "unsigned int", + "params": [ + { + "type": "const char *", + "name": "dirPath" + } + ] + }, + { + "name": "GetDirectoryFileCountEx", + "description": "Get the file count in a directory with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result", + "returnType": "unsigned int", + "params": [ + { + "type": "const char *", + "name": "basePath" + }, + { + "type": "const char *", + "name": "filter" + }, + { + "type": "bool", + "name": "scanSubdirs" + } + ] + }, { "name": "CompressData", "description": "Compress data (DEFLATE algorithm), memory must be MemFree()", diff --git a/tools/rlparser/output/raylib_api.lua b/tools/rlparser/output/raylib_api.lua index f2836e1ff..2de69f69c 100644 --- a/tools/rlparser/output/raylib_api.lua +++ b/tools/rlparser/output/raylib_api.lua @@ -1324,11 +1324,6 @@ return { name = "FilePathList", description = "File path list", fields = { - { - type = "unsigned int", - name = "capacity", - description = "Filepaths max entries" - }, { type = "unsigned int", name = "count", @@ -4230,6 +4225,24 @@ return { {type = "FilePathList", name = "files"} } }, + { + name = "GetDirectoryFileCount", + description = "Get the file count in a directory", + returnType = "unsigned int", + params = { + {type = "const char *", name = "dirPath"} + } + }, + { + name = "GetDirectoryFileCountEx", + description = "Get the file count in a directory with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result", + returnType = "unsigned int", + params = { + {type = "const char *", name = "basePath"}, + {type = "const char *", name = "filter"}, + {type = "bool", name = "scanSubdirs"} + } + }, { name = "CompressData", description = "Compress data (DEFLATE algorithm), memory must be MemFree()", diff --git a/tools/rlparser/output/raylib_api.txt b/tools/rlparser/output/raylib_api.txt index 0676b8138..53dbf8813 100644 --- a/tools/rlparser/output/raylib_api.txt +++ b/tools/rlparser/output/raylib_api.txt @@ -540,12 +540,11 @@ Struct 31: VrStereoConfig (8 fields) Field[6]: float[2] rightScreenCenter // VR right screen center Field[7]: float[2] scale // VR distortion scale Field[8]: float[2] scaleIn // VR distortion scale in -Struct 32: FilePathList (3 fields) +Struct 32: FilePathList (2 fields) Name: FilePathList Description: File path list - Field[1]: unsigned int capacity // Filepaths max entries - Field[2]: unsigned int count // Filepaths entries count - Field[3]: char ** paths // Filepaths entries + Field[1]: unsigned int count // Filepaths entries count + Field[2]: char ** paths // Filepaths entries Struct 33: AutomationEvent (3 fields) Name: AutomationEvent Description: Automation event @@ -993,7 +992,7 @@ Callback 006: AudioCallback() (2 input parameters) Param[1]: bufferData (type: void *) Param[2]: frames (type: unsigned int) -Functions found: 597 +Functions found: 599 Function 001: InitWindow() (3 input parameters) Name: InitWindow @@ -1806,199 +1805,211 @@ Function 151: UnloadDroppedFiles() (1 input parameters) Return type: void Description: Unload dropped filepaths Param[1]: files (type: FilePathList) -Function 152: CompressData() (3 input parameters) +Function 152: GetDirectoryFileCount() (1 input parameters) + Name: GetDirectoryFileCount + Return type: unsigned int + Description: Get the file count in a directory + Param[1]: dirPath (type: const char *) +Function 153: GetDirectoryFileCountEx() (3 input parameters) + Name: GetDirectoryFileCountEx + Return type: unsigned int + Description: Get the file count in a directory with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result + Param[1]: basePath (type: const char *) + Param[2]: filter (type: const char *) + Param[3]: scanSubdirs (type: bool) +Function 154: CompressData() (3 input parameters) Name: CompressData Return type: unsigned char * Description: Compress data (DEFLATE algorithm), memory must be MemFree() Param[1]: data (type: const unsigned char *) Param[2]: dataSize (type: int) Param[3]: compDataSize (type: int *) -Function 153: DecompressData() (3 input parameters) +Function 155: DecompressData() (3 input parameters) Name: DecompressData Return type: unsigned char * Description: Decompress data (DEFLATE algorithm), memory must be MemFree() Param[1]: compData (type: const unsigned char *) Param[2]: compDataSize (type: int) Param[3]: dataSize (type: int *) -Function 154: EncodeDataBase64() (3 input parameters) +Function 156: EncodeDataBase64() (3 input parameters) Name: EncodeDataBase64 Return type: char * Description: Encode data to Base64 string (includes NULL terminator), memory must be MemFree() Param[1]: data (type: const unsigned char *) Param[2]: dataSize (type: int) Param[3]: outputSize (type: int *) -Function 155: DecodeDataBase64() (2 input parameters) +Function 157: DecodeDataBase64() (2 input parameters) Name: DecodeDataBase64 Return type: unsigned char * Description: Decode Base64 string (expected NULL terminated), memory must be MemFree() Param[1]: text (type: const char *) Param[2]: outputSize (type: int *) -Function 156: ComputeCRC32() (2 input parameters) +Function 158: ComputeCRC32() (2 input parameters) Name: ComputeCRC32 Return type: unsigned int Description: Compute CRC32 hash code Param[1]: data (type: unsigned char *) Param[2]: dataSize (type: int) -Function 157: ComputeMD5() (2 input parameters) +Function 159: ComputeMD5() (2 input parameters) Name: ComputeMD5 Return type: unsigned int * Description: Compute MD5 hash code, returns static int[4] (16 bytes) Param[1]: data (type: unsigned char *) Param[2]: dataSize (type: int) -Function 158: ComputeSHA1() (2 input parameters) +Function 160: ComputeSHA1() (2 input parameters) Name: ComputeSHA1 Return type: unsigned int * Description: Compute SHA1 hash code, returns static int[5] (20 bytes) Param[1]: data (type: unsigned char *) Param[2]: dataSize (type: int) -Function 159: ComputeSHA256() (2 input parameters) +Function 161: ComputeSHA256() (2 input parameters) Name: ComputeSHA256 Return type: unsigned int * Description: Compute SHA256 hash code, returns static int[8] (32 bytes) Param[1]: data (type: unsigned char *) Param[2]: dataSize (type: int) -Function 160: LoadAutomationEventList() (1 input parameters) +Function 162: LoadAutomationEventList() (1 input parameters) Name: LoadAutomationEventList Return type: AutomationEventList Description: Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS Param[1]: fileName (type: const char *) -Function 161: UnloadAutomationEventList() (1 input parameters) +Function 163: UnloadAutomationEventList() (1 input parameters) Name: UnloadAutomationEventList Return type: void Description: Unload automation events list from file Param[1]: list (type: AutomationEventList) -Function 162: ExportAutomationEventList() (2 input parameters) +Function 164: ExportAutomationEventList() (2 input parameters) Name: ExportAutomationEventList Return type: bool Description: Export automation events list as text file Param[1]: list (type: AutomationEventList) Param[2]: fileName (type: const char *) -Function 163: SetAutomationEventList() (1 input parameters) +Function 165: SetAutomationEventList() (1 input parameters) Name: SetAutomationEventList Return type: void Description: Set automation event list to record to Param[1]: list (type: AutomationEventList *) -Function 164: SetAutomationEventBaseFrame() (1 input parameters) +Function 166: SetAutomationEventBaseFrame() (1 input parameters) Name: SetAutomationEventBaseFrame Return type: void Description: Set automation event internal base frame to start recording Param[1]: frame (type: int) -Function 165: StartAutomationEventRecording() (0 input parameters) +Function 167: StartAutomationEventRecording() (0 input parameters) Name: StartAutomationEventRecording Return type: void Description: Start recording automation events (AutomationEventList must be set) No input parameters -Function 166: StopAutomationEventRecording() (0 input parameters) +Function 168: StopAutomationEventRecording() (0 input parameters) Name: StopAutomationEventRecording Return type: void Description: Stop recording automation events No input parameters -Function 167: PlayAutomationEvent() (1 input parameters) +Function 169: PlayAutomationEvent() (1 input parameters) Name: PlayAutomationEvent Return type: void Description: Play a recorded automation event Param[1]: event (type: AutomationEvent) -Function 168: IsKeyPressed() (1 input parameters) +Function 170: IsKeyPressed() (1 input parameters) Name: IsKeyPressed Return type: bool Description: Check if a key has been pressed once Param[1]: key (type: int) -Function 169: IsKeyPressedRepeat() (1 input parameters) +Function 171: IsKeyPressedRepeat() (1 input parameters) Name: IsKeyPressedRepeat Return type: bool Description: Check if a key has been pressed again Param[1]: key (type: int) -Function 170: IsKeyDown() (1 input parameters) +Function 172: IsKeyDown() (1 input parameters) Name: IsKeyDown Return type: bool Description: Check if a key is being pressed Param[1]: key (type: int) -Function 171: IsKeyReleased() (1 input parameters) +Function 173: IsKeyReleased() (1 input parameters) Name: IsKeyReleased Return type: bool Description: Check if a key has been released once Param[1]: key (type: int) -Function 172: IsKeyUp() (1 input parameters) +Function 174: IsKeyUp() (1 input parameters) Name: IsKeyUp Return type: bool Description: Check if a key is NOT being pressed Param[1]: key (type: int) -Function 173: GetKeyPressed() (0 input parameters) +Function 175: GetKeyPressed() (0 input parameters) Name: GetKeyPressed Return type: int Description: Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty No input parameters -Function 174: GetCharPressed() (0 input parameters) +Function 176: GetCharPressed() (0 input parameters) Name: GetCharPressed Return type: int Description: Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty No input parameters -Function 175: GetKeyName() (1 input parameters) +Function 177: GetKeyName() (1 input parameters) Name: GetKeyName Return type: const char * Description: Get name of a QWERTY key on the current keyboard layout (eg returns string 'q' for KEY_A on an AZERTY keyboard) Param[1]: key (type: int) -Function 176: SetExitKey() (1 input parameters) +Function 178: SetExitKey() (1 input parameters) Name: SetExitKey Return type: void Description: Set a custom key to exit program (default is ESC) Param[1]: key (type: int) -Function 177: IsGamepadAvailable() (1 input parameters) +Function 179: IsGamepadAvailable() (1 input parameters) Name: IsGamepadAvailable Return type: bool Description: Check if a gamepad is available Param[1]: gamepad (type: int) -Function 178: GetGamepadName() (1 input parameters) +Function 180: GetGamepadName() (1 input parameters) Name: GetGamepadName Return type: const char * Description: Get gamepad internal name id Param[1]: gamepad (type: int) -Function 179: IsGamepadButtonPressed() (2 input parameters) +Function 181: IsGamepadButtonPressed() (2 input parameters) Name: IsGamepadButtonPressed Return type: bool Description: Check if a gamepad button has been pressed once Param[1]: gamepad (type: int) Param[2]: button (type: int) -Function 180: IsGamepadButtonDown() (2 input parameters) +Function 182: IsGamepadButtonDown() (2 input parameters) Name: IsGamepadButtonDown Return type: bool Description: Check if a gamepad button is being pressed Param[1]: gamepad (type: int) Param[2]: button (type: int) -Function 181: IsGamepadButtonReleased() (2 input parameters) +Function 183: IsGamepadButtonReleased() (2 input parameters) Name: IsGamepadButtonReleased Return type: bool Description: Check if a gamepad button has been released once Param[1]: gamepad (type: int) Param[2]: button (type: int) -Function 182: IsGamepadButtonUp() (2 input parameters) +Function 184: IsGamepadButtonUp() (2 input parameters) Name: IsGamepadButtonUp Return type: bool Description: Check if a gamepad button is NOT being pressed Param[1]: gamepad (type: int) Param[2]: button (type: int) -Function 183: GetGamepadButtonPressed() (0 input parameters) +Function 185: GetGamepadButtonPressed() (0 input parameters) Name: GetGamepadButtonPressed Return type: int Description: Get the last gamepad button pressed No input parameters -Function 184: GetGamepadAxisCount() (1 input parameters) +Function 186: GetGamepadAxisCount() (1 input parameters) Name: GetGamepadAxisCount Return type: int Description: Get axis count for a gamepad Param[1]: gamepad (type: int) -Function 185: GetGamepadAxisMovement() (2 input parameters) +Function 187: GetGamepadAxisMovement() (2 input parameters) Name: GetGamepadAxisMovement Return type: float Description: Get movement value for a gamepad axis Param[1]: gamepad (type: int) Param[2]: axis (type: int) -Function 186: SetGamepadMappings() (1 input parameters) +Function 188: SetGamepadMappings() (1 input parameters) Name: SetGamepadMappings Return type: int Description: Set internal gamepad mappings (SDL_GameControllerDB) Param[1]: mappings (type: const char *) -Function 187: SetGamepadVibration() (4 input parameters) +Function 189: SetGamepadVibration() (4 input parameters) Name: SetGamepadVibration Return type: void Description: Set gamepad vibration for both motors (duration in seconds) @@ -2006,151 +2017,151 @@ Function 187: SetGamepadVibration() (4 input parameters) Param[2]: leftMotor (type: float) Param[3]: rightMotor (type: float) Param[4]: duration (type: float) -Function 188: IsMouseButtonPressed() (1 input parameters) +Function 190: IsMouseButtonPressed() (1 input parameters) Name: IsMouseButtonPressed Return type: bool Description: Check if a mouse button has been pressed once Param[1]: button (type: int) -Function 189: IsMouseButtonDown() (1 input parameters) +Function 191: IsMouseButtonDown() (1 input parameters) Name: IsMouseButtonDown Return type: bool Description: Check if a mouse button is being pressed Param[1]: button (type: int) -Function 190: IsMouseButtonReleased() (1 input parameters) +Function 192: IsMouseButtonReleased() (1 input parameters) Name: IsMouseButtonReleased Return type: bool Description: Check if a mouse button has been released once Param[1]: button (type: int) -Function 191: IsMouseButtonUp() (1 input parameters) +Function 193: IsMouseButtonUp() (1 input parameters) Name: IsMouseButtonUp Return type: bool Description: Check if a mouse button is NOT being pressed Param[1]: button (type: int) -Function 192: GetMouseX() (0 input parameters) +Function 194: GetMouseX() (0 input parameters) Name: GetMouseX Return type: int Description: Get mouse position X No input parameters -Function 193: GetMouseY() (0 input parameters) +Function 195: GetMouseY() (0 input parameters) Name: GetMouseY Return type: int Description: Get mouse position Y No input parameters -Function 194: GetMousePosition() (0 input parameters) +Function 196: GetMousePosition() (0 input parameters) Name: GetMousePosition Return type: Vector2 Description: Get mouse position XY No input parameters -Function 195: GetMouseDelta() (0 input parameters) +Function 197: GetMouseDelta() (0 input parameters) Name: GetMouseDelta Return type: Vector2 Description: Get mouse delta between frames No input parameters -Function 196: SetMousePosition() (2 input parameters) +Function 198: SetMousePosition() (2 input parameters) Name: SetMousePosition Return type: void Description: Set mouse position XY Param[1]: x (type: int) Param[2]: y (type: int) -Function 197: SetMouseOffset() (2 input parameters) +Function 199: SetMouseOffset() (2 input parameters) Name: SetMouseOffset Return type: void Description: Set mouse offset Param[1]: offsetX (type: int) Param[2]: offsetY (type: int) -Function 198: SetMouseScale() (2 input parameters) +Function 200: SetMouseScale() (2 input parameters) Name: SetMouseScale Return type: void Description: Set mouse scaling Param[1]: scaleX (type: float) Param[2]: scaleY (type: float) -Function 199: GetMouseWheelMove() (0 input parameters) +Function 201: GetMouseWheelMove() (0 input parameters) Name: GetMouseWheelMove Return type: float Description: Get mouse wheel movement for X or Y, whichever is larger No input parameters -Function 200: GetMouseWheelMoveV() (0 input parameters) +Function 202: GetMouseWheelMoveV() (0 input parameters) Name: GetMouseWheelMoveV Return type: Vector2 Description: Get mouse wheel movement for both X and Y No input parameters -Function 201: SetMouseCursor() (1 input parameters) +Function 203: SetMouseCursor() (1 input parameters) Name: SetMouseCursor Return type: void Description: Set mouse cursor Param[1]: cursor (type: int) -Function 202: GetTouchX() (0 input parameters) +Function 204: GetTouchX() (0 input parameters) Name: GetTouchX Return type: int Description: Get touch position X for touch point 0 (relative to screen size) No input parameters -Function 203: GetTouchY() (0 input parameters) +Function 205: GetTouchY() (0 input parameters) Name: GetTouchY Return type: int Description: Get touch position Y for touch point 0 (relative to screen size) No input parameters -Function 204: GetTouchPosition() (1 input parameters) +Function 206: GetTouchPosition() (1 input parameters) Name: GetTouchPosition Return type: Vector2 Description: Get touch position XY for a touch point index (relative to screen size) Param[1]: index (type: int) -Function 205: GetTouchPointId() (1 input parameters) +Function 207: GetTouchPointId() (1 input parameters) Name: GetTouchPointId Return type: int Description: Get touch point identifier for given index Param[1]: index (type: int) -Function 206: GetTouchPointCount() (0 input parameters) +Function 208: GetTouchPointCount() (0 input parameters) Name: GetTouchPointCount Return type: int Description: Get number of touch points No input parameters -Function 207: SetGesturesEnabled() (1 input parameters) +Function 209: SetGesturesEnabled() (1 input parameters) Name: SetGesturesEnabled Return type: void Description: Enable a set of gestures using flags Param[1]: flags (type: unsigned int) -Function 208: IsGestureDetected() (1 input parameters) +Function 210: IsGestureDetected() (1 input parameters) Name: IsGestureDetected Return type: bool Description: Check if a gesture have been detected Param[1]: gesture (type: unsigned int) -Function 209: GetGestureDetected() (0 input parameters) +Function 211: GetGestureDetected() (0 input parameters) Name: GetGestureDetected Return type: int Description: Get latest detected gesture No input parameters -Function 210: GetGestureHoldDuration() (0 input parameters) +Function 212: GetGestureHoldDuration() (0 input parameters) Name: GetGestureHoldDuration Return type: float Description: Get gesture hold time in seconds No input parameters -Function 211: GetGestureDragVector() (0 input parameters) +Function 213: GetGestureDragVector() (0 input parameters) Name: GetGestureDragVector Return type: Vector2 Description: Get gesture drag vector No input parameters -Function 212: GetGestureDragAngle() (0 input parameters) +Function 214: GetGestureDragAngle() (0 input parameters) Name: GetGestureDragAngle Return type: float Description: Get gesture drag angle No input parameters -Function 213: GetGesturePinchVector() (0 input parameters) +Function 215: GetGesturePinchVector() (0 input parameters) Name: GetGesturePinchVector Return type: Vector2 Description: Get gesture pinch delta No input parameters -Function 214: GetGesturePinchAngle() (0 input parameters) +Function 216: GetGesturePinchAngle() (0 input parameters) Name: GetGesturePinchAngle Return type: float Description: Get gesture pinch angle No input parameters -Function 215: UpdateCamera() (2 input parameters) +Function 217: UpdateCamera() (2 input parameters) Name: UpdateCamera Return type: void Description: Update camera position for selected mode Param[1]: camera (type: Camera *) Param[2]: mode (type: int) -Function 216: UpdateCameraPro() (4 input parameters) +Function 218: UpdateCameraPro() (4 input parameters) Name: UpdateCameraPro Return type: void Description: Update camera movement/rotation @@ -2158,36 +2169,36 @@ Function 216: UpdateCameraPro() (4 input parameters) Param[2]: movement (type: Vector3) Param[3]: rotation (type: Vector3) Param[4]: zoom (type: float) -Function 217: SetShapesTexture() (2 input parameters) +Function 219: SetShapesTexture() (2 input parameters) Name: SetShapesTexture Return type: void Description: Set texture and rectangle to be used on shapes drawing Param[1]: texture (type: Texture2D) Param[2]: source (type: Rectangle) -Function 218: GetShapesTexture() (0 input parameters) +Function 220: GetShapesTexture() (0 input parameters) Name: GetShapesTexture Return type: Texture2D Description: Get texture that is used for shapes drawing No input parameters -Function 219: GetShapesTextureRectangle() (0 input parameters) +Function 221: GetShapesTextureRectangle() (0 input parameters) Name: GetShapesTextureRectangle Return type: Rectangle Description: Get texture source rectangle that is used for shapes drawing No input parameters -Function 220: DrawPixel() (3 input parameters) +Function 222: DrawPixel() (3 input parameters) Name: DrawPixel Return type: void Description: Draw a pixel using geometry [Can be slow, use with care] Param[1]: posX (type: int) Param[2]: posY (type: int) Param[3]: color (type: Color) -Function 221: DrawPixelV() (2 input parameters) +Function 223: DrawPixelV() (2 input parameters) Name: DrawPixelV Return type: void Description: Draw a pixel using geometry (Vector version) [Can be slow, use with care] Param[1]: position (type: Vector2) Param[2]: color (type: Color) -Function 222: DrawLine() (5 input parameters) +Function 224: DrawLine() (5 input parameters) Name: DrawLine Return type: void Description: Draw a line @@ -2196,14 +2207,14 @@ Function 222: DrawLine() (5 input parameters) Param[3]: endPosX (type: int) Param[4]: endPosY (type: int) Param[5]: color (type: Color) -Function 223: DrawLineV() (3 input parameters) +Function 225: DrawLineV() (3 input parameters) Name: DrawLineV Return type: void Description: Draw a line (using gl lines) Param[1]: startPos (type: Vector2) Param[2]: endPos (type: Vector2) Param[3]: color (type: Color) -Function 224: DrawLineEx() (4 input parameters) +Function 226: DrawLineEx() (4 input parameters) Name: DrawLineEx Return type: void Description: Draw a line (using triangles/quads) @@ -2211,14 +2222,14 @@ Function 224: DrawLineEx() (4 input parameters) Param[2]: endPos (type: Vector2) Param[3]: thick (type: float) Param[4]: color (type: Color) -Function 225: DrawLineStrip() (3 input parameters) +Function 227: DrawLineStrip() (3 input parameters) Name: DrawLineStrip Return type: void Description: Draw lines sequence (using gl lines) Param[1]: points (type: const Vector2 *) Param[2]: pointCount (type: int) Param[3]: color (type: Color) -Function 226: DrawLineBezier() (4 input parameters) +Function 228: DrawLineBezier() (4 input parameters) Name: DrawLineBezier Return type: void Description: Draw line segment cubic-bezier in-out interpolation @@ -2226,7 +2237,7 @@ Function 226: DrawLineBezier() (4 input parameters) Param[2]: endPos (type: Vector2) Param[3]: thick (type: float) Param[4]: color (type: Color) -Function 227: DrawLineDashed() (5 input parameters) +Function 229: DrawLineDashed() (5 input parameters) Name: DrawLineDashed Return type: void Description: Draw a dashed line @@ -2235,7 +2246,7 @@ Function 227: DrawLineDashed() (5 input parameters) Param[3]: dashSize (type: int) Param[4]: spaceSize (type: int) Param[5]: color (type: Color) -Function 228: DrawCircle() (4 input parameters) +Function 230: DrawCircle() (4 input parameters) Name: DrawCircle Return type: void Description: Draw a color-filled circle @@ -2243,7 +2254,7 @@ Function 228: DrawCircle() (4 input parameters) Param[2]: centerY (type: int) Param[3]: radius (type: float) Param[4]: color (type: Color) -Function 229: DrawCircleSector() (6 input parameters) +Function 231: DrawCircleSector() (6 input parameters) Name: DrawCircleSector Return type: void Description: Draw a piece of a circle @@ -2253,7 +2264,7 @@ Function 229: DrawCircleSector() (6 input parameters) Param[4]: endAngle (type: float) Param[5]: segments (type: int) Param[6]: color (type: Color) -Function 230: DrawCircleSectorLines() (6 input parameters) +Function 232: DrawCircleSectorLines() (6 input parameters) Name: DrawCircleSectorLines Return type: void Description: Draw circle sector outline @@ -2263,7 +2274,7 @@ Function 230: DrawCircleSectorLines() (6 input parameters) Param[4]: endAngle (type: float) Param[5]: segments (type: int) Param[6]: color (type: Color) -Function 231: DrawCircleGradient() (5 input parameters) +Function 233: DrawCircleGradient() (5 input parameters) Name: DrawCircleGradient Return type: void Description: Draw a gradient-filled circle @@ -2272,14 +2283,14 @@ Function 231: DrawCircleGradient() (5 input parameters) Param[3]: radius (type: float) Param[4]: inner (type: Color) Param[5]: outer (type: Color) -Function 232: DrawCircleV() (3 input parameters) +Function 234: DrawCircleV() (3 input parameters) Name: DrawCircleV Return type: void Description: Draw a color-filled circle (Vector version) Param[1]: center (type: Vector2) Param[2]: radius (type: float) Param[3]: color (type: Color) -Function 233: DrawCircleLines() (4 input parameters) +Function 235: DrawCircleLines() (4 input parameters) Name: DrawCircleLines Return type: void Description: Draw circle outline @@ -2287,14 +2298,14 @@ Function 233: DrawCircleLines() (4 input parameters) Param[2]: centerY (type: int) Param[3]: radius (type: float) Param[4]: color (type: Color) -Function 234: DrawCircleLinesV() (3 input parameters) +Function 236: DrawCircleLinesV() (3 input parameters) Name: DrawCircleLinesV Return type: void Description: Draw circle outline (Vector version) Param[1]: center (type: Vector2) Param[2]: radius (type: float) Param[3]: color (type: Color) -Function 235: DrawEllipse() (5 input parameters) +Function 237: DrawEllipse() (5 input parameters) Name: DrawEllipse Return type: void Description: Draw ellipse @@ -2303,7 +2314,7 @@ Function 235: DrawEllipse() (5 input parameters) Param[3]: radiusH (type: float) Param[4]: radiusV (type: float) Param[5]: color (type: Color) -Function 236: DrawEllipseV() (4 input parameters) +Function 238: DrawEllipseV() (4 input parameters) Name: DrawEllipseV Return type: void Description: Draw ellipse (Vector version) @@ -2311,7 +2322,7 @@ Function 236: DrawEllipseV() (4 input parameters) Param[2]: radiusH (type: float) Param[3]: radiusV (type: float) Param[4]: color (type: Color) -Function 237: DrawEllipseLines() (5 input parameters) +Function 239: DrawEllipseLines() (5 input parameters) Name: DrawEllipseLines Return type: void Description: Draw ellipse outline @@ -2320,7 +2331,7 @@ Function 237: DrawEllipseLines() (5 input parameters) Param[3]: radiusH (type: float) Param[4]: radiusV (type: float) Param[5]: color (type: Color) -Function 238: DrawEllipseLinesV() (4 input parameters) +Function 240: DrawEllipseLinesV() (4 input parameters) Name: DrawEllipseLinesV Return type: void Description: Draw ellipse outline (Vector version) @@ -2328,7 +2339,7 @@ Function 238: DrawEllipseLinesV() (4 input parameters) Param[2]: radiusH (type: float) Param[3]: radiusV (type: float) Param[4]: color (type: Color) -Function 239: DrawRing() (7 input parameters) +Function 241: DrawRing() (7 input parameters) Name: DrawRing Return type: void Description: Draw ring @@ -2339,7 +2350,7 @@ Function 239: DrawRing() (7 input parameters) Param[5]: endAngle (type: float) Param[6]: segments (type: int) Param[7]: color (type: Color) -Function 240: DrawRingLines() (7 input parameters) +Function 242: DrawRingLines() (7 input parameters) Name: DrawRingLines Return type: void Description: Draw ring outline @@ -2350,7 +2361,7 @@ Function 240: DrawRingLines() (7 input parameters) Param[5]: endAngle (type: float) Param[6]: segments (type: int) Param[7]: color (type: Color) -Function 241: DrawRectangle() (5 input parameters) +Function 243: DrawRectangle() (5 input parameters) Name: DrawRectangle Return type: void Description: Draw a color-filled rectangle @@ -2359,20 +2370,20 @@ Function 241: DrawRectangle() (5 input parameters) Param[3]: width (type: int) Param[4]: height (type: int) Param[5]: color (type: Color) -Function 242: DrawRectangleV() (3 input parameters) +Function 244: DrawRectangleV() (3 input parameters) Name: DrawRectangleV Return type: void Description: Draw a color-filled rectangle (Vector version) Param[1]: position (type: Vector2) Param[2]: size (type: Vector2) Param[3]: color (type: Color) -Function 243: DrawRectangleRec() (2 input parameters) +Function 245: DrawRectangleRec() (2 input parameters) Name: DrawRectangleRec Return type: void Description: Draw a color-filled rectangle Param[1]: rec (type: Rectangle) Param[2]: color (type: Color) -Function 244: DrawRectanglePro() (4 input parameters) +Function 246: DrawRectanglePro() (4 input parameters) Name: DrawRectanglePro Return type: void Description: Draw a color-filled rectangle with pro parameters @@ -2380,7 +2391,7 @@ Function 244: DrawRectanglePro() (4 input parameters) Param[2]: origin (type: Vector2) Param[3]: rotation (type: float) Param[4]: color (type: Color) -Function 245: DrawRectangleGradientV() (6 input parameters) +Function 247: DrawRectangleGradientV() (6 input parameters) Name: DrawRectangleGradientV Return type: void Description: Draw a vertical-gradient-filled rectangle @@ -2390,7 +2401,7 @@ Function 245: DrawRectangleGradientV() (6 input parameters) Param[4]: height (type: int) Param[5]: top (type: Color) Param[6]: bottom (type: Color) -Function 246: DrawRectangleGradientH() (6 input parameters) +Function 248: DrawRectangleGradientH() (6 input parameters) Name: DrawRectangleGradientH Return type: void Description: Draw a horizontal-gradient-filled rectangle @@ -2400,7 +2411,7 @@ Function 246: DrawRectangleGradientH() (6 input parameters) Param[4]: height (type: int) Param[5]: left (type: Color) Param[6]: right (type: Color) -Function 247: DrawRectangleGradientEx() (5 input parameters) +Function 249: DrawRectangleGradientEx() (5 input parameters) Name: DrawRectangleGradientEx Return type: void Description: Draw a gradient-filled rectangle with custom vertex colors @@ -2409,7 +2420,7 @@ Function 247: DrawRectangleGradientEx() (5 input parameters) Param[3]: bottomLeft (type: Color) Param[4]: bottomRight (type: Color) Param[5]: topRight (type: Color) -Function 248: DrawRectangleLines() (5 input parameters) +Function 250: DrawRectangleLines() (5 input parameters) Name: DrawRectangleLines Return type: void Description: Draw rectangle outline @@ -2418,14 +2429,14 @@ Function 248: DrawRectangleLines() (5 input parameters) Param[3]: width (type: int) Param[4]: height (type: int) Param[5]: color (type: Color) -Function 249: DrawRectangleLinesEx() (3 input parameters) +Function 251: DrawRectangleLinesEx() (3 input parameters) Name: DrawRectangleLinesEx Return type: void Description: Draw rectangle outline with extended parameters Param[1]: rec (type: Rectangle) Param[2]: lineThick (type: float) Param[3]: color (type: Color) -Function 250: DrawRectangleRounded() (4 input parameters) +Function 252: DrawRectangleRounded() (4 input parameters) Name: DrawRectangleRounded Return type: void Description: Draw rectangle with rounded edges @@ -2433,7 +2444,7 @@ Function 250: DrawRectangleRounded() (4 input parameters) Param[2]: roundness (type: float) Param[3]: segments (type: int) Param[4]: color (type: Color) -Function 251: DrawRectangleRoundedLines() (4 input parameters) +Function 253: DrawRectangleRoundedLines() (4 input parameters) Name: DrawRectangleRoundedLines Return type: void Description: Draw rectangle lines with rounded edges @@ -2441,7 +2452,7 @@ Function 251: DrawRectangleRoundedLines() (4 input parameters) Param[2]: roundness (type: float) Param[3]: segments (type: int) Param[4]: color (type: Color) -Function 252: DrawRectangleRoundedLinesEx() (5 input parameters) +Function 254: DrawRectangleRoundedLinesEx() (5 input parameters) Name: DrawRectangleRoundedLinesEx Return type: void Description: Draw rectangle with rounded edges outline @@ -2450,7 +2461,7 @@ Function 252: DrawRectangleRoundedLinesEx() (5 input parameters) Param[3]: segments (type: int) Param[4]: lineThick (type: float) Param[5]: color (type: Color) -Function 253: DrawTriangle() (4 input parameters) +Function 255: DrawTriangle() (4 input parameters) Name: DrawTriangle Return type: void Description: Draw a color-filled triangle (vertex in counter-clockwise order!) @@ -2458,7 +2469,7 @@ Function 253: DrawTriangle() (4 input parameters) Param[2]: v2 (type: Vector2) Param[3]: v3 (type: Vector2) Param[4]: color (type: Color) -Function 254: DrawTriangleLines() (4 input parameters) +Function 256: DrawTriangleLines() (4 input parameters) Name: DrawTriangleLines Return type: void Description: Draw triangle outline (vertex in counter-clockwise order!) @@ -2466,21 +2477,21 @@ Function 254: DrawTriangleLines() (4 input parameters) Param[2]: v2 (type: Vector2) Param[3]: v3 (type: Vector2) Param[4]: color (type: Color) -Function 255: DrawTriangleFan() (3 input parameters) +Function 257: DrawTriangleFan() (3 input parameters) Name: DrawTriangleFan Return type: void Description: Draw a triangle fan defined by points (first vertex is the center) Param[1]: points (type: const Vector2 *) Param[2]: pointCount (type: int) Param[3]: color (type: Color) -Function 256: DrawTriangleStrip() (3 input parameters) +Function 258: DrawTriangleStrip() (3 input parameters) Name: DrawTriangleStrip Return type: void Description: Draw a triangle strip defined by points Param[1]: points (type: const Vector2 *) Param[2]: pointCount (type: int) Param[3]: color (type: Color) -Function 257: DrawPoly() (5 input parameters) +Function 259: DrawPoly() (5 input parameters) Name: DrawPoly Return type: void Description: Draw a regular polygon (Vector version) @@ -2489,7 +2500,7 @@ Function 257: DrawPoly() (5 input parameters) Param[3]: radius (type: float) Param[4]: rotation (type: float) Param[5]: color (type: Color) -Function 258: DrawPolyLines() (5 input parameters) +Function 260: DrawPolyLines() (5 input parameters) Name: DrawPolyLines Return type: void Description: Draw a polygon outline of n sides @@ -2498,7 +2509,7 @@ Function 258: DrawPolyLines() (5 input parameters) Param[3]: radius (type: float) Param[4]: rotation (type: float) Param[5]: color (type: Color) -Function 259: DrawPolyLinesEx() (6 input parameters) +Function 261: DrawPolyLinesEx() (6 input parameters) Name: DrawPolyLinesEx Return type: void Description: Draw a polygon outline of n sides with extended parameters @@ -2508,7 +2519,7 @@ Function 259: DrawPolyLinesEx() (6 input parameters) Param[4]: rotation (type: float) Param[5]: lineThick (type: float) Param[6]: color (type: Color) -Function 260: DrawSplineLinear() (4 input parameters) +Function 262: DrawSplineLinear() (4 input parameters) Name: DrawSplineLinear Return type: void Description: Draw spline: Linear, minimum 2 points @@ -2516,7 +2527,7 @@ Function 260: DrawSplineLinear() (4 input parameters) Param[2]: pointCount (type: int) Param[3]: thick (type: float) Param[4]: color (type: Color) -Function 261: DrawSplineBasis() (4 input parameters) +Function 263: DrawSplineBasis() (4 input parameters) Name: DrawSplineBasis Return type: void Description: Draw spline: B-Spline, minimum 4 points @@ -2524,7 +2535,7 @@ Function 261: DrawSplineBasis() (4 input parameters) Param[2]: pointCount (type: int) Param[3]: thick (type: float) Param[4]: color (type: Color) -Function 262: DrawSplineCatmullRom() (4 input parameters) +Function 264: DrawSplineCatmullRom() (4 input parameters) Name: DrawSplineCatmullRom Return type: void Description: Draw spline: Catmull-Rom, minimum 4 points @@ -2532,7 +2543,7 @@ Function 262: DrawSplineCatmullRom() (4 input parameters) Param[2]: pointCount (type: int) Param[3]: thick (type: float) Param[4]: color (type: Color) -Function 263: DrawSplineBezierQuadratic() (4 input parameters) +Function 265: DrawSplineBezierQuadratic() (4 input parameters) Name: DrawSplineBezierQuadratic Return type: void Description: Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...] @@ -2540,7 +2551,7 @@ Function 263: DrawSplineBezierQuadratic() (4 input parameters) Param[2]: pointCount (type: int) Param[3]: thick (type: float) Param[4]: color (type: Color) -Function 264: DrawSplineBezierCubic() (4 input parameters) +Function 266: DrawSplineBezierCubic() (4 input parameters) Name: DrawSplineBezierCubic Return type: void Description: Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...] @@ -2548,7 +2559,7 @@ Function 264: DrawSplineBezierCubic() (4 input parameters) Param[2]: pointCount (type: int) Param[3]: thick (type: float) Param[4]: color (type: Color) -Function 265: DrawSplineSegmentLinear() (4 input parameters) +Function 267: DrawSplineSegmentLinear() (4 input parameters) Name: DrawSplineSegmentLinear Return type: void Description: Draw spline segment: Linear, 2 points @@ -2556,7 +2567,7 @@ Function 265: DrawSplineSegmentLinear() (4 input parameters) Param[2]: p2 (type: Vector2) Param[3]: thick (type: float) Param[4]: color (type: Color) -Function 266: DrawSplineSegmentBasis() (6 input parameters) +Function 268: DrawSplineSegmentBasis() (6 input parameters) Name: DrawSplineSegmentBasis Return type: void Description: Draw spline segment: B-Spline, 4 points @@ -2566,7 +2577,7 @@ Function 266: DrawSplineSegmentBasis() (6 input parameters) Param[4]: p4 (type: Vector2) Param[5]: thick (type: float) Param[6]: color (type: Color) -Function 267: DrawSplineSegmentCatmullRom() (6 input parameters) +Function 269: DrawSplineSegmentCatmullRom() (6 input parameters) Name: DrawSplineSegmentCatmullRom Return type: void Description: Draw spline segment: Catmull-Rom, 4 points @@ -2576,7 +2587,7 @@ Function 267: DrawSplineSegmentCatmullRom() (6 input parameters) Param[4]: p4 (type: Vector2) Param[5]: thick (type: float) Param[6]: color (type: Color) -Function 268: DrawSplineSegmentBezierQuadratic() (5 input parameters) +Function 270: DrawSplineSegmentBezierQuadratic() (5 input parameters) Name: DrawSplineSegmentBezierQuadratic Return type: void Description: Draw spline segment: Quadratic Bezier, 2 points, 1 control point @@ -2585,7 +2596,7 @@ Function 268: DrawSplineSegmentBezierQuadratic() (5 input parameters) Param[3]: p3 (type: Vector2) Param[4]: thick (type: float) Param[5]: color (type: Color) -Function 269: DrawSplineSegmentBezierCubic() (6 input parameters) +Function 271: DrawSplineSegmentBezierCubic() (6 input parameters) Name: DrawSplineSegmentBezierCubic Return type: void Description: Draw spline segment: Cubic Bezier, 2 points, 2 control points @@ -2595,14 +2606,14 @@ Function 269: DrawSplineSegmentBezierCubic() (6 input parameters) Param[4]: p4 (type: Vector2) Param[5]: thick (type: float) Param[6]: color (type: Color) -Function 270: GetSplinePointLinear() (3 input parameters) +Function 272: GetSplinePointLinear() (3 input parameters) Name: GetSplinePointLinear Return type: Vector2 Description: Get (evaluate) spline point: Linear Param[1]: startPos (type: Vector2) Param[2]: endPos (type: Vector2) Param[3]: t (type: float) -Function 271: GetSplinePointBasis() (5 input parameters) +Function 273: GetSplinePointBasis() (5 input parameters) Name: GetSplinePointBasis Return type: Vector2 Description: Get (evaluate) spline point: B-Spline @@ -2611,7 +2622,7 @@ Function 271: GetSplinePointBasis() (5 input parameters) Param[3]: p3 (type: Vector2) Param[4]: p4 (type: Vector2) Param[5]: t (type: float) -Function 272: GetSplinePointCatmullRom() (5 input parameters) +Function 274: GetSplinePointCatmullRom() (5 input parameters) Name: GetSplinePointCatmullRom Return type: Vector2 Description: Get (evaluate) spline point: Catmull-Rom @@ -2620,7 +2631,7 @@ Function 272: GetSplinePointCatmullRom() (5 input parameters) Param[3]: p3 (type: Vector2) Param[4]: p4 (type: Vector2) Param[5]: t (type: float) -Function 273: GetSplinePointBezierQuad() (4 input parameters) +Function 275: GetSplinePointBezierQuad() (4 input parameters) Name: GetSplinePointBezierQuad Return type: Vector2 Description: Get (evaluate) spline point: Quadratic Bezier @@ -2628,7 +2639,7 @@ Function 273: GetSplinePointBezierQuad() (4 input parameters) Param[2]: c2 (type: Vector2) Param[3]: p3 (type: Vector2) Param[4]: t (type: float) -Function 274: GetSplinePointBezierCubic() (5 input parameters) +Function 276: GetSplinePointBezierCubic() (5 input parameters) Name: GetSplinePointBezierCubic Return type: Vector2 Description: Get (evaluate) spline point: Cubic Bezier @@ -2637,13 +2648,13 @@ Function 274: GetSplinePointBezierCubic() (5 input parameters) Param[3]: c3 (type: Vector2) Param[4]: p4 (type: Vector2) Param[5]: t (type: float) -Function 275: CheckCollisionRecs() (2 input parameters) +Function 277: CheckCollisionRecs() (2 input parameters) Name: CheckCollisionRecs Return type: bool Description: Check collision between two rectangles Param[1]: rec1 (type: Rectangle) Param[2]: rec2 (type: Rectangle) -Function 276: CheckCollisionCircles() (4 input parameters) +Function 278: CheckCollisionCircles() (4 input parameters) Name: CheckCollisionCircles Return type: bool Description: Check collision between two circles @@ -2651,14 +2662,14 @@ Function 276: CheckCollisionCircles() (4 input parameters) Param[2]: radius1 (type: float) Param[3]: center2 (type: Vector2) Param[4]: radius2 (type: float) -Function 277: CheckCollisionCircleRec() (3 input parameters) +Function 279: CheckCollisionCircleRec() (3 input parameters) Name: CheckCollisionCircleRec Return type: bool Description: Check collision between circle and rectangle Param[1]: center (type: Vector2) Param[2]: radius (type: float) Param[3]: rec (type: Rectangle) -Function 278: CheckCollisionCircleLine() (4 input parameters) +Function 280: CheckCollisionCircleLine() (4 input parameters) Name: CheckCollisionCircleLine Return type: bool Description: Check if circle collides with a line created betweeen two points [p1] and [p2] @@ -2666,20 +2677,20 @@ Function 278: CheckCollisionCircleLine() (4 input parameters) Param[2]: radius (type: float) Param[3]: p1 (type: Vector2) Param[4]: p2 (type: Vector2) -Function 279: CheckCollisionPointRec() (2 input parameters) +Function 281: CheckCollisionPointRec() (2 input parameters) Name: CheckCollisionPointRec Return type: bool Description: Check if point is inside rectangle Param[1]: point (type: Vector2) Param[2]: rec (type: Rectangle) -Function 280: CheckCollisionPointCircle() (3 input parameters) +Function 282: CheckCollisionPointCircle() (3 input parameters) Name: CheckCollisionPointCircle Return type: bool Description: Check if point is inside circle Param[1]: point (type: Vector2) Param[2]: center (type: Vector2) Param[3]: radius (type: float) -Function 281: CheckCollisionPointTriangle() (4 input parameters) +Function 283: CheckCollisionPointTriangle() (4 input parameters) Name: CheckCollisionPointTriangle Return type: bool Description: Check if point is inside a triangle @@ -2687,7 +2698,7 @@ Function 281: CheckCollisionPointTriangle() (4 input parameters) Param[2]: p1 (type: Vector2) Param[3]: p2 (type: Vector2) Param[4]: p3 (type: Vector2) -Function 282: CheckCollisionPointLine() (4 input parameters) +Function 284: CheckCollisionPointLine() (4 input parameters) Name: CheckCollisionPointLine Return type: bool Description: Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold] @@ -2695,14 +2706,14 @@ Function 282: CheckCollisionPointLine() (4 input parameters) Param[2]: p1 (type: Vector2) Param[3]: p2 (type: Vector2) Param[4]: threshold (type: int) -Function 283: CheckCollisionPointPoly() (3 input parameters) +Function 285: CheckCollisionPointPoly() (3 input parameters) Name: CheckCollisionPointPoly Return type: bool Description: Check if point is within a polygon described by array of vertices Param[1]: point (type: Vector2) Param[2]: points (type: const Vector2 *) Param[3]: pointCount (type: int) -Function 284: CheckCollisionLines() (5 input parameters) +Function 286: CheckCollisionLines() (5 input parameters) Name: CheckCollisionLines Return type: bool Description: Check the collision between two lines defined by two points each, returns collision point by reference @@ -2711,18 +2722,18 @@ Function 284: CheckCollisionLines() (5 input parameters) Param[3]: startPos2 (type: Vector2) Param[4]: endPos2 (type: Vector2) Param[5]: collisionPoint (type: Vector2 *) -Function 285: GetCollisionRec() (2 input parameters) +Function 287: GetCollisionRec() (2 input parameters) Name: GetCollisionRec Return type: Rectangle Description: Get collision rectangle for two rectangles collision Param[1]: rec1 (type: Rectangle) Param[2]: rec2 (type: Rectangle) -Function 286: LoadImage() (1 input parameters) +Function 288: LoadImage() (1 input parameters) Name: LoadImage Return type: Image Description: Load image from file into CPU memory (RAM) Param[1]: fileName (type: const char *) -Function 287: LoadImageRaw() (5 input parameters) +Function 289: LoadImageRaw() (5 input parameters) Name: LoadImageRaw Return type: Image Description: Load image from RAW file data @@ -2731,13 +2742,13 @@ Function 287: LoadImageRaw() (5 input parameters) Param[3]: height (type: int) Param[4]: format (type: int) Param[5]: headerSize (type: int) -Function 288: LoadImageAnim() (2 input parameters) +Function 290: LoadImageAnim() (2 input parameters) Name: LoadImageAnim Return type: Image Description: Load image sequence from file (frames appended to image.data) Param[1]: fileName (type: const char *) Param[2]: frames (type: int *) -Function 289: LoadImageAnimFromMemory() (4 input parameters) +Function 291: LoadImageAnimFromMemory() (4 input parameters) Name: LoadImageAnimFromMemory Return type: Image Description: Load image sequence from memory buffer @@ -2745,60 +2756,60 @@ Function 289: LoadImageAnimFromMemory() (4 input parameters) Param[2]: fileData (type: const unsigned char *) Param[3]: dataSize (type: int) Param[4]: frames (type: int *) -Function 290: LoadImageFromMemory() (3 input parameters) +Function 292: LoadImageFromMemory() (3 input parameters) Name: LoadImageFromMemory Return type: Image Description: Load image from memory buffer, fileType refers to extension: i.e. '.png' Param[1]: fileType (type: const char *) Param[2]: fileData (type: const unsigned char *) Param[3]: dataSize (type: int) -Function 291: LoadImageFromTexture() (1 input parameters) +Function 293: LoadImageFromTexture() (1 input parameters) Name: LoadImageFromTexture Return type: Image Description: Load image from GPU texture data Param[1]: texture (type: Texture2D) -Function 292: LoadImageFromScreen() (0 input parameters) +Function 294: LoadImageFromScreen() (0 input parameters) Name: LoadImageFromScreen Return type: Image Description: Load image from screen buffer and (screenshot) No input parameters -Function 293: IsImageValid() (1 input parameters) +Function 295: IsImageValid() (1 input parameters) Name: IsImageValid Return type: bool Description: Check if an image is valid (data and parameters) Param[1]: image (type: Image) -Function 294: UnloadImage() (1 input parameters) +Function 296: UnloadImage() (1 input parameters) Name: UnloadImage Return type: void Description: Unload image from CPU memory (RAM) Param[1]: image (type: Image) -Function 295: ExportImage() (2 input parameters) +Function 297: ExportImage() (2 input parameters) Name: ExportImage Return type: bool Description: Export image data to file, returns true on success Param[1]: image (type: Image) Param[2]: fileName (type: const char *) -Function 296: ExportImageToMemory() (3 input parameters) +Function 298: ExportImageToMemory() (3 input parameters) Name: ExportImageToMemory Return type: unsigned char * Description: Export image to memory buffer Param[1]: image (type: Image) Param[2]: fileType (type: const char *) Param[3]: fileSize (type: int *) -Function 297: ExportImageAsCode() (2 input parameters) +Function 299: ExportImageAsCode() (2 input parameters) Name: ExportImageAsCode Return type: bool Description: Export image as code file defining an array of bytes, returns true on success Param[1]: image (type: Image) Param[2]: fileName (type: const char *) -Function 298: GenImageColor() (3 input parameters) +Function 300: GenImageColor() (3 input parameters) Name: GenImageColor Return type: Image Description: Generate image: plain color Param[1]: width (type: int) Param[2]: height (type: int) Param[3]: color (type: Color) -Function 299: GenImageGradientLinear() (5 input parameters) +Function 301: GenImageGradientLinear() (5 input parameters) Name: GenImageGradientLinear Return type: Image Description: Generate image: linear gradient, direction in degrees [0..360], 0=Vertical gradient @@ -2807,7 +2818,7 @@ Function 299: GenImageGradientLinear() (5 input parameters) Param[3]: direction (type: int) Param[4]: start (type: Color) Param[5]: end (type: Color) -Function 300: GenImageGradientRadial() (5 input parameters) +Function 302: GenImageGradientRadial() (5 input parameters) Name: GenImageGradientRadial Return type: Image Description: Generate image: radial gradient @@ -2816,7 +2827,7 @@ Function 300: GenImageGradientRadial() (5 input parameters) Param[3]: density (type: float) Param[4]: inner (type: Color) Param[5]: outer (type: Color) -Function 301: GenImageGradientSquare() (5 input parameters) +Function 303: GenImageGradientSquare() (5 input parameters) Name: GenImageGradientSquare Return type: Image Description: Generate image: square gradient @@ -2825,7 +2836,7 @@ Function 301: GenImageGradientSquare() (5 input parameters) Param[3]: density (type: float) Param[4]: inner (type: Color) Param[5]: outer (type: Color) -Function 302: GenImageChecked() (6 input parameters) +Function 304: GenImageChecked() (6 input parameters) Name: GenImageChecked Return type: Image Description: Generate image: checked @@ -2835,14 +2846,14 @@ Function 302: GenImageChecked() (6 input parameters) Param[4]: checksY (type: int) Param[5]: col1 (type: Color) Param[6]: col2 (type: Color) -Function 303: GenImageWhiteNoise() (3 input parameters) +Function 305: GenImageWhiteNoise() (3 input parameters) Name: GenImageWhiteNoise Return type: Image Description: Generate image: white noise Param[1]: width (type: int) Param[2]: height (type: int) Param[3]: factor (type: float) -Function 304: GenImagePerlinNoise() (5 input parameters) +Function 306: GenImagePerlinNoise() (5 input parameters) Name: GenImagePerlinNoise Return type: Image Description: Generate image: perlin noise @@ -2851,45 +2862,45 @@ Function 304: GenImagePerlinNoise() (5 input parameters) Param[3]: offsetX (type: int) Param[4]: offsetY (type: int) Param[5]: scale (type: float) -Function 305: GenImageCellular() (3 input parameters) +Function 307: GenImageCellular() (3 input parameters) Name: GenImageCellular Return type: Image Description: Generate image: cellular algorithm, bigger tileSize means bigger cells Param[1]: width (type: int) Param[2]: height (type: int) Param[3]: tileSize (type: int) -Function 306: GenImageText() (3 input parameters) +Function 308: GenImageText() (3 input parameters) Name: GenImageText Return type: Image Description: Generate image: grayscale image from text data Param[1]: width (type: int) Param[2]: height (type: int) Param[3]: text (type: const char *) -Function 307: ImageCopy() (1 input parameters) +Function 309: ImageCopy() (1 input parameters) Name: ImageCopy Return type: Image Description: Create an image duplicate (useful for transformations) Param[1]: image (type: Image) -Function 308: ImageFromImage() (2 input parameters) +Function 310: ImageFromImage() (2 input parameters) Name: ImageFromImage Return type: Image Description: Create an image from another image piece Param[1]: image (type: Image) Param[2]: rec (type: Rectangle) -Function 309: ImageFromChannel() (2 input parameters) +Function 311: ImageFromChannel() (2 input parameters) Name: ImageFromChannel Return type: Image Description: Create an image from a selected channel of another image (GRAYSCALE) Param[1]: image (type: Image) Param[2]: selectedChannel (type: int) -Function 310: ImageText() (3 input parameters) +Function 312: ImageText() (3 input parameters) Name: ImageText Return type: Image Description: Create an image from text (default font) Param[1]: text (type: const char *) Param[2]: fontSize (type: int) Param[3]: color (type: Color) -Function 311: ImageTextEx() (5 input parameters) +Function 313: ImageTextEx() (5 input parameters) Name: ImageTextEx Return type: Image Description: Create an image from text (custom sprite font) @@ -2898,76 +2909,76 @@ Function 311: ImageTextEx() (5 input parameters) Param[3]: fontSize (type: float) Param[4]: spacing (type: float) Param[5]: tint (type: Color) -Function 312: ImageFormat() (2 input parameters) +Function 314: ImageFormat() (2 input parameters) Name: ImageFormat Return type: void Description: Convert image data to desired format Param[1]: image (type: Image *) Param[2]: newFormat (type: int) -Function 313: ImageToPOT() (2 input parameters) +Function 315: ImageToPOT() (2 input parameters) Name: ImageToPOT Return type: void Description: Convert image to POT (power-of-two) Param[1]: image (type: Image *) Param[2]: fill (type: Color) -Function 314: ImageCrop() (2 input parameters) +Function 316: ImageCrop() (2 input parameters) Name: ImageCrop Return type: void Description: Crop an image to a defined rectangle Param[1]: image (type: Image *) Param[2]: crop (type: Rectangle) -Function 315: ImageAlphaCrop() (2 input parameters) +Function 317: ImageAlphaCrop() (2 input parameters) Name: ImageAlphaCrop Return type: void Description: Crop image depending on alpha value Param[1]: image (type: Image *) Param[2]: threshold (type: float) -Function 316: ImageAlphaClear() (3 input parameters) +Function 318: ImageAlphaClear() (3 input parameters) Name: ImageAlphaClear Return type: void Description: Clear alpha channel to desired color Param[1]: image (type: Image *) Param[2]: color (type: Color) Param[3]: threshold (type: float) -Function 317: ImageAlphaMask() (2 input parameters) +Function 319: ImageAlphaMask() (2 input parameters) Name: ImageAlphaMask Return type: void Description: Apply alpha mask to image Param[1]: image (type: Image *) Param[2]: alphaMask (type: Image) -Function 318: ImageAlphaPremultiply() (1 input parameters) +Function 320: ImageAlphaPremultiply() (1 input parameters) Name: ImageAlphaPremultiply Return type: void Description: Premultiply alpha channel Param[1]: image (type: Image *) -Function 319: ImageBlurGaussian() (2 input parameters) +Function 321: ImageBlurGaussian() (2 input parameters) Name: ImageBlurGaussian Return type: void Description: Apply Gaussian blur using a box blur approximation Param[1]: image (type: Image *) Param[2]: blurSize (type: int) -Function 320: ImageKernelConvolution() (3 input parameters) +Function 322: ImageKernelConvolution() (3 input parameters) Name: ImageKernelConvolution Return type: void Description: Apply custom square convolution kernel to image Param[1]: image (type: Image *) Param[2]: kernel (type: const float *) Param[3]: kernelSize (type: int) -Function 321: ImageResize() (3 input parameters) +Function 323: ImageResize() (3 input parameters) Name: ImageResize Return type: void Description: Resize image (Bicubic scaling algorithm) Param[1]: image (type: Image *) Param[2]: newWidth (type: int) Param[3]: newHeight (type: int) -Function 322: ImageResizeNN() (3 input parameters) +Function 324: ImageResizeNN() (3 input parameters) Name: ImageResizeNN Return type: void Description: Resize image (Nearest-Neighbor scaling algorithm) Param[1]: image (type: Image *) Param[2]: newWidth (type: int) Param[3]: newHeight (type: int) -Function 323: ImageResizeCanvas() (6 input parameters) +Function 325: ImageResizeCanvas() (6 input parameters) Name: ImageResizeCanvas Return type: void Description: Resize canvas and fill with color @@ -2977,12 +2988,12 @@ Function 323: ImageResizeCanvas() (6 input parameters) Param[4]: offsetX (type: int) Param[5]: offsetY (type: int) Param[6]: fill (type: Color) -Function 324: ImageMipmaps() (1 input parameters) +Function 326: ImageMipmaps() (1 input parameters) Name: ImageMipmaps Return type: void Description: Compute all mipmap levels for a provided image Param[1]: image (type: Image *) -Function 325: ImageDither() (5 input parameters) +Function 327: ImageDither() (5 input parameters) Name: ImageDither Return type: void Description: Dither image data to 16bpp or lower (Floyd-Steinberg dithering) @@ -2991,109 +3002,109 @@ Function 325: ImageDither() (5 input parameters) Param[3]: gBpp (type: int) Param[4]: bBpp (type: int) Param[5]: aBpp (type: int) -Function 326: ImageFlipVertical() (1 input parameters) +Function 328: ImageFlipVertical() (1 input parameters) Name: ImageFlipVertical Return type: void Description: Flip image vertically Param[1]: image (type: Image *) -Function 327: ImageFlipHorizontal() (1 input parameters) +Function 329: ImageFlipHorizontal() (1 input parameters) Name: ImageFlipHorizontal Return type: void Description: Flip image horizontally Param[1]: image (type: Image *) -Function 328: ImageRotate() (2 input parameters) +Function 330: ImageRotate() (2 input parameters) Name: ImageRotate Return type: void Description: Rotate image by input angle in degrees (-359 to 359) Param[1]: image (type: Image *) Param[2]: degrees (type: int) -Function 329: ImageRotateCW() (1 input parameters) +Function 331: ImageRotateCW() (1 input parameters) Name: ImageRotateCW Return type: void Description: Rotate image clockwise 90deg Param[1]: image (type: Image *) -Function 330: ImageRotateCCW() (1 input parameters) +Function 332: ImageRotateCCW() (1 input parameters) Name: ImageRotateCCW Return type: void Description: Rotate image counter-clockwise 90deg Param[1]: image (type: Image *) -Function 331: ImageColorTint() (2 input parameters) +Function 333: ImageColorTint() (2 input parameters) Name: ImageColorTint Return type: void Description: Modify image color: tint Param[1]: image (type: Image *) Param[2]: color (type: Color) -Function 332: ImageColorInvert() (1 input parameters) +Function 334: ImageColorInvert() (1 input parameters) Name: ImageColorInvert Return type: void Description: Modify image color: invert Param[1]: image (type: Image *) -Function 333: ImageColorGrayscale() (1 input parameters) +Function 335: ImageColorGrayscale() (1 input parameters) Name: ImageColorGrayscale Return type: void Description: Modify image color: grayscale Param[1]: image (type: Image *) -Function 334: ImageColorContrast() (2 input parameters) +Function 336: ImageColorContrast() (2 input parameters) Name: ImageColorContrast Return type: void Description: Modify image color: contrast (-100 to 100) Param[1]: image (type: Image *) Param[2]: contrast (type: float) -Function 335: ImageColorBrightness() (2 input parameters) +Function 337: ImageColorBrightness() (2 input parameters) Name: ImageColorBrightness Return type: void Description: Modify image color: brightness (-255 to 255) Param[1]: image (type: Image *) Param[2]: brightness (type: int) -Function 336: ImageColorReplace() (3 input parameters) +Function 338: ImageColorReplace() (3 input parameters) Name: ImageColorReplace Return type: void Description: Modify image color: replace color Param[1]: image (type: Image *) Param[2]: color (type: Color) Param[3]: replace (type: Color) -Function 337: LoadImageColors() (1 input parameters) +Function 339: LoadImageColors() (1 input parameters) Name: LoadImageColors Return type: Color * Description: Load color data from image as a Color array (RGBA - 32bit) Param[1]: image (type: Image) -Function 338: LoadImagePalette() (3 input parameters) +Function 340: LoadImagePalette() (3 input parameters) Name: LoadImagePalette Return type: Color * Description: Load colors palette from image as a Color array (RGBA - 32bit) Param[1]: image (type: Image) Param[2]: maxPaletteSize (type: int) Param[3]: colorCount (type: int *) -Function 339: UnloadImageColors() (1 input parameters) +Function 341: UnloadImageColors() (1 input parameters) Name: UnloadImageColors Return type: void Description: Unload color data loaded with LoadImageColors() Param[1]: colors (type: Color *) -Function 340: UnloadImagePalette() (1 input parameters) +Function 342: UnloadImagePalette() (1 input parameters) Name: UnloadImagePalette Return type: void Description: Unload colors palette loaded with LoadImagePalette() Param[1]: colors (type: Color *) -Function 341: GetImageAlphaBorder() (2 input parameters) +Function 343: GetImageAlphaBorder() (2 input parameters) Name: GetImageAlphaBorder Return type: Rectangle Description: Get image alpha border rectangle Param[1]: image (type: Image) Param[2]: threshold (type: float) -Function 342: GetImageColor() (3 input parameters) +Function 344: GetImageColor() (3 input parameters) Name: GetImageColor Return type: Color Description: Get image pixel color at (x, y) position Param[1]: image (type: Image) Param[2]: x (type: int) Param[3]: y (type: int) -Function 343: ImageClearBackground() (2 input parameters) +Function 345: ImageClearBackground() (2 input parameters) Name: ImageClearBackground Return type: void Description: Clear image background with given color Param[1]: dst (type: Image *) Param[2]: color (type: Color) -Function 344: ImageDrawPixel() (4 input parameters) +Function 346: ImageDrawPixel() (4 input parameters) Name: ImageDrawPixel Return type: void Description: Draw pixel within an image @@ -3101,14 +3112,14 @@ Function 344: ImageDrawPixel() (4 input parameters) Param[2]: posX (type: int) Param[3]: posY (type: int) Param[4]: color (type: Color) -Function 345: ImageDrawPixelV() (3 input parameters) +Function 347: ImageDrawPixelV() (3 input parameters) Name: ImageDrawPixelV Return type: void Description: Draw pixel within an image (Vector version) Param[1]: dst (type: Image *) Param[2]: position (type: Vector2) Param[3]: color (type: Color) -Function 346: ImageDrawLine() (6 input parameters) +Function 348: ImageDrawLine() (6 input parameters) Name: ImageDrawLine Return type: void Description: Draw line within an image @@ -3118,7 +3129,7 @@ Function 346: ImageDrawLine() (6 input parameters) Param[4]: endPosX (type: int) Param[5]: endPosY (type: int) Param[6]: color (type: Color) -Function 347: ImageDrawLineV() (4 input parameters) +Function 349: ImageDrawLineV() (4 input parameters) Name: ImageDrawLineV Return type: void Description: Draw line within an image (Vector version) @@ -3126,7 +3137,7 @@ Function 347: ImageDrawLineV() (4 input parameters) Param[2]: start (type: Vector2) Param[3]: end (type: Vector2) Param[4]: color (type: Color) -Function 348: ImageDrawLineEx() (5 input parameters) +Function 350: ImageDrawLineEx() (5 input parameters) Name: ImageDrawLineEx Return type: void Description: Draw a line defining thickness within an image @@ -3135,7 +3146,7 @@ Function 348: ImageDrawLineEx() (5 input parameters) Param[3]: end (type: Vector2) Param[4]: thick (type: int) Param[5]: color (type: Color) -Function 349: ImageDrawCircle() (5 input parameters) +Function 351: ImageDrawCircle() (5 input parameters) Name: ImageDrawCircle Return type: void Description: Draw a filled circle within an image @@ -3144,7 +3155,7 @@ Function 349: ImageDrawCircle() (5 input parameters) Param[3]: centerY (type: int) Param[4]: radius (type: int) Param[5]: color (type: Color) -Function 350: ImageDrawCircleV() (4 input parameters) +Function 352: ImageDrawCircleV() (4 input parameters) Name: ImageDrawCircleV Return type: void Description: Draw a filled circle within an image (Vector version) @@ -3152,7 +3163,7 @@ Function 350: ImageDrawCircleV() (4 input parameters) Param[2]: center (type: Vector2) Param[3]: radius (type: int) Param[4]: color (type: Color) -Function 351: ImageDrawCircleLines() (5 input parameters) +Function 353: ImageDrawCircleLines() (5 input parameters) Name: ImageDrawCircleLines Return type: void Description: Draw circle outline within an image @@ -3161,7 +3172,7 @@ Function 351: ImageDrawCircleLines() (5 input parameters) Param[3]: centerY (type: int) Param[4]: radius (type: int) Param[5]: color (type: Color) -Function 352: ImageDrawCircleLinesV() (4 input parameters) +Function 354: ImageDrawCircleLinesV() (4 input parameters) Name: ImageDrawCircleLinesV Return type: void Description: Draw circle outline within an image (Vector version) @@ -3169,7 +3180,7 @@ Function 352: ImageDrawCircleLinesV() (4 input parameters) Param[2]: center (type: Vector2) Param[3]: radius (type: int) Param[4]: color (type: Color) -Function 353: ImageDrawRectangle() (6 input parameters) +Function 355: ImageDrawRectangle() (6 input parameters) Name: ImageDrawRectangle Return type: void Description: Draw rectangle within an image @@ -3179,7 +3190,7 @@ Function 353: ImageDrawRectangle() (6 input parameters) Param[4]: width (type: int) Param[5]: height (type: int) Param[6]: color (type: Color) -Function 354: ImageDrawRectangleV() (4 input parameters) +Function 356: ImageDrawRectangleV() (4 input parameters) Name: ImageDrawRectangleV Return type: void Description: Draw rectangle within an image (Vector version) @@ -3187,14 +3198,14 @@ Function 354: ImageDrawRectangleV() (4 input parameters) Param[2]: position (type: Vector2) Param[3]: size (type: Vector2) Param[4]: color (type: Color) -Function 355: ImageDrawRectangleRec() (3 input parameters) +Function 357: ImageDrawRectangleRec() (3 input parameters) Name: ImageDrawRectangleRec Return type: void Description: Draw rectangle within an image Param[1]: dst (type: Image *) Param[2]: rec (type: Rectangle) Param[3]: color (type: Color) -Function 356: ImageDrawRectangleLines() (4 input parameters) +Function 358: ImageDrawRectangleLines() (4 input parameters) Name: ImageDrawRectangleLines Return type: void Description: Draw rectangle lines within an image @@ -3202,7 +3213,7 @@ Function 356: ImageDrawRectangleLines() (4 input parameters) Param[2]: rec (type: Rectangle) Param[3]: thick (type: int) Param[4]: color (type: Color) -Function 357: ImageDrawTriangle() (5 input parameters) +Function 359: ImageDrawTriangle() (5 input parameters) Name: ImageDrawTriangle Return type: void Description: Draw triangle within an image @@ -3211,7 +3222,7 @@ Function 357: ImageDrawTriangle() (5 input parameters) Param[3]: v2 (type: Vector2) Param[4]: v3 (type: Vector2) Param[5]: color (type: Color) -Function 358: ImageDrawTriangleEx() (7 input parameters) +Function 360: ImageDrawTriangleEx() (7 input parameters) Name: ImageDrawTriangleEx Return type: void Description: Draw triangle with interpolated colors within an image @@ -3222,7 +3233,7 @@ Function 358: ImageDrawTriangleEx() (7 input parameters) Param[5]: c1 (type: Color) Param[6]: c2 (type: Color) Param[7]: c3 (type: Color) -Function 359: ImageDrawTriangleLines() (5 input parameters) +Function 361: ImageDrawTriangleLines() (5 input parameters) Name: ImageDrawTriangleLines Return type: void Description: Draw triangle outline within an image @@ -3231,7 +3242,7 @@ Function 359: ImageDrawTriangleLines() (5 input parameters) Param[3]: v2 (type: Vector2) Param[4]: v3 (type: Vector2) Param[5]: color (type: Color) -Function 360: ImageDrawTriangleFan() (4 input parameters) +Function 362: ImageDrawTriangleFan() (4 input parameters) Name: ImageDrawTriangleFan Return type: void Description: Draw a triangle fan defined by points within an image (first vertex is the center) @@ -3239,7 +3250,7 @@ Function 360: ImageDrawTriangleFan() (4 input parameters) Param[2]: points (type: const Vector2 *) Param[3]: pointCount (type: int) Param[4]: color (type: Color) -Function 361: ImageDrawTriangleStrip() (4 input parameters) +Function 363: ImageDrawTriangleStrip() (4 input parameters) Name: ImageDrawTriangleStrip Return type: void Description: Draw a triangle strip defined by points within an image @@ -3247,7 +3258,7 @@ Function 361: ImageDrawTriangleStrip() (4 input parameters) Param[2]: points (type: const Vector2 *) Param[3]: pointCount (type: int) Param[4]: color (type: Color) -Function 362: ImageDraw() (5 input parameters) +Function 364: ImageDraw() (5 input parameters) Name: ImageDraw Return type: void Description: Draw a source image within a destination image (tint applied to source) @@ -3256,7 +3267,7 @@ Function 362: ImageDraw() (5 input parameters) Param[3]: srcRec (type: Rectangle) Param[4]: dstRec (type: Rectangle) Param[5]: tint (type: Color) -Function 363: ImageDrawText() (6 input parameters) +Function 365: ImageDrawText() (6 input parameters) Name: ImageDrawText Return type: void Description: Draw text (using default font) within an image (destination) @@ -3266,7 +3277,7 @@ Function 363: ImageDrawText() (6 input parameters) Param[4]: posY (type: int) Param[5]: fontSize (type: int) Param[6]: color (type: Color) -Function 364: ImageDrawTextEx() (7 input parameters) +Function 366: ImageDrawTextEx() (7 input parameters) Name: ImageDrawTextEx Return type: void Description: Draw text (custom sprite font) within an image (destination) @@ -3277,79 +3288,79 @@ Function 364: ImageDrawTextEx() (7 input parameters) Param[5]: fontSize (type: float) Param[6]: spacing (type: float) Param[7]: tint (type: Color) -Function 365: LoadTexture() (1 input parameters) +Function 367: LoadTexture() (1 input parameters) Name: LoadTexture Return type: Texture2D Description: Load texture from file into GPU memory (VRAM) Param[1]: fileName (type: const char *) -Function 366: LoadTextureFromImage() (1 input parameters) +Function 368: LoadTextureFromImage() (1 input parameters) Name: LoadTextureFromImage Return type: Texture2D Description: Load texture from image data Param[1]: image (type: Image) -Function 367: LoadTextureCubemap() (2 input parameters) +Function 369: LoadTextureCubemap() (2 input parameters) Name: LoadTextureCubemap Return type: TextureCubemap Description: Load cubemap from image, multiple image cubemap layouts supported Param[1]: image (type: Image) Param[2]: layout (type: int) -Function 368: LoadRenderTexture() (2 input parameters) +Function 370: LoadRenderTexture() (2 input parameters) Name: LoadRenderTexture Return type: RenderTexture2D Description: Load texture for rendering (framebuffer) Param[1]: width (type: int) Param[2]: height (type: int) -Function 369: IsTextureValid() (1 input parameters) +Function 371: IsTextureValid() (1 input parameters) Name: IsTextureValid Return type: bool Description: Check if a texture is valid (loaded in GPU) Param[1]: texture (type: Texture2D) -Function 370: UnloadTexture() (1 input parameters) +Function 372: UnloadTexture() (1 input parameters) Name: UnloadTexture Return type: void Description: Unload texture from GPU memory (VRAM) Param[1]: texture (type: Texture2D) -Function 371: IsRenderTextureValid() (1 input parameters) +Function 373: IsRenderTextureValid() (1 input parameters) Name: IsRenderTextureValid Return type: bool Description: Check if a render texture is valid (loaded in GPU) Param[1]: target (type: RenderTexture2D) -Function 372: UnloadRenderTexture() (1 input parameters) +Function 374: UnloadRenderTexture() (1 input parameters) Name: UnloadRenderTexture Return type: void Description: Unload render texture from GPU memory (VRAM) Param[1]: target (type: RenderTexture2D) -Function 373: UpdateTexture() (2 input parameters) +Function 375: UpdateTexture() (2 input parameters) Name: UpdateTexture Return type: void Description: Update GPU texture with new data (pixels should be able to fill texture) Param[1]: texture (type: Texture2D) Param[2]: pixels (type: const void *) -Function 374: UpdateTextureRec() (3 input parameters) +Function 376: UpdateTextureRec() (3 input parameters) Name: UpdateTextureRec Return type: void Description: Update GPU texture rectangle with new data (pixels and rec should fit in texture) Param[1]: texture (type: Texture2D) Param[2]: rec (type: Rectangle) Param[3]: pixels (type: const void *) -Function 375: GenTextureMipmaps() (1 input parameters) +Function 377: GenTextureMipmaps() (1 input parameters) Name: GenTextureMipmaps Return type: void Description: Generate GPU mipmaps for a texture Param[1]: texture (type: Texture2D *) -Function 376: SetTextureFilter() (2 input parameters) +Function 378: SetTextureFilter() (2 input parameters) Name: SetTextureFilter Return type: void Description: Set texture scaling filter mode Param[1]: texture (type: Texture2D) Param[2]: filter (type: int) -Function 377: SetTextureWrap() (2 input parameters) +Function 379: SetTextureWrap() (2 input parameters) Name: SetTextureWrap Return type: void Description: Set texture wrapping mode Param[1]: texture (type: Texture2D) Param[2]: wrap (type: int) -Function 378: DrawTexture() (4 input parameters) +Function 380: DrawTexture() (4 input parameters) Name: DrawTexture Return type: void Description: Draw a Texture2D @@ -3357,14 +3368,14 @@ Function 378: DrawTexture() (4 input parameters) Param[2]: posX (type: int) Param[3]: posY (type: int) Param[4]: tint (type: Color) -Function 379: DrawTextureV() (3 input parameters) +Function 381: DrawTextureV() (3 input parameters) Name: DrawTextureV Return type: void Description: Draw a Texture2D with position defined as Vector2 Param[1]: texture (type: Texture2D) Param[2]: position (type: Vector2) Param[3]: tint (type: Color) -Function 380: DrawTextureEx() (5 input parameters) +Function 382: DrawTextureEx() (5 input parameters) Name: DrawTextureEx Return type: void Description: Draw a Texture2D with extended parameters @@ -3373,7 +3384,7 @@ Function 380: DrawTextureEx() (5 input parameters) Param[3]: rotation (type: float) Param[4]: scale (type: float) Param[5]: tint (type: Color) -Function 381: DrawTextureRec() (4 input parameters) +Function 383: DrawTextureRec() (4 input parameters) Name: DrawTextureRec Return type: void Description: Draw a part of a texture defined by a rectangle @@ -3381,7 +3392,7 @@ Function 381: DrawTextureRec() (4 input parameters) Param[2]: source (type: Rectangle) Param[3]: position (type: Vector2) Param[4]: tint (type: Color) -Function 382: DrawTexturePro() (6 input parameters) +Function 384: DrawTexturePro() (6 input parameters) Name: DrawTexturePro Return type: void Description: Draw a part of a texture defined by a rectangle with 'pro' parameters @@ -3391,7 +3402,7 @@ Function 382: DrawTexturePro() (6 input parameters) Param[4]: origin (type: Vector2) Param[5]: rotation (type: float) Param[6]: tint (type: Color) -Function 383: DrawTextureNPatch() (6 input parameters) +Function 385: DrawTextureNPatch() (6 input parameters) Name: DrawTextureNPatch Return type: void Description: Draws a texture (or part of it) that stretches or shrinks nicely @@ -3401,119 +3412,119 @@ Function 383: DrawTextureNPatch() (6 input parameters) Param[4]: origin (type: Vector2) Param[5]: rotation (type: float) Param[6]: tint (type: Color) -Function 384: ColorIsEqual() (2 input parameters) +Function 386: ColorIsEqual() (2 input parameters) Name: ColorIsEqual Return type: bool Description: Check if two colors are equal Param[1]: col1 (type: Color) Param[2]: col2 (type: Color) -Function 385: Fade() (2 input parameters) +Function 387: Fade() (2 input parameters) Name: Fade Return type: Color Description: Get color with alpha applied, alpha goes from 0.0f to 1.0f Param[1]: color (type: Color) Param[2]: alpha (type: float) -Function 386: ColorToInt() (1 input parameters) +Function 388: ColorToInt() (1 input parameters) Name: ColorToInt Return type: int Description: Get hexadecimal value for a Color (0xRRGGBBAA) Param[1]: color (type: Color) -Function 387: ColorNormalize() (1 input parameters) +Function 389: ColorNormalize() (1 input parameters) Name: ColorNormalize Return type: Vector4 Description: Get Color normalized as float [0..1] Param[1]: color (type: Color) -Function 388: ColorFromNormalized() (1 input parameters) +Function 390: ColorFromNormalized() (1 input parameters) Name: ColorFromNormalized Return type: Color Description: Get Color from normalized values [0..1] Param[1]: normalized (type: Vector4) -Function 389: ColorToHSV() (1 input parameters) +Function 391: ColorToHSV() (1 input parameters) Name: ColorToHSV Return type: Vector3 Description: Get HSV values for a Color, hue [0..360], saturation/value [0..1] Param[1]: color (type: Color) -Function 390: ColorFromHSV() (3 input parameters) +Function 392: ColorFromHSV() (3 input parameters) Name: ColorFromHSV Return type: Color Description: Get a Color from HSV values, hue [0..360], saturation/value [0..1] Param[1]: hue (type: float) Param[2]: saturation (type: float) Param[3]: value (type: float) -Function 391: ColorTint() (2 input parameters) +Function 393: ColorTint() (2 input parameters) Name: ColorTint Return type: Color Description: Get color multiplied with another color Param[1]: color (type: Color) Param[2]: tint (type: Color) -Function 392: ColorBrightness() (2 input parameters) +Function 394: ColorBrightness() (2 input parameters) Name: ColorBrightness Return type: Color Description: Get color with brightness correction, brightness factor goes from -1.0f to 1.0f Param[1]: color (type: Color) Param[2]: factor (type: float) -Function 393: ColorContrast() (2 input parameters) +Function 395: ColorContrast() (2 input parameters) Name: ColorContrast Return type: Color Description: Get color with contrast correction, contrast values between -1.0f and 1.0f Param[1]: color (type: Color) Param[2]: contrast (type: float) -Function 394: ColorAlpha() (2 input parameters) +Function 396: ColorAlpha() (2 input parameters) Name: ColorAlpha Return type: Color Description: Get color with alpha applied, alpha goes from 0.0f to 1.0f Param[1]: color (type: Color) Param[2]: alpha (type: float) -Function 395: ColorAlphaBlend() (3 input parameters) +Function 397: ColorAlphaBlend() (3 input parameters) Name: ColorAlphaBlend Return type: Color Description: Get src alpha-blended into dst color with tint Param[1]: dst (type: Color) Param[2]: src (type: Color) Param[3]: tint (type: Color) -Function 396: ColorLerp() (3 input parameters) +Function 398: ColorLerp() (3 input parameters) Name: ColorLerp Return type: Color Description: Get color lerp interpolation between two colors, factor [0.0f..1.0f] Param[1]: color1 (type: Color) Param[2]: color2 (type: Color) Param[3]: factor (type: float) -Function 397: GetColor() (1 input parameters) +Function 399: GetColor() (1 input parameters) Name: GetColor Return type: Color Description: Get Color structure from hexadecimal value Param[1]: hexValue (type: unsigned int) -Function 398: GetPixelColor() (2 input parameters) +Function 400: GetPixelColor() (2 input parameters) Name: GetPixelColor Return type: Color Description: Get Color from a source pixel pointer of certain format Param[1]: srcPtr (type: void *) Param[2]: format (type: int) -Function 399: SetPixelColor() (3 input parameters) +Function 401: SetPixelColor() (3 input parameters) Name: SetPixelColor Return type: void Description: Set color formatted into destination pixel pointer Param[1]: dstPtr (type: void *) Param[2]: color (type: Color) Param[3]: format (type: int) -Function 400: GetPixelDataSize() (3 input parameters) +Function 402: GetPixelDataSize() (3 input parameters) Name: GetPixelDataSize Return type: int Description: Get pixel data size in bytes for certain format Param[1]: width (type: int) Param[2]: height (type: int) Param[3]: format (type: int) -Function 401: GetFontDefault() (0 input parameters) +Function 403: GetFontDefault() (0 input parameters) Name: GetFontDefault Return type: Font Description: Get the default Font No input parameters -Function 402: LoadFont() (1 input parameters) +Function 404: LoadFont() (1 input parameters) Name: LoadFont Return type: Font Description: Load font from file into GPU memory (VRAM) Param[1]: fileName (type: const char *) -Function 403: LoadFontEx() (4 input parameters) +Function 405: LoadFontEx() (4 input parameters) Name: LoadFontEx Return type: Font Description: Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set, font size is provided in pixels height @@ -3521,14 +3532,14 @@ Function 403: LoadFontEx() (4 input parameters) Param[2]: fontSize (type: int) Param[3]: codepoints (type: const int *) Param[4]: codepointCount (type: int) -Function 404: LoadFontFromImage() (3 input parameters) +Function 406: LoadFontFromImage() (3 input parameters) Name: LoadFontFromImage Return type: Font Description: Load font from Image (XNA style) Param[1]: image (type: Image) Param[2]: key (type: Color) Param[3]: firstChar (type: int) -Function 405: LoadFontFromMemory() (6 input parameters) +Function 407: LoadFontFromMemory() (6 input parameters) Name: LoadFontFromMemory Return type: Font Description: Load font from memory buffer, fileType refers to extension: i.e. '.ttf' @@ -3538,12 +3549,12 @@ Function 405: LoadFontFromMemory() (6 input parameters) Param[4]: fontSize (type: int) Param[5]: codepoints (type: const int *) Param[6]: codepointCount (type: int) -Function 406: IsFontValid() (1 input parameters) +Function 408: IsFontValid() (1 input parameters) Name: IsFontValid Return type: bool Description: Check if a font is valid (font data loaded, WARNING: GPU texture not checked) Param[1]: font (type: Font) -Function 407: LoadFontData() (7 input parameters) +Function 409: LoadFontData() (7 input parameters) Name: LoadFontData Return type: GlyphInfo * Description: Load font data for further use @@ -3554,7 +3565,7 @@ Function 407: LoadFontData() (7 input parameters) Param[5]: codepointCount (type: int) Param[6]: type (type: int) Param[7]: glyphCount (type: int *) -Function 408: GenImageFontAtlas() (6 input parameters) +Function 410: GenImageFontAtlas() (6 input parameters) Name: GenImageFontAtlas Return type: Image Description: Generate image font atlas using chars info @@ -3564,30 +3575,30 @@ Function 408: GenImageFontAtlas() (6 input parameters) Param[4]: fontSize (type: int) Param[5]: padding (type: int) Param[6]: packMethod (type: int) -Function 409: UnloadFontData() (2 input parameters) +Function 411: UnloadFontData() (2 input parameters) Name: UnloadFontData Return type: void Description: Unload font chars info data (RAM) Param[1]: glyphs (type: GlyphInfo *) Param[2]: glyphCount (type: int) -Function 410: UnloadFont() (1 input parameters) +Function 412: UnloadFont() (1 input parameters) Name: UnloadFont Return type: void Description: Unload font from GPU memory (VRAM) Param[1]: font (type: Font) -Function 411: ExportFontAsCode() (2 input parameters) +Function 413: ExportFontAsCode() (2 input parameters) Name: ExportFontAsCode Return type: bool Description: Export font as code file, returns true on success Param[1]: font (type: Font) Param[2]: fileName (type: const char *) -Function 412: DrawFPS() (2 input parameters) +Function 414: DrawFPS() (2 input parameters) Name: DrawFPS Return type: void Description: Draw current FPS Param[1]: posX (type: int) Param[2]: posY (type: int) -Function 413: DrawText() (5 input parameters) +Function 415: DrawText() (5 input parameters) Name: DrawText Return type: void Description: Draw text (using default font) @@ -3596,7 +3607,7 @@ Function 413: DrawText() (5 input parameters) Param[3]: posY (type: int) Param[4]: fontSize (type: int) Param[5]: color (type: Color) -Function 414: DrawTextEx() (6 input parameters) +Function 416: DrawTextEx() (6 input parameters) Name: DrawTextEx Return type: void Description: Draw text using font and additional parameters @@ -3606,7 +3617,7 @@ Function 414: DrawTextEx() (6 input parameters) Param[4]: fontSize (type: float) Param[5]: spacing (type: float) Param[6]: tint (type: Color) -Function 415: DrawTextPro() (8 input parameters) +Function 417: DrawTextPro() (8 input parameters) Name: DrawTextPro Return type: void Description: Draw text using Font and pro parameters (rotation) @@ -3618,7 +3629,7 @@ Function 415: DrawTextPro() (8 input parameters) Param[6]: fontSize (type: float) Param[7]: spacing (type: float) Param[8]: tint (type: Color) -Function 416: DrawTextCodepoint() (5 input parameters) +Function 418: DrawTextCodepoint() (5 input parameters) Name: DrawTextCodepoint Return type: void Description: Draw one character (codepoint) @@ -3627,7 +3638,7 @@ Function 416: DrawTextCodepoint() (5 input parameters) Param[3]: position (type: Vector2) Param[4]: fontSize (type: float) Param[5]: tint (type: Color) -Function 417: DrawTextCodepoints() (7 input parameters) +Function 419: DrawTextCodepoints() (7 input parameters) Name: DrawTextCodepoints Return type: void Description: Draw multiple character (codepoint) @@ -3638,18 +3649,18 @@ Function 417: DrawTextCodepoints() (7 input parameters) Param[5]: fontSize (type: float) Param[6]: spacing (type: float) Param[7]: tint (type: Color) -Function 418: SetTextLineSpacing() (1 input parameters) +Function 420: SetTextLineSpacing() (1 input parameters) Name: SetTextLineSpacing Return type: void Description: Set vertical line spacing when drawing with line-breaks Param[1]: spacing (type: int) -Function 419: MeasureText() (2 input parameters) +Function 421: MeasureText() (2 input parameters) Name: MeasureText Return type: int Description: Measure string width for default font Param[1]: text (type: const char *) Param[2]: fontSize (type: int) -Function 420: MeasureTextEx() (4 input parameters) +Function 422: MeasureTextEx() (4 input parameters) Name: MeasureTextEx Return type: Vector2 Description: Measure string size for Font @@ -3657,137 +3668,137 @@ Function 420: MeasureTextEx() (4 input parameters) Param[2]: text (type: const char *) Param[3]: fontSize (type: float) Param[4]: spacing (type: float) -Function 421: GetGlyphIndex() (2 input parameters) +Function 423: GetGlyphIndex() (2 input parameters) Name: GetGlyphIndex Return type: int Description: Get glyph index position in font for a codepoint (unicode character), fallback to '?' if not found Param[1]: font (type: Font) Param[2]: codepoint (type: int) -Function 422: GetGlyphInfo() (2 input parameters) +Function 424: GetGlyphInfo() (2 input parameters) Name: GetGlyphInfo Return type: GlyphInfo Description: Get glyph font info data for a codepoint (unicode character), fallback to '?' if not found Param[1]: font (type: Font) Param[2]: codepoint (type: int) -Function 423: GetGlyphAtlasRec() (2 input parameters) +Function 425: GetGlyphAtlasRec() (2 input parameters) Name: GetGlyphAtlasRec Return type: Rectangle Description: Get glyph rectangle in font atlas for a codepoint (unicode character), fallback to '?' if not found Param[1]: font (type: Font) Param[2]: codepoint (type: int) -Function 424: LoadUTF8() (2 input parameters) +Function 426: LoadUTF8() (2 input parameters) Name: LoadUTF8 Return type: char * Description: Load UTF-8 text encoded from codepoints array Param[1]: codepoints (type: const int *) Param[2]: length (type: int) -Function 425: UnloadUTF8() (1 input parameters) +Function 427: UnloadUTF8() (1 input parameters) Name: UnloadUTF8 Return type: void Description: Unload UTF-8 text encoded from codepoints array Param[1]: text (type: char *) -Function 426: LoadCodepoints() (2 input parameters) +Function 428: LoadCodepoints() (2 input parameters) Name: LoadCodepoints Return type: int * Description: Load all codepoints from a UTF-8 text string, codepoints count returned by parameter Param[1]: text (type: const char *) Param[2]: count (type: int *) -Function 427: UnloadCodepoints() (1 input parameters) +Function 429: UnloadCodepoints() (1 input parameters) Name: UnloadCodepoints Return type: void Description: Unload codepoints data from memory Param[1]: codepoints (type: int *) -Function 428: GetCodepointCount() (1 input parameters) +Function 430: GetCodepointCount() (1 input parameters) Name: GetCodepointCount Return type: int Description: Get total number of codepoints in a UTF-8 encoded string Param[1]: text (type: const char *) -Function 429: GetCodepoint() (2 input parameters) +Function 431: GetCodepoint() (2 input parameters) Name: GetCodepoint Return type: int Description: Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure Param[1]: text (type: const char *) Param[2]: codepointSize (type: int *) -Function 430: GetCodepointNext() (2 input parameters) +Function 432: GetCodepointNext() (2 input parameters) Name: GetCodepointNext Return type: int Description: Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure Param[1]: text (type: const char *) Param[2]: codepointSize (type: int *) -Function 431: GetCodepointPrevious() (2 input parameters) +Function 433: GetCodepointPrevious() (2 input parameters) Name: GetCodepointPrevious Return type: int Description: Get previous codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure Param[1]: text (type: const char *) Param[2]: codepointSize (type: int *) -Function 432: CodepointToUTF8() (2 input parameters) +Function 434: CodepointToUTF8() (2 input parameters) Name: CodepointToUTF8 Return type: const char * Description: Encode one codepoint into UTF-8 byte array (array length returned as parameter) Param[1]: codepoint (type: int) Param[2]: utf8Size (type: int *) -Function 433: LoadTextLines() (2 input parameters) +Function 435: LoadTextLines() (2 input parameters) Name: LoadTextLines Return type: char ** Description: Load text as separate lines ('\n') Param[1]: text (type: const char *) Param[2]: count (type: int *) -Function 434: UnloadTextLines() (2 input parameters) +Function 436: UnloadTextLines() (2 input parameters) Name: UnloadTextLines Return type: void Description: Unload text lines Param[1]: text (type: char **) Param[2]: lineCount (type: int) -Function 435: TextCopy() (2 input parameters) +Function 437: TextCopy() (2 input parameters) Name: TextCopy Return type: int Description: Copy one string to another, returns bytes copied Param[1]: dst (type: char *) Param[2]: src (type: const char *) -Function 436: TextIsEqual() (2 input parameters) +Function 438: TextIsEqual() (2 input parameters) Name: TextIsEqual Return type: bool Description: Check if two text string are equal Param[1]: text1 (type: const char *) Param[2]: text2 (type: const char *) -Function 437: TextLength() (1 input parameters) +Function 439: TextLength() (1 input parameters) Name: TextLength Return type: unsigned int Description: Get text length, checks for '\0' ending Param[1]: text (type: const char *) -Function 438: TextFormat() (2 input parameters) +Function 440: TextFormat() (2 input parameters) Name: TextFormat Return type: const char * Description: Text formatting with variables (sprintf() style) Param[1]: text (type: const char *) Param[2]: args (type: ...) -Function 439: TextSubtext() (3 input parameters) +Function 441: TextSubtext() (3 input parameters) Name: TextSubtext Return type: const char * Description: Get a piece of a text string Param[1]: text (type: const char *) Param[2]: position (type: int) Param[3]: length (type: int) -Function 440: TextRemoveSpaces() (1 input parameters) +Function 442: TextRemoveSpaces() (1 input parameters) Name: TextRemoveSpaces Return type: const char * Description: Remove text spaces, concat words Param[1]: text (type: const char *) -Function 441: GetTextBetween() (3 input parameters) +Function 443: GetTextBetween() (3 input parameters) Name: GetTextBetween Return type: char * Description: Get text between two strings Param[1]: text (type: const char *) Param[2]: begin (type: const char *) Param[3]: end (type: const char *) -Function 442: TextReplace() (3 input parameters) +Function 444: TextReplace() (3 input parameters) Name: TextReplace Return type: char * Description: Replace text string (WARNING: memory must be freed!) Param[1]: text (type: const char *) Param[2]: search (type: const char *) Param[3]: replacement (type: const char *) -Function 443: TextReplaceBetween() (4 input parameters) +Function 445: TextReplaceBetween() (4 input parameters) Name: TextReplaceBetween Return type: char * Description: Replace text between two specific strings (WARNING: memory must be freed!) @@ -3795,89 +3806,89 @@ Function 443: TextReplaceBetween() (4 input parameters) Param[2]: begin (type: const char *) Param[3]: end (type: const char *) Param[4]: replacement (type: const char *) -Function 444: TextInsert() (3 input parameters) +Function 446: TextInsert() (3 input parameters) Name: TextInsert Return type: char * Description: Insert text in a position (WARNING: memory must be freed!) Param[1]: text (type: const char *) Param[2]: insert (type: const char *) Param[3]: position (type: int) -Function 445: TextJoin() (3 input parameters) +Function 447: TextJoin() (3 input parameters) Name: TextJoin Return type: char * Description: Join text strings with delimiter Param[1]: textList (type: char **) Param[2]: count (type: int) Param[3]: delimiter (type: const char *) -Function 446: TextSplit() (3 input parameters) +Function 448: TextSplit() (3 input parameters) Name: TextSplit Return type: char ** Description: Split text into multiple strings, using MAX_TEXTSPLIT_COUNT static strings Param[1]: text (type: const char *) Param[2]: delimiter (type: char) Param[3]: count (type: int *) -Function 447: TextAppend() (3 input parameters) +Function 449: TextAppend() (3 input parameters) Name: TextAppend Return type: void Description: Append text at specific position and move cursor Param[1]: text (type: char *) Param[2]: append (type: const char *) Param[3]: position (type: int *) -Function 448: TextFindIndex() (2 input parameters) +Function 450: TextFindIndex() (2 input parameters) Name: TextFindIndex Return type: int Description: Find first text occurrence within a string, -1 if not found Param[1]: text (type: const char *) Param[2]: search (type: const char *) -Function 449: TextToUpper() (1 input parameters) +Function 451: TextToUpper() (1 input parameters) Name: TextToUpper Return type: char * Description: Get upper case version of provided string Param[1]: text (type: const char *) -Function 450: TextToLower() (1 input parameters) +Function 452: TextToLower() (1 input parameters) Name: TextToLower Return type: char * Description: Get lower case version of provided string Param[1]: text (type: const char *) -Function 451: TextToPascal() (1 input parameters) +Function 453: TextToPascal() (1 input parameters) Name: TextToPascal Return type: char * Description: Get Pascal case notation version of provided string Param[1]: text (type: const char *) -Function 452: TextToSnake() (1 input parameters) +Function 454: TextToSnake() (1 input parameters) Name: TextToSnake Return type: char * Description: Get Snake case notation version of provided string Param[1]: text (type: const char *) -Function 453: TextToCamel() (1 input parameters) +Function 455: TextToCamel() (1 input parameters) Name: TextToCamel Return type: char * Description: Get Camel case notation version of provided string Param[1]: text (type: const char *) -Function 454: TextToInteger() (1 input parameters) +Function 456: TextToInteger() (1 input parameters) Name: TextToInteger Return type: int Description: Get integer value from text Param[1]: text (type: const char *) -Function 455: TextToFloat() (1 input parameters) +Function 457: TextToFloat() (1 input parameters) Name: TextToFloat Return type: float Description: Get float value from text Param[1]: text (type: const char *) -Function 456: DrawLine3D() (3 input parameters) +Function 458: DrawLine3D() (3 input parameters) Name: DrawLine3D Return type: void Description: Draw a line in 3D world space Param[1]: startPos (type: Vector3) Param[2]: endPos (type: Vector3) Param[3]: color (type: Color) -Function 457: DrawPoint3D() (2 input parameters) +Function 459: DrawPoint3D() (2 input parameters) Name: DrawPoint3D Return type: void Description: Draw a point in 3D space, actually a small line Param[1]: position (type: Vector3) Param[2]: color (type: Color) -Function 458: DrawCircle3D() (5 input parameters) +Function 460: DrawCircle3D() (5 input parameters) Name: DrawCircle3D Return type: void Description: Draw a circle in 3D world space @@ -3886,7 +3897,7 @@ Function 458: DrawCircle3D() (5 input parameters) Param[3]: rotationAxis (type: Vector3) Param[4]: rotationAngle (type: float) Param[5]: color (type: Color) -Function 459: DrawTriangle3D() (4 input parameters) +Function 461: DrawTriangle3D() (4 input parameters) Name: DrawTriangle3D Return type: void Description: Draw a color-filled triangle (vertex in counter-clockwise order!) @@ -3894,14 +3905,14 @@ Function 459: DrawTriangle3D() (4 input parameters) Param[2]: v2 (type: Vector3) Param[3]: v3 (type: Vector3) Param[4]: color (type: Color) -Function 460: DrawTriangleStrip3D() (3 input parameters) +Function 462: DrawTriangleStrip3D() (3 input parameters) Name: DrawTriangleStrip3D Return type: void Description: Draw a triangle strip defined by points Param[1]: points (type: const Vector3 *) Param[2]: pointCount (type: int) Param[3]: color (type: Color) -Function 461: DrawCube() (5 input parameters) +Function 463: DrawCube() (5 input parameters) Name: DrawCube Return type: void Description: Draw cube @@ -3910,14 +3921,14 @@ Function 461: DrawCube() (5 input parameters) Param[3]: height (type: float) Param[4]: length (type: float) Param[5]: color (type: Color) -Function 462: DrawCubeV() (3 input parameters) +Function 464: DrawCubeV() (3 input parameters) Name: DrawCubeV Return type: void Description: Draw cube (Vector version) Param[1]: position (type: Vector3) Param[2]: size (type: Vector3) Param[3]: color (type: Color) -Function 463: DrawCubeWires() (5 input parameters) +Function 465: DrawCubeWires() (5 input parameters) Name: DrawCubeWires Return type: void Description: Draw cube wires @@ -3926,21 +3937,21 @@ Function 463: DrawCubeWires() (5 input parameters) Param[3]: height (type: float) Param[4]: length (type: float) Param[5]: color (type: Color) -Function 464: DrawCubeWiresV() (3 input parameters) +Function 466: DrawCubeWiresV() (3 input parameters) Name: DrawCubeWiresV Return type: void Description: Draw cube wires (Vector version) Param[1]: position (type: Vector3) Param[2]: size (type: Vector3) Param[3]: color (type: Color) -Function 465: DrawSphere() (3 input parameters) +Function 467: DrawSphere() (3 input parameters) Name: DrawSphere Return type: void Description: Draw sphere Param[1]: centerPos (type: Vector3) Param[2]: radius (type: float) Param[3]: color (type: Color) -Function 466: DrawSphereEx() (5 input parameters) +Function 468: DrawSphereEx() (5 input parameters) Name: DrawSphereEx Return type: void Description: Draw sphere with extended parameters @@ -3949,7 +3960,7 @@ Function 466: DrawSphereEx() (5 input parameters) Param[3]: rings (type: int) Param[4]: slices (type: int) Param[5]: color (type: Color) -Function 467: DrawSphereWires() (5 input parameters) +Function 469: DrawSphereWires() (5 input parameters) Name: DrawSphereWires Return type: void Description: Draw sphere wires @@ -3958,7 +3969,7 @@ Function 467: DrawSphereWires() (5 input parameters) Param[3]: rings (type: int) Param[4]: slices (type: int) Param[5]: color (type: Color) -Function 468: DrawCylinder() (6 input parameters) +Function 470: DrawCylinder() (6 input parameters) Name: DrawCylinder Return type: void Description: Draw a cylinder/cone @@ -3968,7 +3979,7 @@ Function 468: DrawCylinder() (6 input parameters) Param[4]: height (type: float) Param[5]: slices (type: int) Param[6]: color (type: Color) -Function 469: DrawCylinderEx() (6 input parameters) +Function 471: DrawCylinderEx() (6 input parameters) Name: DrawCylinderEx Return type: void Description: Draw a cylinder with base at startPos and top at endPos @@ -3978,7 +3989,7 @@ Function 469: DrawCylinderEx() (6 input parameters) Param[4]: endRadius (type: float) Param[5]: sides (type: int) Param[6]: color (type: Color) -Function 470: DrawCylinderWires() (6 input parameters) +Function 472: DrawCylinderWires() (6 input parameters) Name: DrawCylinderWires Return type: void Description: Draw a cylinder/cone wires @@ -3988,7 +3999,7 @@ Function 470: DrawCylinderWires() (6 input parameters) Param[4]: height (type: float) Param[5]: slices (type: int) Param[6]: color (type: Color) -Function 471: DrawCylinderWiresEx() (6 input parameters) +Function 473: DrawCylinderWiresEx() (6 input parameters) Name: DrawCylinderWiresEx Return type: void Description: Draw a cylinder wires with base at startPos and top at endPos @@ -3998,7 +4009,7 @@ Function 471: DrawCylinderWiresEx() (6 input parameters) Param[4]: endRadius (type: float) Param[5]: sides (type: int) Param[6]: color (type: Color) -Function 472: DrawCapsule() (6 input parameters) +Function 474: DrawCapsule() (6 input parameters) Name: DrawCapsule Return type: void Description: Draw a capsule with the center of its sphere caps at startPos and endPos @@ -4008,7 +4019,7 @@ Function 472: DrawCapsule() (6 input parameters) Param[4]: slices (type: int) Param[5]: rings (type: int) Param[6]: color (type: Color) -Function 473: DrawCapsuleWires() (6 input parameters) +Function 475: DrawCapsuleWires() (6 input parameters) Name: DrawCapsuleWires Return type: void Description: Draw capsule wireframe with the center of its sphere caps at startPos and endPos @@ -4018,51 +4029,51 @@ Function 473: DrawCapsuleWires() (6 input parameters) Param[4]: slices (type: int) Param[5]: rings (type: int) Param[6]: color (type: Color) -Function 474: DrawPlane() (3 input parameters) +Function 476: DrawPlane() (3 input parameters) Name: DrawPlane Return type: void Description: Draw a plane XZ Param[1]: centerPos (type: Vector3) Param[2]: size (type: Vector2) Param[3]: color (type: Color) -Function 475: DrawRay() (2 input parameters) +Function 477: DrawRay() (2 input parameters) Name: DrawRay Return type: void Description: Draw a ray line Param[1]: ray (type: Ray) Param[2]: color (type: Color) -Function 476: DrawGrid() (2 input parameters) +Function 478: DrawGrid() (2 input parameters) Name: DrawGrid Return type: void Description: Draw a grid (centered at (0, 0, 0)) Param[1]: slices (type: int) Param[2]: spacing (type: float) -Function 477: LoadModel() (1 input parameters) +Function 479: LoadModel() (1 input parameters) Name: LoadModel Return type: Model Description: Load model from files (meshes and materials) Param[1]: fileName (type: const char *) -Function 478: LoadModelFromMesh() (1 input parameters) +Function 480: LoadModelFromMesh() (1 input parameters) Name: LoadModelFromMesh Return type: Model Description: Load model from generated mesh (default material) Param[1]: mesh (type: Mesh) -Function 479: IsModelValid() (1 input parameters) +Function 481: IsModelValid() (1 input parameters) Name: IsModelValid Return type: bool Description: Check if a model is valid (loaded in GPU, VAO/VBOs) Param[1]: model (type: Model) -Function 480: UnloadModel() (1 input parameters) +Function 482: UnloadModel() (1 input parameters) Name: UnloadModel Return type: void Description: Unload model (including meshes) from memory (RAM and/or VRAM) Param[1]: model (type: Model) -Function 481: GetModelBoundingBox() (1 input parameters) +Function 483: GetModelBoundingBox() (1 input parameters) Name: GetModelBoundingBox Return type: BoundingBox Description: Compute model bounding box limits (considers all meshes) Param[1]: model (type: Model) -Function 482: DrawModel() (4 input parameters) +Function 484: DrawModel() (4 input parameters) Name: DrawModel Return type: void Description: Draw a model (with texture if set) @@ -4070,7 +4081,7 @@ Function 482: DrawModel() (4 input parameters) Param[2]: position (type: Vector3) Param[3]: scale (type: float) Param[4]: tint (type: Color) -Function 483: DrawModelEx() (6 input parameters) +Function 485: DrawModelEx() (6 input parameters) Name: DrawModelEx Return type: void Description: Draw a model with extended parameters @@ -4080,7 +4091,7 @@ Function 483: DrawModelEx() (6 input parameters) Param[4]: rotationAngle (type: float) Param[5]: scale (type: Vector3) Param[6]: tint (type: Color) -Function 484: DrawModelWires() (4 input parameters) +Function 486: DrawModelWires() (4 input parameters) Name: DrawModelWires Return type: void Description: Draw a model wires (with texture if set) @@ -4088,7 +4099,7 @@ Function 484: DrawModelWires() (4 input parameters) Param[2]: position (type: Vector3) Param[3]: scale (type: float) Param[4]: tint (type: Color) -Function 485: DrawModelWiresEx() (6 input parameters) +Function 487: DrawModelWiresEx() (6 input parameters) Name: DrawModelWiresEx Return type: void Description: Draw a model wires (with texture if set) with extended parameters @@ -4098,7 +4109,7 @@ Function 485: DrawModelWiresEx() (6 input parameters) Param[4]: rotationAngle (type: float) Param[5]: scale (type: Vector3) Param[6]: tint (type: Color) -Function 486: DrawModelPoints() (4 input parameters) +Function 488: DrawModelPoints() (4 input parameters) Name: DrawModelPoints Return type: void Description: Draw a model as points @@ -4106,7 +4117,7 @@ Function 486: DrawModelPoints() (4 input parameters) Param[2]: position (type: Vector3) Param[3]: scale (type: float) Param[4]: tint (type: Color) -Function 487: DrawModelPointsEx() (6 input parameters) +Function 489: DrawModelPointsEx() (6 input parameters) Name: DrawModelPointsEx Return type: void Description: Draw a model as points with extended parameters @@ -4116,13 +4127,13 @@ Function 487: DrawModelPointsEx() (6 input parameters) Param[4]: rotationAngle (type: float) Param[5]: scale (type: Vector3) Param[6]: tint (type: Color) -Function 488: DrawBoundingBox() (2 input parameters) +Function 490: DrawBoundingBox() (2 input parameters) Name: DrawBoundingBox Return type: void Description: Draw bounding box (wires) Param[1]: box (type: BoundingBox) Param[2]: color (type: Color) -Function 489: DrawBillboard() (5 input parameters) +Function 491: DrawBillboard() (5 input parameters) Name: DrawBillboard Return type: void Description: Draw a billboard texture @@ -4131,7 +4142,7 @@ Function 489: DrawBillboard() (5 input parameters) Param[3]: position (type: Vector3) Param[4]: scale (type: float) Param[5]: tint (type: Color) -Function 490: DrawBillboardRec() (6 input parameters) +Function 492: DrawBillboardRec() (6 input parameters) Name: DrawBillboardRec Return type: void Description: Draw a billboard texture defined by source @@ -4141,7 +4152,7 @@ Function 490: DrawBillboardRec() (6 input parameters) Param[4]: position (type: Vector3) Param[5]: size (type: Vector2) Param[6]: tint (type: Color) -Function 491: DrawBillboardPro() (9 input parameters) +Function 493: DrawBillboardPro() (9 input parameters) Name: DrawBillboardPro Return type: void Description: Draw a billboard texture defined by source and rotation @@ -4154,13 +4165,13 @@ Function 491: DrawBillboardPro() (9 input parameters) Param[7]: origin (type: Vector2) Param[8]: rotation (type: float) Param[9]: tint (type: Color) -Function 492: UploadMesh() (2 input parameters) +Function 494: UploadMesh() (2 input parameters) Name: UploadMesh Return type: void Description: Upload mesh vertex data in GPU and provide VAO/VBO ids Param[1]: mesh (type: Mesh *) Param[2]: dynamic (type: bool) -Function 493: UpdateMeshBuffer() (5 input parameters) +Function 495: UpdateMeshBuffer() (5 input parameters) Name: UpdateMeshBuffer Return type: void Description: Update mesh vertex data in GPU for a specific buffer index @@ -4169,19 +4180,19 @@ Function 493: UpdateMeshBuffer() (5 input parameters) Param[3]: data (type: const void *) Param[4]: dataSize (type: int) Param[5]: offset (type: int) -Function 494: UnloadMesh() (1 input parameters) +Function 496: UnloadMesh() (1 input parameters) Name: UnloadMesh Return type: void Description: Unload mesh data from CPU and GPU Param[1]: mesh (type: Mesh) -Function 495: DrawMesh() (3 input parameters) +Function 497: DrawMesh() (3 input parameters) Name: DrawMesh Return type: void Description: Draw a 3d mesh with material and transform Param[1]: mesh (type: Mesh) Param[2]: material (type: Material) Param[3]: transform (type: Matrix) -Function 496: DrawMeshInstanced() (4 input parameters) +Function 498: DrawMeshInstanced() (4 input parameters) Name: DrawMeshInstanced Return type: void Description: Draw multiple mesh instances with material and different transforms @@ -4189,35 +4200,35 @@ Function 496: DrawMeshInstanced() (4 input parameters) Param[2]: material (type: Material) Param[3]: transforms (type: const Matrix *) Param[4]: instances (type: int) -Function 497: GetMeshBoundingBox() (1 input parameters) +Function 499: GetMeshBoundingBox() (1 input parameters) Name: GetMeshBoundingBox Return type: BoundingBox Description: Compute mesh bounding box limits Param[1]: mesh (type: Mesh) -Function 498: GenMeshTangents() (1 input parameters) +Function 500: GenMeshTangents() (1 input parameters) Name: GenMeshTangents Return type: void Description: Compute mesh tangents Param[1]: mesh (type: Mesh *) -Function 499: ExportMesh() (2 input parameters) +Function 501: ExportMesh() (2 input parameters) Name: ExportMesh Return type: bool Description: Export mesh data to file, returns true on success Param[1]: mesh (type: Mesh) Param[2]: fileName (type: const char *) -Function 500: ExportMeshAsCode() (2 input parameters) +Function 502: ExportMeshAsCode() (2 input parameters) Name: ExportMeshAsCode Return type: bool Description: Export mesh as code file (.h) defining multiple arrays of vertex attributes Param[1]: mesh (type: Mesh) Param[2]: fileName (type: const char *) -Function 501: GenMeshPoly() (2 input parameters) +Function 503: GenMeshPoly() (2 input parameters) Name: GenMeshPoly Return type: Mesh Description: Generate polygonal mesh Param[1]: sides (type: int) Param[2]: radius (type: float) -Function 502: GenMeshPlane() (4 input parameters) +Function 504: GenMeshPlane() (4 input parameters) Name: GenMeshPlane Return type: Mesh Description: Generate plane mesh (with subdivisions) @@ -4225,42 +4236,42 @@ Function 502: GenMeshPlane() (4 input parameters) Param[2]: length (type: float) Param[3]: resX (type: int) Param[4]: resZ (type: int) -Function 503: GenMeshCube() (3 input parameters) +Function 505: GenMeshCube() (3 input parameters) Name: GenMeshCube Return type: Mesh Description: Generate cuboid mesh Param[1]: width (type: float) Param[2]: height (type: float) Param[3]: length (type: float) -Function 504: GenMeshSphere() (3 input parameters) +Function 506: GenMeshSphere() (3 input parameters) Name: GenMeshSphere Return type: Mesh Description: Generate sphere mesh (standard sphere) Param[1]: radius (type: float) Param[2]: rings (type: int) Param[3]: slices (type: int) -Function 505: GenMeshHemiSphere() (3 input parameters) +Function 507: GenMeshHemiSphere() (3 input parameters) Name: GenMeshHemiSphere Return type: Mesh Description: Generate half-sphere mesh (no bottom cap) Param[1]: radius (type: float) Param[2]: rings (type: int) Param[3]: slices (type: int) -Function 506: GenMeshCylinder() (3 input parameters) +Function 508: GenMeshCylinder() (3 input parameters) Name: GenMeshCylinder Return type: Mesh Description: Generate cylinder mesh Param[1]: radius (type: float) Param[2]: height (type: float) Param[3]: slices (type: int) -Function 507: GenMeshCone() (3 input parameters) +Function 509: GenMeshCone() (3 input parameters) Name: GenMeshCone Return type: Mesh Description: Generate cone/pyramid mesh Param[1]: radius (type: float) Param[2]: height (type: float) Param[3]: slices (type: int) -Function 508: GenMeshTorus() (4 input parameters) +Function 510: GenMeshTorus() (4 input parameters) Name: GenMeshTorus Return type: Mesh Description: Generate torus mesh @@ -4268,7 +4279,7 @@ Function 508: GenMeshTorus() (4 input parameters) Param[2]: size (type: float) Param[3]: radSeg (type: int) Param[4]: sides (type: int) -Function 509: GenMeshKnot() (4 input parameters) +Function 511: GenMeshKnot() (4 input parameters) Name: GenMeshKnot Return type: Mesh Description: Generate trefoil knot mesh @@ -4276,91 +4287,91 @@ Function 509: GenMeshKnot() (4 input parameters) Param[2]: size (type: float) Param[3]: radSeg (type: int) Param[4]: sides (type: int) -Function 510: GenMeshHeightmap() (2 input parameters) +Function 512: GenMeshHeightmap() (2 input parameters) Name: GenMeshHeightmap Return type: Mesh Description: Generate heightmap mesh from image data Param[1]: heightmap (type: Image) Param[2]: size (type: Vector3) -Function 511: GenMeshCubicmap() (2 input parameters) +Function 513: GenMeshCubicmap() (2 input parameters) Name: GenMeshCubicmap Return type: Mesh Description: Generate cubes-based map mesh from image data Param[1]: cubicmap (type: Image) Param[2]: cubeSize (type: Vector3) -Function 512: LoadMaterials() (2 input parameters) +Function 514: LoadMaterials() (2 input parameters) Name: LoadMaterials Return type: Material * Description: Load materials from model file Param[1]: fileName (type: const char *) Param[2]: materialCount (type: int *) -Function 513: LoadMaterialDefault() (0 input parameters) +Function 515: LoadMaterialDefault() (0 input parameters) Name: LoadMaterialDefault Return type: Material Description: Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps) No input parameters -Function 514: IsMaterialValid() (1 input parameters) +Function 516: IsMaterialValid() (1 input parameters) Name: IsMaterialValid Return type: bool Description: Check if a material is valid (shader assigned, map textures loaded in GPU) Param[1]: material (type: Material) -Function 515: UnloadMaterial() (1 input parameters) +Function 517: UnloadMaterial() (1 input parameters) Name: UnloadMaterial Return type: void Description: Unload material from GPU memory (VRAM) Param[1]: material (type: Material) -Function 516: SetMaterialTexture() (3 input parameters) +Function 518: SetMaterialTexture() (3 input parameters) Name: SetMaterialTexture Return type: void Description: Set texture for a material map type (MATERIAL_MAP_DIFFUSE, MATERIAL_MAP_SPECULAR...) Param[1]: material (type: Material *) Param[2]: mapType (type: int) Param[3]: texture (type: Texture2D) -Function 517: SetModelMeshMaterial() (3 input parameters) +Function 519: SetModelMeshMaterial() (3 input parameters) Name: SetModelMeshMaterial Return type: void Description: Set material for a mesh Param[1]: model (type: Model *) Param[2]: meshId (type: int) Param[3]: materialId (type: int) -Function 518: LoadModelAnimations() (2 input parameters) +Function 520: LoadModelAnimations() (2 input parameters) Name: LoadModelAnimations Return type: ModelAnimation * Description: Load model animations from file Param[1]: fileName (type: const char *) Param[2]: animCount (type: int *) -Function 519: UpdateModelAnimation() (3 input parameters) +Function 521: UpdateModelAnimation() (3 input parameters) Name: UpdateModelAnimation Return type: void Description: Update model animation pose (CPU) Param[1]: model (type: Model) Param[2]: anim (type: ModelAnimation) Param[3]: frame (type: int) -Function 520: UpdateModelAnimationBones() (3 input parameters) +Function 522: UpdateModelAnimationBones() (3 input parameters) Name: UpdateModelAnimationBones Return type: void Description: Update model animation mesh bone matrices (GPU skinning) Param[1]: model (type: Model) Param[2]: anim (type: ModelAnimation) Param[3]: frame (type: int) -Function 521: UnloadModelAnimation() (1 input parameters) +Function 523: UnloadModelAnimation() (1 input parameters) Name: UnloadModelAnimation Return type: void Description: Unload animation data Param[1]: anim (type: ModelAnimation) -Function 522: UnloadModelAnimations() (2 input parameters) +Function 524: UnloadModelAnimations() (2 input parameters) Name: UnloadModelAnimations Return type: void Description: Unload animation array data Param[1]: animations (type: ModelAnimation *) Param[2]: animCount (type: int) -Function 523: IsModelAnimationValid() (2 input parameters) +Function 525: IsModelAnimationValid() (2 input parameters) Name: IsModelAnimationValid Return type: bool Description: Check model animation skeleton match Param[1]: model (type: Model) Param[2]: anim (type: ModelAnimation) -Function 524: CheckCollisionSpheres() (4 input parameters) +Function 526: CheckCollisionSpheres() (4 input parameters) Name: CheckCollisionSpheres Return type: bool Description: Check collision between two spheres @@ -4368,40 +4379,40 @@ Function 524: CheckCollisionSpheres() (4 input parameters) Param[2]: radius1 (type: float) Param[3]: center2 (type: Vector3) Param[4]: radius2 (type: float) -Function 525: CheckCollisionBoxes() (2 input parameters) +Function 527: CheckCollisionBoxes() (2 input parameters) Name: CheckCollisionBoxes Return type: bool Description: Check collision between two bounding boxes Param[1]: box1 (type: BoundingBox) Param[2]: box2 (type: BoundingBox) -Function 526: CheckCollisionBoxSphere() (3 input parameters) +Function 528: CheckCollisionBoxSphere() (3 input parameters) Name: CheckCollisionBoxSphere Return type: bool Description: Check collision between box and sphere Param[1]: box (type: BoundingBox) Param[2]: center (type: Vector3) Param[3]: radius (type: float) -Function 527: GetRayCollisionSphere() (3 input parameters) +Function 529: GetRayCollisionSphere() (3 input parameters) Name: GetRayCollisionSphere Return type: RayCollision Description: Get collision info between ray and sphere Param[1]: ray (type: Ray) Param[2]: center (type: Vector3) Param[3]: radius (type: float) -Function 528: GetRayCollisionBox() (2 input parameters) +Function 530: GetRayCollisionBox() (2 input parameters) Name: GetRayCollisionBox Return type: RayCollision Description: Get collision info between ray and box Param[1]: ray (type: Ray) Param[2]: box (type: BoundingBox) -Function 529: GetRayCollisionMesh() (3 input parameters) +Function 531: GetRayCollisionMesh() (3 input parameters) Name: GetRayCollisionMesh Return type: RayCollision Description: Get collision info between ray and mesh Param[1]: ray (type: Ray) Param[2]: mesh (type: Mesh) Param[3]: transform (type: Matrix) -Function 530: GetRayCollisionTriangle() (4 input parameters) +Function 532: GetRayCollisionTriangle() (4 input parameters) Name: GetRayCollisionTriangle Return type: RayCollision Description: Get collision info between ray and triangle @@ -4409,7 +4420,7 @@ Function 530: GetRayCollisionTriangle() (4 input parameters) Param[2]: p1 (type: Vector3) Param[3]: p2 (type: Vector3) Param[4]: p3 (type: Vector3) -Function 531: GetRayCollisionQuad() (5 input parameters) +Function 533: GetRayCollisionQuad() (5 input parameters) Name: GetRayCollisionQuad Return type: RayCollision Description: Get collision info between ray and quad @@ -4418,158 +4429,158 @@ Function 531: GetRayCollisionQuad() (5 input parameters) Param[3]: p2 (type: Vector3) Param[4]: p3 (type: Vector3) Param[5]: p4 (type: Vector3) -Function 532: InitAudioDevice() (0 input parameters) +Function 534: InitAudioDevice() (0 input parameters) Name: InitAudioDevice Return type: void Description: Initialize audio device and context No input parameters -Function 533: CloseAudioDevice() (0 input parameters) +Function 535: CloseAudioDevice() (0 input parameters) Name: CloseAudioDevice Return type: void Description: Close the audio device and context No input parameters -Function 534: IsAudioDeviceReady() (0 input parameters) +Function 536: IsAudioDeviceReady() (0 input parameters) Name: IsAudioDeviceReady Return type: bool Description: Check if audio device has been initialized successfully No input parameters -Function 535: SetMasterVolume() (1 input parameters) +Function 537: SetMasterVolume() (1 input parameters) Name: SetMasterVolume Return type: void Description: Set master volume (listener) Param[1]: volume (type: float) -Function 536: GetMasterVolume() (0 input parameters) +Function 538: GetMasterVolume() (0 input parameters) Name: GetMasterVolume Return type: float Description: Get master volume (listener) No input parameters -Function 537: LoadWave() (1 input parameters) +Function 539: LoadWave() (1 input parameters) Name: LoadWave Return type: Wave Description: Load wave data from file Param[1]: fileName (type: const char *) -Function 538: LoadWaveFromMemory() (3 input parameters) +Function 540: LoadWaveFromMemory() (3 input parameters) Name: LoadWaveFromMemory Return type: Wave Description: Load wave from memory buffer, fileType refers to extension: i.e. '.wav' Param[1]: fileType (type: const char *) Param[2]: fileData (type: const unsigned char *) Param[3]: dataSize (type: int) -Function 539: IsWaveValid() (1 input parameters) +Function 541: IsWaveValid() (1 input parameters) Name: IsWaveValid Return type: bool Description: Checks if wave data is valid (data loaded and parameters) Param[1]: wave (type: Wave) -Function 540: LoadSound() (1 input parameters) +Function 542: LoadSound() (1 input parameters) Name: LoadSound Return type: Sound Description: Load sound from file Param[1]: fileName (type: const char *) -Function 541: LoadSoundFromWave() (1 input parameters) +Function 543: LoadSoundFromWave() (1 input parameters) Name: LoadSoundFromWave Return type: Sound Description: Load sound from wave data Param[1]: wave (type: Wave) -Function 542: LoadSoundAlias() (1 input parameters) +Function 544: LoadSoundAlias() (1 input parameters) Name: LoadSoundAlias Return type: Sound Description: Create a new sound that shares the same sample data as the source sound, does not own the sound data Param[1]: source (type: Sound) -Function 543: IsSoundValid() (1 input parameters) +Function 545: IsSoundValid() (1 input parameters) Name: IsSoundValid Return type: bool Description: Checks if a sound is valid (data loaded and buffers initialized) Param[1]: sound (type: Sound) -Function 544: UpdateSound() (3 input parameters) +Function 546: UpdateSound() (3 input parameters) Name: UpdateSound Return type: void Description: Update sound buffer with new data (default data format: 32 bit float, stereo) Param[1]: sound (type: Sound) Param[2]: data (type: const void *) Param[3]: sampleCount (type: int) -Function 545: UnloadWave() (1 input parameters) +Function 547: UnloadWave() (1 input parameters) Name: UnloadWave Return type: void Description: Unload wave data Param[1]: wave (type: Wave) -Function 546: UnloadSound() (1 input parameters) +Function 548: UnloadSound() (1 input parameters) Name: UnloadSound Return type: void Description: Unload sound Param[1]: sound (type: Sound) -Function 547: UnloadSoundAlias() (1 input parameters) +Function 549: UnloadSoundAlias() (1 input parameters) Name: UnloadSoundAlias Return type: void Description: Unload a sound alias (does not deallocate sample data) Param[1]: alias (type: Sound) -Function 548: ExportWave() (2 input parameters) +Function 550: ExportWave() (2 input parameters) Name: ExportWave Return type: bool Description: Export wave data to file, returns true on success Param[1]: wave (type: Wave) Param[2]: fileName (type: const char *) -Function 549: ExportWaveAsCode() (2 input parameters) +Function 551: ExportWaveAsCode() (2 input parameters) Name: ExportWaveAsCode Return type: bool Description: Export wave sample data to code (.h), returns true on success Param[1]: wave (type: Wave) Param[2]: fileName (type: const char *) -Function 550: PlaySound() (1 input parameters) +Function 552: PlaySound() (1 input parameters) Name: PlaySound Return type: void Description: Play a sound Param[1]: sound (type: Sound) -Function 551: StopSound() (1 input parameters) +Function 553: StopSound() (1 input parameters) Name: StopSound Return type: void Description: Stop playing a sound Param[1]: sound (type: Sound) -Function 552: PauseSound() (1 input parameters) +Function 554: PauseSound() (1 input parameters) Name: PauseSound Return type: void Description: Pause a sound Param[1]: sound (type: Sound) -Function 553: ResumeSound() (1 input parameters) +Function 555: ResumeSound() (1 input parameters) Name: ResumeSound Return type: void Description: Resume a paused sound Param[1]: sound (type: Sound) -Function 554: IsSoundPlaying() (1 input parameters) +Function 556: IsSoundPlaying() (1 input parameters) Name: IsSoundPlaying Return type: bool Description: Check if a sound is currently playing Param[1]: sound (type: Sound) -Function 555: SetSoundVolume() (2 input parameters) +Function 557: SetSoundVolume() (2 input parameters) Name: SetSoundVolume Return type: void Description: Set volume for a sound (1.0 is max level) Param[1]: sound (type: Sound) Param[2]: volume (type: float) -Function 556: SetSoundPitch() (2 input parameters) +Function 558: SetSoundPitch() (2 input parameters) Name: SetSoundPitch Return type: void Description: Set pitch for a sound (1.0 is base level) Param[1]: sound (type: Sound) Param[2]: pitch (type: float) -Function 557: SetSoundPan() (2 input parameters) +Function 559: SetSoundPan() (2 input parameters) Name: SetSoundPan Return type: void Description: Set pan for a sound (-1.0 left, 0.0 center, 1.0 right) Param[1]: sound (type: Sound) Param[2]: pan (type: float) -Function 558: WaveCopy() (1 input parameters) +Function 560: WaveCopy() (1 input parameters) Name: WaveCopy Return type: Wave Description: Copy a wave to a new wave Param[1]: wave (type: Wave) -Function 559: WaveCrop() (3 input parameters) +Function 561: WaveCrop() (3 input parameters) Name: WaveCrop Return type: void Description: Crop a wave to defined frames range Param[1]: wave (type: Wave *) Param[2]: initFrame (type: int) Param[3]: finalFrame (type: int) -Function 560: WaveFormat() (4 input parameters) +Function 562: WaveFormat() (4 input parameters) Name: WaveFormat Return type: void Description: Convert wave data to desired format @@ -4577,203 +4588,203 @@ Function 560: WaveFormat() (4 input parameters) Param[2]: sampleRate (type: int) Param[3]: sampleSize (type: int) Param[4]: channels (type: int) -Function 561: LoadWaveSamples() (1 input parameters) +Function 563: LoadWaveSamples() (1 input parameters) Name: LoadWaveSamples Return type: float * Description: Load samples data from wave as a 32bit float data array Param[1]: wave (type: Wave) -Function 562: UnloadWaveSamples() (1 input parameters) +Function 564: UnloadWaveSamples() (1 input parameters) Name: UnloadWaveSamples Return type: void Description: Unload samples data loaded with LoadWaveSamples() Param[1]: samples (type: float *) -Function 563: LoadMusicStream() (1 input parameters) +Function 565: LoadMusicStream() (1 input parameters) Name: LoadMusicStream Return type: Music Description: Load music stream from file Param[1]: fileName (type: const char *) -Function 564: LoadMusicStreamFromMemory() (3 input parameters) +Function 566: LoadMusicStreamFromMemory() (3 input parameters) Name: LoadMusicStreamFromMemory Return type: Music Description: Load music stream from data Param[1]: fileType (type: const char *) Param[2]: data (type: const unsigned char *) Param[3]: dataSize (type: int) -Function 565: IsMusicValid() (1 input parameters) +Function 567: IsMusicValid() (1 input parameters) Name: IsMusicValid Return type: bool Description: Checks if a music stream is valid (context and buffers initialized) Param[1]: music (type: Music) -Function 566: UnloadMusicStream() (1 input parameters) +Function 568: UnloadMusicStream() (1 input parameters) Name: UnloadMusicStream Return type: void Description: Unload music stream Param[1]: music (type: Music) -Function 567: PlayMusicStream() (1 input parameters) +Function 569: PlayMusicStream() (1 input parameters) Name: PlayMusicStream Return type: void Description: Start music playing Param[1]: music (type: Music) -Function 568: IsMusicStreamPlaying() (1 input parameters) +Function 570: IsMusicStreamPlaying() (1 input parameters) Name: IsMusicStreamPlaying Return type: bool Description: Check if music is playing Param[1]: music (type: Music) -Function 569: UpdateMusicStream() (1 input parameters) +Function 571: UpdateMusicStream() (1 input parameters) Name: UpdateMusicStream Return type: void Description: Updates buffers for music streaming Param[1]: music (type: Music) -Function 570: StopMusicStream() (1 input parameters) +Function 572: StopMusicStream() (1 input parameters) Name: StopMusicStream Return type: void Description: Stop music playing Param[1]: music (type: Music) -Function 571: PauseMusicStream() (1 input parameters) +Function 573: PauseMusicStream() (1 input parameters) Name: PauseMusicStream Return type: void Description: Pause music playing Param[1]: music (type: Music) -Function 572: ResumeMusicStream() (1 input parameters) +Function 574: ResumeMusicStream() (1 input parameters) Name: ResumeMusicStream Return type: void Description: Resume playing paused music Param[1]: music (type: Music) -Function 573: SeekMusicStream() (2 input parameters) +Function 575: SeekMusicStream() (2 input parameters) Name: SeekMusicStream Return type: void Description: Seek music to a position (in seconds) Param[1]: music (type: Music) Param[2]: position (type: float) -Function 574: SetMusicVolume() (2 input parameters) +Function 576: SetMusicVolume() (2 input parameters) Name: SetMusicVolume Return type: void Description: Set volume for music (1.0 is max level) Param[1]: music (type: Music) Param[2]: volume (type: float) -Function 575: SetMusicPitch() (2 input parameters) +Function 577: SetMusicPitch() (2 input parameters) Name: SetMusicPitch Return type: void Description: Set pitch for a music (1.0 is base level) Param[1]: music (type: Music) Param[2]: pitch (type: float) -Function 576: SetMusicPan() (2 input parameters) +Function 578: SetMusicPan() (2 input parameters) Name: SetMusicPan Return type: void Description: Set pan for a music (-1.0 left, 0.0 center, 1.0 right) Param[1]: music (type: Music) Param[2]: pan (type: float) -Function 577: GetMusicTimeLength() (1 input parameters) +Function 579: GetMusicTimeLength() (1 input parameters) Name: GetMusicTimeLength Return type: float Description: Get music time length (in seconds) Param[1]: music (type: Music) -Function 578: GetMusicTimePlayed() (1 input parameters) +Function 580: GetMusicTimePlayed() (1 input parameters) Name: GetMusicTimePlayed Return type: float Description: Get current music time played (in seconds) Param[1]: music (type: Music) -Function 579: LoadAudioStream() (3 input parameters) +Function 581: LoadAudioStream() (3 input parameters) Name: LoadAudioStream Return type: AudioStream Description: Load audio stream (to stream raw audio pcm data) Param[1]: sampleRate (type: unsigned int) Param[2]: sampleSize (type: unsigned int) Param[3]: channels (type: unsigned int) -Function 580: IsAudioStreamValid() (1 input parameters) +Function 582: IsAudioStreamValid() (1 input parameters) Name: IsAudioStreamValid Return type: bool Description: Checks if an audio stream is valid (buffers initialized) Param[1]: stream (type: AudioStream) -Function 581: UnloadAudioStream() (1 input parameters) +Function 583: UnloadAudioStream() (1 input parameters) Name: UnloadAudioStream Return type: void Description: Unload audio stream and free memory Param[1]: stream (type: AudioStream) -Function 582: UpdateAudioStream() (3 input parameters) +Function 584: UpdateAudioStream() (3 input parameters) Name: UpdateAudioStream Return type: void Description: Update audio stream buffers with data Param[1]: stream (type: AudioStream) Param[2]: data (type: const void *) Param[3]: frameCount (type: int) -Function 583: IsAudioStreamProcessed() (1 input parameters) +Function 585: IsAudioStreamProcessed() (1 input parameters) Name: IsAudioStreamProcessed Return type: bool Description: Check if any audio stream buffers requires refill Param[1]: stream (type: AudioStream) -Function 584: PlayAudioStream() (1 input parameters) +Function 586: PlayAudioStream() (1 input parameters) Name: PlayAudioStream Return type: void Description: Play audio stream Param[1]: stream (type: AudioStream) -Function 585: PauseAudioStream() (1 input parameters) +Function 587: PauseAudioStream() (1 input parameters) Name: PauseAudioStream Return type: void Description: Pause audio stream Param[1]: stream (type: AudioStream) -Function 586: ResumeAudioStream() (1 input parameters) +Function 588: ResumeAudioStream() (1 input parameters) Name: ResumeAudioStream Return type: void Description: Resume audio stream Param[1]: stream (type: AudioStream) -Function 587: IsAudioStreamPlaying() (1 input parameters) +Function 589: IsAudioStreamPlaying() (1 input parameters) Name: IsAudioStreamPlaying Return type: bool Description: Check if audio stream is playing Param[1]: stream (type: AudioStream) -Function 588: StopAudioStream() (1 input parameters) +Function 590: StopAudioStream() (1 input parameters) Name: StopAudioStream Return type: void Description: Stop audio stream Param[1]: stream (type: AudioStream) -Function 589: SetAudioStreamVolume() (2 input parameters) +Function 591: SetAudioStreamVolume() (2 input parameters) Name: SetAudioStreamVolume Return type: void Description: Set volume for audio stream (1.0 is max level) Param[1]: stream (type: AudioStream) Param[2]: volume (type: float) -Function 590: SetAudioStreamPitch() (2 input parameters) +Function 592: SetAudioStreamPitch() (2 input parameters) Name: SetAudioStreamPitch Return type: void Description: Set pitch for audio stream (1.0 is base level) Param[1]: stream (type: AudioStream) Param[2]: pitch (type: float) -Function 591: SetAudioStreamPan() (2 input parameters) +Function 593: SetAudioStreamPan() (2 input parameters) Name: SetAudioStreamPan Return type: void Description: Set pan for audio stream (0.5 is centered) Param[1]: stream (type: AudioStream) Param[2]: pan (type: float) -Function 592: SetAudioStreamBufferSizeDefault() (1 input parameters) +Function 594: SetAudioStreamBufferSizeDefault() (1 input parameters) Name: SetAudioStreamBufferSizeDefault Return type: void Description: Default size for new audio streams Param[1]: size (type: int) -Function 593: SetAudioStreamCallback() (2 input parameters) +Function 595: SetAudioStreamCallback() (2 input parameters) Name: SetAudioStreamCallback Return type: void Description: Audio thread callback to request new data Param[1]: stream (type: AudioStream) Param[2]: callback (type: AudioCallback) -Function 594: AttachAudioStreamProcessor() (2 input parameters) +Function 596: AttachAudioStreamProcessor() (2 input parameters) Name: AttachAudioStreamProcessor Return type: void Description: Attach audio stream processor to stream, receives frames x 2 samples as 'float' (stereo) Param[1]: stream (type: AudioStream) Param[2]: processor (type: AudioCallback) -Function 595: DetachAudioStreamProcessor() (2 input parameters) +Function 597: DetachAudioStreamProcessor() (2 input parameters) Name: DetachAudioStreamProcessor Return type: void Description: Detach audio stream processor from stream Param[1]: stream (type: AudioStream) Param[2]: processor (type: AudioCallback) -Function 596: AttachAudioMixedProcessor() (1 input parameters) +Function 598: AttachAudioMixedProcessor() (1 input parameters) Name: AttachAudioMixedProcessor Return type: void Description: Attach audio stream processor to the entire audio pipeline, receives frames x 2 samples as 'float' (stereo) Param[1]: processor (type: AudioCallback) -Function 597: DetachAudioMixedProcessor() (1 input parameters) +Function 599: DetachAudioMixedProcessor() (1 input parameters) Name: DetachAudioMixedProcessor Return type: void Description: Detach audio stream processor from the entire audio pipeline diff --git a/tools/rlparser/output/raylib_api.xml b/tools/rlparser/output/raylib_api.xml index 3853ac74f..c1f9bc818 100644 --- a/tools/rlparser/output/raylib_api.xml +++ b/tools/rlparser/output/raylib_api.xml @@ -280,8 +280,7 @@ - - + @@ -679,7 +678,7 @@ - + @@ -1137,6 +1136,14 @@ + + + + + + + + From e16467e8b69cfad51ba4d380eef2017cebd9292f Mon Sep 17 00:00:00 2001 From: nate Date: Fri, 23 Jan 2026 22:53:57 +1000 Subject: [PATCH 127/232] Clean up Matrix handling and rl* functions to follow convention (#5505) - Use named fields in rlTranslatef and rlScalef instead of array literals - Label implicit row-major to column-major transpose in MatrixToFloatV - Update rlSetUniformMatrix to use rlMatrixToFloat convention --- src/rlgl.h | 47 +++++++++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/src/rlgl.h b/src/rlgl.h index c604553ee..d3e86cf1f 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -1270,12 +1270,12 @@ void rlLoadIdentity(void) // Multiply the current matrix by a translation matrix void rlTranslatef(float x, float y, float z) { - Matrix matTranslation = { - 1.0f, 0.0f, 0.0f, x, - 0.0f, 1.0f, 0.0f, y, - 0.0f, 0.0f, 1.0f, z, - 0.0f, 0.0f, 0.0f, 1.0f - }; + Matrix matTranslation = rlMatrixIdentity(); + + // Set translation component of matrix + matTranslation.m12 = x; + matTranslation.m13 = y; + matTranslation.m14 = z; // NOTE: We transpose matrix with multiplication order *RLGL.State.currentMatrix = rlMatrixMultiply(matTranslation, *RLGL.State.currentMatrix); @@ -1329,12 +1329,12 @@ void rlRotatef(float angle, float x, float y, float z) // Multiply the current matrix by a scaling matrix void rlScalef(float x, float y, float z) { - Matrix matScale = { - x, 0.0f, 0.0f, 0.0f, - 0.0f, y, 0.0f, 0.0f, - 0.0f, 0.0f, z, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f - }; + Matrix matScale = rlMatrixIdentity(); + + // Set scale component of matrix + matScale.m0 = x; + matScale.m5 = y; + matScale.m10 = z; // NOTE: We transpose matrix with multiplication order *RLGL.State.currentMatrix = rlMatrixMultiply(matScale, *RLGL.State.currentMatrix); @@ -1344,6 +1344,7 @@ void rlScalef(float x, float y, float z) void rlMultMatrixf(const float *matf) { // Matrix creation from array + // Conversion from column-major to row-major memory order Matrix mat = { matf[0], matf[4], matf[8], matf[12], matf[1], matf[5], matf[9], matf[13], matf[2], matf[6], matf[10], matf[14], @@ -4463,13 +4464,7 @@ void rlSetVertexAttributeDefault(int locIndex, const void *value, int attribType void rlSetUniformMatrix(int locIndex, Matrix mat) { #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - float matfloat[16] = { - mat.m0, mat.m1, mat.m2, mat.m3, - mat.m4, mat.m5, mat.m6, mat.m7, - mat.m8, mat.m9, mat.m10, mat.m11, - mat.m12, mat.m13, mat.m14, mat.m15 - }; - glUniformMatrix4fv(locIndex, 1, false, matfloat); + glUniformMatrix4fv(locIndex, 1, false, rlMatrixToFloat(mat)); #endif } @@ -5255,17 +5250,17 @@ static int rlGetPixelDataSize(int width, int height, int format) // Get identity matrix static Matrix rlMatrixIdentity(void) { - Matrix result = { - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f - }; + Matrix matIdentity = { 0 }; + matIdentity.m0 = 1.0f; + matIdentity.m5 = 1.0f; + matIdentity.m10 = 1.0f; + matIdentity.m15 = 1.0f; - return result; + return matIdentity; } #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) // Get float array of matrix data +// Explicit conversion to column-major memory layout static rl_float16 rlMatrixToFloatV(Matrix mat) { rl_float16 result = { 0 }; From eda915232d91a48770735fa69bca9e9866dab9f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Dem=C4=8D=C3=A1k?= <71095952+vdemcak@users.noreply.github.com> Date: Fri, 23 Jan 2026 14:13:17 +0100 Subject: [PATCH 128/232] Update miniaudio to v0.11.24 (#5506) --- src/external/miniaudio.h | 879 ++++++++++++++++++++++++--------------- 1 file changed, 537 insertions(+), 342 deletions(-) diff --git a/src/external/miniaudio.h b/src/external/miniaudio.h index b7e7a54dd..24e676bb2 100644 --- a/src/external/miniaudio.h +++ b/src/external/miniaudio.h @@ -1,6 +1,6 @@ /* Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file. -miniaudio - v0.11.23 - 2025-09-11 +miniaudio - v0.11.24 - 2026-01-17 David Reid - mackron@gmail.com @@ -3747,7 +3747,7 @@ extern "C" { #define MA_VERSION_MAJOR 0 #define MA_VERSION_MINOR 11 -#define MA_VERSION_REVISION 23 +#define MA_VERSION_REVISION 24 #define MA_VERSION_STRING MA_XSTRINGIFY(MA_VERSION_MAJOR) "." MA_XSTRINGIFY(MA_VERSION_MINOR) "." MA_XSTRINGIFY(MA_VERSION_REVISION) #if defined(_MSC_VER) && !defined(__clang__) @@ -3858,7 +3858,7 @@ typedef ma_uint16 wchar_t; /* Platform/backend detection. */ -#if defined(_WIN32) || defined(__COSMOPOLITAN__) +#if defined(_WIN32) #define MA_WIN32 #if defined(MA_FORCE_UWP) || (defined(WINAPI_FAMILY) && ((defined(WINAPI_FAMILY_PC_APP) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) || (defined(WINAPI_FAMILY_PHONE_APP) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP))) #define MA_WIN32_UWP @@ -4182,9 +4182,13 @@ typedef enum MA_CHANNEL_AUX_29 = 49, MA_CHANNEL_AUX_30 = 50, MA_CHANNEL_AUX_31 = 51, + + /* Count. */ + MA_CHANNEL_POSITION_COUNT, + + /* Aliases. */ MA_CHANNEL_LEFT = MA_CHANNEL_FRONT_LEFT, MA_CHANNEL_RIGHT = MA_CHANNEL_FRONT_RIGHT, - MA_CHANNEL_POSITION_COUNT = (MA_CHANNEL_AUX_31 + 1) } _ma_channel_position; /* Do not use `_ma_channel_position` directly. Use `ma_channel` instead. */ typedef enum @@ -6604,16 +6608,12 @@ This section contains the APIs for device playback and capture. Here is where yo #if defined(MA_WIN32_DESKTOP) /* DirectSound and WinMM backends are only supported on desktops. */ #define MA_SUPPORT_DSOUND #define MA_SUPPORT_WINMM - - /* Don't enable JACK here if compiling with Cosmopolitan. It'll be enabled in the Linux section below. */ - #if !defined(__COSMOPOLITAN__) - #define MA_SUPPORT_JACK /* JACK is technically supported on Windows, but I don't know how many people use it in practice... */ - #endif + #define MA_SUPPORT_JACK /* JACK is technically supported on Windows, but I don't know how many people use it in practice... */ #endif #endif #if defined(MA_UNIX) && !defined(MA_ORBIS) && !defined(MA_PROSPERO) #if defined(MA_LINUX) - #if !defined(MA_ANDROID) && !defined(__COSMOPOLITAN__) /* ALSA is not supported on Android. */ + #if !defined(MA_ANDROID) && !defined(MA_EMSCRIPTEN) /* ALSA is not supported on Android. */ #define MA_SUPPORT_ALSA #endif #endif @@ -9675,7 +9675,7 @@ Parameters ---------- pBackends (out, optional) A pointer to the buffer that will receive the enabled backends. Set to NULL to retrieve the backend count. Setting - the capacity of the buffer to `MA_BUFFER_COUNT` will guarantee it's large enough for all backends. + the capacity of the buffer to `MA_BACKEND_COUNT` will guarantee it's large enough for all backends. backendCap (in) The capacity of the `pBackends` buffer. @@ -10520,6 +10520,7 @@ typedef struct ma_decoding_backend_vtable** ppCustomDecodingBackendVTables; ma_uint32 customDecodingBackendCount; void* pCustomDecodingBackendUserData; + ma_resampler_config resampling; } ma_resource_manager_config; MA_API ma_resource_manager_config ma_resource_manager_config_init(void); @@ -10847,6 +10848,7 @@ MA_API ma_result ma_node_graph_read_pcm_frames(ma_node_graph* pNodeGraph, void* MA_API ma_uint32 ma_node_graph_get_channels(const ma_node_graph* pNodeGraph); MA_API ma_uint64 ma_node_graph_get_time(const ma_node_graph* pNodeGraph); MA_API ma_result ma_node_graph_set_time(ma_node_graph* pNodeGraph, ma_uint64 globalTime); +MA_API ma_uint32 ma_node_graph_get_processing_size_in_frames(const ma_node_graph* pNodeGraph); @@ -11154,6 +11156,7 @@ typedef struct ma_bool8 isPitchDisabled; /* Pitching can be explicitly disabled with MA_SOUND_FLAG_NO_PITCH to optimize processing. */ ma_bool8 isSpatializationDisabled; /* Spatialization can be explicitly disabled with MA_SOUND_FLAG_NO_SPATIALIZATION. */ ma_uint8 pinnedListenerIndex; /* The index of the listener this node should always use for spatialization. If set to MA_LISTENER_INDEX_CLOSEST the engine will use the closest listener. */ + ma_resampler_config resampling; } ma_engine_node_config; MA_API ma_engine_node_config ma_engine_node_config_init(ma_engine* pEngine, ma_engine_node_type type, ma_uint32 flags); @@ -11168,7 +11171,7 @@ typedef struct ma_uint32 volumeSmoothTimeInPCMFrames; ma_mono_expansion_mode monoExpansionMode; ma_fader fader; - ma_linear_resampler resampler; /* For pitch shift. */ + ma_resampler resampler; /* For pitch shift. */ ma_spatializer spatializer; ma_panner panner; ma_gainer volumeGainer; /* This will only be used if volumeSmoothTimeInPCMFrames is > 0. */ @@ -11224,6 +11227,7 @@ typedef struct ma_uint64 loopPointEndInPCMFrames; ma_sound_end_proc endCallback; /* Fired when the sound reaches the end. Will be fired from the audio thread. Do not restart, uninitialize or otherwise change the state of the sound from here. Instead fire an event or set a variable to indicate to a different thread to change the start of the sound. Will not be fired in response to a scheduled stop with ma_sound_set_stop_time_*(). */ void* pEndCallbackUserData; + ma_resampler_config pitchResampling; #ifndef MA_NO_RESOURCE_MANAGER ma_resource_manager_pipeline_notifications initNotifications; #endif @@ -11242,7 +11246,10 @@ struct ma_sound MA_ATOMIC(4, ma_bool32) atEnd; ma_sound_end_proc endCallback; void* pEndCallbackUserData; - ma_bool8 ownsDataSource; + float* pProcessingCache; /* Will be null if pDataSource is null. */ + ma_uint32 processingCacheFramesRemaining; + ma_uint32 processingCacheCap; + ma_bool8 ownsDataSource; /* We're declaring a resource manager data source object here to save us a malloc when loading a @@ -11300,6 +11307,8 @@ typedef struct ma_vfs* pResourceManagerVFS; /* A pointer to a pre-allocated VFS object to use with the resource manager. This is ignored if pResourceManager is not NULL. */ ma_engine_process_proc onProcess; /* Fired at the end of each call to ma_engine_read_pcm_frames(). For engine's that manage their own internal device (the default configuration), this will be fired from the audio thread, and you do not need to call ma_engine_read_pcm_frames() manually in order to trigger this. */ void* pProcessUserData; /* User data that's passed into onProcess. */ + ma_resampler_config resourceManagerResampling; /* The resampling config to use with the resource manager. */ + ma_resampler_config pitchResampling; /* The resampling config for the pitch and Doppler effects. You will typically want this to be a fast resampler. For high quality stuff, it's recommended that you pre-resample. */ } ma_engine_config; MA_API ma_engine_config ma_engine_config_init(void); @@ -11329,6 +11338,7 @@ struct ma_engine ma_mono_expansion_mode monoExpansionMode; ma_engine_process_proc onProcess; void* pProcessUserData; + ma_resampler_config pitchResamplingConfig; }; MA_API ma_result ma_engine_init(const ma_engine_config* pConfig, ma_engine* pEngine); @@ -11389,8 +11399,12 @@ MA_API ma_engine* ma_sound_get_engine(const ma_sound* pSound); MA_API ma_data_source* ma_sound_get_data_source(const ma_sound* pSound); MA_API ma_result ma_sound_start(ma_sound* pSound); MA_API ma_result ma_sound_stop(ma_sound* pSound); -MA_API ma_result ma_sound_stop_with_fade_in_pcm_frames(ma_sound* pSound, ma_uint64 fadeLengthInFrames); /* Will overwrite any scheduled stop and fade. */ -MA_API ma_result ma_sound_stop_with_fade_in_milliseconds(ma_sound* pSound, ma_uint64 fadeLengthInFrames); /* Will overwrite any scheduled stop and fade. */ +MA_API ma_result ma_sound_stop_with_fade_in_pcm_frames(ma_sound* pSound, ma_uint64 fadeLengthInFrames); /* Will overwrite any scheduled stop and fade. If you want to restart the sound, first reset it with `ma_sound_reset_stop_time_and_fade()`. There are plans to make this less awkward in the future. */ +MA_API ma_result ma_sound_stop_with_fade_in_milliseconds(ma_sound* pSound, ma_uint64 fadeLengthInFrames); /* Will overwrite any scheduled stop and fade. If you want to restart the sound, first reset it with `ma_sound_reset_stop_time_and_fade()`. There are plans to make this less awkward in the future. */ +MA_API void ma_sound_reset_start_time(ma_sound* pSound); +MA_API void ma_sound_reset_stop_time(ma_sound* pSound); +MA_API void ma_sound_reset_fade(ma_sound* pSound); +MA_API void ma_sound_reset_stop_time_and_fade(ma_sound* pSound); /* Resets fades and scheduled stop time. Does not seek back to the start. */ MA_API void ma_sound_set_volume(ma_sound* pSound, float volume); MA_API float ma_sound_get_volume(const ma_sound* pSound); MA_API void ma_sound_set_pan(ma_sound* pSound, float pan); @@ -11643,7 +11657,7 @@ IMPLEMENTATION #endif /* Intrinsics Support */ -#if (defined(MA_X64) || defined(MA_X86)) && !defined(__COSMOPOLITAN__) +#if defined(MA_X64) || defined(MA_X86) #if defined(_MSC_VER) && !defined(__clang__) /* MSVC. */ #if _MSC_VER >= 1400 && !defined(MA_NO_SSE2) /* 2005 */ @@ -12080,7 +12094,7 @@ static MA_INLINE unsigned int ma_disable_denormals(void) } #elif defined(MA_X86) || defined(MA_X64) { - #if defined(MA_SUPPORT_SSE2) && defined(__SSE2__) && !(defined(__TINYC__) || defined(__WATCOMC__) || defined(__COSMOPOLITAN__)) /* <-- Add compilers that lack support for _mm_getcsr() and _mm_setcsr() to this list. */ + #if defined(MA_SUPPORT_SSE2) && defined(__SSE2__) && !(defined(__TINYC__) || defined(__WATCOMC__)) /* <-- Add compilers that lack support for _mm_getcsr() and _mm_setcsr() to this list. */ { prevState = _mm_getcsr(); _mm_setcsr(prevState | MA_MM_DENORMALS_ZERO_MASK | MA_MM_FLUSH_ZERO_MASK); @@ -12120,7 +12134,7 @@ static MA_INLINE void ma_restore_denormals(unsigned int prevState) } #elif defined(MA_X86) || defined(MA_X64) { - #if defined(MA_SUPPORT_SSE2) && defined(__SSE2__) && !(defined(__TINYC__) || defined(__WATCOMC__) || defined(__COSMOPOLITAN__)) /* <-- Add compilers that lack support for _mm_getcsr() and _mm_setcsr() to this list. */ + #if defined(MA_SUPPORT_SSE2) && defined(__SSE2__) && !(defined(__TINYC__) || defined(__WATCOMC__)) /* <-- Add compilers that lack support for _mm_getcsr() and _mm_setcsr() to this list. */ { _mm_setcsr(prevState); } @@ -14241,6 +14255,29 @@ typedef int ma_atomic_memory_order; #define ma_atomic_memory_order_release 4 #define ma_atomic_memory_order_acq_rel 5 #define ma_atomic_memory_order_seq_cst 6 + #define MA_ATOMIC_MSVC_ARM_INTRINSIC_NORETURN(dst, src, order, intrin, ma_atomicType, msvcType) \ + switch (order) \ + { \ + case ma_atomic_memory_order_relaxed: \ + { \ + intrin##_nf((volatile msvcType*)dst, (msvcType)src); \ + } break; \ + case ma_atomic_memory_order_consume: \ + case ma_atomic_memory_order_acquire: \ + { \ + intrin##_acq((volatile msvcType*)dst, (msvcType)src); \ + } break; \ + case ma_atomic_memory_order_release: \ + { \ + intrin##_rel((volatile msvcType*)dst, (msvcType)src); \ + } break; \ + case ma_atomic_memory_order_acq_rel: \ + case ma_atomic_memory_order_seq_cst: \ + default: \ + { \ + intrin((volatile msvcType*)dst, (msvcType)src); \ + } break; \ + } #define MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, intrin, ma_atomicType, msvcType) \ ma_atomicType result; \ switch (order) \ @@ -14284,7 +14321,7 @@ typedef int ma_atomic_memory_order; { #if defined(MA_ARM) { - MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, 0, order, _InterlockedExchange, ma_atomic_flag, long); + MA_ATOMIC_MSVC_ARM_INTRINSIC_NORETURN(dst, 0, order, _InterlockedExchange, ma_atomic_flag, long); } #else { @@ -17593,7 +17630,7 @@ static ma_result ma_thread_create__posix(ma_thread* pThread, ma_thread_priority int priorityStep = (priorityMax - priorityMin) / 7; /* 7 = number of priorities supported by miniaudio. */ struct sched_param sched; - if (pthread_attr_getschedparam(&attr, &sched) == 0) { + if (priorityMin != -1 && priorityMax != -1 && pthread_attr_getschedparam(&attr, &sched) == 0) { if (priority == ma_thread_priority_idle) { sched.sched_priority = priorityMin; } else if (priority == ma_thread_priority_realtime) { @@ -20050,7 +20087,7 @@ Timing struct timespec newTime; clock_gettime(MA_CLOCK_ID, &newTime); - pTimer->counter = (newTime.tv_sec * 1000000000) + newTime.tv_nsec; + pTimer->counter = ((ma_int64)newTime.tv_sec * 1000000000) + newTime.tv_nsec; } static MA_INLINE double ma_timer_get_time_in_seconds(ma_timer* pTimer) @@ -20061,7 +20098,7 @@ Timing struct timespec newTime; clock_gettime(MA_CLOCK_ID, &newTime); - newTimeCounter = (newTime.tv_sec * 1000000000) + newTime.tv_nsec; + newTimeCounter = ((ma_uint64)newTime.tv_sec * 1000000000) + newTime.tv_nsec; oldTimeCounter = pTimer->counter; return (newTimeCounter - oldTimeCounter) / 1000000000.0; @@ -20072,7 +20109,7 @@ Timing struct timeval newTime; gettimeofday(&newTime, NULL); - pTimer->counter = (newTime.tv_sec * 1000000) + newTime.tv_usec; + pTimer->counter = ((ma_int64)newTime.tv_sec * 1000000) + newTime.tv_usec; } static MA_INLINE double ma_timer_get_time_in_seconds(ma_timer* pTimer) @@ -20083,7 +20120,7 @@ Timing struct timeval newTime; gettimeofday(&newTime, NULL); - newTimeCounter = (newTime.tv_sec * 1000000) + newTime.tv_usec; + newTimeCounter = ((ma_uint64)newTime.tv_sec * 1000000) + newTime.tv_usec; oldTimeCounter = pTimer->counter; return (newTimeCounter - oldTimeCounter) / 1000000.0; @@ -31205,6 +31242,7 @@ static ma_result ma_init_pa_mainloop_and_pa_context__pulse(ma_context* pContext, result = ma_result_from_pulse(((ma_pa_context_connect_proc)pContext->pulse.pa_context_connect)((ma_pa_context*)pPulseContext, pServerName, (tryAutoSpawn) ? MA_PA_CONTEXT_NOFLAGS : MA_PA_CONTEXT_NOAUTOSPAWN, NULL)); if (result != MA_SUCCESS) { ma_log_postf(ma_context_get_log(pContext), MA_LOG_LEVEL_ERROR, "[PulseAudio] Failed to connect PulseAudio context."); + ((ma_pa_context_unref_proc)pContext->pulse.pa_context_unref)((ma_pa_context*)(pPulseContext)); ((ma_pa_mainloop_free_proc)pContext->pulse.pa_mainloop_free)((ma_pa_mainloop*)(pMainLoop)); return result; } @@ -31213,6 +31251,7 @@ static ma_result ma_init_pa_mainloop_and_pa_context__pulse(ma_context* pContext, result = ma_wait_for_pa_context_to_connect__pulse(pContext, pMainLoop, pPulseContext); if (result != MA_SUCCESS) { ma_log_postf(ma_context_get_log(pContext), MA_LOG_LEVEL_ERROR, "[PulseAudio] Waiting for connection failed."); + ((ma_pa_context_unref_proc)pContext->pulse.pa_context_unref)((ma_pa_context*)(pPulseContext)); ((ma_pa_mainloop_free_proc)pContext->pulse.pa_mainloop_free)((ma_pa_mainloop*)(pMainLoop)); return result; } @@ -41724,8 +41763,11 @@ static EM_BOOL ma_audio_worklet_process_callback__webaudio(int inputCount, const frameCount = pDevice->capture.internalPeriodSizeInFrames; } + /* + If this is called by the device has not yet been started we need to return early, making sure we output silence to + the output buffer. + */ if (ma_device_get_state(pDevice) != ma_device_state_started) { - /* Fill the output buffer with zero to avoid a noise sound */ for (int i = 0; i < outputCount; i += 1) { MA_ZERO_MEMORY(pOutputs[i].data, pOutputs[i].numberOfChannels * frameCount * sizeof(float)); } @@ -41747,7 +41789,9 @@ static EM_BOOL ma_audio_worklet_process_callback__webaudio(int inputCount, const if (outputCount > 0) { /* If it's a capture-only device, we'll need to output silence. */ if (pDevice->type == ma_device_type_capture) { - MA_ZERO_MEMORY(pOutputs[0].data, frameCount * pDevice->playback.internalChannels * sizeof(float)); + for (int i = 0; i < outputCount; i += 1) { + MA_ZERO_MEMORY(pOutputs[i].data, pOutputs[i].numberOfChannels * frameCount * sizeof(float)); + } } else { ma_device_process_pcm_frames_playback__webaudio(pDevice, frameCount, pDevice->webaudio.pIntermediaryBuffer); @@ -41757,6 +41801,14 @@ static EM_BOOL ma_audio_worklet_process_callback__webaudio(int inputCount, const pOutputs[0].data[frameCount*iChannel + iFrame] = pDevice->webaudio.pIntermediaryBuffer[iFrame*pDevice->playback.internalChannels + iChannel]; } } + + /* + Just above we output data to the first output buffer. Here we just make sure we're putting silence into any + remaining output buffers. + */ + for (int i = 1; i < outputCount; i += 1) { /* <-- Note that the counter starts at 1 instead of 0. */ + MA_ZERO_MEMORY(pOutputs[i].data, pOutputs[i].numberOfChannels * frameCount * sizeof(float)); + } } } @@ -42237,8 +42289,8 @@ static ma_result ma_context_uninit__webaudio(ma_context* pContext) /* Remove the global miniaudio object from window if there are no more references to it. */ EM_ASM({ if (typeof(window.miniaudio) !== 'undefined') { - miniaudio.unlock_event_types.map(function(event_type) { - document.removeEventListener(event_type, miniaudio.unlock, true); + window.miniaudio.unlock_event_types.map(function(event_type) { + document.removeEventListener(event_type, window.miniaudio.unlock, true); }); window.miniaudio.referenceCount -= 1; @@ -50827,15 +50879,15 @@ static /*__attribute__((noinline))*/ ma_result ma_gainer_process_pcm_frames_inte a += d; } } + + pFramesOut = ma_offset_ptr(pFramesOut, interpolatedFrameCount * sizeof(float)); + pFramesIn = ma_offset_ptr(pFramesIn, interpolatedFrameCount * sizeof(float)); } + frameCount -= interpolatedFrameCount; + /* Make sure the timer is updated. */ pGainer->t = (ma_uint32)ma_min(pGainer->t + interpolatedFrameCount, pGainer->config.smoothTimeInFrames); - - /* Adjust our arguments so the next part can work normally. */ - frameCount -= interpolatedFrameCount; - pFramesOut = ma_offset_ptr(pFramesOut, interpolatedFrameCount * sizeof(float)); - pFramesIn = ma_offset_ptr(pFramesIn, interpolatedFrameCount * sizeof(float)); } /* All we need to do here is apply the new gains using an optimized path. */ @@ -52263,13 +52315,16 @@ static float ma_calculate_angular_gain(ma_vec3f dirA, ma_vec3f dirB, float coneI MA_API ma_result ma_spatializer_process_pcm_frames(ma_spatializer* pSpatializer, ma_spatializer_listener* pListener, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount) { - ma_channel* pChannelMapIn = pSpatializer->pChannelMapIn; - ma_channel* pChannelMapOut = pListener->config.pChannelMapOut; + ma_channel* pChannelMapIn; + ma_channel* pChannelMapOut; - if (pSpatializer == NULL) { + if (pSpatializer == NULL || pListener == NULL) { return MA_INVALID_ARGS; } + pChannelMapIn = pSpatializer->pChannelMapIn; + pChannelMapOut = pListener->config.pChannelMapOut; + /* If we're not spatializing we need to run an optimized path. */ if (ma_atomic_load_i32(&pSpatializer->attenuationModel) == ma_attenuation_model_none) { if (ma_spatializer_listener_is_enabled(pListener)) { @@ -52314,23 +52369,17 @@ MA_API ma_result ma_spatializer_process_pcm_frames(ma_spatializer* pSpatializer, We'll need the listener velocity for doppler pitch calculations. The speed of sound is defined by the listener, so we'll grab that here too. */ - if (pListener != NULL) { - listenerVel = ma_spatializer_listener_get_velocity(pListener); - speedOfSound = pListener->config.speedOfSound; - } else { - listenerVel = ma_vec3f_init_3f(0, 0, 0); - speedOfSound = MA_DEFAULT_SPEED_OF_SOUND; - } + listenerVel = ma_spatializer_listener_get_velocity(pListener); + speedOfSound = pListener->config.speedOfSound; - if (pListener == NULL || ma_spatializer_get_positioning(pSpatializer) == ma_positioning_relative) { - /* There's no listener or we're using relative positioning. */ + if (ma_spatializer_get_positioning(pSpatializer) == ma_positioning_relative) { relativePos = ma_spatializer_get_position(pSpatializer); relativeDir = ma_spatializer_get_direction(pSpatializer); } else { /* - We've found a listener and we're using absolute positioning. We need to transform the - sound's position and direction so that it's relative to listener. Later on we'll use - this for determining the factors to apply to each channel to apply the panning effect. + We're using absolute positioning. We need to transform the sound's position and + direction so that it's relative to listener. Later on we'll use this for determining + the factors to apply to each channel to apply the panning effect. */ ma_spatializer_get_relative_position_and_direction(pSpatializer, pListener, &relativePos, &relativeDir); } @@ -54365,7 +54414,7 @@ static ma_bool32 ma_is_spatial_channel_position(ma_channel channelPosition) return MA_FALSE; } - if (channelPosition >= MA_CHANNEL_AUX_0 && channelPosition <= MA_CHANNEL_AUX_31) { + if (channelPosition >= MA_CHANNEL_AUX_0) { return MA_FALSE; } @@ -61653,7 +61702,6 @@ static ma_result ma_default_vfs_info(ma_vfs* pVFS, ma_vfs_file file, ma_file_inf if (result == MA_NOT_IMPLEMENTED) { /* Not implemented. Fall back to seek/tell/seek. */ - ma_result result; ma_int64 cursor; ma_int64 sizeInBytes; @@ -61861,6 +61909,8 @@ Decoding and Encoding Headers. These are auto-generated from a tool. **************************************************************************************************************************************************************/ #if !defined(MA_NO_WAV) && (!defined(MA_NO_DECODING) || !defined(MA_NO_ENCODING)) +#define MA_HAS_WAV + /* dr_wav_h begin */ #ifndef ma_dr_wav_h #define ma_dr_wav_h @@ -61871,7 +61921,7 @@ extern "C" { #define MA_DR_WAV_XSTRINGIFY(x) MA_DR_WAV_STRINGIFY(x) #define MA_DR_WAV_VERSION_MAJOR 0 #define MA_DR_WAV_VERSION_MINOR 14 -#define MA_DR_WAV_VERSION_REVISION 1 +#define MA_DR_WAV_VERSION_REVISION 4 #define MA_DR_WAV_VERSION_STRING MA_DR_WAV_XSTRINGIFY(MA_DR_WAV_VERSION_MAJOR) "." MA_DR_WAV_XSTRINGIFY(MA_DR_WAV_VERSION_MINOR) "." MA_DR_WAV_XSTRINGIFY(MA_DR_WAV_VERSION_REVISION) #include #define MA_DR_WAVE_FORMAT_PCM 0x1 @@ -62294,6 +62344,8 @@ MA_API ma_bool32 ma_dr_wav_fourcc_equal(const ma_uint8* a, const char* b); #endif /* MA_NO_WAV */ #if !defined(MA_NO_FLAC) && !defined(MA_NO_DECODING) +#define MA_HAS_FLAC + /* dr_flac_h begin */ #ifndef ma_dr_flac_h #define ma_dr_flac_h @@ -62304,7 +62356,7 @@ extern "C" { #define MA_DR_FLAC_XSTRINGIFY(x) MA_DR_FLAC_STRINGIFY(x) #define MA_DR_FLAC_VERSION_MAJOR 0 #define MA_DR_FLAC_VERSION_MINOR 13 -#define MA_DR_FLAC_VERSION_REVISION 1 +#define MA_DR_FLAC_VERSION_REVISION 3 #define MA_DR_FLAC_VERSION_STRING MA_DR_FLAC_XSTRINGIFY(MA_DR_FLAC_VERSION_MAJOR) "." MA_DR_FLAC_XSTRINGIFY(MA_DR_FLAC_VERSION_MINOR) "." MA_DR_FLAC_XSTRINGIFY(MA_DR_FLAC_VERSION_REVISION) #include #if defined(_MSC_VER) && _MSC_VER >= 1700 @@ -62392,8 +62444,9 @@ typedef struct typedef struct { ma_uint32 type; - const void* pRawData; ma_uint32 rawDataSize; + ma_uint64 rawDataOffset; + const void* pRawData; union { ma_dr_flac_streaminfo streaminfo; @@ -62439,6 +62492,7 @@ typedef struct ma_uint32 colorDepth; ma_uint32 indexColorCount; ma_uint32 pictureDataSize; + ma_uint64 pictureDataOffset; const ma_uint8* pPictureData; } picture; } data; @@ -62584,6 +62638,8 @@ MA_API ma_bool32 ma_dr_flac_next_cuesheet_track(ma_dr_flac_cuesheet_track_iterat #endif /* MA_NO_FLAC */ #if !defined(MA_NO_MP3) && !defined(MA_NO_DECODING) +#define MA_HAS_MP3 + #ifndef MA_DR_MP3_NO_SIMD #if (defined(MA_NO_NEON) && defined(MA_ARM)) || (defined(MA_NO_SSE2) && (defined(MA_X86) || defined(MA_X64))) #define MA_DR_MP3_NO_SIMD @@ -62600,22 +62656,47 @@ extern "C" { #define MA_DR_MP3_XSTRINGIFY(x) MA_DR_MP3_STRINGIFY(x) #define MA_DR_MP3_VERSION_MAJOR 0 #define MA_DR_MP3_VERSION_MINOR 7 -#define MA_DR_MP3_VERSION_REVISION 1 +#define MA_DR_MP3_VERSION_REVISION 3 #define MA_DR_MP3_VERSION_STRING MA_DR_MP3_XSTRINGIFY(MA_DR_MP3_VERSION_MAJOR) "." MA_DR_MP3_XSTRINGIFY(MA_DR_MP3_VERSION_MINOR) "." MA_DR_MP3_XSTRINGIFY(MA_DR_MP3_VERSION_REVISION) #include #define MA_DR_MP3_MAX_PCM_FRAMES_PER_MP3_FRAME 1152 #define MA_DR_MP3_MAX_SAMPLES_PER_FRAME (MA_DR_MP3_MAX_PCM_FRAMES_PER_MP3_FRAME*2) MA_API void ma_dr_mp3_version(ma_uint32* pMajor, ma_uint32* pMinor, ma_uint32* pRevision); MA_API const char* ma_dr_mp3_version_string(void); +#define MA_DR_MP3_MAX_BITRESERVOIR_BYTES 511 +#define MA_DR_MP3_MAX_FREE_FORMAT_FRAME_SIZE 2304 +#define MA_DR_MP3_MAX_L3_FRAME_PAYLOAD_BYTES MA_DR_MP3_MAX_FREE_FORMAT_FRAME_SIZE typedef struct { int frame_bytes, channels, sample_rate, layer, bitrate_kbps; } ma_dr_mp3dec_frame_info; typedef struct +{ + const ma_uint8 *buf; + int pos, limit; +} ma_dr_mp3_bs; +typedef struct +{ + const ma_uint8 *sfbtab; + ma_uint16 part_23_length, big_values, scalefac_compress; + ma_uint8 global_gain, block_type, mixed_block_flag, n_long_sfb, n_short_sfb; + ma_uint8 table_select[3], region_count[3], subblock_gain[3]; + ma_uint8 preflag, scalefac_scale, count1_table, scfsi; +} ma_dr_mp3_L3_gr_info; +typedef struct +{ + ma_dr_mp3_bs bs; + ma_uint8 maindata[MA_DR_MP3_MAX_BITRESERVOIR_BYTES + MA_DR_MP3_MAX_L3_FRAME_PAYLOAD_BYTES]; + ma_dr_mp3_L3_gr_info gr_info[4]; + float grbuf[2][576], scf[40], syn[18 + 15][2*32]; + ma_uint8 ist_pos[2][39]; +} ma_dr_mp3dec_scratch; +typedef struct { float mdct_overlap[2][9*32], qmf_state[15*2*32]; int reserv, free_format_bytes; ma_uint8 header[4], reserv_buf[511]; + ma_dr_mp3dec_scratch scratch; } ma_dr_mp3dec; MA_API void ma_dr_mp3dec_init(ma_dr_mp3dec *dec); MA_API int ma_dr_mp3dec_decode_frame(ma_dr_mp3dec *dec, const ma_uint8 *mp3, int mp3_bytes, void *pcm, ma_dr_mp3dec_frame_info *info); @@ -63179,7 +63260,6 @@ static ma_result ma_decoder_init_custom_from_memory__internal(const void* pData, /* WAV */ #ifdef ma_dr_wav_h -#define MA_HAS_WAV typedef struct { @@ -63885,7 +63965,6 @@ static ma_result ma_decoder_init_wav_from_memory__internal(const void* pData, si /* FLAC */ #ifdef ma_dr_flac_h -#define MA_HAS_FLAC typedef struct { @@ -64529,7 +64608,6 @@ static ma_result ma_decoder_init_flac_from_memory__internal(const void* pData, s /* MP3 */ #ifdef ma_dr_mp3_h -#define MA_HAS_MP3 typedef struct { @@ -66207,11 +66285,9 @@ static ma_result ma_decoder_init__internal(ma_decoder_read_proc onRead, ma_decod We use trial and error to open a decoder. We prioritize custom decoders so that if they implement the same encoding format they take priority over the built-in decoders. */ + result = ma_decoder_init_custom__internal(pConfig, pDecoder); if (result != MA_SUCCESS) { - result = ma_decoder_init_custom__internal(pConfig, pDecoder); - if (result != MA_SUCCESS) { - onSeek(pDecoder, 0, ma_seek_origin_start); - } + onSeek(pDecoder, 0, ma_seek_origin_start); } /* @@ -66475,14 +66551,6 @@ MA_API ma_result ma_decoder_init_memory(const void* pData, size_t dataSize, cons /* Initialization was successful. Finish up. */ result = ma_decoder__postinit(&config, pDecoder); if (result != MA_SUCCESS) { - /* - The backend was initialized successfully, but for some reason post-initialization failed. This is most likely - due to an out of memory error. We're going to abort with an error here and not try to recover. - */ - if (pDecoder->pBackendVTable != NULL && pDecoder->pBackendVTable->onUninit != NULL) { - pDecoder->pBackendVTable->onUninit(pDecoder->pBackendUserData, &pDecoder->pBackend, &pDecoder->allocationCallbacks); - } - return result; } } else { @@ -66783,11 +66851,9 @@ MA_API ma_result ma_decoder_init_vfs(ma_vfs* pVFS, const char* pFilePath, const We use trial and error to open a decoder. We prioritize custom decoders so that if they implement the same encoding format they take priority over the built-in decoders. */ + result = ma_decoder_init_custom__internal(&config, pDecoder); if (result != MA_SUCCESS) { - result = ma_decoder_init_custom__internal(&config, pDecoder); - if (result != MA_SUCCESS) { - ma_decoder__on_seek_vfs(pDecoder, 0, ma_seek_origin_start); - } + ma_decoder__on_seek_vfs(pDecoder, 0, ma_seek_origin_start); } /* @@ -66916,11 +66982,9 @@ MA_API ma_result ma_decoder_init_vfs_w(ma_vfs* pVFS, const wchar_t* pFilePath, c We use trial and error to open a decoder. We prioritize custom decoders so that if they implement the same encoding format they take priority over the built-in decoders. */ + result = ma_decoder_init_custom__internal(&config, pDecoder); if (result != MA_SUCCESS) { - result = ma_decoder_init_custom__internal(&config, pDecoder); - if (result != MA_SUCCESS) { - ma_decoder__on_seek_vfs(pDecoder, 0, ma_seek_origin_start); - } + ma_decoder__on_seek_vfs(pDecoder, 0, ma_seek_origin_start); } /* @@ -67102,14 +67166,6 @@ MA_API ma_result ma_decoder_init_file(const char* pFilePath, const ma_decoder_co /* Initialization was successful. Finish up. */ result = ma_decoder__postinit(&config, pDecoder); if (result != MA_SUCCESS) { - /* - The backend was initialized successfully, but for some reason post-initialization failed. This is most likely - due to an out of memory error. We're going to abort with an error here and not try to recover. - */ - if (pDecoder->pBackendVTable != NULL && pDecoder->pBackendVTable->onUninit != NULL) { - pDecoder->pBackendVTable->onUninit(pDecoder->pBackendUserData, &pDecoder->pBackend, &pDecoder->allocationCallbacks); - } - return result; } } else { @@ -67252,14 +67308,6 @@ MA_API ma_result ma_decoder_init_file_w(const wchar_t* pFilePath, const ma_decod /* Initialization was successful. Finish up. */ result = ma_decoder__postinit(&config, pDecoder); if (result != MA_SUCCESS) { - /* - The backend was initialized successfully, but for some reason post-initialization failed. This is most likely - due to an out of memory error. We're going to abort with an error here and not try to recover. - */ - if (pDecoder->pBackendVTable != NULL && pDecoder->pBackendVTable->onUninit != NULL) { - pDecoder->pBackendVTable->onUninit(pDecoder->pBackendUserData, &pDecoder->pBackend, &pDecoder->allocationCallbacks); - } - return result; } } else { @@ -69905,6 +69953,7 @@ MA_API ma_resource_manager_config ma_resource_manager_config_init(void) config.decodedSampleRate = 0; config.jobThreadCount = 1; /* A single miniaudio-managed job thread by default. */ config.jobQueueCapacity = MA_JOB_TYPE_RESOURCE_MANAGER_QUEUE_CAPACITY; + config.resampling = ma_resampler_config_init(ma_format_unknown, 0, 0, 0, ma_resample_algorithm_linear); /* Format/channels/rate doesn't matter here. */ /* Flags. */ config.flags = 0; @@ -70158,6 +70207,7 @@ static ma_decoder_config ma_resource_manager__init_decoder_config(ma_resource_ma config.ppCustomBackendVTables = pResourceManager->config.ppCustomDecodingBackendVTables; config.customBackendCount = pResourceManager->config.customDecodingBackendCount; config.pCustomBackendUserData = pResourceManager->config.pCustomDecodingBackendUserData; + config.resampling = pResourceManager->config.resampling; return config; } @@ -71483,13 +71533,13 @@ MA_API ma_result ma_resource_manager_data_buffer_get_data_format(ma_resource_man MA_API ma_result ma_resource_manager_data_buffer_get_cursor_in_pcm_frames(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64* pCursor) { - /* We cannot be using the data source after it's been uninitialized. */ - MA_ASSERT(ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) != MA_UNAVAILABLE); - if (pDataBuffer == NULL || pCursor == NULL) { return MA_INVALID_ARGS; } + /* We cannot be using the data source after it's been uninitialized. */ + MA_ASSERT(ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) != MA_UNAVAILABLE); + *pCursor = 0; switch (ma_resource_manager_data_buffer_node_get_data_supply_type(pDataBuffer->pNode)) @@ -71523,13 +71573,13 @@ MA_API ma_result ma_resource_manager_data_buffer_get_cursor_in_pcm_frames(ma_res MA_API ma_result ma_resource_manager_data_buffer_get_length_in_pcm_frames(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64* pLength) { - /* We cannot be using the data source after it's been uninitialized. */ - MA_ASSERT(ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) != MA_UNAVAILABLE); - if (pDataBuffer == NULL || pLength == NULL) { return MA_INVALID_ARGS; } + /* We cannot be using the data source after it's been uninitialized. */ + MA_ASSERT(ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) != MA_UNAVAILABLE); + if (ma_resource_manager_data_buffer_node_get_data_supply_type(pDataBuffer->pNode) == ma_resource_manager_data_supply_type_unknown) { return MA_BUSY; /* Still loading. */ } @@ -72884,8 +72934,6 @@ static ma_result ma_job_process__resource_manager__free_data_buffer_node(ma_job* return ma_resource_manager_post_job(pResourceManager, pJob); /* Out of order. */ } - ma_resource_manager_data_buffer_node_free(pResourceManager, pDataBufferNode); - /* The event needs to be signalled last. */ if (pJob->data.resourceManager.freeDataBufferNode.pDoneNotification != NULL) { ma_async_notification_signal(pJob->data.resourceManager.freeDataBufferNode.pDoneNotification); @@ -72896,6 +72944,9 @@ static ma_result ma_job_process__resource_manager__free_data_buffer_node(ma_job* } ma_atomic_fetch_add_32(&pDataBufferNode->executionPointer, 1); + + ma_resource_manager_data_buffer_node_free(pResourceManager, pDataBufferNode); + return MA_SUCCESS; } @@ -73768,6 +73819,15 @@ MA_API ma_result ma_node_graph_set_time(ma_node_graph* pNodeGraph, ma_uint64 glo return ma_node_set_time(&pNodeGraph->endpoint, globalTime); /* Global time is just the local time of the endpoint. */ } +MA_API ma_uint32 ma_node_graph_get_processing_size_in_frames(const ma_node_graph* pNodeGraph) +{ + if (pNodeGraph == NULL) { + return 0; + } + + return pNodeGraph->processingSizeInFrames; +} + #define MA_NODE_OUTPUT_BUS_FLAG_HAS_READ 0x01 /* Whether or not this bus ready to read more data. Only used on nodes with multiple output buses. */ @@ -74927,12 +74987,12 @@ MA_API ma_node_state ma_node_get_state_by_time_range(const ma_node* pNode, ma_ui its start time not having been reached yet. Also, the stop time may have also been reached in which case it'll be considered stopped. */ - if (ma_node_get_state_time(pNode, ma_node_state_started) > globalTimeBeg) { - return ma_node_state_stopped; /* Start time has not yet been reached. */ + if (ma_node_get_state_time(pNode, ma_node_state_stopped) < globalTimeBeg) { + return ma_node_state_stopped; /* End time is before the start of the range. */ } - if (ma_node_get_state_time(pNode, ma_node_state_stopped) <= globalTimeEnd) { - return ma_node_state_stopped; /* Stop time has been reached. */ + if (ma_node_get_state_time(pNode, ma_node_state_started) > globalTimeEnd) { + return ma_node_state_stopped; /* Start time is after the end of the range. */ } /* Getting here means the node is marked as started and is within its start/stop times. */ @@ -75012,14 +75072,14 @@ static ma_result ma_node_read_pcm_frames(ma_node* pNode, ma_uint32 outputBusInde return MA_INVALID_ARGS; /* Invalid output bus index. */ } + globalTimeBeg = globalTime; + globalTimeEnd = globalTime + frameCount; + /* Don't do anything if we're in a stopped state. */ - if (ma_node_get_state_by_time_range(pNode, globalTime, globalTime + frameCount) != ma_node_state_started) { + if (ma_node_get_state_by_time_range(pNode, globalTimeBeg, globalTimeEnd) != ma_node_state_started) { return MA_SUCCESS; /* We're in a stopped state. This is not an error - we just need to not read anything. */ } - - globalTimeBeg = globalTime; - globalTimeEnd = globalTime + frameCount; startTime = ma_node_get_state_time(pNode, ma_node_state_started); stopTime = ma_node_get_state_time(pNode, ma_node_state_stopped); @@ -75032,11 +75092,16 @@ static ma_result ma_node_read_pcm_frames(ma_node* pNode, ma_uint32 outputBusInde therefore need to offset it by a number of frames to accommodate. The same thing applies for the stop time. */ - timeOffsetBeg = (globalTimeBeg < startTime) ? (ma_uint32)(globalTimeEnd - startTime) : 0; + timeOffsetBeg = (globalTimeBeg < startTime) ? (ma_uint32)(startTime - globalTimeBeg) : 0; timeOffsetEnd = (globalTimeEnd > stopTime) ? (ma_uint32)(globalTimeEnd - stopTime) : 0; /* Trim based on the start offset. We need to silence the start of the buffer. */ if (timeOffsetBeg > 0) { + MA_ASSERT(timeOffsetBeg <= frameCount); + if (timeOffsetBeg > frameCount) { + timeOffsetBeg = frameCount; + } + ma_silence_pcm_frames(pFramesOut, timeOffsetBeg, ma_format_f32, ma_node_get_output_channels(pNode, outputBusIndex)); pFramesOut += timeOffsetBeg * ma_node_get_output_channels(pNode, outputBusIndex); frameCount -= timeOffsetBeg; @@ -75044,6 +75109,11 @@ static ma_result ma_node_read_pcm_frames(ma_node* pNode, ma_uint32 outputBusInde /* Trim based on the end offset. We don't need to silence the tail section because we'll just have a reduced value written to pFramesRead. */ if (timeOffsetEnd > 0) { + MA_ASSERT(timeOffsetEnd <= frameCount); + if (timeOffsetEnd > frameCount) { + timeOffsetEnd = frameCount; + } + frameCount -= timeOffsetEnd; } @@ -76458,12 +76528,20 @@ static void ma_sound_set_at_end(ma_sound* pSound, ma_bool32 atEnd) MA_ASSERT(pSound != NULL); ma_atomic_exchange_32(&pSound->atEnd, atEnd); + /* + When this function is called the state of the sound will not yet be in a stopped state. This makes it confusing + because an end callback will intuitively expect ma_sound_is_playing() to return false from inside the callback. + I'm therefore no longer firing the callback here and will instead fire it manually in the *next* processing step + when the state should be set to stopped as expected. + */ + #if 0 /* Fire any callbacks or events. */ if (atEnd) { if (pSound->endCallback != NULL) { pSound->endCallback(pSound->pEndCallbackUserData, pSound); } } + #endif } static ma_bool32 ma_sound_get_at_end(const ma_sound* pSound) @@ -76483,6 +76561,7 @@ MA_API ma_engine_node_config ma_engine_node_config_init(ma_engine* pEngine, ma_e config.isPitchDisabled = (flags & MA_SOUND_FLAG_NO_PITCH) != 0; config.isSpatializationDisabled = (flags & MA_SOUND_FLAG_NO_SPATIALIZATION) != 0; config.monoExpansionMode = pEngine->monoExpansionMode; + config.resampling = pEngine->pitchResamplingConfig; return config; } @@ -76509,7 +76588,7 @@ static void ma_engine_node_update_pitch_if_required(ma_engine_node* pEngineNode) if (isUpdateRequired) { float basePitch = (float)pEngineNode->sampleRate / ma_engine_get_sample_rate(pEngineNode->pEngine); - ma_linear_resampler_set_rate_ratio(&pEngineNode->resampler, basePitch * pEngineNode->oldPitch * pEngineNode->oldDopplerPitch); + ma_resampler_set_rate_ratio(&pEngineNode->resampler, basePitch * pEngineNode->oldPitch * pEngineNode->oldDopplerPitch); } } @@ -76528,22 +76607,6 @@ static ma_bool32 ma_engine_node_is_spatialization_enabled(const ma_engine_node* return !ma_atomic_load_explicit_32(&pEngineNode->isSpatializationDisabled, ma_atomic_memory_order_acquire); } -static ma_uint64 ma_engine_node_get_required_input_frame_count(const ma_engine_node* pEngineNode, ma_uint64 outputFrameCount) -{ - ma_uint64 inputFrameCount = 0; - - if (ma_engine_node_is_pitching_enabled(pEngineNode)) { - ma_result result = ma_linear_resampler_get_required_input_frame_count(&pEngineNode->resampler, outputFrameCount, &inputFrameCount); - if (result != MA_SUCCESS) { - inputFrameCount = 0; - } - } else { - inputFrameCount = outputFrameCount; /* No resampling, so 1:1. */ - } - - return inputFrameCount; -} - static ma_result ma_engine_node_set_volume(ma_engine_node* pEngineNode, float volume) { if (pEngineNode == NULL) { @@ -76685,7 +76748,7 @@ static void ma_engine_node_process_pcm_frames__general(ma_engine_node* pEngineNo ma_uint64 resampleFrameCountIn = framesAvailableIn; ma_uint64 resampleFrameCountOut = framesAvailableOut; - ma_linear_resampler_process_pcm_frames(&pEngineNode->resampler, pRunningFramesIn, &resampleFrameCountIn, pWorkingBuffer, &resampleFrameCountOut); + ma_resampler_process_pcm_frames(&pEngineNode->resampler, pRunningFramesIn, &resampleFrameCountIn, pWorkingBuffer, &resampleFrameCountOut); isWorkingBufferValid = MA_TRUE; framesJustProcessedIn = (ma_uint32)resampleFrameCountIn; @@ -76809,6 +76872,11 @@ static void ma_engine_node_process_pcm_frames__sound(ma_node* pNode, const float /* If we're marked at the end we need to stop the sound and do nothing. */ if (ma_sound_at_end(pSound)) { ma_sound_stop(pSound); + + if (pSound->endCallback != NULL) { + pSound->endCallback(pSound->pEndCallbackUserData, pSound); + } + *pFrameCountOut = 0; return; } @@ -76846,55 +76914,74 @@ static void ma_engine_node_process_pcm_frames__sound(ma_node* pNode, const float /* Keep reading until we've read as much as was requested or we reach the end of the data source. */ while (totalFramesRead < frameCount) { ma_uint32 framesRemaining = frameCount - totalFramesRead; - ma_uint32 framesToRead; ma_uint64 framesJustRead; ma_uint32 frameCountIn; ma_uint32 frameCountOut; const float* pRunningFramesIn; float* pRunningFramesOut; - /* - The first thing we need to do is read into the temporary buffer. We can calculate exactly - how many input frames we'll need after resampling. - */ - framesToRead = (ma_uint32)ma_engine_node_get_required_input_frame_count(&pSound->engineNode, framesRemaining); - if (framesToRead > tempCapInFrames) { - framesToRead = tempCapInFrames; - } + /* If there's any input frames sitting in the cache get those processed first. */ + if (pSound->processingCacheFramesRemaining > 0) { + pRunningFramesIn = pSound->pProcessingCache; + frameCountIn = pSound->processingCacheFramesRemaining; - result = ma_data_source_read_pcm_frames(pSound->pDataSource, temp, framesToRead, &framesJustRead); + pRunningFramesOut = ma_offset_pcm_frames_ptr_f32(ppFramesOut[0], totalFramesRead, ma_node_get_output_channels(pNode, 0)); + frameCountOut = framesRemaining; - /* If we reached the end of the sound we'll want to mark it as at the end and stop it. This should never be returned for looping sounds. */ - if (result == MA_AT_END) { - ma_sound_set_at_end(pSound, MA_TRUE); /* This will be set to false in ma_sound_start(). */ - } - - pRunningFramesOut = ma_offset_pcm_frames_ptr_f32(ppFramesOut[0], totalFramesRead, ma_node_get_output_channels(pNode, 0)); - - frameCountIn = (ma_uint32)framesJustRead; - frameCountOut = framesRemaining; - - /* Convert if necessary. */ - if (dataSourceFormat == ma_format_f32) { - /* Fast path. No data conversion necessary. */ - pRunningFramesIn = (float*)temp; ma_engine_node_process_pcm_frames__general(&pSound->engineNode, &pRunningFramesIn, &frameCountIn, &pRunningFramesOut, &frameCountOut); + + MA_ASSERT(frameCountIn <= pSound->processingCacheFramesRemaining); + pSound->processingCacheFramesRemaining -= frameCountIn; + + /* Move any remaining data in the cache down. */ + if (pSound->processingCacheFramesRemaining > 0) { + MA_MOVE_MEMORY(pSound->pProcessingCache, ma_offset_pcm_frames_ptr_f32(pSound->pProcessingCache, frameCountIn, dataSourceChannels), pSound->processingCacheFramesRemaining * ma_get_bytes_per_frame(ma_format_f32, dataSourceChannels)); + } + + totalFramesRead += (ma_uint32)frameCountOut; /* Safe cast. */ + + if (result != MA_SUCCESS || ma_sound_at_end(pSound)) { + break; /* Might have reached the end. */ + } } else { - /* Slow path. Need to do sample format conversion to f32. If we give the f32 buffer the same count as the first temp buffer, we're guaranteed it'll be large enough. */ - float tempf32[MA_DATA_CONVERTER_STACK_BUFFER_SIZE]; /* Do not do `MA_DATA_CONVERTER_STACK_BUFFER_SIZE/sizeof(float)` here like we've done in other places. */ - ma_convert_pcm_frames_format(tempf32, ma_format_f32, temp, dataSourceFormat, framesJustRead, dataSourceChannels, ma_dither_mode_none); + /* Getting here means there's nothing in the cache. Read more data from the data source. */ + if (dataSourceFormat == ma_format_f32) { + /* Fast path. No conversion to f32 necessary. */ + result = ma_data_source_read_pcm_frames(pSound->pDataSource, pSound->pProcessingCache, pSound->processingCacheCap, &framesJustRead); + } else { + /* Slow path. Need to convert to f32. */ + ma_uint64 totalFramesConverted = 0; - /* Now that we have our samples in f32 format we can process like normal. */ - pRunningFramesIn = tempf32; - ma_engine_node_process_pcm_frames__general(&pSound->engineNode, &pRunningFramesIn, &frameCountIn, &pRunningFramesOut, &frameCountOut); - } + while (totalFramesConverted < pSound->processingCacheCap) { + ma_uint64 framesConverted; + ma_uint32 framesToConvertThisIteration = pSound->processingCacheCap - (ma_uint32)totalFramesConverted; + if (framesToConvertThisIteration > tempCapInFrames) { + framesToConvertThisIteration = tempCapInFrames; + } - /* We should have processed all of our input frames since we calculated the required number of input frames at the top. */ - MA_ASSERT(frameCountIn == framesJustRead); - totalFramesRead += (ma_uint32)frameCountOut; /* Safe cast. */ + result = ma_data_source_read_pcm_frames(pSound->pDataSource, temp, framesToConvertThisIteration, &framesConverted); + if (result != MA_SUCCESS) { + break; + } - if (result != MA_SUCCESS || ma_sound_at_end(pSound)) { - break; /* Might have reached the end. */ + ma_convert_pcm_frames_format(ma_offset_pcm_frames_ptr_f32(pSound->pProcessingCache, totalFramesConverted, dataSourceChannels), ma_format_f32, temp, dataSourceFormat, framesConverted, dataSourceChannels, ma_dither_mode_none); + totalFramesConverted += framesConverted; + } + + framesJustRead = totalFramesConverted; + } + + MA_ASSERT(framesJustRead <= pSound->processingCacheCap); + pSound->processingCacheFramesRemaining = (ma_uint32)framesJustRead; + + /* If we reached the end of the sound we'll want to mark it as at the end and stop it. This should never be returned for looping sounds. */ + if (result == MA_AT_END) { + ma_sound_set_at_end(pSound, MA_TRUE); /* This will be set to false in ma_sound_start(). */ + } + + if (result != MA_SUCCESS || ma_sound_at_end(pSound)) { + break; + } } } } @@ -76917,25 +77004,6 @@ static void ma_engine_node_process_pcm_frames__group(ma_node* pNode, const float ma_engine_node_process_pcm_frames__general((ma_engine_node*)pNode, ppFramesIn, pFrameCountIn, ppFramesOut, pFrameCountOut); } -static ma_result ma_engine_node_get_required_input_frame_count__group(ma_node* pNode, ma_uint32 outputFrameCount, ma_uint32* pInputFrameCount) -{ - ma_uint64 inputFrameCount; - - MA_ASSERT(pInputFrameCount != NULL); - - /* Our pitch will affect this calculation. We need to update it. */ - ma_engine_node_update_pitch_if_required((ma_engine_node*)pNode); - - inputFrameCount = ma_engine_node_get_required_input_frame_count((ma_engine_node*)pNode, outputFrameCount); - if (inputFrameCount > 0xFFFFFFFF) { - inputFrameCount = 0xFFFFFFFF; /* Will never happen because miniaudio will only ever process in relatively small chunks. */ - } - - *pInputFrameCount = (ma_uint32)inputFrameCount; - - return MA_SUCCESS; -} - static ma_node_vtable g_ma_engine_node_vtable__sound = { @@ -76949,7 +77017,7 @@ static ma_node_vtable g_ma_engine_node_vtable__sound = static ma_node_vtable g_ma_engine_node_vtable__group = { ma_engine_node_process_pcm_frames__group, - ma_engine_node_get_required_input_frame_count__group, + NULL, /* onGetRequiredInputFrameCount */ 1, /* Groups have one input bus. */ 1, /* Groups have one output bus. */ MA_NODE_FLAG_DIFFERENT_PROCESSING_RATES /* The engine node does resampling so should let miniaudio know about it. */ @@ -76995,9 +77063,10 @@ static ma_result ma_engine_node_get_heap_layout(const ma_engine_node_config* pCo ma_result result; size_t tempHeapSize; ma_node_config baseNodeConfig; - ma_linear_resampler_config resamplerConfig; + ma_resampler_config resamplerConfig; ma_spatializer_config spatializerConfig; ma_gainer_config gainerConfig; + ma_uint32 sampleRate; ma_uint32 channelsIn; ma_uint32 channelsOut; ma_channel defaultStereoChannelMap[2] = {MA_CHANNEL_SIDE_LEFT, MA_CHANNEL_SIDE_RIGHT}; /* <-- Consistent with the default channel map of a stereo listener. Means channel conversion can run on a fast path. */ @@ -77016,6 +77085,7 @@ static ma_result ma_engine_node_get_heap_layout(const ma_engine_node_config* pCo pHeapLayout->sizeInBytes = 0; + sampleRate = (pConfig->sampleRate > 0) ? pConfig->sampleRate : ma_engine_get_sample_rate(pConfig->pEngine); channelsIn = (pConfig->channelsIn != 0) ? pConfig->channelsIn : ma_engine_get_channels(pConfig->pEngine); channelsOut = (pConfig->channelsOut != 0) ? pConfig->channelsOut : ma_engine_get_channels(pConfig->pEngine); @@ -77035,10 +77105,13 @@ static ma_result ma_engine_node_get_heap_layout(const ma_engine_node_config* pCo /* Resmapler. */ - resamplerConfig = ma_linear_resampler_config_init(ma_format_f32, channelsIn, 1, 1); /* Input and output sample rates don't affect the calculation of the heap size. */ - resamplerConfig.lpfOrder = 0; + resamplerConfig = pConfig->resampling; + resamplerConfig.format = ma_format_f32; + resamplerConfig.channels = channelsIn; + resamplerConfig.sampleRateIn = sampleRate; + resamplerConfig.sampleRateOut = ma_engine_get_sample_rate(pConfig->pEngine); - result = ma_linear_resampler_get_heap_size(&resamplerConfig, &tempHeapSize); + result = ma_resampler_get_heap_size(&resamplerConfig, &tempHeapSize); if (result != MA_SUCCESS) { return result; /* Failed to retrieve the size of the heap for the resampler. */ } @@ -77106,7 +77179,7 @@ MA_API ma_result ma_engine_node_init_preallocated(const ma_engine_node_config* p ma_result result; ma_engine_node_heap_layout heapLayout; ma_node_config baseNodeConfig; - ma_linear_resampler_config resamplerConfig; + ma_resampler_config resamplerConfig; ma_fader_config faderConfig; ma_spatializer_config spatializerConfig; ma_panner_config pannerConfig; @@ -77181,10 +77254,13 @@ MA_API ma_result ma_engine_node_init_preallocated(const ma_engine_node_config* p */ /* We'll always do resampling first. */ - resamplerConfig = ma_linear_resampler_config_init(ma_format_f32, baseNodeConfig.pInputChannels[0], pEngineNode->sampleRate, ma_engine_get_sample_rate(pEngineNode->pEngine)); - resamplerConfig.lpfOrder = 0; /* <-- Need to disable low-pass filtering for pitch shifting for now because there's cases where the biquads are becoming unstable. Need to figure out a better fix for this. */ + resamplerConfig = pConfig->resampling; + resamplerConfig.format = ma_format_f32; + resamplerConfig.channels = baseNodeConfig.pInputChannels[0]; + resamplerConfig.sampleRateIn = pEngineNode->sampleRate; + resamplerConfig.sampleRateOut = ma_engine_get_sample_rate(pEngineNode->pEngine); - result = ma_linear_resampler_init_preallocated(&resamplerConfig, ma_offset_ptr(pHeap, heapLayout.resamplerOffset), &pEngineNode->resampler); + result = ma_resampler_init_preallocated(&resamplerConfig, ma_offset_ptr(pHeap, heapLayout.resamplerOffset), &pEngineNode->resampler); if (result != MA_SUCCESS) { goto error1; } @@ -77243,7 +77319,7 @@ MA_API ma_result ma_engine_node_init_preallocated(const ma_engine_node_config* p /* No need for allocation callbacks here because we use a preallocated heap. */ error3: ma_spatializer_uninit(&pEngineNode->spatializer, NULL); -error2: ma_linear_resampler_uninit(&pEngineNode->resampler, NULL); +error2: ma_resampler_uninit(&pEngineNode->resampler, NULL); error1: ma_node_uninit(&pEngineNode->baseNode, NULL); error0: return result; } @@ -77292,7 +77368,7 @@ MA_API void ma_engine_node_uninit(ma_engine_node* pEngineNode, const ma_allocati } ma_spatializer_uninit(&pEngineNode->spatializer, pAllocationCallbacks); - ma_linear_resampler_uninit(&pEngineNode->resampler, pAllocationCallbacks); + ma_resampler_uninit(&pEngineNode->resampler, pAllocationCallbacks); /* Free the heap last. */ if (pEngineNode->_ownsHeap) { @@ -77314,8 +77390,12 @@ MA_API ma_sound_config ma_sound_config_init_2(ma_engine* pEngine) if (pEngine != NULL) { config.monoExpansionMode = pEngine->monoExpansionMode; + config.pitchResampling = pEngine->pitchResamplingConfig; } else { config.monoExpansionMode = ma_mono_expansion_mode_default; + + config.pitchResampling = ma_resampler_config_init(ma_format_f32, 0, 0, 0, ma_resample_algorithm_linear); + config.pitchResampling.linear.lpfOrder = 0; /* <-- Need to disable low-pass filtering for pitch shifting for now because there's cases where the biquads are becoming unstable. Need to figure out a better fix for this. */ } config.rangeEndInPCMFrames = ~((ma_uint64)0); @@ -77337,8 +77417,12 @@ MA_API ma_sound_group_config ma_sound_group_config_init_2(ma_engine* pEngine) if (pEngine != NULL) { config.monoExpansionMode = pEngine->monoExpansionMode; + config.pitchResampling = pEngine->pitchResamplingConfig; } else { config.monoExpansionMode = ma_mono_expansion_mode_default; + + config.pitchResampling = ma_resampler_config_init(ma_format_f32, 0, 0, 0, ma_resample_algorithm_linear); + config.pitchResampling.linear.lpfOrder = 0; /* <-- Need to disable low-pass filtering for pitch shifting for now because there's cases where the biquads are becoming unstable. Need to figure out a better fix for this. */ } return config; @@ -77350,8 +77434,12 @@ MA_API ma_engine_config ma_engine_config_init(void) ma_engine_config config; MA_ZERO_OBJECT(&config); - config.listenerCount = 1; /* Always want at least one listener. */ - config.monoExpansionMode = ma_mono_expansion_mode_default; + config.listenerCount = 1; /* Always want at least one listener. */ + config.monoExpansionMode = ma_mono_expansion_mode_default; + config.resourceManagerResampling = ma_resampler_config_init(ma_format_unknown, 0, 0, 0, ma_resample_algorithm_linear); + + config.pitchResampling = ma_resampler_config_init(ma_format_f32, 0, 0, 0, ma_resample_algorithm_linear); + config.pitchResampling.linear.lpfOrder = 0; /* <-- Need to disable low-pass filtering for pitch shifting for now because there's cases where the biquads are becoming unstable. Need to figure out a better fix for this. */ return config; } @@ -77432,6 +77520,7 @@ MA_API ma_result ma_engine_init(const ma_engine_config* pConfig, ma_engine* pEng pEngine->defaultVolumeSmoothTimeInPCMFrames = engineConfig.defaultVolumeSmoothTimeInPCMFrames; pEngine->onProcess = engineConfig.onProcess; pEngine->pProcessUserData = engineConfig.pProcessUserData; + pEngine->pitchResamplingConfig = engineConfig.pitchResampling; ma_allocation_callbacks_init_copy(&pEngine->allocationCallbacks, &engineConfig.allocationCallbacks); #if !defined(MA_NO_RESOURCE_MANAGER) @@ -77614,6 +77703,7 @@ MA_API ma_result ma_engine_init(const ma_engine_config* pConfig, ma_engine* pEng resourceManagerConfig.decodedSampleRate = ma_engine_get_sample_rate(pEngine); ma_allocation_callbacks_init_copy(&resourceManagerConfig.allocationCallbacks, &pEngine->allocationCallbacks); resourceManagerConfig.pVFS = engineConfig.pResourceManagerVFS; + resourceManagerConfig.resampling = engineConfig.resourceManagerResampling; /* The Emscripten build cannot use threads unless it's targeting pthreads. */ #if defined(MA_EMSCRIPTEN) && !defined(__EMSCRIPTEN_PTHREADS__) @@ -78339,6 +78429,25 @@ static ma_result ma_sound_init_from_data_source_internal(ma_engine* pEngine, con } + /* + When pulling data from a data source we need a processing cache to hold onto unprocessed input data from the data source + after doing resampling. + */ + if (pSound->pDataSource != NULL) { + pSound->processingCacheFramesRemaining = 0; + pSound->processingCacheCap = ma_node_graph_get_processing_size_in_frames(&pEngine->nodeGraph); + if (pSound->processingCacheCap == 0) { + pSound->processingCacheCap = 512; + } + + pSound->pProcessingCache = (float*)ma_calloc(pSound->processingCacheCap * ma_get_bytes_per_frame(ma_format_f32, engineNodeConfig.channelsIn), &pEngine->allocationCallbacks); + if (pSound->pProcessingCache == NULL) { + ma_engine_node_uninit(&pSound->engineNode, &pEngine->allocationCallbacks); + return MA_OUT_OF_MEMORY; + } + } + + /* Apply initial range and looping state to the data source if applicable. */ if (pConfig->rangeBegInPCMFrames != 0 || pConfig->rangeEndInPCMFrames != ~((ma_uint64)0)) { ma_data_source_set_range_in_pcm_frames(ma_sound_get_data_source(pSound), pConfig->rangeBegInPCMFrames, pConfig->rangeEndInPCMFrames); @@ -78576,6 +78685,11 @@ MA_API void ma_sound_uninit(ma_sound* pSound) */ ma_engine_node_uninit(&pSound->engineNode, &pSound->engineNode.pEngine->allocationCallbacks); + if (pSound->pProcessingCache != NULL) { + ma_free(pSound->pProcessingCache, &pSound->engineNode.pEngine->allocationCallbacks); + pSound->pProcessingCache = NULL; + } + /* Once the sound is detached from the group we can guarantee that it won't be referenced by the mixer thread which means it's safe for us to destroy the data source. */ #ifndef MA_NO_RESOURCE_MANAGER if (pSound->ownsDataSource) { @@ -78671,6 +78785,27 @@ MA_API ma_result ma_sound_stop_with_fade_in_milliseconds(ma_sound* pSound, ma_ui return ma_sound_stop_with_fade_in_pcm_frames(pSound, (fadeLengthInMilliseconds * sampleRate) / 1000); } +MA_API void ma_sound_reset_start_time(ma_sound* pSound) +{ + ma_sound_set_start_time_in_pcm_frames(pSound, 0); +} + +MA_API void ma_sound_reset_stop_time(ma_sound* pSound) +{ + ma_sound_set_stop_time_in_pcm_frames(pSound, ~(ma_uint64)0); +} + +MA_API void ma_sound_reset_fade(ma_sound* pSound) +{ + ma_sound_set_fade_in_pcm_frames(pSound, 0, 1, 0); +} + +MA_API void ma_sound_reset_stop_time_and_fade(ma_sound* pSound) +{ + ma_sound_reset_stop_time(pSound); + ma_sound_reset_fade(pSound); +} + MA_API void ma_sound_set_volume(ma_sound* pSound, float volume) { if (pSound == NULL) { @@ -79322,7 +79457,7 @@ MA_API ma_result ma_sound_get_data_format(const ma_sound* pSound, ma_format* pFo } if (pSampleRate != NULL) { - *pSampleRate = pSound->engineNode.resampler.config.sampleRateIn; + *pSampleRate = pSound->engineNode.resampler.sampleRateIn; } if (pChannelMap != NULL) { @@ -82386,7 +82521,6 @@ MA_PRIVATE ma_bool32 ma_dr_wav__on_seek_memory(void* pUserData, int offset, ma_d ma_dr_wav* pWav = (ma_dr_wav*)pUserData; ma_int64 newCursor; MA_DR_WAV_ASSERT(pWav != NULL); - newCursor = pWav->memoryStream.currentReadPos; if (origin == MA_DR_WAV_SEEK_SET) { newCursor = 0; } else if (origin == MA_DR_WAV_SEEK_CUR) { @@ -82440,7 +82574,6 @@ MA_PRIVATE ma_bool32 ma_dr_wav__on_seek_memory_write(void* pUserData, int offset ma_dr_wav* pWav = (ma_dr_wav*)pUserData; ma_int64 newCursor; MA_DR_WAV_ASSERT(pWav != NULL); - newCursor = pWav->memoryStreamWrite.currentWritePos; if (origin == MA_DR_WAV_SEEK_SET) { newCursor = 0; } else if (origin == MA_DR_WAV_SEEK_CUR) { @@ -82449,7 +82582,7 @@ MA_PRIVATE ma_bool32 ma_dr_wav__on_seek_memory_write(void* pUserData, int offset newCursor = (ma_int64)pWav->memoryStreamWrite.dataSize; } else { MA_DR_WAV_ASSERT(!"Invalid seek origin"); - return MA_INVALID_ARGS; + return MA_FALSE; } newCursor += offset; if (newCursor < 0) { @@ -82950,7 +83083,7 @@ MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s16__msadpcm(ma_dr_wav* pWav, ma_ pWav->msadpcm.cachedFrames[2] = pWav->msadpcm.prevFrames[0][0]; pWav->msadpcm.cachedFrames[3] = pWav->msadpcm.prevFrames[0][1]; pWav->msadpcm.cachedFrameCount = 2; - if (pWav->msadpcm.predictor[0] >= ma_dr_wav_countof(coeff1Table)) { + if (pWav->msadpcm.predictor[0] >= ma_dr_wav_countof(coeff1Table) || pWav->msadpcm.predictor[0] >= ma_dr_wav_countof(coeff2Table)) { return totalFramesRead; } } else { @@ -82972,7 +83105,8 @@ MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s16__msadpcm(ma_dr_wav* pWav, ma_ pWav->msadpcm.cachedFrames[2] = pWav->msadpcm.prevFrames[0][1]; pWav->msadpcm.cachedFrames[3] = pWav->msadpcm.prevFrames[1][1]; pWav->msadpcm.cachedFrameCount = 2; - if (pWav->msadpcm.predictor[0] >= ma_dr_wav_countof(coeff1Table) || pWav->msadpcm.predictor[1] >= ma_dr_wav_countof(coeff2Table)) { + if (pWav->msadpcm.predictor[0] >= ma_dr_wav_countof(coeff1Table) || pWav->msadpcm.predictor[0] >= ma_dr_wav_countof(coeff2Table) || + pWav->msadpcm.predictor[1] >= ma_dr_wav_countof(coeff1Table) || pWav->msadpcm.predictor[1] >= ma_dr_wav_countof(coeff2Table)) { return totalFramesRead; } } @@ -83009,6 +83143,9 @@ MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s16__msadpcm(ma_dr_wav* pWav, ma_ if (pWav->channels == 1) { ma_int32 newSample0; ma_int32 newSample1; + if (pWav->msadpcm.predictor[0] >= ma_dr_wav_countof(coeff1Table) || pWav->msadpcm.predictor[0] >= ma_dr_wav_countof(coeff2Table)) { + return totalFramesRead; + } newSample0 = ((pWav->msadpcm.prevFrames[0][1] * coeff1Table[pWav->msadpcm.predictor[0]]) + (pWav->msadpcm.prevFrames[0][0] * coeff2Table[pWav->msadpcm.predictor[0]])) >> 8; newSample0 += nibble0 * pWav->msadpcm.delta[0]; newSample0 = ma_dr_wav_clamp(newSample0, -32768, 32767); @@ -83033,6 +83170,9 @@ MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s16__msadpcm(ma_dr_wav* pWav, ma_ } else { ma_int32 newSample0; ma_int32 newSample1; + if (pWav->msadpcm.predictor[0] >= ma_dr_wav_countof(coeff1Table) || pWav->msadpcm.predictor[0] >= ma_dr_wav_countof(coeff2Table)) { + return totalFramesRead; + } newSample0 = ((pWav->msadpcm.prevFrames[0][1] * coeff1Table[pWav->msadpcm.predictor[0]]) + (pWav->msadpcm.prevFrames[0][0] * coeff2Table[pWav->msadpcm.predictor[0]])) >> 8; newSample0 += nibble0 * pWav->msadpcm.delta[0]; newSample0 = ma_dr_wav_clamp(newSample0, -32768, 32767); @@ -83042,6 +83182,9 @@ MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s16__msadpcm(ma_dr_wav* pWav, ma_ } pWav->msadpcm.prevFrames[0][0] = pWav->msadpcm.prevFrames[0][1]; pWav->msadpcm.prevFrames[0][1] = newSample0; + if (pWav->msadpcm.predictor[1] >= ma_dr_wav_countof(coeff1Table) || pWav->msadpcm.predictor[1] >= ma_dr_wav_countof(coeff2Table)) { + return totalFramesRead; + } newSample1 = ((pWav->msadpcm.prevFrames[1][1] * coeff1Table[pWav->msadpcm.predictor[1]]) + (pWav->msadpcm.prevFrames[1][0] * coeff2Table[pWav->msadpcm.predictor[1]])) >> 8; newSample1 += nibble1 * pWav->msadpcm.delta[1]; newSample1 = ma_dr_wav_clamp(newSample1, -32768, 32767); @@ -84286,6 +84429,10 @@ MA_PRIVATE ma_int16* ma_dr_wav__read_pcm_frames_and_close_s16(ma_dr_wav* pWav, u ma_int16* pSampleData; ma_uint64 framesRead; MA_DR_WAV_ASSERT(pWav != NULL); + if (pWav->channels == 0 || pWav->totalPCMFrameCount > MA_SIZE_MAX / pWav->channels / sizeof(ma_int16)) { + ma_dr_wav_uninit(pWav); + return NULL; + } sampleDataSize = pWav->totalPCMFrameCount * pWav->channels * sizeof(ma_int16); if (sampleDataSize > MA_SIZE_MAX) { ma_dr_wav_uninit(pWav); @@ -84320,6 +84467,10 @@ MA_PRIVATE float* ma_dr_wav__read_pcm_frames_and_close_f32(ma_dr_wav* pWav, unsi float* pSampleData; ma_uint64 framesRead; MA_DR_WAV_ASSERT(pWav != NULL); + if (pWav->channels == 0 || pWav->totalPCMFrameCount > MA_SIZE_MAX / pWav->channels / sizeof(float)) { + ma_dr_wav_uninit(pWav); + return NULL; + } sampleDataSize = pWav->totalPCMFrameCount * pWav->channels * sizeof(float); if (sampleDataSize > MA_SIZE_MAX) { ma_dr_wav_uninit(pWav); @@ -84354,6 +84505,10 @@ MA_PRIVATE ma_int32* ma_dr_wav__read_pcm_frames_and_close_s32(ma_dr_wav* pWav, u ma_int32* pSampleData; ma_uint64 framesRead; MA_DR_WAV_ASSERT(pWav != NULL); + if (pWav->channels == 0 || pWav->totalPCMFrameCount > MA_SIZE_MAX / pWav->channels / sizeof(ma_int32)) { + ma_dr_wav_uninit(pWav); + return NULL; + } sampleDataSize = pWav->totalPCMFrameCount * pWav->channels * sizeof(ma_int32); if (sampleDataSize > MA_SIZE_MAX) { ma_dr_wav_uninit(pWav); @@ -85736,7 +85891,7 @@ static MA_INLINE ma_uint32 ma_dr_flac__clz_lzcnt(ma_dr_flac_cache_t x) { ma_uint64 r; __asm__ __volatile__ ( - "lzcnt{ %1, %0| %0, %1}" : "=r"(r) : "r"(x) : "cc" + "rep; bsr{q %1, %0| %0, %1}" : "=r"(r) : "r"(x) : "cc" ); return (ma_uint32)r; } @@ -85744,11 +85899,11 @@ static MA_INLINE ma_uint32 ma_dr_flac__clz_lzcnt(ma_dr_flac_cache_t x) { ma_uint32 r; __asm__ __volatile__ ( - "lzcnt{l %1, %0| %0, %1}" : "=r"(r) : "r"(x) : "cc" + "rep; bsr{l %1, %0| %0, %1}" : "=r"(r) : "r"(x) : "cc" ); return r; } - #elif defined(MA_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5) && !defined(__ARM_ARCH_6M__) && !defined(MA_64BIT) + #elif defined(MA_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5) && !defined(__ARM_ARCH_6M__) && !(defined(__thumb__) && !defined(__thumb2__)) && !defined(MA_64BIT) { unsigned int r; __asm__ __volatile__ ( @@ -88502,8 +88657,9 @@ static ma_bool32 ma_dr_flac__read_and_decode_metadata(ma_dr_flac_read_proc onRea } runningFilePos += 4; metadata.type = blockType; - metadata.pRawData = NULL; metadata.rawDataSize = 0; + metadata.rawDataOffset = runningFilePos; + metadata.pRawData = NULL; switch (blockType) { case MA_DR_FLAC_METADATA_BLOCK_TYPE_APPLICATION: @@ -88703,46 +88859,117 @@ static ma_bool32 ma_dr_flac__read_and_decode_metadata(ma_dr_flac_read_proc onRea return MA_FALSE; } if (onMeta) { - void* pRawData; - const char* pRunningData; - const char* pRunningDataEnd; - pRawData = ma_dr_flac__malloc_from_callbacks(blockSize, pAllocationCallbacks); - if (pRawData == NULL) { + ma_bool32 result = MA_TRUE; + ma_uint32 blockSizeRemaining = blockSize; + char* pMime = NULL; + char* pDescription = NULL; + void* pPictureData = NULL; + if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.type, 4) != 4) { + result = MA_FALSE; + goto done_flac; + } + blockSizeRemaining -= 4; + metadata.data.picture.type = ma_dr_flac__be2host_32(metadata.data.picture.type); + if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.mimeLength, 4) != 4) { + result = MA_FALSE; + goto done_flac; + } + blockSizeRemaining -= 4; + metadata.data.picture.mimeLength = ma_dr_flac__be2host_32(metadata.data.picture.mimeLength); + pMime = (char*)ma_dr_flac__malloc_from_callbacks(metadata.data.picture.mimeLength + 1, pAllocationCallbacks); + if (pMime == NULL) { + result = MA_FALSE; + goto done_flac; + } + if (blockSizeRemaining < metadata.data.picture.mimeLength || onRead(pUserData, pMime, metadata.data.picture.mimeLength) != metadata.data.picture.mimeLength) { + result = MA_FALSE; + goto done_flac; + } + blockSizeRemaining -= metadata.data.picture.mimeLength; + pMime[metadata.data.picture.mimeLength] = '\0'; + metadata.data.picture.mime = (const char*)pMime; + if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.descriptionLength, 4) != 4) { + result = MA_FALSE; + goto done_flac; + } + blockSizeRemaining -= 4; + metadata.data.picture.descriptionLength = ma_dr_flac__be2host_32(metadata.data.picture.descriptionLength); + pDescription = (char*)ma_dr_flac__malloc_from_callbacks(metadata.data.picture.descriptionLength + 1, pAllocationCallbacks); + if (pDescription == NULL) { + result = MA_FALSE; + goto done_flac; + } + if (blockSizeRemaining < metadata.data.picture.descriptionLength || onRead(pUserData, pDescription, metadata.data.picture.descriptionLength) != metadata.data.picture.descriptionLength) { + result = MA_FALSE; + goto done_flac; + } + blockSizeRemaining -= metadata.data.picture.descriptionLength; + pDescription[metadata.data.picture.descriptionLength] = '\0'; + metadata.data.picture.description = (const char*)pDescription; + if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.width, 4) != 4) { + result = MA_FALSE; + goto done_flac; + } + blockSizeRemaining -= 4; + metadata.data.picture.width = ma_dr_flac__be2host_32(metadata.data.picture.width); + if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.height, 4) != 4) { + result = MA_FALSE; + goto done_flac; + } + blockSizeRemaining -= 4; + metadata.data.picture.height = ma_dr_flac__be2host_32(metadata.data.picture.height); + if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.colorDepth, 4) != 4) { + result = MA_FALSE; + goto done_flac; + } + blockSizeRemaining -= 4; + metadata.data.picture.colorDepth = ma_dr_flac__be2host_32(metadata.data.picture.colorDepth); + if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.indexColorCount, 4) != 4) { + result = MA_FALSE; + goto done_flac; + } + blockSizeRemaining -= 4; + metadata.data.picture.indexColorCount = ma_dr_flac__be2host_32(metadata.data.picture.indexColorCount); + if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.pictureDataSize, 4) != 4) { + result = MA_FALSE; + goto done_flac; + } + blockSizeRemaining -= 4; + metadata.data.picture.pictureDataSize = ma_dr_flac__be2host_32(metadata.data.picture.pictureDataSize); + if (blockSizeRemaining < metadata.data.picture.pictureDataSize) { + result = MA_FALSE; + goto done_flac; + } + metadata.data.picture.pictureDataOffset = runningFilePos + (blockSize - blockSizeRemaining); + #ifndef MA_DR_FLAC_NO_PICTURE_METADATA_MALLOC + pPictureData = ma_dr_flac__malloc_from_callbacks(metadata.data.picture.pictureDataSize, pAllocationCallbacks); + if (pPictureData != NULL) { + if (onRead(pUserData, pPictureData, metadata.data.picture.pictureDataSize) != metadata.data.picture.pictureDataSize) { + result = MA_FALSE; + goto done_flac; + } + } else + #endif + { + if (!onSeek(pUserData, metadata.data.picture.pictureDataSize, MA_DR_FLAC_SEEK_CUR)) { + result = MA_FALSE; + goto done_flac; + } + } + blockSizeRemaining -= metadata.data.picture.pictureDataSize; + (void)blockSizeRemaining; + metadata.data.picture.pPictureData = (const ma_uint8*)pPictureData; + if (metadata.data.picture.pictureDataOffset != 0 || metadata.data.picture.pPictureData != NULL) { + onMeta(pUserDataMD, &metadata); + } else { + } + done_flac: + ma_dr_flac__free_from_callbacks(pMime, pAllocationCallbacks); + ma_dr_flac__free_from_callbacks(pDescription, pAllocationCallbacks); + ma_dr_flac__free_from_callbacks(pPictureData, pAllocationCallbacks); + if (result != MA_TRUE) { return MA_FALSE; } - if (onRead(pUserData, pRawData, blockSize) != blockSize) { - ma_dr_flac__free_from_callbacks(pRawData, pAllocationCallbacks); - return MA_FALSE; - } - metadata.pRawData = pRawData; - metadata.rawDataSize = blockSize; - pRunningData = (const char*)pRawData; - pRunningDataEnd = (const char*)pRawData + blockSize; - metadata.data.picture.type = ma_dr_flac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4; - metadata.data.picture.mimeLength = ma_dr_flac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4; - if ((pRunningDataEnd - pRunningData) - 24 < (ma_int64)metadata.data.picture.mimeLength) { - ma_dr_flac__free_from_callbacks(pRawData, pAllocationCallbacks); - return MA_FALSE; - } - metadata.data.picture.mime = pRunningData; pRunningData += metadata.data.picture.mimeLength; - metadata.data.picture.descriptionLength = ma_dr_flac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4; - if ((pRunningDataEnd - pRunningData) - 20 < (ma_int64)metadata.data.picture.descriptionLength) { - ma_dr_flac__free_from_callbacks(pRawData, pAllocationCallbacks); - return MA_FALSE; - } - metadata.data.picture.description = pRunningData; pRunningData += metadata.data.picture.descriptionLength; - metadata.data.picture.width = ma_dr_flac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4; - metadata.data.picture.height = ma_dr_flac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4; - metadata.data.picture.colorDepth = ma_dr_flac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4; - metadata.data.picture.indexColorCount = ma_dr_flac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4; - metadata.data.picture.pictureDataSize = ma_dr_flac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4; - metadata.data.picture.pPictureData = (const ma_uint8*)pRunningData; - if (pRunningDataEnd - pRunningData < (ma_int64)metadata.data.picture.pictureDataSize) { - ma_dr_flac__free_from_callbacks(pRawData, pAllocationCallbacks); - return MA_FALSE; - } - onMeta(pUserDataMD, &metadata); - ma_dr_flac__free_from_callbacks(pRawData, pAllocationCallbacks); } } break; case MA_DR_FLAC_METADATA_BLOCK_TYPE_PADDING: @@ -88768,12 +88995,15 @@ static ma_bool32 ma_dr_flac__read_and_decode_metadata(ma_dr_flac_read_proc onRea { if (onMeta) { void* pRawData = ma_dr_flac__malloc_from_callbacks(blockSize, pAllocationCallbacks); - if (pRawData == NULL) { - return MA_FALSE; - } - if (onRead(pUserData, pRawData, blockSize) != blockSize) { - ma_dr_flac__free_from_callbacks(pRawData, pAllocationCallbacks); - return MA_FALSE; + if (pRawData != NULL) { + if (onRead(pUserData, pRawData, blockSize) != blockSize) { + ma_dr_flac__free_from_callbacks(pRawData, pAllocationCallbacks); + return MA_FALSE; + } + } else { + if (!onSeek(pUserData, blockSize, MA_DR_FLAC_SEEK_CUR)) { + return MA_FALSE; + } } metadata.pRawData = pRawData; metadata.rawDataSize = blockSize; @@ -89832,7 +90062,6 @@ static ma_bool32 ma_dr_flac__on_seek_memory(void* pUserData, int offset, ma_dr_f ma_dr_flac__memory_stream* memoryStream = (ma_dr_flac__memory_stream*)pUserData; ma_int64 newCursor; MA_DR_FLAC_ASSERT(memoryStream != NULL); - newCursor = memoryStream->currentReadPos; if (origin == MA_DR_FLAC_SEEK_SET) { newCursor = 0; } else if (origin == MA_DR_FLAC_SEEK_CUR) { @@ -92153,56 +92382,41 @@ static type* ma_dr_flac__full_read_and_close_ ## extension (ma_dr_flac* pFlac, u { \ type* pSampleData = NULL; \ ma_uint64 totalPCMFrameCount; \ + type buffer[4096]; \ + ma_uint64 pcmFramesRead; \ + size_t sampleDataBufferSize = sizeof(buffer); \ \ MA_DR_FLAC_ASSERT(pFlac != NULL); \ \ - totalPCMFrameCount = pFlac->totalPCMFrameCount; \ + totalPCMFrameCount = 0; \ \ - if (totalPCMFrameCount == 0) { \ - type buffer[4096]; \ - ma_uint64 pcmFramesRead; \ - size_t sampleDataBufferSize = sizeof(buffer); \ + pSampleData = (type*)ma_dr_flac__malloc_from_callbacks(sampleDataBufferSize, &pFlac->allocationCallbacks); \ + if (pSampleData == NULL) { \ + goto on_error; \ + } \ \ - pSampleData = (type*)ma_dr_flac__malloc_from_callbacks(sampleDataBufferSize, &pFlac->allocationCallbacks); \ - if (pSampleData == NULL) { \ - goto on_error; \ - } \ + while ((pcmFramesRead = (ma_uint64)ma_dr_flac_read_pcm_frames_##extension(pFlac, sizeof(buffer)/sizeof(buffer[0])/pFlac->channels, buffer)) > 0) { \ + if (((totalPCMFrameCount + pcmFramesRead) * pFlac->channels * sizeof(type)) > sampleDataBufferSize) { \ + type* pNewSampleData; \ + size_t newSampleDataBufferSize; \ \ - while ((pcmFramesRead = (ma_uint64)ma_dr_flac_read_pcm_frames_##extension(pFlac, sizeof(buffer)/sizeof(buffer[0])/pFlac->channels, buffer)) > 0) { \ - if (((totalPCMFrameCount + pcmFramesRead) * pFlac->channels * sizeof(type)) > sampleDataBufferSize) { \ - type* pNewSampleData; \ - size_t newSampleDataBufferSize; \ - \ - newSampleDataBufferSize = sampleDataBufferSize * 2; \ - pNewSampleData = (type*)ma_dr_flac__realloc_from_callbacks(pSampleData, newSampleDataBufferSize, sampleDataBufferSize, &pFlac->allocationCallbacks); \ - if (pNewSampleData == NULL) { \ - ma_dr_flac__free_from_callbacks(pSampleData, &pFlac->allocationCallbacks); \ - goto on_error; \ - } \ - \ - sampleDataBufferSize = newSampleDataBufferSize; \ - pSampleData = pNewSampleData; \ + newSampleDataBufferSize = sampleDataBufferSize * 2; \ + pNewSampleData = (type*)ma_dr_flac__realloc_from_callbacks(pSampleData, newSampleDataBufferSize, sampleDataBufferSize, &pFlac->allocationCallbacks); \ + if (pNewSampleData == NULL) { \ + ma_dr_flac__free_from_callbacks(pSampleData, &pFlac->allocationCallbacks); \ + goto on_error; \ } \ \ - MA_DR_FLAC_COPY_MEMORY(pSampleData + (totalPCMFrameCount*pFlac->channels), buffer, (size_t)(pcmFramesRead*pFlac->channels*sizeof(type))); \ - totalPCMFrameCount += pcmFramesRead; \ + sampleDataBufferSize = newSampleDataBufferSize; \ + pSampleData = pNewSampleData; \ } \ \ + MA_DR_FLAC_COPY_MEMORY(pSampleData + (totalPCMFrameCount*pFlac->channels), buffer, (size_t)(pcmFramesRead*pFlac->channels*sizeof(type))); \ + totalPCMFrameCount += pcmFramesRead; \ + } \ + \ \ - MA_DR_FLAC_ZERO_MEMORY(pSampleData + (totalPCMFrameCount*pFlac->channels), (size_t)(sampleDataBufferSize - totalPCMFrameCount*pFlac->channels*sizeof(type))); \ - } else { \ - ma_uint64 dataSize = totalPCMFrameCount*pFlac->channels*sizeof(type); \ - if (dataSize > (ma_uint64)MA_SIZE_MAX) { \ - goto on_error; \ - } \ - \ - pSampleData = (type*)ma_dr_flac__malloc_from_callbacks((size_t)dataSize, &pFlac->allocationCallbacks); \ - if (pSampleData == NULL) { \ - goto on_error; \ - } \ - \ - totalPCMFrameCount = ma_dr_flac_read_pcm_frames_##extension(pFlac, pFlac->totalPCMFrameCount, pSampleData); \ - } \ + MA_DR_FLAC_ZERO_MEMORY(pSampleData + (totalPCMFrameCount*pFlac->channels), (size_t)(sampleDataBufferSize - totalPCMFrameCount*pFlac->channels*sizeof(type))); \ \ if (sampleRateOut) *sampleRateOut = pFlac->sampleRate; \ if (channelsOut) *channelsOut = pFlac->channels; \ @@ -92488,12 +92702,9 @@ MA_API const char* ma_dr_mp3_version_string(void) #define MA_DR_MP3_NO_SIMD #endif #define MA_DR_MP3_OFFSET_PTR(p, offset) ((void*)((ma_uint8*)(p) + (offset))) -#define MA_DR_MP3_MAX_FREE_FORMAT_FRAME_SIZE 2304 #ifndef MA_DR_MP3_MAX_FRAME_SYNC_MATCHES #define MA_DR_MP3_MAX_FRAME_SYNC_MATCHES 10 #endif -#define MA_DR_MP3_MAX_L3_FRAME_PAYLOAD_BYTES MA_DR_MP3_MAX_FREE_FORMAT_FRAME_SIZE -#define MA_DR_MP3_MAX_BITRESERVOIR_BYTES 511 #define MA_DR_MP3_SHORT_BLOCK_TYPE 2 #define MA_DR_MP3_STOP_BLOCK_TYPE 3 #define MA_DR_MP3_MODE_MONO 3 @@ -92543,7 +92754,7 @@ MA_API const char* ma_dr_mp3_version_string(void) #define MA_DR_MP3_VMUL_S(x, s) _mm_mul_ps(x, _mm_set1_ps(s)) #define MA_DR_MP3_VREV(x) _mm_shuffle_ps(x, x, _MM_SHUFFLE(0, 1, 2, 3)) typedef __m128 ma_dr_mp3_f4; -#if defined(_MSC_VER) || defined(MA_DR_MP3_ONLY_SIMD) +#if (defined(_MSC_VER) || defined(MA_DR_MP3_ONLY_SIMD)) && !defined(__clang__) #define ma_dr_mp3_cpuid __cpuid #else static __inline__ __attribute__((always_inline)) void ma_dr_mp3_cpuid(int CPUInfo[], const int InfoType) @@ -92659,11 +92870,6 @@ static __inline__ __attribute__((always_inline)) ma_int32 ma_dr_mp3_clip_int16_a #define MA_DR_MP3_FREE(p) free((p)) #endif typedef struct -{ - const ma_uint8 *buf; - int pos, limit; -} ma_dr_mp3_bs; -typedef struct { float scf[3*64]; ma_uint8 total_bands, stereo_bands, bitalloc[64], scfcod[64]; @@ -92672,22 +92878,6 @@ typedef struct { ma_uint8 tab_offset, code_tab_width, band_count; } ma_dr_mp3_L12_subband_alloc; -typedef struct -{ - const ma_uint8 *sfbtab; - ma_uint16 part_23_length, big_values, scalefac_compress; - ma_uint8 global_gain, block_type, mixed_block_flag, n_long_sfb, n_short_sfb; - ma_uint8 table_select[3], region_count[3], subblock_gain[3]; - ma_uint8 preflag, scalefac_scale, count1_table, scfsi; -} ma_dr_mp3_L3_gr_info; -typedef struct -{ - ma_dr_mp3_bs bs; - ma_uint8 maindata[MA_DR_MP3_MAX_BITRESERVOIR_BYTES + MA_DR_MP3_MAX_L3_FRAME_PAYLOAD_BYTES]; - ma_dr_mp3_L3_gr_info gr_info[4]; - float grbuf[2][576], scf[40], syn[18 + 15][2*32]; - ma_uint8 ist_pos[2][39]; -} ma_dr_mp3dec_scratch; static void ma_dr_mp3_bs_init(ma_dr_mp3_bs *bs, const ma_uint8 *data, int bytes) { bs->buf = data; @@ -93070,7 +93260,7 @@ static float ma_dr_mp3_L3_ldexp_q2(float y, int exp_q2) } while ((exp_q2 -= e) > 0); return y; } -#if (defined(__GNUC__) && (__GNUC__ >= 14)) && !defined(__clang__) +#if (defined(__GNUC__) && (__GNUC__ >= 13)) && !defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstringop-overflow" #endif @@ -93132,7 +93322,7 @@ static void ma_dr_mp3_L3_decode_scalefactors(const ma_uint8 *hdr, ma_uint8 *ist_ scf[i] = ma_dr_mp3_L3_ldexp_q2(gain, iscf[i] << scf_shift); } } -#if (defined(__GNUC__) && (__GNUC__ >= 14)) && !defined(__clang__) +#if (defined(__GNUC__) && (__GNUC__ >= 13)) && !defined(__clang__) #pragma GCC diagnostic pop #endif static const float ma_dr_mp3_g_pow43[129 + 16] = { @@ -94060,7 +94250,6 @@ MA_API int ma_dr_mp3dec_decode_frame(ma_dr_mp3dec *dec, const ma_uint8 *mp3, int int i = 0, igr, frame_size = 0, success = 1; const ma_uint8 *hdr; ma_dr_mp3_bs bs_frame[1]; - ma_dr_mp3dec_scratch scratch; if (mp3_bytes > 4 && dec->header[0] == 0xff && ma_dr_mp3_hdr_compare(dec->header, mp3)) { frame_size = ma_dr_mp3_hdr_frame_bytes(mp3, dec->free_format_bytes) + ma_dr_mp3_hdr_padding(mp3); @@ -94093,23 +94282,23 @@ MA_API int ma_dr_mp3dec_decode_frame(ma_dr_mp3dec *dec, const ma_uint8 *mp3, int } if (info->layer == 3) { - int main_data_begin = ma_dr_mp3_L3_read_side_info(bs_frame, scratch.gr_info, hdr); + int main_data_begin = ma_dr_mp3_L3_read_side_info(bs_frame, dec->scratch.gr_info, hdr); if (main_data_begin < 0 || bs_frame->pos > bs_frame->limit) { ma_dr_mp3dec_init(dec); return 0; } - success = ma_dr_mp3_L3_restore_reservoir(dec, bs_frame, &scratch, main_data_begin); + success = ma_dr_mp3_L3_restore_reservoir(dec, bs_frame, &dec->scratch, main_data_begin); if (success && pcm != NULL) { for (igr = 0; igr < (MA_DR_MP3_HDR_TEST_MPEG1(hdr) ? 2 : 1); igr++, pcm = MA_DR_MP3_OFFSET_PTR(pcm, sizeof(ma_dr_mp3d_sample_t)*576*info->channels)) { - MA_DR_MP3_ZERO_MEMORY(scratch.grbuf[0], 576*2*sizeof(float)); - ma_dr_mp3_L3_decode(dec, &scratch, scratch.gr_info + igr*info->channels, info->channels); - ma_dr_mp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 18, info->channels, (ma_dr_mp3d_sample_t*)pcm, scratch.syn[0]); + MA_DR_MP3_ZERO_MEMORY(dec->scratch.grbuf[0], 576*2*sizeof(float)); + ma_dr_mp3_L3_decode(dec, &dec->scratch, dec->scratch.gr_info + igr*info->channels, info->channels); + ma_dr_mp3d_synth_granule(dec->qmf_state, dec->scratch.grbuf[0], 18, info->channels, (ma_dr_mp3d_sample_t*)pcm, dec->scratch.syn[0]); } } - ma_dr_mp3_L3_save_reservoir(dec, &scratch); + ma_dr_mp3_L3_save_reservoir(dec, &dec->scratch); } else { #ifdef MA_DR_MP3_ONLY_MP3 @@ -94120,15 +94309,15 @@ MA_API int ma_dr_mp3dec_decode_frame(ma_dr_mp3dec *dec, const ma_uint8 *mp3, int return ma_dr_mp3_hdr_frame_samples(hdr); } ma_dr_mp3_L12_read_scale_info(hdr, bs_frame, sci); - MA_DR_MP3_ZERO_MEMORY(scratch.grbuf[0], 576*2*sizeof(float)); + MA_DR_MP3_ZERO_MEMORY(dec->scratch.grbuf[0], 576*2*sizeof(float)); for (i = 0, igr = 0; igr < 3; igr++) { - if (12 == (i += ma_dr_mp3_L12_dequantize_granule(scratch.grbuf[0] + i, bs_frame, sci, info->layer | 1))) + if (12 == (i += ma_dr_mp3_L12_dequantize_granule(dec->scratch.grbuf[0] + i, bs_frame, sci, info->layer | 1))) { i = 0; - ma_dr_mp3_L12_apply_scf_384(sci, sci->scf + igr, scratch.grbuf[0]); - ma_dr_mp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 12, info->channels, (ma_dr_mp3d_sample_t*)pcm, scratch.syn[0]); - MA_DR_MP3_ZERO_MEMORY(scratch.grbuf[0], 576*2*sizeof(float)); + ma_dr_mp3_L12_apply_scf_384(sci, sci->scf + igr, dec->scratch.grbuf[0]); + ma_dr_mp3d_synth_granule(dec->qmf_state, dec->scratch.grbuf[0], 12, info->channels, (ma_dr_mp3d_sample_t*)pcm, dec->scratch.syn[0]); + MA_DR_MP3_ZERO_MEMORY(dec->scratch.grbuf[0], 576*2*sizeof(float)); pcm = MA_DR_MP3_OFFSET_PTR(pcm, sizeof(ma_dr_mp3d_sample_t)*384*info->channels); } if (bs_frame->pos > bs_frame->limit) @@ -94587,19 +94776,22 @@ static ma_bool32 ma_dr_mp3_init_internal(ma_dr_mp3* pMP3, ma_dr_mp3_read_proc on ((ma_uint32)ape[25] << 8) | ((ma_uint32)ape[26] << 16) | ((ma_uint32)ape[27] << 24); - streamEndOffset -= 32 + tagSize; - streamLen -= 32 + tagSize; - if (onMeta != NULL) { - if (onSeek(pUserData, streamEndOffset, MA_DR_MP3_SEEK_END)) { - size_t apeTagSize = (size_t)tagSize + 32; - ma_uint8* pTagData = (ma_uint8*)ma_dr_mp3_malloc(apeTagSize, pAllocationCallbacks); - if (pTagData != NULL) { - if (onRead(pUserData, pTagData, apeTagSize) == apeTagSize) { - ma_dr_mp3__on_meta(pMP3, MA_DR_MP3_METADATA_TYPE_APE, pTagData, apeTagSize); + if (32 + tagSize < streamLen) { + streamEndOffset -= 32 + tagSize; + streamLen -= 32 + tagSize; + if (onMeta != NULL) { + if (onSeek(pUserData, streamEndOffset, MA_DR_MP3_SEEK_END)) { + size_t apeTagSize = (size_t)tagSize + 32; + ma_uint8* pTagData = (ma_uint8*)ma_dr_mp3_malloc(apeTagSize, pAllocationCallbacks); + if (pTagData != NULL) { + if (onRead(pUserData, pTagData, apeTagSize) == apeTagSize) { + ma_dr_mp3__on_meta(pMP3, MA_DR_MP3_METADATA_TYPE_APE, pTagData, apeTagSize); + } + ma_dr_mp3_free(pTagData, pAllocationCallbacks); } - ma_dr_mp3_free(pTagData, pAllocationCallbacks); } } + } else { } } } @@ -94687,7 +94879,6 @@ static ma_bool32 ma_dr_mp3_init_internal(ma_dr_mp3* pMP3, ma_dr_mp3_read_proc on { ma_dr_mp3_bs bs; ma_dr_mp3_L3_gr_info grInfo[4]; - const ma_uint8* pTagData = pFirstFrameData; ma_dr_mp3_bs_init(&bs, pFirstFrameData + MA_DR_MP3_HDR_SIZE, firstFrameInfo.frame_bytes - MA_DR_MP3_HDR_SIZE); if (MA_DR_MP3_HDR_IS_CRC(pFirstFrameData)) { ma_dr_mp3_bs_get_bits(&bs, 16); @@ -94695,6 +94886,7 @@ static ma_bool32 ma_dr_mp3_init_internal(ma_dr_mp3* pMP3, ma_dr_mp3_read_proc on if (ma_dr_mp3_L3_read_side_info(&bs, grInfo, pFirstFrameData) >= 0) { ma_bool32 isXing = MA_FALSE; ma_bool32 isInfo = MA_FALSE; + const ma_uint8* pTagData; const ma_uint8* pTagDataBeg; pTagDataBeg = pFirstFrameData + MA_DR_MP3_HDR_SIZE + (bs.pos/8); pTagData = pTagDataBeg; @@ -94794,7 +94986,6 @@ static ma_bool32 ma_dr_mp3__on_seek_memory(void* pUserData, int byteOffset, ma_d ma_dr_mp3* pMP3 = (ma_dr_mp3*)pUserData; ma_int64 newCursor; MA_DR_MP3_ASSERT(pMP3 != NULL); - newCursor = pMP3->memory.currentReadPos; if (origin == MA_DR_MP3_SEEK_SET) { newCursor = 0; } else if (origin == MA_DR_MP3_SEEK_CUR) { @@ -95445,6 +95636,8 @@ static float* ma_dr_mp3__full_read_and_close_f32(ma_dr_mp3* pMP3, ma_dr_mp3_conf pNewFrames = (float*)ma_dr_mp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks); if (pNewFrames == NULL) { ma_dr_mp3__free_from_callbacks(pFrames, &pMP3->allocationCallbacks); + pFrames = NULL; + totalFramesRead = 0; break; } pFrames = pNewFrames; @@ -95496,6 +95689,8 @@ static ma_int16* ma_dr_mp3__full_read_and_close_s16(ma_dr_mp3* pMP3, ma_dr_mp3_c pNewFrames = (ma_int16*)ma_dr_mp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks); if (pNewFrames == NULL) { ma_dr_mp3__free_from_callbacks(pFrames, &pMP3->allocationCallbacks); + pFrames = NULL; + totalFramesRead = 0; break; } pFrames = pNewFrames; @@ -95646,4 +95841,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ \ No newline at end of file +*/ From b21d7f234b8ca1e8887830f7b4d65edeba22e3ac Mon Sep 17 00:00:00 2001 From: The4codeblocks <72419529+The4codeblocks@users.noreply.github.com> Date: Fri, 23 Jan 2026 11:08:10 -0500 Subject: [PATCH 129/232] [raymath] `QuaternionFromVector3ToVector3()`, math is wrong (#5508) * the math in QuaternionFromVector3ToVector3 is wrong * fix styling --- src/raymath.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/raymath.h b/src/raymath.h index 7b58d410e..91c858e2a 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -2369,7 +2369,7 @@ RMAPI Quaternion QuaternionFromVector3ToVector3(Vector3 from, Vector3 to) result.x = cross.x; result.y = cross.y; result.z = cross.z; - result.w = 1.0f + cos2Theta; + result.w = sqrtf(cross.x*cross.x + cross.y*cross.y + cross.z*cross.z + cos2Theta*cos2Theta) + cos2Theta; // sqrtf(Vector3DotProduct(cross, cross) + cos2Theta * cos2Theta) + cos2Theta // QuaternionNormalize(q); // NOTE: Normalize to essentially nlerp the original and identity to 0.5 From a33ae4a8ef8809cc7f3c078651bd91e6e56591f4 Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 23 Jan 2026 17:11:37 +0100 Subject: [PATCH 130/232] Update raymath.h --- src/raymath.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/raymath.h b/src/raymath.h index 91c858e2a..0f9cbc38b 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -2363,13 +2363,13 @@ RMAPI Quaternion QuaternionFromVector3ToVector3(Vector3 from, Vector3 to) { Quaternion result = { 0 }; - float cos2Theta = (from.x*to.x + from.y*to.y + from.z*to.z); // Vector3DotProduct(from, to) + float cos2Theta = (from.x*to.x + from.y*to.y + from.z*to.z); // Vector3DotProduct(from, to) Vector3 cross = { from.y*to.z - from.z*to.y, from.z*to.x - from.x*to.z, from.x*to.y - from.y*to.x }; // Vector3CrossProduct(from, to) result.x = cross.x; result.y = cross.y; result.z = cross.z; - result.w = sqrtf(cross.x*cross.x + cross.y*cross.y + cross.z*cross.z + cos2Theta*cos2Theta) + cos2Theta; // sqrtf(Vector3DotProduct(cross, cross) + cos2Theta * cos2Theta) + cos2Theta + result.w = sqrtf(cross.x*cross.x + cross.y*cross.y + cross.z*cross.z + cos2Theta*cos2Theta) + cos2Theta; // QuaternionNormalize(q); // NOTE: Normalize to essentially nlerp the original and identity to 0.5 From 70a63f7c626bf1982d7ee9d09e7a2ca943fcf046 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Dem=C4=8D=C3=A1k?= <71095952+vdemcak@users.noreply.github.com> Date: Sat, 24 Jan 2026 21:21:43 +0100 Subject: [PATCH 131/232] [web] Fix Emscripten's Closure compiler error: undeclared canvas variable (#5507) * Fix Emscripten Closure compiler error: undeclared canvas variable * Fix hardcoded canvas IDs in web targets --- src/platforms/rcore_web.c | 9 +++++---- src/platforms/rcore_web_emscripten.c | 5 +++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/platforms/rcore_web.c b/src/platforms/rcore_web.c index b0a145f67..986197b9d 100644 --- a/src/platforms/rcore_web.c +++ b/src/platforms/rcore_web.c @@ -316,15 +316,16 @@ void ToggleBorderlessWindowed(void) // 2. The style unset handles the possibility of a width="value%" like on the default shell.html file EM_ASM ( + const canvasId = UTF8ToString($0); setTimeout(function() { Module.requestFullscreen(false, true); setTimeout(function() { - canvas.style.width="unset"; + document.querySelector(canvasId).style.width="unset"; }, 100); }, 100); - ); + , platform.canvasId); FLAG_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); } } @@ -1238,9 +1239,9 @@ int InitPlatform(void) // 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"); + const canvas = document.querySelector(UTF8ToString($0)); Module.canvas = canvas; - }); + }, platform.canvasId); // Load memory framebuffer with desired screen size // NOTE: Despite using a software framebuffer for blitting, GLFW still creates a WebGL canvas, diff --git a/src/platforms/rcore_web_emscripten.c b/src/platforms/rcore_web_emscripten.c index ad26077f4..ba2489a31 100644 --- a/src/platforms/rcore_web_emscripten.c +++ b/src/platforms/rcore_web_emscripten.c @@ -280,15 +280,16 @@ void ToggleBorderlessWindowed(void) // 2. The style unset handles the possibility of a width="value%" like on the default shell.html file EM_ASM ( + const canvasId = UTF8ToString($0); setTimeout(function() { Module.requestFullscreen(false, true); setTimeout(function() { - canvas.style.width="unset"; + document.querySelector(canvasId).style.width="unset"; }, 100); }, 100); - ); + , platform.canvasId); FLAG_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); } } From afe74c1c707a7c0d9499fb63f0120466c719c6fe Mon Sep 17 00:00:00 2001 From: Maicon Santana Date: Sat, 24 Jan 2026 20:53:22 +0000 Subject: [PATCH 132/232] Refactor int to float missing parse (#5503) * refactor int to float parse * Reverting as requested --------- Co-authored-by: Maicon --- examples/core/core_2d_camera_platformer.c | 8 ++--- examples/core/core_automation_events.c | 8 ++--- examples/core/core_viewport_scaling.c | 4 +-- examples/models/models_rlgl_solar_system.c | 36 +++++++++---------- examples/models/models_waving_cubes.c | 6 ++-- examples/shaders/shaders_game_of_life.c | 4 +-- examples/shapes/shapes_colors_palette.c | 2 +- examples/shapes/shapes_digital_clock.c | 2 +- examples/shapes/shapes_double_pendulum.c | 8 ++--- examples/text/text_font_sdf.c | 4 +-- examples/text/text_rectangle_bounds.c | 6 ++-- examples/text/text_unicode_emojis.c | 8 ++--- examples/text/text_words_alignment.c | 2 +- examples/textures/textures_bunnymark.c | 8 ++--- .../textures/textures_cellular_automata.c | 2 +- examples/textures/textures_fog_of_war.c | 4 +-- examples/textures/textures_image_processing.c | 2 +- examples/textures/textures_image_text.c | 2 +- examples/textures/textures_sprite_button.c | 2 +- examples/textures/textures_sprite_explosion.c | 4 +-- src/rtextures.c | 2 +- 21 files changed, 62 insertions(+), 62 deletions(-) diff --git a/examples/core/core_2d_camera_platformer.c b/examples/core/core_2d_camera_platformer.c index 45bad4015..49d0a940c 100644 --- a/examples/core/core_2d_camera_platformer.c +++ b/examples/core/core_2d_camera_platformer.c @@ -226,10 +226,10 @@ void UpdateCameraCenterInsideMap(Camera2D *camera, Player *player, EnvItem *envI Vector2 max = GetWorldToScreen2D((Vector2){ maxX, maxY }, *camera); Vector2 min = GetWorldToScreen2D((Vector2){ minX, minY }, *camera); - if (max.x < width) camera->offset.x = width - (max.x - width/2); - if (max.y < height) camera->offset.y = height - (max.y - height/2); - if (min.x > 0) camera->offset.x = width/2 - min.x; - if (min.y > 0) camera->offset.y = height/2 - min.y; + if (max.x < width) camera->offset.x = width - (max.x - (float)width/2); + if (max.y < height) camera->offset.y = height - (max.y - (float)height/2); + if (min.x > 0) camera->offset.x = (float)width/2 - min.x; + if (min.y > 0) camera->offset.y = (float)height/2 - min.y; } void UpdateCameraCenterSmoothFollow(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height) diff --git a/examples/core/core_automation_events.c b/examples/core/core_automation_events.c index b98b37c69..50204187f 100644 --- a/examples/core/core_automation_events.c +++ b/examples/core/core_automation_events.c @@ -225,10 +225,10 @@ int main(void) Vector2 max = GetWorldToScreen2D((Vector2){ maxX, maxY }, camera); Vector2 min = GetWorldToScreen2D((Vector2){ minX, minY }, camera); - if (max.x < screenWidth) camera.offset.x = screenWidth - (max.x - screenWidth/2); - if (max.y < screenHeight) camera.offset.y = screenHeight - (max.y - screenHeight/2); - if (min.x > 0) camera.offset.x = screenWidth/2 - min.x; - if (min.y > 0) camera.offset.y = screenHeight/2 - min.y; + if (max.x < screenWidth) camera.offset.x = screenWidth - (max.x - (float)screenWidth/2); + if (max.y < screenHeight) camera.offset.y = screenHeight - (max.y - (float)screenHeight/2); + if (min.x > 0) camera.offset.x = (float)screenWidth/2 - min.x; + if (min.y > 0) camera.offset.y = (float)screenHeight/2 - min.y; //---------------------------------------------------------------------------------- // Events management diff --git a/examples/core/core_viewport_scaling.c b/examples/core/core_viewport_scaling.c index 6ff5ac9c4..4a608e96d 100644 --- a/examples/core/core_viewport_scaling.c +++ b/examples/core/core_viewport_scaling.c @@ -216,7 +216,7 @@ static void KeepAspectCenteredInteger(int screenWidth, int screenHeight, int gam static void KeepHeightCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect) { - const float resizeRatio = (float)(screenHeight/gameHeight); + const float resizeRatio = (float)screenHeight/gameHeight; sourceRect->x = 0.0f; sourceRect->y = 0.0f; sourceRect->width = (float)(int)(screenWidth/resizeRatio); @@ -230,7 +230,7 @@ static void KeepHeightCenteredInteger(int screenWidth, int screenHeight, int gam static void KeepWidthCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect) { - const float resizeRatio = (float)(screenWidth/gameWidth); + const float resizeRatio = (float)screenWidth/gameWidth; sourceRect->x = 0.0f; sourceRect->y = 0.0f; sourceRect->width = (float)gameWidth; diff --git a/examples/models/models_rlgl_solar_system.c b/examples/models/models_rlgl_solar_system.c index d8d86d69a..0988ede8d 100644 --- a/examples/models/models_rlgl_solar_system.c +++ b/examples/models/models_rlgl_solar_system.c @@ -148,25 +148,25 @@ void DrawSphereBasic(Color color) { for (int j = 0; j < slices; j++) { - rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*i))*sinf(DEG2RAD*(j*360/slices)), - sinf(DEG2RAD*(270+(180/(rings + 1))*i)), - cosf(DEG2RAD*(270+(180/(rings + 1))*i))*cosf(DEG2RAD*(j*360/slices))); - rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360/slices)), - sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))), - cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360/slices))); - rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*(j*360/slices)), - sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))), - cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*(j*360/slices))); + rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*i))*sinf(DEG2RAD*(j*360.0f/slices)), + sinf(DEG2RAD*(270+(180.0f/(rings + 1))*i)), + cosf(DEG2RAD*(270+(180.0f/(rings + 1))*i))*cosf(DEG2RAD*(j*360.0f/slices))); + rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360.0f/slices)), + sinf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1))), + cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360.0f/slices))); + rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*sinf(DEG2RAD*(j*360.0f/slices)), + sinf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1))), + cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*cosf(DEG2RAD*(j*360.0f/slices))); - rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*i))*sinf(DEG2RAD*(j*360/slices)), - sinf(DEG2RAD*(270+(180/(rings + 1))*i)), - cosf(DEG2RAD*(270+(180/(rings + 1))*i))*cosf(DEG2RAD*(j*360/slices))); - rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i)))*sinf(DEG2RAD*((j+1)*360/slices)), - sinf(DEG2RAD*(270+(180/(rings + 1))*(i))), - cosf(DEG2RAD*(270+(180/(rings + 1))*(i)))*cosf(DEG2RAD*((j+1)*360/slices))); - rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360/slices)), - sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))), - cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360/slices))); + rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*i))*sinf(DEG2RAD*(j*360.0f/slices)), + sinf(DEG2RAD*(270+(180.0f/(rings + 1))*i)), + cosf(DEG2RAD*(270+(180.0f/(rings + 1))*i))*cosf(DEG2RAD*(j*360.0f/slices))); + rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i)))*sinf(DEG2RAD*((j+1)*360.0f/slices)), + sinf(DEG2RAD*(270+(180.0f/(rings + 1))*(i))), + cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i)))*cosf(DEG2RAD*((j+1)*360.0f/slices))); + rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360.0f/slices)), + sinf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1))), + cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360.0f/slices))); } } rlEnd(); diff --git a/examples/models/models_waving_cubes.c b/examples/models/models_waving_cubes.c index 7996c1c8a..36e8bccf7 100644 --- a/examples/models/models_waving_cubes.c +++ b/examples/models/models_waving_cubes.c @@ -85,9 +85,9 @@ int main(void) // Calculate the cube position Vector3 cubePos = { - (float)(x - numBlocks/2)*(scale*3.0f) + scatter, - (float)(y - numBlocks/2)*(scale*2.0f) + scatter, - (float)(z - numBlocks/2)*(scale*3.0f) + scatter + (float)(x - (float)numBlocks/2)*(scale*3.0f) + scatter, + (float)(y - (float)numBlocks/2)*(scale*2.0f) + scatter, + (float)(z - (float)numBlocks/2)*(scale*3.0f) + scatter }; // Pick a color with a hue depending on cube position for the rainbow color effect diff --git a/examples/shaders/shaders_game_of_life.c b/examples/shaders/shaders_game_of_life.c index 9b9242a0d..0ae91b756 100644 --- a/examples/shaders/shaders_game_of_life.c +++ b/examples/shaders/shaders_game_of_life.c @@ -258,8 +258,8 @@ int main(void) 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; + offsetX = worldWidth*presetPatterns[preset].position.x - (float)windowWidth/zoom/2.0f; + offsetY = worldHeight*presetPatterns[preset].position.y - (float)windowHeight/zoom/2.0f; } // Check window draw inside world limits diff --git a/examples/shapes/shapes_colors_palette.c b/examples/shapes/shapes_colors_palette.c index 9fbcf3063..44da323eb 100644 --- a/examples/shapes/shapes_colors_palette.c +++ b/examples/shapes/shapes_colors_palette.c @@ -45,7 +45,7 @@ int main(void) for (int i = 0; i < MAX_COLORS_COUNT; i++) { colorsRecs[i].x = 20.0f + 100.0f *(i%7) + 10.0f *(i%7); - colorsRecs[i].y = 80.0f + 100.0f *(i/7) + 10.0f *(i/7); + colorsRecs[i].y = 80.0f + 100.0f *((float)i/7) + 10.0f *((float)i/7); colorsRecs[i].width = 100.0f; colorsRecs[i].height = 100.0f; } diff --git a/examples/shapes/shapes_digital_clock.c b/examples/shapes/shapes_digital_clock.c index cca3f3c44..fb9ae80e6 100644 --- a/examples/shapes/shapes_digital_clock.c +++ b/examples/shapes/shapes_digital_clock.c @@ -311,7 +311,7 @@ static void DrawDisplaySegment(Vector2 center, int length, int thick, bool verti (Vector2){ center.x + thick/2.0f, center.y - length/2.0f }, // Point 3 (Vector2){ center.x - thick/2.0f, center.y + length/2.0f }, // Point 4 (Vector2){ center.x + thick/2.0f, center.y + length/2.0f }, // Point 5 - (Vector2){ center.x, center.y + length/2 + thick/2.0f }, // Point 6 + (Vector2){ center.x, center.y + (float)length/2 + thick/2.0f }, // Point 6 }; DrawTriangleStrip(segmentPointsV, 6, color); diff --git a/examples/shapes/shapes_double_pendulum.c b/examples/shapes/shapes_double_pendulum.c index 760d66203..5b357c9f3 100644 --- a/examples/shapes/shapes_double_pendulum.c +++ b/examples/shapes/shapes_double_pendulum.c @@ -49,8 +49,8 @@ int main(void) float totalM = m1 + m2; Vector2 previousPosition = CalculateDoublePendulumEndPoint(l1, theta1, l2, theta2); - previousPosition.x += (screenWidth/2); - previousPosition.y += (screenHeight/2 - 100); + previousPosition.x += ((float)screenWidth/2); + previousPosition.y += ((float)screenHeight/2 - 100); // Scale length float L1 = l1*lengthScaler; @@ -105,8 +105,8 @@ int main(void) // Calculate position Vector2 currentPosition = CalculateDoublePendulumEndPoint(l1, theta1, l2, theta2); - currentPosition.x += screenWidth/2; - currentPosition.y += screenHeight/2 - 100; + currentPosition.x += (float)screenWidth/2; + currentPosition.y += (float)screenHeight/2 - 100; // Draw to render texture BeginTextureMode(target); diff --git a/examples/text/text_font_sdf.c b/examples/text/text_font_sdf.c index 744450fa6..42b7495e2 100644 --- a/examples/text/text_font_sdf.c +++ b/examples/text/text_font_sdf.c @@ -97,8 +97,8 @@ int main(void) if (currentFont == 0) textSize = MeasureTextEx(fontDefault, msg, fontSize, 0); else textSize = MeasureTextEx(fontSDF, msg, fontSize, 0); - fontPosition.x = GetScreenWidth()/2 - textSize.x/2; - fontPosition.y = GetScreenHeight()/2 - textSize.y/2 + 80; + fontPosition.x = (float)GetScreenWidth()/2 - textSize.x/2; + fontPosition.y = (float)GetScreenHeight()/2 - textSize.y/2 + 80; //---------------------------------------------------------------------------------- // Draw diff --git a/examples/text/text_rectangle_bounds.c b/examples/text/text_rectangle_bounds.c index e180ae475..b87a3a956 100644 --- a/examples/text/text_rectangle_bounds.c +++ b/examples/text/text_rectangle_bounds.c @@ -226,7 +226,7 @@ static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec, { if (!wordWrap) { - textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor; + textOffsetY += (font.baseSize + (float)font.baseSize/2)*scaleFactor; textOffsetX = 0; } } @@ -234,7 +234,7 @@ static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec, { if (!wordWrap && ((textOffsetX + glyphWidth) > rec.width)) { - textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor; + textOffsetY += (font.baseSize + (float)font.baseSize/2)*scaleFactor; textOffsetX = 0; } @@ -258,7 +258,7 @@ static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec, if (wordWrap && (i == endLine)) { - textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor; + textOffsetY += (font.baseSize + (float)font.baseSize/2)*scaleFactor; textOffsetX = 0; startLine = endLine; endLine = -1; diff --git a/examples/text/text_unicode_emojis.c b/examples/text/text_unicode_emojis.c index 00712745d..240b50052 100644 --- a/examples/text/text_unicode_emojis.c +++ b/examples/text/text_unicode_emojis.c @@ -277,7 +277,7 @@ int main(void) DrawTriangle(a, b, c, emoji[selected].color); // Draw the main text message - Rectangle textRect = { msgRect.x + horizontalPadding/2, msgRect.y + verticalPadding/2, msgRect.width - horizontalPadding, msgRect.height }; + Rectangle textRect = { msgRect.x + (float)horizontalPadding/2, msgRect.y + (float)verticalPadding/2, msgRect.width - horizontalPadding, msgRect.height }; DrawTextBoxed(*font, messages[message].text, textRect, (float)font->baseSize, 1.0f, true, WHITE); // Draw the info text below the main message @@ -421,7 +421,7 @@ static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec, { if (!wordWrap) { - textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor; + textOffsetY += (font.baseSize + (float)font.baseSize/2)*scaleFactor; textOffsetX = 0; } } @@ -429,7 +429,7 @@ static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec, { if (!wordWrap && ((textOffsetX + glyphWidth) > rec.width)) { - textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor; + textOffsetY += (font.baseSize + (float)font.baseSize/2)*scaleFactor; textOffsetX = 0; } @@ -453,7 +453,7 @@ static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec, if (wordWrap && (i == endLine)) { - textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor; + textOffsetY += (font.baseSize + (float)font.baseSize/2)*scaleFactor; textOffsetX = 0; startLine = endLine; endLine = -1; diff --git a/examples/text/text_words_alignment.c b/examples/text/text_words_alignment.c index dbd9cd03e..f7ffa74af 100644 --- a/examples/text/text_words_alignment.c +++ b/examples/text/text_words_alignment.c @@ -41,7 +41,7 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [text] example - words alignment"); // Define the rectangle we will draw the text in - Rectangle textContainerRect = (Rectangle){ screenWidth/2-screenWidth/4, screenHeight/2-screenHeight/3, screenWidth/2, screenHeight*2/3 }; + Rectangle textContainerRect = (Rectangle){ (float)screenWidth/2-(float)screenWidth/4, (float)screenHeight/2-(float)screenHeight/3, (float)screenWidth/2, (float)screenHeight*2/3 }; // Some text to display the current alignment const char *textAlignNameH[] = { "Left", "Centre", "Right" }; diff --git a/examples/textures/textures_bunnymark.c b/examples/textures/textures_bunnymark.c index a95181ed6..3279abb8f 100644 --- a/examples/textures/textures_bunnymark.c +++ b/examples/textures/textures_bunnymark.c @@ -83,10 +83,10 @@ int main(void) bunnies[i].position.x += bunnies[i].speed.x; bunnies[i].position.y += bunnies[i].speed.y; - if (((bunnies[i].position.x + texBunny.width/2) > GetScreenWidth()) || - ((bunnies[i].position.x + texBunny.width/2) < 0)) bunnies[i].speed.x *= -1; - if (((bunnies[i].position.y + texBunny.height/2) > GetScreenHeight()) || - ((bunnies[i].position.y + texBunny.height/2 - 40) < 0)) bunnies[i].speed.y *= -1; + if (((bunnies[i].position.x + (float)texBunny.width/2) > GetScreenWidth()) || + ((bunnies[i].position.x + (float)texBunny.width/2) < 0)) bunnies[i].speed.x *= -1; + if (((bunnies[i].position.y + (float)texBunny.height/2) > GetScreenHeight()) || + ((bunnies[i].position.y + (float)texBunny.height/2 - 40) < 0)) bunnies[i].speed.y *= -1; } //---------------------------------------------------------------------------------- diff --git a/examples/textures/textures_cellular_automata.c b/examples/textures/textures_cellular_automata.c index affeeda93..802de3611 100644 --- a/examples/textures/textures_cellular_automata.c +++ b/examples/textures/textures_cellular_automata.c @@ -165,7 +165,7 @@ int main(void) // If the mouse is on this preset, highlight it if (mouseInCell == i + 8) - DrawRectangleLinesEx((Rectangle) { 2 + (presetsSizeX + 2.0f)*(i/2), + DrawRectangleLinesEx((Rectangle) { 2 + (presetsSizeX + 2.0f)*((float)i/2), (presetsSizeY + 2.0f)*(i%2), presetsSizeX + 4.0f, presetsSizeY + 4.0f }, 3, RED); } diff --git a/examples/textures/textures_fog_of_war.c b/examples/textures/textures_fog_of_war.c index 4733caeb4..ea98b03ce 100644 --- a/examples/textures/textures_fog_of_war.c +++ b/examples/textures/textures_fog_of_war.c @@ -93,8 +93,8 @@ int main(void) for (unsigned int i = 0; i < map.tilesX*map.tilesY; i++) if (map.tileFog[i] == 1) map.tileFog[i] = 2; // Get current tile position from player pixel position - playerTileX = (int)((playerPosition.x + MAP_TILE_SIZE/2)/MAP_TILE_SIZE); - playerTileY = (int)((playerPosition.y + MAP_TILE_SIZE/2)/MAP_TILE_SIZE); + playerTileX = (int)((playerPosition.x + (float)MAP_TILE_SIZE/2)/MAP_TILE_SIZE); + playerTileY = (int)((playerPosition.y + (float)MAP_TILE_SIZE/2)/MAP_TILE_SIZE); // Check visibility and update fog // NOTE: We check tilemap limits to avoid processing tiles out-of-array-bounds (it could crash program) diff --git a/examples/textures/textures_image_processing.c b/examples/textures/textures_image_processing.c index 474974f97..8d2472c0a 100644 --- a/examples/textures/textures_image_processing.c +++ b/examples/textures/textures_image_processing.c @@ -156,7 +156,7 @@ int main(void) { DrawRectangleRec(toggleRecs[i], ((i == currentProcess) || (i == mouseHoverRec)) ? SKYBLUE : LIGHTGRAY); DrawRectangleLines((int)toggleRecs[i].x, (int) toggleRecs[i].y, (int) toggleRecs[i].width, (int) toggleRecs[i].height, ((i == currentProcess) || (i == mouseHoverRec)) ? BLUE : GRAY); - DrawText( processText[i], (int)( toggleRecs[i].x + toggleRecs[i].width/2 - MeasureText(processText[i], 10)/2), (int) toggleRecs[i].y + 11, 10, ((i == currentProcess) || (i == mouseHoverRec)) ? DARKBLUE : DARKGRAY); + DrawText( processText[i], (int)( toggleRecs[i].x + toggleRecs[i].width/2 - (float)MeasureText(processText[i], 10)/2), (int) toggleRecs[i].y + 11, 10, ((i == currentProcess) || (i == mouseHoverRec)) ? DARKBLUE : DARKGRAY); } DrawTexture(texture, screenWidth - texture.width - 60, screenHeight/2 - texture.height/2, WHITE); diff --git a/examples/textures/textures_image_text.c b/examples/textures/textures_image_text.c index e6777261a..b71ca4792 100644 --- a/examples/textures/textures_image_text.c +++ b/examples/textures/textures_image_text.c @@ -38,7 +38,7 @@ int main(void) Texture2D texture = LoadTextureFromImage(parrots); // Image converted to texture, uploaded to GPU memory (VRAM) UnloadImage(parrots); // Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM - Vector2 position = { (float)(screenWidth/2 - texture.width/2), (float)(screenHeight/2 - texture.height/2 - 20) }; + Vector2 position = { (float)screenWidth/2 - (float)texture.width/2, (float)screenHeight/2 - (float)texture.height/2 - 20 }; bool showFont = false; diff --git a/examples/textures/textures_sprite_button.c b/examples/textures/textures_sprite_button.c index a7db93c4f..7fe2adfd6 100644 --- a/examples/textures/textures_sprite_button.c +++ b/examples/textures/textures_sprite_button.c @@ -39,7 +39,7 @@ int main(void) Rectangle sourceRec = { 0, 0, (float)button.width, frameHeight }; // Define button bounds on screen - Rectangle btnBounds = { screenWidth/2.0f - button.width/2.0f, screenHeight/2.0f - button.height/NUM_FRAMES/2.0f, (float)button.width, frameHeight }; + Rectangle btnBounds = { screenWidth/2.0f - button.width/2.0f, screenHeight/2.0f - (float)button.height/NUM_FRAMES/2.0f, (float)button.width, frameHeight }; int btnState = 0; // Button state: 0-NORMAL, 1-MOUSE_HOVER, 2-PRESSED bool btnAction = false; // Button action should be activated diff --git a/examples/textures/textures_sprite_explosion.c b/examples/textures/textures_sprite_explosion.c index fe9669224..7efe8cf17 100644 --- a/examples/textures/textures_sprite_explosion.c +++ b/examples/textures/textures_sprite_explosion.c @@ -39,8 +39,8 @@ int main(void) Texture2D explosion = LoadTexture("resources/explosion.png"); // Init variables for animation - float frameWidth = (float)(explosion.width/NUM_FRAMES_PER_LINE); // Sprite one frame rectangle width - float frameHeight = (float)(explosion.height/NUM_LINES); // Sprite one frame rectangle height + float frameWidth = (float)explosion.width/NUM_FRAMES_PER_LINE; // Sprite one frame rectangle width + float frameHeight = (float)explosion.height/NUM_LINES; // Sprite one frame rectangle height int currentFrame = 0; int currentLine = 0; diff --git a/src/rtextures.c b/src/rtextures.c index a20b5e516..a57f9037d 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -5602,4 +5602,4 @@ static Vector4 *LoadImageDataNormalized(Image image) return pixels; } -#endif // SUPPORT_MODULE_RTEXTURES +#endif // SUPPORT_MODULE_RTEXTURES \ No newline at end of file From 65cddc852eb9cfde70ca6409c30ca1b87f64dff2 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 25 Jan 2026 19:06:08 +0100 Subject: [PATCH 133/232] Reviewed comments --- src/platforms/rcore_desktop_glfw.c | 2 +- src/rcore.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index fd9632700..ffbbc6668 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -1211,7 +1211,7 @@ void PollInputEvents(void) CORE.Input.Keyboard.charPressedQueueCount = 0; // Reset last gamepad button/axis registered state - CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN + CORE.Input.Gamepad.lastButtonPressed = GAMEPAD_BUTTON_UNKNOWN; //CORE.Input.Gamepad.axisCount = 0; // Keyboard/Mouse input polling (automatically managed by GLFW3 through callback) diff --git a/src/rcore.c b/src/rcore.c index aabf85022..8d2a9ca0a 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -4013,6 +4013,7 @@ bool IsGamepadButtonUp(int gamepad, int button) } // Get the last gamepad button pressed +// NOTE: Returns last gamepad button down, down->up change not considered int GetGamepadButtonPressed(void) { return CORE.Input.Gamepad.lastButtonPressed; From 3568b6e2932623e53da3194bb5f915fbdf999e1f Mon Sep 17 00:00:00 2001 From: ssszcmawo Date: Mon, 26 Jan 2026 12:04:22 +0100 Subject: [PATCH 134/232] [rtext] Fix and enhance `TextReplace()` function (#5511) * add check for replacement,replace strcpy,strncpy with memcpy * add 4 spaces in if statement * add spaces --- src/rtext.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/rtext.c b/src/rtext.c index 45aa19b13..2c871cc49 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -1727,14 +1727,15 @@ char *GetTextBetween(const char *text, const char *begin, const char *end) // Replace text string // 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 != NULL) && (search != NULL)) - { + { + if (replacement == NULL) replacement = ""; + char *insertPoint = NULL; // Next insert point char *temp = NULL; // Temp pointer int textLen = 0; // Text string length @@ -1767,16 +1768,15 @@ char *TextReplace(const char *text, const char *search, const char *replacement) { insertPoint = (char *)strstr(text, search); lastReplacePos = (int)(insertPoint - text); - - // TODO: Review logic to avoid strcpy() - // OK - Those lines work - temp = strncpy(temp, text, lastReplacePos) + lastReplacePos; - temp = strcpy(temp, replacement) + replaceLen; - // WRONG - But not those ones - //temp = strncpy(temp, text, tempLen - 1) + lastReplacePos; - //tempLen -= lastReplacePos; - //temp = strncpy(temp, replacement, tempLen - 1) + replaceLen; - //tempLen -= replaceLen; + + memcpy(temp, text, lastReplacePos); + temp += lastReplacePos; + + if (replaceLen > 0) + { + memcpy(temp, replacement, replaceLen); + temp += replaceLen; + } text += lastReplacePos + searchLen; // Move to next "end of replace" } From 4c71625730fe4520266fad4036f8ba11f7740429 Mon Sep 17 00:00:00 2001 From: Maicon Santana Date: Mon, 26 Jan 2026 11:04:45 +0000 Subject: [PATCH 135/232] [CI] Removing double zip and misleading zip type (#5512) * Removing double zip and misleading zip type * Removing extra spaces --------- Co-authored-by: maiconpintoabreu --- .github/workflows/build_android.yml | 6 ++++-- .github/workflows/build_linux.yml | 6 ++++-- .github/workflows/build_macos.yml | 6 ++++-- .github/workflows/build_webassembly.yml | 6 ++++-- .github/workflows/build_windows.yml | 6 ++++-- 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build_android.yml b/.github/workflows/build_android.yml index 80520d0b2..6993eb292 100644 --- a/.github/workflows/build_android.yml +++ b/.github/workflows/build_android.yml @@ -84,8 +84,10 @@ jobs: - name: Upload Artifacts uses: actions/upload-artifact@v4 with: - name: ${{ env.RELEASE_NAME }}.tar.gz - path: ./build/${{ env.RELEASE_NAME }}.tar.gz + name: ${{ env.RELEASE_NAME }} + path: | + ./build/${{ env.RELEASE_NAME }} + !./build/${{ env.RELEASE_NAME }}.tar.gz - name: Upload Artifact to Release uses: softprops/action-gh-release@v1 diff --git a/.github/workflows/build_linux.yml b/.github/workflows/build_linux.yml index a76345b90..b101750bc 100644 --- a/.github/workflows/build_linux.yml +++ b/.github/workflows/build_linux.yml @@ -114,8 +114,10 @@ jobs: - name: Upload Artifacts uses: actions/upload-artifact@v4 with: - name: ${{ env.RELEASE_NAME }}.tar.gz - path: ./build/${{ env.RELEASE_NAME }}.tar.gz + name: ${{ env.RELEASE_NAME }} + path: | + ./build/${{ env.RELEASE_NAME }} + !./build/${{ env.RELEASE_NAME }}.tar.gz - name: Upload Artifact to Release uses: softprops/action-gh-release@v1 diff --git a/.github/workflows/build_macos.yml b/.github/workflows/build_macos.yml index 965efe249..f27140107 100644 --- a/.github/workflows/build_macos.yml +++ b/.github/workflows/build_macos.yml @@ -101,8 +101,10 @@ jobs: - name: Upload Artifacts uses: actions/upload-artifact@v4 with: - name: ${{ env.RELEASE_NAME }}.tar.gz - path: ./build/${{ env.RELEASE_NAME }}.tar.gz + name: ${{ env.RELEASE_NAME }} + path: | + ./build/${{ env.RELEASE_NAME }} + !./build/${{ env.RELEASE_NAME }}.tar.gz - name: Upload Artifact to Release uses: softprops/action-gh-release@v1 diff --git a/.github/workflows/build_webassembly.yml b/.github/workflows/build_webassembly.yml index 32ae94215..d79b12b1c 100644 --- a/.github/workflows/build_webassembly.yml +++ b/.github/workflows/build_webassembly.yml @@ -71,8 +71,10 @@ jobs: - name: Upload Artifacts uses: actions/upload-artifact@v4 with: - name: ${{ env.RELEASE_NAME }}.zip - path: ./build/${{ env.RELEASE_NAME }}.zip + name: ${{ env.RELEASE_NAME }} + path: | + ./build/${{ env.RELEASE_NAME }} + !./build/${{ env.RELEASE_NAME }}.zip - name: Upload Artifact to Release uses: softprops/action-gh-release@v1 diff --git a/.github/workflows/build_windows.yml b/.github/workflows/build_windows.yml index 7a92c208a..988428403 100644 --- a/.github/workflows/build_windows.yml +++ b/.github/workflows/build_windows.yml @@ -142,8 +142,10 @@ jobs: - name: Upload Artifacts uses: actions/upload-artifact@v4 with: - name: ${{ env.RELEASE_NAME }}.zip - path: ./build/${{ env.RELEASE_NAME }}.zip + name: ${{ env.RELEASE_NAME }} + path: | + ./build/${{ env.RELEASE_NAME }} + !./build/${{ env.RELEASE_NAME }}.zip - name: Upload Artifact to Release uses: softprops/action-gh-release@v1 From 63e4fd838d5e201799eec70fa826022f08b9b3bf Mon Sep 17 00:00:00 2001 From: mikeemm <42421968+mikeemm@users.noreply.github.com> Date: Tue, 27 Jan 2026 17:38:51 +0100 Subject: [PATCH 136/232] fixed typos preventing launch of native win32 backend (#5515) --- src/platforms/rcore_desktop_win32.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/platforms/rcore_desktop_win32.c b/src/platforms/rcore_desktop_win32.c index 28094b53f..70ebd8b92 100644 --- a/src/platforms/rcore_desktop_win32.c +++ b/src/platforms/rcore_desktop_win32.c @@ -1227,7 +1227,7 @@ void SwapScreenBuffer(void) // Get elapsed time measure in seconds double GetTime(void) { - LARGE_INTEGER now = 0; + LARGE_INTEGER now = { 0 }; QueryPerformanceCounter(&now); return (double)(now.QuadPart - CORE.Time.base)/(double)platform.timerFrequency.QuadPart; } @@ -1875,8 +1875,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara case WM_DPICHANGED: { // Get current dpi scale factor - float scalex = HIWORD(wParam)/96.0f; - float scaley = LOWORD(wParam)/96.0f; + float scalex = HIWORD(wparam)/96.0f; + float scaley = LOWORD(wparam)/96.0f; RECT *suggestedRect = (RECT *)lparam; From d0a6892989752ec508afa58facf8736011df20ba Mon Sep 17 00:00:00 2001 From: Jason Mao <64656764+jasoncnm@users.noreply.github.com> Date: Wed, 28 Jan 2026 13:26:07 -0500 Subject: [PATCH 137/232] [rcore] `IsMouseButton*()`, random key codes return unexpected results (#5516) * update * update * stuff * update * move headerfile to root * delete .h * update ignore * fix IsMouseButtonDown\Pressed\Released\Up will get randomly returned to true when the button code is outside the range of mouse button * remove unessary macro * refactor IsMouseButton*() early returns --- src/rcore.c | 60 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/src/rcore.c b/src/rcore.c index 8d2a9ca0a..42d92547e 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -4052,12 +4052,17 @@ float GetGamepadAxisMovement(int gamepad, int axis) bool IsMouseButtonPressed(int button) { bool pressed = false; + + if ((button >= 0) && (button <= MOUSE_BUTTON_BACK)) + { + + if ((CORE.Input.Mouse.currentButtonState[button] == 1) && (CORE.Input.Mouse.previousButtonState[button] == 0)) pressed = true; - if ((CORE.Input.Mouse.currentButtonState[button] == 1) && (CORE.Input.Mouse.previousButtonState[button] == 0)) pressed = true; - - // Map touches to mouse buttons checking - if ((CORE.Input.Touch.currentTouchState[button] == 1) && (CORE.Input.Touch.previousTouchState[button] == 0)) pressed = true; - + // Map touches to mouse buttons checking + if ((CORE.Input.Touch.currentTouchState[button] == 1) && (CORE.Input.Touch.previousTouchState[button] == 0)) pressed = true; + + } + return pressed; } @@ -4065,12 +4070,17 @@ bool IsMouseButtonPressed(int button) bool IsMouseButtonDown(int button) { bool down = false; + + if ((button >= 0) && (button <= MOUSE_BUTTON_BACK)) + { + + if (CORE.Input.Mouse.currentButtonState[button] == 1) down = true; - if (CORE.Input.Mouse.currentButtonState[button] == 1) down = true; - - // NOTE: Touches are considered like mouse buttons - if (CORE.Input.Touch.currentTouchState[button] == 1) down = true; - + // NOTE: Touches are considered like mouse buttons + if (CORE.Input.Touch.currentTouchState[button] == 1) down = true; + + } + return down; } @@ -4078,12 +4088,17 @@ bool IsMouseButtonDown(int button) bool IsMouseButtonReleased(int button) { bool released = false; + + if ((button >= 0) && (button <= MOUSE_BUTTON_BACK)) + { + + if ((CORE.Input.Mouse.currentButtonState[button] == 0) && (CORE.Input.Mouse.previousButtonState[button] == 1)) released = true; - if ((CORE.Input.Mouse.currentButtonState[button] == 0) && (CORE.Input.Mouse.previousButtonState[button] == 1)) released = true; - - // Map touches to mouse buttons checking - if ((CORE.Input.Touch.currentTouchState[button] == 0) && (CORE.Input.Touch.previousTouchState[button] == 1)) released = true; - + // Map touches to mouse buttons checking + if ((CORE.Input.Touch.currentTouchState[button] == 0) && (CORE.Input.Touch.previousTouchState[button] == 1)) released = true; + + } + return released; } @@ -4091,12 +4106,17 @@ bool IsMouseButtonReleased(int button) bool IsMouseButtonUp(int button) { bool up = false; + + if ((button >= 0) && (button <= MOUSE_BUTTON_BACK)) + { + + if (CORE.Input.Mouse.currentButtonState[button] == 0) up = true; - if (CORE.Input.Mouse.currentButtonState[button] == 0) up = true; - - // NOTE: Touches are considered like mouse buttons - if (CORE.Input.Touch.currentTouchState[button] == 0) up = true; - + // NOTE: Touches are considered like mouse buttons + if (CORE.Input.Touch.currentTouchState[button] == 0) up = true; + + } + return up; } From af37fa2a96c091799cb7877de4d122e154ebd1bb Mon Sep 17 00:00:00 2001 From: Maicon Santana Date: Wed, 28 Jan 2026 18:27:03 +0000 Subject: [PATCH 138/232] Refactoring based on Coding Style Conventions (#5517) Co-authored-by: maiconpintoabreu --- src/platforms/rcore_desktop_glfw.c | 10 +++++----- src/platforms/rcore_desktop_sdl.c | 2 +- src/rmodels.c | 2 +- src/rtextures.c | 4 ++-- tools/rlparser/rlparser.c | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index ffbbc6668..e3078dacf 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -100,7 +100,7 @@ #include // Required for: usleep() //#define GLFW_EXPOSE_NATIVE_COCOA // WARNING: Fails due to type redefinition - void *glfwGetCocoaWindow(GLFWwindow* handle); + void *glfwGetCocoaWindow(GLFWwindow *handle); #include "GLFW/glfw3native.h" // Required for: glfwGetCocoaWindow() #endif @@ -224,8 +224,8 @@ void ToggleFullscreen(void) if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) { Vector2 scaleDpi = GetWindowScaleDPI(); - CORE.Window.screen.width = (unsigned int)(CORE.Window.screen.width * scaleDpi.x); - CORE.Window.screen.height = (unsigned int)(CORE.Window.screen.height * scaleDpi.y); + CORE.Window.screen.width = (unsigned int)(CORE.Window.screen.width*scaleDpi.x); + CORE.Window.screen.height = (unsigned int)(CORE.Window.screen.height*scaleDpi.y); } #endif @@ -303,8 +303,8 @@ void ToggleBorderlessWindowed(void) if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) { Vector2 scaleDpi = GetWindowScaleDPI(); - CORE.Window.screen.width = (unsigned int)(CORE.Window.screen.width * scaleDpi.x); - CORE.Window.screen.height = (unsigned int)(CORE.Window.screen.height * scaleDpi.y); + CORE.Window.screen.width = (unsigned int)(CORE.Window.screen.width*scaleDpi.x); + CORE.Window.screen.height = (unsigned int)(CORE.Window.screen.height*scaleDpi.y); } #endif diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index 45bb30c65..66a917da2 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -323,7 +323,7 @@ Uint8 SDL_EventState(Uint32 type, int state) return stateBefore; } -void SDL_GetCurrentDisplayMode_Adapter(SDL_DisplayID displayID, SDL_DisplayMode* mode) +void SDL_GetCurrentDisplayMode_Adapter(SDL_DisplayID displayID, SDL_DisplayMode *mode) { const SDL_DisplayMode *currentMode = SDL_GetCurrentDisplayMode(displayID); diff --git a/src/rmodels.c b/src/rmodels.c index 26fc7bcf8..2988dfaba 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -6517,7 +6517,7 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo }; } - Transform* root = &animations[i].framePoses[j][0]; + Transform *root = &animations[i].framePoses[j][0]; root->rotation = QuaternionMultiply(worldTransform.rotation, root->rotation); root->scale = Vector3Multiply(root->scale, worldTransform.scale); root->translation = Vector3Multiply(root->translation, worldTransform.scale); diff --git a/src/rtextures.c b/src/rtextures.c index a57f9037d..1aced0533 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -3625,7 +3625,7 @@ void ImageDrawLineEx(Image *dst, Vector2 start, Vector2 end, int thick, Color co } // Draw circle within an image -void ImageDrawCircle(Image* dst, int centerX, int centerY, int radius, Color color) +void ImageDrawCircle(Image *dst, int centerX, int centerY, int radius, Color color) { int x = 0; int y = radius; @@ -3649,7 +3649,7 @@ void ImageDrawCircle(Image* dst, int centerX, int centerY, int radius, Color col } // Draw circle within an image (Vector version) -void ImageDrawCircleV(Image* dst, Vector2 center, int radius, Color color) +void ImageDrawCircleV(Image *dst, Vector2 center, int radius, Color color) { ImageDrawCircle(dst, (int)center.x, (int)center.y, radius, color); } diff --git a/tools/rlparser/rlparser.c b/tools/rlparser/rlparser.c index c291c3038..899ba7db6 100644 --- a/tools/rlparser/rlparser.c +++ b/tools/rlparser/rlparser.c @@ -198,7 +198,7 @@ static void ExportParsedData(const char *fileName, int format); // Export parsed //---------------------------------------------------------------------------------- // Program main entry point //---------------------------------------------------------------------------------- -int main(int argc, char* argv[]) +int main(int argc, char *argv[]) { if (argc > 1) ProcessCommandLine(argc, argv); From 8a2da96eed62171ebfeaceed61907b0ec1069549 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 28 Jan 2026 19:34:55 +0100 Subject: [PATCH 139/232] Reviewed formating and spacing --- src/rcore.c | 41 +++++++++++++++++------------------------ 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/src/rcore.c b/src/rcore.c index 42d92547e..503eea086 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -1936,7 +1936,7 @@ void TraceLog(int logType, const char *text, ...) // Set custom trace log void SetTraceLogCallback(TraceLogCallback callback) -{ +{ traceLog = callback; } @@ -2771,7 +2771,7 @@ FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool { // SCAN 1: Count files unsigned int fileCounter = GetDirectoryFileCountEx(basePath, filter, scanSubdirs); - + // Memory allocation for dirFileCount files.paths = (char **)RL_CALLOC(fileCounter, sizeof(char *)); for (unsigned int i = 0; i < fileCounter; i++) files.paths[i] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); @@ -3670,13 +3670,13 @@ bool ExportAutomationEventList(AutomationEventList list, const char *fileName) int binarySize = 4 + sizeof(int) + sizeof(AutomationEvent)*list.count; unsigned char *binBuffer = (unsigned char *)RL_CALLOC(binarySize, 1); int offset = 0; - memcpy(binBuffer + offset, "rAE ", 4); + memcpy(binBuffer + offset, "rAE ", 4); offset += 4; - memcpy(binBuffer + offset, &list.count, sizeof(int)); + memcpy(binBuffer + offset, &list.count, sizeof(int)); offset += sizeof(int); memcpy(binBuffer + offset, list.events, sizeof(AutomationEvent)*list.count); offset += sizeof(AutomationEvent)*list.count; - + success = SaveFileData(TextFormat("%s.rae",fileName), binBuffer, binarySize); RL_FREE(binBuffer); } @@ -3831,7 +3831,6 @@ void PlayAutomationEvent(AutomationEvent event) // Check if a key has been pressed once bool IsKeyPressed(int key) { - bool pressed = false; if ((key > 0) && (key < MAX_KEYBOARD_KEYS)) @@ -4052,17 +4051,15 @@ float GetGamepadAxisMovement(int gamepad, int axis) bool IsMouseButtonPressed(int button) { bool pressed = false; - + if ((button >= 0) && (button <= MOUSE_BUTTON_BACK)) { - if ((CORE.Input.Mouse.currentButtonState[button] == 1) && (CORE.Input.Mouse.previousButtonState[button] == 0)) pressed = true; // Map touches to mouse buttons checking if ((CORE.Input.Touch.currentTouchState[button] == 1) && (CORE.Input.Touch.previousTouchState[button] == 0)) pressed = true; - } - + return pressed; } @@ -4070,17 +4067,15 @@ bool IsMouseButtonPressed(int button) bool IsMouseButtonDown(int button) { bool down = false; - + if ((button >= 0) && (button <= MOUSE_BUTTON_BACK)) { - if (CORE.Input.Mouse.currentButtonState[button] == 1) down = true; // NOTE: Touches are considered like mouse buttons if (CORE.Input.Touch.currentTouchState[button] == 1) down = true; - } - + return down; } @@ -4088,17 +4083,15 @@ bool IsMouseButtonDown(int button) bool IsMouseButtonReleased(int button) { bool released = false; - + if ((button >= 0) && (button <= MOUSE_BUTTON_BACK)) { - if ((CORE.Input.Mouse.currentButtonState[button] == 0) && (CORE.Input.Mouse.previousButtonState[button] == 1)) released = true; // Map touches to mouse buttons checking if ((CORE.Input.Touch.currentTouchState[button] == 0) && (CORE.Input.Touch.previousTouchState[button] == 1)) released = true; - } - + return released; } @@ -4106,17 +4099,15 @@ bool IsMouseButtonReleased(int button) bool IsMouseButtonUp(int button) { bool up = false; - + if ((button >= 0) && (button <= MOUSE_BUTTON_BACK)) { - if (CORE.Input.Mouse.currentButtonState[button] == 0) up = true; // NOTE: Touches are considered like mouse buttons if (CORE.Input.Touch.currentTouchState[button] == 0) up = true; - } - + return up; } @@ -4124,6 +4115,7 @@ bool IsMouseButtonUp(int button) int GetMouseX(void) { int mouseX = (int)((CORE.Input.Mouse.currentPosition.x + CORE.Input.Mouse.offset.x)*CORE.Input.Mouse.scale.x); + return mouseX; } @@ -4131,6 +4123,7 @@ int GetMouseX(void) int GetMouseY(void) { int mouseY = (int)((CORE.Input.Mouse.currentPosition.y + CORE.Input.Mouse.offset.y)*CORE.Input.Mouse.scale.y); + return mouseY; } @@ -4490,7 +4483,7 @@ static void RecordAutomationEvent(void) if (currentEventList->count == currentEventList->capacity) return; // Security check - // Event type: INPUT_TOUCH_POSITION + // Event type: INPUT_TOUCH_POSITION if (((int)CORE.Input.Touch.position[id].x != (int)CORE.Input.Touch.previousPosition[id].x) || ((int)CORE.Input.Touch.position[id].y != (int)CORE.Input.Touch.previousPosition[id].y)) { @@ -4503,7 +4496,7 @@ static void RecordAutomationEvent(void) TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_TOUCH_POSITION | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]); currentEventList->count++; } - + if (currentEventList->count == currentEventList->capacity) return; // Security check } From de7fc12be03f8c6b960f41b7ee9f86abf3890771 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 28 Jan 2026 19:35:54 +0100 Subject: [PATCH 140/232] REVIEWED: `IsGamepadButton*()` for consistency with key and mouse equivalents --- src/rcore.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/rcore.c b/src/rcore.c index 503eea086..810915040 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -3972,8 +3972,10 @@ bool IsGamepadButtonPressed(int gamepad, int button) { bool pressed = false; - if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS) && - (CORE.Input.Gamepad.previousButtonState[gamepad][button] == 0) && (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 1)) pressed = true; + if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS)) + { + if ((CORE.Input.Gamepad.previousButtonState[gamepad][button] == 0) && (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 1)) pressed = true; + } return pressed; } @@ -3983,8 +3985,10 @@ bool IsGamepadButtonDown(int gamepad, int button) { bool down = false; - if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS) && - (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 1)) down = true; + if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS)) + { + if (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 1) down = true; + } return down; } @@ -3994,8 +3998,10 @@ bool IsGamepadButtonReleased(int gamepad, int button) { bool released = false; - if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS) && - (CORE.Input.Gamepad.previousButtonState[gamepad][button] == 1) && (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 0)) released = true; + if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS)) + { + if ((CORE.Input.Gamepad.previousButtonState[gamepad][button] == 1) && (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 0)) released = true; + } return released; } @@ -4005,8 +4011,10 @@ bool IsGamepadButtonUp(int gamepad, int button) { bool up = false; - if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS) && - (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 0)) up = true; + if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS)) + { + if (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 0) up = true; + } return up; } From 08e79a16b01816a9ea730cef9ec0a437081f438d Mon Sep 17 00:00:00 2001 From: Maicon Santana Date: Thu, 29 Jan 2026 16:30:03 +0000 Subject: [PATCH 141/232] Refactoring {0} to { 0 } to follow conventions (#5519) Co-authored-by: maiconpintoabreu --- examples/core/msf_gif.h | 6 +++--- examples/models/models_decals.c | 4 ++-- examples/shaders/shaders_hybrid_rendering.c | 2 +- examples/shaders/shaders_vertex_displacement.c | 2 +- examples/shapes/shapes_ball_physics.c | 2 +- examples/shapes/shapes_pie_chart.c | 4 ++-- examples/text/text_3d_drawing.c | 4 ++-- examples/text/text_strings_management.c | 2 +- src/platforms/rcore_android.c | 4 ++-- src/platforms/rcore_drm.c | 8 ++++---- tools/rexm/rexm.c | 2 +- 11 files changed, 20 insertions(+), 20 deletions(-) diff --git a/examples/core/msf_gif.h b/examples/core/msf_gif.h index bc2c6edef..6aa11fdbd 100644 --- a/examples/core/msf_gif.h +++ b/examples/core/msf_gif.h @@ -413,7 +413,7 @@ static MsfGifBuffer * msf_compress_frame(void * allocContext, int width, int hei //generate palette typedef struct { uint8_t r, g, b; } Color3; - Color3 table[256] = { {0} }; + Color3 table[256] = { { 0 } }; int tableIdx = 1; //we start counting at 1 because 0 is the transparent color //transparent is always last in the table tlb[tlbSize-1] = 0; @@ -550,7 +550,7 @@ static void msf_free_gif_state(MsfGifState * handle) { int msf_gif_begin(MsfGifState * handle, int width, int height) { MsfTimeFunc //NOTE: we cannot stomp the entire struct to zero because we must preserve `customAllocatorContext`. - MsfCookedFrame empty = {0}; //god I hate MSVC... + MsfCookedFrame empty = { 0 }; //god I hate MSVC... handle->previousFrame = empty; handle->currentFrame = empty; handle->width = width; @@ -614,7 +614,7 @@ int msf_gif_frame(MsfGifState * handle, uint8_t * pixelData, int centiSecondsPer } MsfGifResult msf_gif_end(MsfGifState * handle) { MsfTimeFunc - if (!handle->listHead) { MsfGifResult empty = {0}; return empty; } + if (!handle->listHead) { MsfGifResult empty = { 0 }; return empty; } //first pass: determine total size size_t total = 1; //1 byte for trailing marker diff --git a/examples/models/models_decals.c b/examples/models/models_decals.c index 71122dd68..9eba33de6 100644 --- a/examples/models/models_decals.c +++ b/examples/models/models_decals.c @@ -183,7 +183,7 @@ int main(void) if (showModel) DrawModel(model, (Vector3){0.0f, 0.0f, 0.0f}, 1.0f, WHITE); // Draw the decal models - for (int i = 0; i < decalCount; i++) DrawModel(decalModels[i], (Vector3){0}, 1.0f, WHITE); + for (int i = 0; i < decalCount; i++) DrawModel(decalModels[i], (Vector3){ 0 }, 1.0f, WHITE); // If we hit the mesh, draw the box for the decal if (collision.hit) @@ -191,7 +191,7 @@ int main(void) Vector3 origin = Vector3Add(collision.point, Vector3Scale(collision.normal, 1.0f)); Matrix splat = MatrixLookAt(collision.point, origin, (Vector3){0,1,0}); placementCube.transform = MatrixInvert(splat); - DrawModel(placementCube, (Vector3){0}, 1.0f, Fade(WHITE, 0.5f)); + DrawModel(placementCube, (Vector3){ 0 }, 1.0f, Fade(WHITE, 0.5f)); } DrawGrid(10, 10.0f); diff --git a/examples/shaders/shaders_hybrid_rendering.c b/examples/shaders/shaders_hybrid_rendering.c index 439965fd6..ca6e93d9c 100644 --- a/examples/shaders/shaders_hybrid_rendering.c +++ b/examples/shaders/shaders_hybrid_rendering.c @@ -65,7 +65,7 @@ int main(void) Shader shdrRaster = LoadShader(0, TextFormat("resources/shaders/glsl%i/hybrid_raster.fs", GLSL_VERSION)); // Declare Struct used to store camera locs - RayLocs marchLocs = {0}; + RayLocs marchLocs = { 0 }; // Fill the struct with shader locs marchLocs.camPos = GetShaderLocation(shdrRaymarch, "camPos"); diff --git a/examples/shaders/shaders_vertex_displacement.c b/examples/shaders/shaders_vertex_displacement.c index 3eff34e00..8978b0fce 100644 --- a/examples/shaders/shaders_vertex_displacement.c +++ b/examples/shaders/shaders_vertex_displacement.c @@ -41,7 +41,7 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [shaders] example - vertex displacement"); // set up camera - Camera camera = {0}; + Camera camera = { 0 }; camera.position = (Vector3) {20.0f, 5.0f, -20.0f}; camera.target = (Vector3) {0.0f, 0.0f, 0.0f}; camera.up = (Vector3) {0.0f, 1.0f, 0.0f}; diff --git a/examples/shapes/shapes_ball_physics.c b/examples/shapes/shapes_ball_physics.c index 0c98ccf9d..293be1cd5 100644 --- a/examples/shapes/shapes_ball_physics.c +++ b/examples/shapes/shapes_ball_physics.c @@ -58,7 +58,7 @@ int main(void) int ballCount = 1; Ball *grabbedBall = NULL; // A pointer to the current ball that is grabbed - Vector2 pressOffset = {0}; // Mouse press offset relative to the ball that grabbedd + Vector2 pressOffset = { 0 }; // Mouse press offset relative to the ball that grabbedd float gravity = 100; // World gravity diff --git a/examples/shapes/shapes_pie_chart.c b/examples/shapes/shapes_pie_chart.c index 6db7f96da..baf0a3652 100644 --- a/examples/shapes/shapes_pie_chart.c +++ b/examples/shapes/shapes_pie_chart.c @@ -49,8 +49,8 @@ int main(void) bool showPercentages = false; bool showDonut = false; int hoveredSlice = -1; - Rectangle scrollPanelBounds = {0}; - Vector2 scrollContentOffset = {0}; + Rectangle scrollPanelBounds = { 0 }; + Vector2 scrollContentOffset = { 0 }; Rectangle view = { 0 }; // UI layout parameters diff --git a/examples/text/text_3d_drawing.c b/examples/text/text_3d_drawing.c index 80b617b2e..aebf33837 100644 --- a/examples/text/text_3d_drawing.c +++ b/examples/text/text_3d_drawing.c @@ -113,7 +113,7 @@ int main(void) // Set the text (using markdown!) char text[64] = "Hello ~~World~~ in 3D!"; - Vector3 tbox = {0}; + Vector3 tbox = { 0 }; int layers = 1; int quads = 0; float layerDistance = 0.01f; @@ -133,7 +133,7 @@ int main(void) Shader alphaDiscard = LoadShader(NULL, TextFormat("resources/shaders/glsl%i/alpha_discard.fs", GLSL_VERSION)); // Array filled with multiple random colors (when multicolor mode is set) - Color multi[TEXT_MAX_LAYERS] = {0}; + Color multi[TEXT_MAX_LAYERS] = { 0 }; DisableCursor(); // Limit cursor to relative movement inside the window diff --git a/examples/text/text_strings_management.c b/examples/text/text_strings_management.c index e4a7ab2af..db4540081 100644 --- a/examples/text/text_strings_management.c +++ b/examples/text/text_strings_management.c @@ -65,7 +65,7 @@ int main(void) TextParticle textParticles[MAX_TEXT_PARTICLES] = { 0 }; int particleCount = 0; TextParticle *grabbedTextParticle = NULL; - Vector2 pressOffset = {0}; + Vector2 pressOffset = { 0 }; PrepareFirstTextParticle("raylib => fun videogames programming!", textParticles, &particleCount); diff --git a/src/platforms/rcore_android.c b/src/platforms/rcore_android.c index 65d1c2ddf..65236be0f 100644 --- a/src/platforms/rcore_android.c +++ b/src/platforms/rcore_android.c @@ -886,8 +886,8 @@ void ClosePlatform(void) // NOTE: Reset global state in case the activity is being relaunched if (platform.app->destroyRequested != 0) { - CORE = (CoreData){0}; - platform = (PlatformData){0}; + CORE = (CoreData){ 0 }; + platform = (PlatformData){ 0 }; } } diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index b296e0042..68431030b 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -915,7 +915,7 @@ void SwapScreenBuffer(void) { TRACELOG(LOG_ERROR, "DISPLAY: Failed to get DRM resources"); drmModeRmFB(platform.fd, fb); - struct drm_mode_destroy_dumb dreq = {0}; + struct drm_mode_destroy_dumb dreq = { 0 }; dreq.handle = creq.handle; drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq); return; @@ -955,7 +955,7 @@ void SwapScreenBuffer(void) { TRACELOG(LOG_ERROR, "DISPLAY: No compatible CRTC found"); drmModeRmFB(platform.fd, fb); - struct drm_mode_destroy_dumb dreq = {0}; + struct drm_mode_destroy_dumb dreq = { 0 }; dreq.handle = creq.handle; drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq); return; @@ -971,7 +971,7 @@ void SwapScreenBuffer(void) TRACELOG(LOG_ERROR, "DISPLAY: Mode: %dx%d@%d", mode->hdisplay, mode->vdisplay, mode->vrefresh); drmModeRmFB(platform.fd, fb); - struct drm_mode_destroy_dumb dreq = {0}; + struct drm_mode_destroy_dumb dreq = { 0 }; dreq.handle = creq.handle; drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq); return; @@ -989,7 +989,7 @@ void SwapScreenBuffer(void) // Clean up previous dumb buffer if (platform.prevDumbHandle) { - struct drm_mode_destroy_dumb dreq = {0}; + struct drm_mode_destroy_dumb dreq = { 0 }; dreq.handle = platform.prevDumbHandle; drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq); } diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index ad9bcbed0..70001a5f3 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -1556,7 +1556,7 @@ int main(int argc, char *argv[]) "#include \n" "#include \n" "#include \n\n" - "static char logText[4096] = {0};\n" + "static char logText[4096] = { 0 };\n" "static int logTextOffset = 0;\n\n" "void CustomTraceLog(int msgType, const char *text, va_list args)\n{\n" " if (logTextOffset < 3800)\n {\n" From d5ae12f3eb1f625a2cd65447ca4fa48db1e0fd74 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 29 Jan 2026 19:50:59 +0100 Subject: [PATCH 142/232] Update raylib_1024x1024.png --- logo/raylib_1024x1024.png | Bin 4591 -> 4591 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/logo/raylib_1024x1024.png b/logo/raylib_1024x1024.png index 3930aeb79e595f2571e1035391bc4c1e32bf059c..9b5a808ffffd2310416ed81c4b322d0a773c26e1 100644 GIT binary patch delta 24 gcmaE_{9bv2^5k`b<{OoJ1UVTzUHx3vIVCg!0C+(N%>V!Z delta 24 fcmaE_{9bv2^2Vqh!HFtnTnr4Ju6{1-oD!M Date: Thu, 29 Jan 2026 19:51:04 +0100 Subject: [PATCH 143/232] Update raylib_144x144.png --- logo/raylib_144x144.png | Bin 475 -> 490 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/logo/raylib_144x144.png b/logo/raylib_144x144.png index f89d90b23ce52f7c11155258738a45d48bb47ee5..011214b61f7ac37d5e3da765371f83dcb00e10b1 100644 GIT binary patch delta 302 zcmV+}0nz^31L^~iSx9_IL_t(|+U(gej>0eyKv5=2>HDA5bwrU8VoZ>2oV;J51*BCT zGZ=`7cxav$mjIZ62^cT|6EI-v+FH0T=j;LvDWzn>tVEH&8wO0kfC-p@k>DYbygGjx z-RcrlmQvbp`zqLBIZQJ`PSr!v!CCW-1ey}uQ0;bEa#HOb*6DD9*;;gT}?^oZ66XyPu zn$PtuRg8%>k07*qoM6N<$f_#^Y A(EtDd delta 307 zcmaFGe4BYfq<^lbi(^Q|tv9zE^9~sZI0WWA{pT)sut~PdaATXr$KT#uLT69&EX&ed zYEv?Il{bUW0T!Ma4V)4Nf48pvxVfXC@tox1DBl@VH4>QEKyniwicEZLHSv{jy;{Nn z7M}wRoHH62g$)>))j$f;x9?=xyS=RT{vE-Kbv5s2s-5wgGPUBj(YJY=#)&`Yzx})Y z+X?S)&ldlGaG~Pab@Q?WE8iK;?bmEdzO3*5x7PIJdV^1OK0wRvAAWYHLe1yEnj Date: Sat, 31 Jan 2026 23:17:55 +0100 Subject: [PATCH 144/232] fixed win32 vsync flag not being applied (#5521) --- src/platforms/rcore_desktop_win32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platforms/rcore_desktop_win32.c b/src/platforms/rcore_desktop_win32.c index 70ebd8b92..4e39d554d 100644 --- a/src/platforms/rcore_desktop_win32.c +++ b/src/platforms/rcore_desktop_win32.c @@ -2149,10 +2149,10 @@ static void UpdateFlags(HWND hwnd, unsigned desiredFlags, int width, int height) // Flags that just apply immediately without needing any operations CORE.Window.flags |= (desiredFlags & FLAG_MASK_NO_UPDATE); - int vsync = (CORE.Window.flags & FLAG_VSYNC_HINT)? 1 : 0; + int vsync = (desiredFlags & FLAG_VSYNC_HINT)? 1 : 0; if (wglSwapIntervalEXT) { - (*wglSwapIntervalEXT)(vsync); + wglSwapIntervalEXT(vsync); if (vsync) CORE.Window.flags |= FLAG_VSYNC_HINT; else CORE.Window.flags &= ~FLAG_VSYNC_HINT; } From 403c2cbccff44cac0c0bbae034c00191eeee7b4c Mon Sep 17 00:00:00 2001 From: Eddy Jansson Date: Sat, 31 Jan 2026 23:18:52 +0100 Subject: [PATCH 145/232] trivial: Correct typo in log message. (#5523) * trivial: Correct typo in log message. * trivial: Correct typo in rlparser. --- src/platforms/rcore_desktop_win32.c | 2 +- tools/rlparser/rlparser.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/platforms/rcore_desktop_win32.c b/src/platforms/rcore_desktop_win32.c index 4e39d554d..5913dfac6 100644 --- a/src/platforms/rcore_desktop_win32.c +++ b/src/platforms/rcore_desktop_win32.c @@ -1777,7 +1777,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara { // looks like windows will automatically "unminimize" a window // if a style changes modifies it's size - TRACELOG(LOG_INFO, "WIN32: WINDOW: Style change modifed window size, removing maximized flag"); + TRACELOG(LOG_INFO, "WIN32: WINDOW: Style change modified window size, removing maximized flag"); deferredFlags->clear |= FLAG_WINDOW_MAXIMIZED; } } diff --git a/tools/rlparser/rlparser.c b/tools/rlparser/rlparser.c index 899ba7db6..f96dcc0bd 100644 --- a/tools/rlparser/rlparser.c +++ b/tools/rlparser/rlparser.c @@ -260,7 +260,7 @@ int main(int argc, char *argv[]) for (int i = 0; i < lineCount; i++) { int j = 0; - while ((lines[i][j] == ' ') || (lines[i][j] == '\t')) j++; // skip spaces and tabs in the begining + while ((lines[i][j] == ' ') || (lines[i][j] == '\t')) j++; // skip spaces and tabs in the beginning // Read define line if (IsTextEqual(lines[i]+j, "#define ", 8)) { @@ -385,7 +385,7 @@ int main(int argc, char *argv[]) char *linePtr = lines[defineLines[i]]; int j = 0; - while ((linePtr[j] == ' ') || (linePtr[j] == '\t')) j++; // Skip spaces and tabs in the begining + while ((linePtr[j] == ' ') || (linePtr[j] == '\t')) j++; // Skip spaces and tabs in the beginning j += 8; // Skip "#define " while ((linePtr[j] == ' ') || (linePtr[j] == '\t')) j++; // Skip spaces and tabs after "#define " From 33dcd6266386f583b81a83ff991ae29367978cf0 Mon Sep 17 00:00:00 2001 From: Aly Date: Mon, 2 Feb 2026 03:21:10 -0700 Subject: [PATCH 146/232] Added documentation comments for (#5525) --- src/rcore.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/rcore.c b/src/rcore.c index 810915040..4cae00f01 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -2762,6 +2762,8 @@ FilePathList LoadDirectoryFiles(const char *dirPath) } // Load directory filepaths with extension filtering and recursive directory scan +// Use 'DIR*' to include directories on directory scan +// Use '*.*' to include all file types and directories on directory scan // WARNING: Directory is scanned twice, first time to get files count FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs) { From 54b12ed56db460fda18d72e8c228a0c2028215f9 Mon Sep 17 00:00:00 2001 From: Thomas Anderson <5776225+CrackedPixel@users.noreply.github.com> Date: Tue, 3 Feb 2026 16:11:20 -0600 Subject: [PATCH 147/232] update cmake for rgfw (#5527) --- cmake/LibraryConfigurations.cmake | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/cmake/LibraryConfigurations.cmake b/cmake/LibraryConfigurations.cmake index 9b8fbdb25..ffc12edda 100644 --- a/cmake/LibraryConfigurations.cmake +++ b/cmake/LibraryConfigurations.cmake @@ -149,6 +149,24 @@ elseif ("${PLATFORM}" MATCHES "SDL") endif() elseif ("${PLATFORM}" MATCHES "RGFW") set(PLATFORM_CPP "PLATFORM_DESKTOP_RGFW") + + if (APPLE) + find_library(COCOA Cocoa) + find_library(OPENGL OpenGL) + + set(LIBS_PRIVATE ${COCOA} ${OPENGL}) + elseif (WIN32) + find_package(OpenGL REQUIRED) + + set(LIBS_PRIVATE ${OPENGL_LIBRARIES} gdi32) + elseif("${CMAKE_SYSTEM_NAME}" MATCHES "QNX") + message(FATAL_ERROR "RGFW platform does not support QNX. Use PLATFORM=Desktop or PLATFORM=SDL instead.") + elseif (UNIX) + find_package(X11 REQUIRED) + find_package(OpenGL REQUIRED) + + set(LIBS_PRIVATE ${X11_LIBRARIES} ${OPENGL_LIBRARIES}) + endif () endif () if (NOT ${OPENGL_VERSION} MATCHES "OFF") From ccfa3f762a4548e893229bfd9e973357c5eae8ff Mon Sep 17 00:00:00 2001 From: Thomas Anderson <5776225+CrackedPixel@users.noreply.github.com> Date: Tue, 3 Feb 2026 16:12:13 -0600 Subject: [PATCH 148/232] fixed an issue when using an empty window title (#5526) --- src/platforms/rcore_desktop_rgfw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platforms/rcore_desktop_rgfw.c b/src/platforms/rcore_desktop_rgfw.c index d1518b909..dbc5e0132 100644 --- a/src/platforms/rcore_desktop_rgfw.c +++ b/src/platforms/rcore_desktop_rgfw.c @@ -1290,7 +1290,7 @@ int InitPlatform(void) if (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED)) FLAG_SET(flags, RGFW_windowFocusOnShow | RGFW_windowFocus); - platform.window = RGFW_createWindow(CORE.Window.title, RGFW_RECT(0, 0, CORE.Window.screen.width, CORE.Window.screen.height), flags); + platform.window = RGFW_createWindow((CORE.Window.title != 0)? CORE.Window.title : " ", RGFW_RECT(0, 0, CORE.Window.screen.width, CORE.Window.screen.height), flags); platform.mon.mode.area.w = 0; if (platform.window != NULL) From 4c1efc2bd3a9b8cb6d399547022813d73c732ba2 Mon Sep 17 00:00:00 2001 From: mikeemm <42421968+mikeemm@users.noreply.github.com> Date: Wed, 4 Feb 2026 19:37:12 +0100 Subject: [PATCH 149/232] [rcore] Fix native win32 window minimizing/maximizing (#5524) * fixed typos preventing window from min/maxing * fixed window style generation ignoring minimize precedence, causing errors in edge cases * added maximize button on resizable windows * fixed infinite loop when resizing the window manually * activate window upon creation to set focus and show taskbar icon * extended SanitizeFlags() to account for problematic resizing/mizing flag mixups --- src/platforms/rcore_desktop_win32.c | 57 +++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/src/platforms/rcore_desktop_win32.c b/src/platforms/rcore_desktop_win32.c index 5913dfac6..fd10fca04 100644 --- a/src/platforms/rcore_desktop_win32.c +++ b/src/platforms/rcore_desktop_win32.c @@ -141,7 +141,7 @@ static PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = NULL; #define STYLE_MASK_READONLY (WS_MINIMIZE | WS_MAXIMIZE) #define STYLE_MASK_WRITABLE (~STYLE_MASK_READONLY) -#define STYLE_FLAGS_RESIZABLE WS_THICKFRAME +#define STYLE_FLAGS_RESIZABLE (WS_THICKFRAME | WS_MAXIMIZEBOX) #define STYLE_FLAGS_UNDECORATED_OFF (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX) #define STYLE_FLAGS_UNDECORATED_ON WS_POPUP @@ -270,8 +270,8 @@ static DWORD MakeWindowStyle(unsigned flags) // Minimized takes precedence over maximized int mized = MIZED_NONE; - if (FLAG_IS_SET(flags, FLAG_WINDOW_MINIMIZED)) mized = MIZED_MIN; - if (flags & FLAG_WINDOW_MAXIMIZED) mized = MIZED_MAX; + if (flags & FLAG_WINDOW_MINIMIZED) mized = MIZED_MIN; + else if (flags & FLAG_WINDOW_MAXIMIZED) mized = MIZED_MAX; switch (mized) { @@ -1590,8 +1590,6 @@ int InitPlatform(void) if (rlGetVersion() == RL_OPENGL_11_SOFTWARE) // Using software renderer { - //ShowWindow(platform.hwnd, SW_SHOWDEFAULT); //SW_SHOWNORMAL - // Initialize software framebuffer BITMAPINFO bmi = { 0 }; ZeroMemory(&bmi, sizeof(bmi)); @@ -1620,6 +1618,9 @@ int InitPlatform(void) CORE.Window.ready = true; + // Activate window to set focus and show taskbar icon + ShowWindow(platform.hwnd, SW_SHOWDEFAULT); + // Update flags (in case of deferred state change required) UpdateFlags(platform.hwnd, platform.desiredFlags, platform.appScreenWidth, platform.appScreenHeight); @@ -1916,6 +1917,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara EndPaint(hwnd, &ps); } + else DefWindowProc(hwnd, msg, wparam, lparam); } case WM_INPUT: { @@ -2090,10 +2092,10 @@ static void UpdateWindowStyle(HWND hwnd, unsigned desiredFlags) // Minimized takes precedence over maximized Mized currentMized = MIZED_NONE; Mized desiredMized = MIZED_NONE; - if (CORE.Window.flags & WS_MINIMIZE) currentMized = MIZED_MIN; - else if (CORE.Window.flags & WS_MAXIMIZE) currentMized = MIZED_MAX; - if (desiredFlags & WS_MINIMIZE) currentMized = MIZED_MIN; - else if (desiredFlags & WS_MAXIMIZE) currentMized = MIZED_MAX; + if (CORE.Window.flags & FLAG_WINDOW_MINIMIZED) currentMized = MIZED_MIN; + else if (CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) currentMized = MIZED_MAX; + if (desiredFlags & FLAG_WINDOW_MINIMIZED) desiredMized = MIZED_MIN; + else if (desiredFlags & FLAG_WINDOW_MAXIMIZED) desiredMized = MIZED_MAX; if (currentMized != desiredMized) { @@ -2109,10 +2111,41 @@ static void UpdateWindowStyle(HWND hwnd, unsigned desiredFlags) // Sanitize flags static unsigned SanitizeFlags(int mode, unsigned flags) { - if ((flags & FLAG_WINDOW_MAXIMIZED) && (flags & FLAG_BORDERLESS_WINDOWED_MODE)) + if (flags & FLAG_WINDOW_MAXIMIZED) { - TRACELOG(LOG_WARNING, "WIN32: WINDOW: Borderless windows mode overriding maximized window flag"); - flags &= ~FLAG_WINDOW_MAXIMIZED; + if (flags & FLAG_BORDERLESS_WINDOWED_MODE) + { + TRACELOG(LOG_WARNING, "WIN32: WINDOW: Borderless windows mode overriding maximized window flag"); + flags &= ~FLAG_WINDOW_MAXIMIZED; + } + + if (~flags & FLAG_WINDOW_RESIZABLE) + { + if (!(CORE.Window.flags & FLAG_WINDOW_MAXIMIZED)) + { + TRACELOG(LOG_WARNING, "WIN32: WINDOW: Cannot maximize a non-resizable window"); + flags &= ~FLAG_WINDOW_MAXIMIZED; + } + else if (CORE.Window.flags & FLAG_WINDOW_RESIZABLE) + { + TRACELOG(LOG_WARNING, "WIN32: WINDOW: Cannot set window as non-resizable when maximized"); + flags |= FLAG_WINDOW_RESIZABLE; + } + } + else if (!(CORE.Window.flags & FLAG_WINDOW_MAXIMIZED)) + { + if (CORE.Window.flags & FLAG_WINDOW_MINIMIZED) + { + // Window needs to be unminimized before it can be maximized since minimizing takes precedence + flags &= ~FLAG_WINDOW_MINIMIZED; + } + else if ((flags & FLAG_WINDOW_MINIMIZED) && !(CORE.Window.flags & FLAG_WINDOW_MINIMIZED)) + { + TRACELOG(LOG_WARNING, "WIN32: WINDOW: Cannot minimize and maximize a window in the same frame"); + flags &= ~FLAG_WINDOW_MINIMIZED; + flags &= ~FLAG_WINDOW_MAXIMIZED; + } + } } if (mode == 1) From a96cbe0183d36a1ffc4d17ff5acfb35e74231388 Mon Sep 17 00:00:00 2001 From: Alexander Fasching Date: Wed, 4 Feb 2026 19:42:44 +0100 Subject: [PATCH 150/232] Close opened directory (#5529) --- src/rcore.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rcore.c b/src/rcore.c index 4cae00f01..26a394131 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -3004,6 +3004,7 @@ unsigned int GetDirectoryFileCountEx(const char *basePath, const char *filter, b } } } + closedir(dir); } else TRACELOG(LOG_WARNING, "FILEIO: Directory cannot be opened (%s)", basePath); // Maybe it's a file... return fileCounter; From d4f636151b2d1e27249d4fe7859f11d6b7bc4d73 Mon Sep 17 00:00:00 2001 From: Maicon Santana Date: Wed, 4 Feb 2026 18:43:55 +0000 Subject: [PATCH 151/232] refactor to follow the CONVENTIONS.md (#5530) Co-authored-by: maiconpintoabreu --- .../shaders/resources/shaders/glsl100/deferred_shading.fs | 2 +- .../shaders/resources/shaders/glsl100/mandelbrot_set.fs | 2 +- .../shaders/resources/shaders/glsl120/deferred_shading.fs | 2 +- .../shaders/resources/shaders/glsl120/mandelbrot_set.fs | 2 +- .../shaders/resources/shaders/glsl330/deferred_shading.fs | 2 +- .../shaders/resources/shaders/glsl330/mandelbrot_set.fs | 2 +- src/rcore.c | 8 ++++---- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/shaders/resources/shaders/glsl100/deferred_shading.fs b/examples/shaders/resources/shaders/glsl100/deferred_shading.fs index 63e9c5bea..f8004ef5e 100644 --- a/examples/shaders/resources/shaders/glsl100/deferred_shading.fs +++ b/examples/shaders/resources/shaders/glsl100/deferred_shading.fs @@ -36,7 +36,7 @@ void main() vec3 ambient = albedo*vec3(0.1); vec3 viewDirection = normalize(viewPosition - fragPosition); - for (int i = 0; i < NR_LIGHTS; ++i) + for (int i = 0; i < NR_LIGHTS; i++) { if (lights[i].enabled == 0) continue; vec3 lightDirection = lights[i].position - fragPosition; diff --git a/examples/shaders/resources/shaders/glsl100/mandelbrot_set.fs b/examples/shaders/resources/shaders/glsl100/mandelbrot_set.fs index fb6dee8b3..7a89e86b0 100644 --- a/examples/shaders/resources/shaders/glsl100/mandelbrot_set.fs +++ b/examples/shaders/resources/shaders/glsl100/mandelbrot_set.fs @@ -34,7 +34,7 @@ void main() // Fc(z) = z^2 + c on the complex numbers c from the plane does not diverge to infinity starting at z = 0 // Here: z = a + bi. Iterations: z -> z^2 + c = (a + bi)^2 + (c.x + c.yi) = (a^2 - b^2 + c.x) + (2ab + c.y)i - for (int iter = 0; iter < maxIterationsLimit; ++iter) + for (int iter = 0; iter < maxIterationsLimit; iter++) { float aa = a*a; float bb = b*b; diff --git a/examples/shaders/resources/shaders/glsl120/deferred_shading.fs b/examples/shaders/resources/shaders/glsl120/deferred_shading.fs index f52454d8c..b3c5f1ea0 100644 --- a/examples/shaders/resources/shaders/glsl120/deferred_shading.fs +++ b/examples/shaders/resources/shaders/glsl120/deferred_shading.fs @@ -34,7 +34,7 @@ void main() vec3 ambient = albedo*vec3(0.1); vec3 viewDirection = normalize(viewPosition - fragPosition); - for (int i = 0; i < NR_LIGHTS; ++i) + for (int i = 0; i < NR_LIGHTS; i++) { if (lights[i].enabled == 0) continue; vec3 lightDirection = lights[i].position - fragPosition; diff --git a/examples/shaders/resources/shaders/glsl120/mandelbrot_set.fs b/examples/shaders/resources/shaders/glsl120/mandelbrot_set.fs index 5da3ef437..1943813a3 100644 --- a/examples/shaders/resources/shaders/glsl120/mandelbrot_set.fs +++ b/examples/shaders/resources/shaders/glsl120/mandelbrot_set.fs @@ -41,7 +41,7 @@ void main() a = aa - bb + c.x; b = twoab + c.y; - ++iter; + iter++; } if (iter >= maxIterations) diff --git a/examples/shaders/resources/shaders/glsl330/deferred_shading.fs b/examples/shaders/resources/shaders/glsl330/deferred_shading.fs index 660db3244..18102e934 100644 --- a/examples/shaders/resources/shaders/glsl330/deferred_shading.fs +++ b/examples/shaders/resources/shaders/glsl330/deferred_shading.fs @@ -32,7 +32,7 @@ void main() { vec3 ambient = albedo*vec3(0.1f); vec3 viewDirection = normalize(viewPosition - fragPosition); - for (int i = 0; i < NR_LIGHTS; ++i) + for (int i = 0; i < NR_LIGHTS; i++) { if (lights[i].enabled == 0) continue; vec3 lightDirection = lights[i].position - fragPosition; diff --git a/examples/shaders/resources/shaders/glsl330/mandelbrot_set.fs b/examples/shaders/resources/shaders/glsl330/mandelbrot_set.fs index bde74565f..06fb1e6f8 100644 --- a/examples/shaders/resources/shaders/glsl330/mandelbrot_set.fs +++ b/examples/shaders/resources/shaders/glsl330/mandelbrot_set.fs @@ -31,7 +31,7 @@ void main() // Here: z = a + bi. Iterations: z -> z^2 + c = (a + bi)^2 + (c.x + c.yi) = (a^2 - b^2 + c.x) + (2ab + c.y)i int iter = 0; - for (iter = 0; iter < maxIterations; ++iter) + for (iter = 0; iter < maxIterations; iter++) { float aa = a*a; float bb = b*b; diff --git a/src/rcore.c b/src/rcore.c index 26a394131..2d7b90b9a 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -2662,7 +2662,7 @@ const char *GetApplicationDirectory(void) if (len > 0) { - for (int i = len; i >= 0; --i) + for (int i = len; i >= 0; i--) { if (appDir[i] == '\\') { @@ -2684,7 +2684,7 @@ const char *GetApplicationDirectory(void) if (len > 0) { - for (int i = len; i >= 0; --i) + for (int i = len; i >= 0; i--) { if (appDir[i] == '/') { @@ -2706,7 +2706,7 @@ const char *GetApplicationDirectory(void) if (_NSGetExecutablePath(appDir, &size) == 0) { int appDirLength = (int)strlen(appDir); - for (int i = appDirLength; i >= 0; --i) + for (int i = appDirLength; i >= 0; i--) { if (appDir[i] == '/') { @@ -2729,7 +2729,7 @@ const char *GetApplicationDirectory(void) if (sysctl(mib, 4, appDir, &size, NULL, 0) == 0) { int appDirLength = (int)strlen(appDir); - for (int i = appDirLength; i >= 0; --i) + for (int i = appDirLength; i >= 0; i--) { if (appDir[i] == '/') { From f43e049444d65c4492d60fa7dfb3a7932fc81ab9 Mon Sep 17 00:00:00 2001 From: Maicon Santana Date: Thu, 5 Feb 2026 14:10:55 +0000 Subject: [PATCH 152/232] Refactor removing extra space and add break line for { (#5533) Co-authored-by: maiconpintoabreu --- CONTRIBUTING.md | 2 +- examples/shaders/resources/shaders/glsl100/ascii.fs | 2 +- .../shaders/resources/shaders/glsl100/hybrid_raymarch.fs | 2 +- examples/shaders/resources/shaders/glsl100/wave.fs | 3 ++- examples/shaders/resources/shaders/glsl120/ascii.fs | 2 +- .../shaders/resources/shaders/glsl120/hybrid_raymarch.fs | 2 +- examples/shaders/resources/shaders/glsl120/wave.fs | 3 ++- examples/shaders/resources/shaders/glsl330/ascii.fs | 2 +- .../shaders/resources/shaders/glsl330/deferred_shading.fs | 3 ++- .../shaders/resources/shaders/glsl330/deferred_shading.vs | 3 ++- examples/shaders/resources/shaders/glsl330/gbuffer.fs | 3 ++- .../shaders/resources/shaders/glsl330/hybrid_raymarch.fs | 2 +- examples/shaders/resources/shaders/glsl330/wave.fs | 3 ++- examples/shapes/shapes_ball_physics.c | 8 ++++---- projects/4coder/main.c | 6 ++++-- src/platforms/rcore_web.c | 3 ++- src/platforms/rcore_web_emscripten.c | 3 ++- tools/rlparser/rlparser.c | 6 ++++-- 18 files changed, 35 insertions(+), 23 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6d6a2d1d9..3ce54d39e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,7 @@ Hello contributors! Welcome to raylib! Do you enjoy raylib and want to contribute? Nice! You can help with the following points: -- `C programming` - Can you write/review/test/improve the code? +- `C programming` - Can you write/review/test/improve the code? - `Documentation/Tutorials/Example` - Can you write some tutorials/examples? - `Porting to other platforms` - Can you port/adapt/compile raylib on other systems? - `Web Development` - Can you help [with the website](https://github.com/raysan5/raylib.com)? diff --git a/examples/shaders/resources/shaders/glsl100/ascii.fs b/examples/shaders/resources/shaders/glsl100/ascii.fs index 54e20bf66..11b46e471 100644 --- a/examples/shaders/resources/shaders/glsl100/ascii.fs +++ b/examples/shaders/resources/shaders/glsl100/ascii.fs @@ -44,7 +44,7 @@ float GetCharacter(float n, vec2 p) // Main shader logic // ----------------------------------------------------------------------------- -void main() +void main() { vec2 charPixelSize = vec2(fontSize, fontSize); vec2 uvCellSize = charPixelSize/resolution; diff --git a/examples/shaders/resources/shaders/glsl100/hybrid_raymarch.fs b/examples/shaders/resources/shaders/glsl100/hybrid_raymarch.fs index 8f9fa0907..e3287fc04 100644 --- a/examples/shaders/resources/shaders/glsl100/hybrid_raymarch.fs +++ b/examples/shaders/resources/shaders/glsl100/hybrid_raymarch.fs @@ -63,7 +63,7 @@ float sdSixWayCutHollowSphere(vec3 p, float r, float h, float t) } // SRC: https://iquilezles.org/articles/boxfunctions -vec2 iBox(in vec3 ro, in vec3 rd, in vec3 rad) +vec2 iBox(in vec3 ro, in vec3 rd, in vec3 rad) { vec3 m = 1.0/rd; vec3 n = m*ro; diff --git a/examples/shaders/resources/shaders/glsl100/wave.fs b/examples/shaders/resources/shaders/glsl100/wave.fs index df12df9ba..00097f2c4 100644 --- a/examples/shaders/resources/shaders/glsl100/wave.fs +++ b/examples/shaders/resources/shaders/glsl100/wave.fs @@ -19,7 +19,8 @@ uniform float ampY; uniform float speedX; uniform float speedY; -void main() { +void main() +{ float pixelWidth = 1.0/size.x; float pixelHeight = 1.0/size.y; float aspect = pixelHeight/pixelWidth; diff --git a/examples/shaders/resources/shaders/glsl120/ascii.fs b/examples/shaders/resources/shaders/glsl120/ascii.fs index 09c572ae5..e4e9927b9 100644 --- a/examples/shaders/resources/shaders/glsl120/ascii.fs +++ b/examples/shaders/resources/shaders/glsl120/ascii.fs @@ -42,7 +42,7 @@ float GetCharacter(float n, vec2 p) // Main shader logic // ----------------------------------------------------------------------------- -void main() +void main() { vec2 charPixelSize = vec2(fontSize, fontSize); vec2 uvCellSize = charPixelSize / resolution; diff --git a/examples/shaders/resources/shaders/glsl120/hybrid_raymarch.fs b/examples/shaders/resources/shaders/glsl120/hybrid_raymarch.fs index 3118e1861..6090df6b1 100644 --- a/examples/shaders/resources/shaders/glsl120/hybrid_raymarch.fs +++ b/examples/shaders/resources/shaders/glsl120/hybrid_raymarch.fs @@ -61,7 +61,7 @@ float sdSixWayCutHollowSphere(vec3 p, float r, float h, float t) } // SRC: https://iquilezles.org/articles/boxfunctions -vec2 iBox(in vec3 ro, in vec3 rd, in vec3 rad) +vec2 iBox(in vec3 ro, in vec3 rd, in vec3 rad) { vec3 m = 1.0/rd; vec3 n = m*ro; diff --git a/examples/shaders/resources/shaders/glsl120/wave.fs b/examples/shaders/resources/shaders/glsl120/wave.fs index dd6bb2e22..9f0f300e1 100644 --- a/examples/shaders/resources/shaders/glsl120/wave.fs +++ b/examples/shaders/resources/shaders/glsl120/wave.fs @@ -17,7 +17,8 @@ uniform float ampY; uniform float speedX; uniform float speedY; -void main() { +void main() +{ float pixelWidth = 1.0/size.x; float pixelHeight = 1.0/size.y; float aspect = pixelHeight/pixelWidth; diff --git a/examples/shaders/resources/shaders/glsl330/ascii.fs b/examples/shaders/resources/shaders/glsl330/ascii.fs index 3f73bf288..3934c5dc1 100644 --- a/examples/shaders/resources/shaders/glsl330/ascii.fs +++ b/examples/shaders/resources/shaders/glsl330/ascii.fs @@ -38,7 +38,7 @@ float GetCharacter(int n, vec2 p) // Main shader logic // ----------------------------------------------------------------------------- -void main() +void main() { vec2 charPixelSize = vec2(fontSize, fontSize); vec2 uvCellSize = charPixelSize/resolution; diff --git a/examples/shaders/resources/shaders/glsl330/deferred_shading.fs b/examples/shaders/resources/shaders/glsl330/deferred_shading.fs index 18102e934..93a13319c 100644 --- a/examples/shaders/resources/shaders/glsl330/deferred_shading.fs +++ b/examples/shaders/resources/shaders/glsl330/deferred_shading.fs @@ -23,7 +23,8 @@ uniform vec3 viewPosition; const float QUADRATIC = 0.032; const float LINEAR = 0.09; -void main() { +void main() +{ vec3 fragPosition = texture(gPosition, texCoord).rgb; vec3 normal = texture(gNormal, texCoord).rgb; vec3 albedo = texture(gAlbedoSpec, texCoord).rgb; diff --git a/examples/shaders/resources/shaders/glsl330/deferred_shading.vs b/examples/shaders/resources/shaders/glsl330/deferred_shading.vs index f2b1bd7c4..3a6c1612c 100644 --- a/examples/shaders/resources/shaders/glsl330/deferred_shading.vs +++ b/examples/shaders/resources/shaders/glsl330/deferred_shading.vs @@ -5,7 +5,8 @@ layout (location = 1) in vec2 vertexTexCoord; out vec2 texCoord; -void main() { +void main() +{ gl_Position = vec4(vertexPosition, 1.0); texCoord = vertexTexCoord; } diff --git a/examples/shaders/resources/shaders/glsl330/gbuffer.fs b/examples/shaders/resources/shaders/glsl330/gbuffer.fs index c86e20a9e..cbb6d38dc 100644 --- a/examples/shaders/resources/shaders/glsl330/gbuffer.fs +++ b/examples/shaders/resources/shaders/glsl330/gbuffer.fs @@ -10,7 +10,8 @@ in vec3 fragNormal; uniform sampler2D diffuseTexture; uniform sampler2D specularTexture; -void main() { +void main() +{ // store the fragment position vector in the first gbuffer texture gPosition = fragPosition; // also store the per-fragment normals into the gbuffer diff --git a/examples/shaders/resources/shaders/glsl330/hybrid_raymarch.fs b/examples/shaders/resources/shaders/glsl330/hybrid_raymarch.fs index f1fafc640..073fef4f1 100644 --- a/examples/shaders/resources/shaders/glsl330/hybrid_raymarch.fs +++ b/examples/shaders/resources/shaders/glsl330/hybrid_raymarch.fs @@ -59,7 +59,7 @@ float sdSixWayCutHollowSphere(vec3 p, float r, float h, float t) } // https://iquilezles.org/articles/boxfunctions -vec2 iBox(in vec3 ro, in vec3 rd, in vec3 rad) +vec2 iBox(in vec3 ro, in vec3 rd, in vec3 rad) { vec3 m = 1.0/rd; vec3 n = m*ro; diff --git a/examples/shaders/resources/shaders/glsl330/wave.fs b/examples/shaders/resources/shaders/glsl330/wave.fs index 393f1bde2..be07ccd05 100644 --- a/examples/shaders/resources/shaders/glsl330/wave.fs +++ b/examples/shaders/resources/shaders/glsl330/wave.fs @@ -22,7 +22,8 @@ uniform float ampY; uniform float speedX; uniform float speedY; -void main() { +void main() +{ float pixelWidth = 1.0/size.x; float pixelHeight = 1.0/size.y; float aspect = pixelHeight/pixelWidth; diff --git a/examples/shapes/shapes_ball_physics.c b/examples/shapes/shapes_ball_physics.c index 293be1cd5..b790c7e90 100644 --- a/examples/shapes/shapes_ball_physics.c +++ b/examples/shapes/shapes_ball_physics.c @@ -139,14 +139,14 @@ int main(void) Ball *ball = &balls[i]; // The ball is not grabbed - if (!ball->grabbed) + if (!ball->grabbed) { // Ball repositioning using the velocity ball->pos.x += ball->vel.x * delta; ball->pos.y += ball->vel.y * delta; // Does the ball hit the screen right boundary? - if ((ball->pos.x + ball->radius) >= screenWidth) + if ((ball->pos.x + ball->radius) >= screenWidth) { ball->pos.x = screenWidth - ball->radius; // Ball repositioning ball->vel.x = -ball->vel.x*ball->elasticity; // Elasticity makes the ball lose 10% of its velocity on hit @@ -159,12 +159,12 @@ int main(void) } // The same for y axis - if ((ball->pos.y + ball->radius) >= screenHeight) + if ((ball->pos.y + ball->radius) >= screenHeight) { ball->pos.y = screenHeight - ball->radius; ball->vel.y = -ball->vel.y*ball->elasticity; } - else if ((ball->pos.y - ball->radius) <= 0) + else if ((ball->pos.y - ball->radius) <= 0) { ball->pos.y = ball->radius; ball->vel.y = -ball->vel.y*ball->elasticity; diff --git a/projects/4coder/main.c b/projects/4coder/main.c index 062d1d7db..e33f9a1db 100644 --- a/projects/4coder/main.c +++ b/projects/4coder/main.c @@ -1,7 +1,8 @@ #include #include "raylib.h" -int main() { +int main() +{ int screenWidth = 800; int screenHeight = 450; @@ -17,7 +18,8 @@ int main() { SetTargetFPS(60); - while (!WindowShouldClose()) { + while (!WindowShouldClose()) + { cam.position.x = sin(GetTime())*10.0f; cam.position.z = cos(GetTime())*10.0f; diff --git a/src/platforms/rcore_web.c b/src/platforms/rcore_web.c index 986197b9d..3dd3eb9df 100644 --- a/src/platforms/rcore_web.c +++ b/src/platforms/rcore_web.c @@ -894,7 +894,8 @@ void SwapScreenBuffer(void) const canvas = Module.canvas; const ctx = canvas.getContext('2d'); - if (!Module.__img || (Module.__img.width !== width) || (Module.__img.height !== height)) { + if (!Module.__img || (Module.__img.width !== width) || (Module.__img.height !== height)) + { Module.__img = ctx.createImageData(width, height); } diff --git a/src/platforms/rcore_web_emscripten.c b/src/platforms/rcore_web_emscripten.c index ba2489a31..92caae99f 100644 --- a/src/platforms/rcore_web_emscripten.c +++ b/src/platforms/rcore_web_emscripten.c @@ -875,7 +875,8 @@ void SwapScreenBuffer(void) //const canvas = Module['canvas']; const ctx = canvas.getContext('2d'); - if (!Module.__img || (Module.__img.width !== width) || (Module.__img.height !== height)) { + if (!Module.__img || (Module.__img.width !== width) || (Module.__img.height !== height)) + { Module.__img = ctx.createImageData(width, height); } diff --git a/tools/rlparser/rlparser.c b/tools/rlparser/rlparser.c index f96dcc0bd..e69f7ad56 100644 --- a/tools/rlparser/rlparser.c +++ b/tools/rlparser/rlparser.c @@ -721,7 +721,8 @@ int main(int argc, char *argv[]) char v = structs[i].fieldType[originalIndex][k]; if ((v == '*') || (v == ' ') || (v == ',')) { - if (nameEnd != -1) { + if (nameEnd != -1) + { // Don't copy to last additional field if (fieldsRemaining != additionalFields) { @@ -1011,7 +1012,8 @@ int main(int argc, char *argv[]) ((linePtr[c - 4] == 'v') && (linePtr[c - 3] == 'o') && (linePtr[c - 2] == 'i') && - (linePtr[c - 1] == 'd'))) { + (linePtr[c - 1] == 'd'))) + { break; } From 3881d2aac25a11dca6890aee9983ebaf0c44241d Mon Sep 17 00:00:00 2001 From: bielern <917465+bielern@users.noreply.github.com> Date: Thu, 5 Feb 2026 19:21:45 +0100 Subject: [PATCH 153/232] Fix: Detect collision if one line is almost vertical (#5510) (#5531) --- src/rshapes.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/rshapes.c b/src/rshapes.c index 7487e6296..4f6e86c18 100644 --- a/src/rshapes.c +++ b/src/rshapes.c @@ -2365,30 +2365,30 @@ bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec) // Check the collision between two lines defined by two points each, returns collision point by reference bool CheckCollisionLines(Vector2 startPos1, Vector2 endPos1, Vector2 startPos2, Vector2 endPos2, Vector2 *collisionPoint) { - bool collision = false; + // According to https://en.wikipedia.org/wiki/Line–line_intersection#Given_two_points_on_each_line_segment + float rx = endPos1.x - startPos1.x; + float ry = endPos1.y - startPos1.y; + float sx = endPos2.x - startPos2.x; + float sy = endPos2.y - startPos2.y; - float div = (endPos2.y - startPos2.y)*(endPos1.x - startPos1.x) - (endPos2.x - startPos2.x)*(endPos1.y - startPos1.y); + float div = rx * sy - ry * sx; - if (fabsf(div) >= FLT_EPSILON) - { - collision = true; - - float xi = ((startPos2.x - endPos2.x)*(startPos1.x*endPos1.y - startPos1.y*endPos1.x) - (startPos1.x - endPos1.x)*(startPos2.x*endPos2.y - startPos2.y*endPos2.x))/div; - float yi = ((startPos2.y - endPos2.y)*(startPos1.x*endPos1.y - startPos1.y*endPos1.x) - (startPos1.y - endPos1.y)*(startPos2.x*endPos2.y - startPos2.y*endPos2.x))/div; - - if (((fabsf(startPos1.x - endPos1.x) > FLT_EPSILON) && (xi < fminf(startPos1.x, endPos1.x) || (xi > fmaxf(startPos1.x, endPos1.x)))) || - ((fabsf(startPos2.x - endPos2.x) > FLT_EPSILON) && (xi < fminf(startPos2.x, endPos2.x) || (xi > fmaxf(startPos2.x, endPos2.x)))) || - ((fabsf(startPos1.y - endPos1.y) > FLT_EPSILON) && (yi < fminf(startPos1.y, endPos1.y) || (yi > fmaxf(startPos1.y, endPos1.y)))) || - ((fabsf(startPos2.y - endPos2.y) > FLT_EPSILON) && (yi < fminf(startPos2.y, endPos2.y) || (yi > fmaxf(startPos2.y, endPos2.y))))) collision = false; - - if (collision && (collisionPoint != 0)) - { - collisionPoint->x = xi; - collisionPoint->y = yi; - } + if (fabsf(div) < FLT_EPSILON) { + return false; } - return collision; + float s12x = startPos2.x - startPos1.x; + float s12y = startPos2.y - startPos1.y; + + float t = (s12x * sy - s12y * sx) / div; + float u = (s12x * ry - s12y * rx) / div; + + if (0.0f <= t && t <= 1.0f && 0.0f <= u && u <= 1.0f) { + collisionPoint->x = startPos1.x + t * rx; + collisionPoint->y = startPos1.y + t * ry; + return true; + } + return false; } // Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold] From 4f76b896d52a4e11c088b5bc5ce006f3a2f889b8 Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 6 Feb 2026 10:55:42 +0100 Subject: [PATCH 154/232] REVIEWED: `CheckCollisionLines()`, formating and follow raylib conventions --- src/rshapes.c | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/rshapes.c b/src/rshapes.c index 4f6e86c18..35614bd6c 100644 --- a/src/rshapes.c +++ b/src/rshapes.c @@ -2363,32 +2363,36 @@ bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec) } // Check the collision between two lines defined by two points each, returns collision point by reference +// REF: https://en.wikipedia.org/wiki/Line–line_intersection#Given_two_points_on_each_line_segment bool CheckCollisionLines(Vector2 startPos1, Vector2 endPos1, Vector2 startPos2, Vector2 endPos2, Vector2 *collisionPoint) { - // According to https://en.wikipedia.org/wiki/Line–line_intersection#Given_two_points_on_each_line_segment + bool collision = false; + float rx = endPos1.x - startPos1.x; float ry = endPos1.y - startPos1.y; float sx = endPos2.x - startPos2.x; float sy = endPos2.y - startPos2.y; - float div = rx * sy - ry * sx; + float div = rx*sy - ry*sx; - if (fabsf(div) < FLT_EPSILON) { - return false; + if (fabsf(div) >= FLT_EPSILON) + { + float s12x = startPos2.x - startPos1.x; + float s12y = startPos2.y - startPos1.y; + + float t = (s12x*sy - s12y*sx)/div; + float u = (s12x*ry - s12y*rx)/div; + + if ((0.0f <= t) && (t <= 1.0f) && (0.0f <= u) && (u <= 1.0f)) + { + collisionPoint->x = startPos1.x + t*rx; + collisionPoint->y = startPos1.y + t*ry; + + collision = true; + } } - - float s12x = startPos2.x - startPos1.x; - float s12y = startPos2.y - startPos1.y; - - float t = (s12x * sy - s12y * sx) / div; - float u = (s12x * ry - s12y * rx) / div; - - if (0.0f <= t && t <= 1.0f && 0.0f <= u && u <= 1.0f) { - collisionPoint->x = startPos1.x + t * rx; - collisionPoint->y = startPos1.y + t * ry; - return true; - } - return false; + + return collision; } // Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold] From a6fa8b9ff44a83aad9962141804cfcaa2a86928d Mon Sep 17 00:00:00 2001 From: Ross Martin Date: Fri, 6 Feb 2026 13:58:27 +0100 Subject: [PATCH 155/232] Fix out of bound Memory read in Material.maps (#5534) * Fix out of bounds Memory read in Material.Maps by using the MATERIAL_MAP_SPECULAR define instead of the SHADER_LOG_SPECULAR enum * Fix out of bounds Memory read in Material.Maps by using the MATERIAL_MAP_SPECULAR define instead of the SHADER_LOG_SPECULAR enum --- src/rmodels.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rmodels.c b/src/rmodels.c index 2988dfaba..6f3ae995f 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -1719,10 +1719,10 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i if (material.shader.locs[SHADER_LOC_COLOR_SPECULAR] != -1) { float values[4] = { - (float)material.maps[SHADER_LOC_COLOR_SPECULAR].color.r/255.0f, - (float)material.maps[SHADER_LOC_COLOR_SPECULAR].color.g/255.0f, - (float)material.maps[SHADER_LOC_COLOR_SPECULAR].color.b/255.0f, - (float)material.maps[SHADER_LOC_COLOR_SPECULAR].color.a/255.0f + (float)material.maps[MATERIAL_MAP_SPECULAR].color.r/255.0f, + (float)material.maps[MATERIAL_MAP_SPECULAR].color.g/255.0f, + (float)material.maps[MATERIAL_MAP_SPECULAR].color.b/255.0f, + (float)material.maps[MATERIAL_MAP_SPECULAR].color.a/255.0f }; rlSetUniform(material.shader.locs[SHADER_LOC_COLOR_SPECULAR], values, SHADER_UNIFORM_VEC4, 1); From b29d6ee4627d7dd707372249030df370d210292f Mon Sep 17 00:00:00 2001 From: SabeDoesThings <122580233+SabeDoesThings@users.noreply.github.com> Date: Mon, 9 Feb 2026 05:51:43 -0600 Subject: [PATCH 156/232] Update BINDINGS.md (#5538) --- BINDINGS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BINDINGS.md b/BINDINGS.md index 6ef57035f..e39602e4b 100644 --- a/BINDINGS.md +++ b/BINDINGS.md @@ -78,7 +78,6 @@ 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 | @@ -95,6 +94,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers | [raylib-sunder](https://github.com/ashn-dot-dev/raylib-sunder) | **auto** | [Sunder](https://github.com/ashn-dot-dev/sunder) | 0BSD | | [raylib-bqn](https://github.com/Brian-ED/raylib-bqn) | **5.0** | [BQN](https://mlochbaum.github.io/BQN) | MIT | | [rayjs](https://github.com/mode777/rayjs) | 4.6-dev | [QuickJS](https://bellard.org/quickjs) | MIT | +| [rayjule](https://github.com/SabeDoesThings/rayjule) | **5.5** | [Jule](https://jule.dev/) | MIT | | [raylib-raku](https://github.com/vushu/raylib-raku) | **auto** | [Raku](https://www.raku.org) | Artistic License 2.0 | | [Raylib.lean](https://github.com/KislyjKisel/Raylib.lean) | **5.5-dev** | [Lean4](https://lean-lang.org) | BSD-3-Clause | | [raylib-cobol](https://codeberg.org/glowiak/raylib-cobol) | **auto** | [COBOL](https://gnucobol.sourceforge.io) | Public domain | From 5a36ce5e7c2e7b278901c022caeb427b8635f9a4 Mon Sep 17 00:00:00 2001 From: mikeemm <42421968+mikeemm@users.noreply.github.com> Date: Mon, 9 Feb 2026 13:00:18 +0100 Subject: [PATCH 157/232] [rcore] Implemented SetWindowMaxSize, SetWindowMinSize, and SetWindowSize (#5536) * implemented SetWindowMaxSize, SetWindowMinSize and SetWindowSize * removed outdated warning * prevented incompatible size limits --- src/platforms/rcore_desktop_win32.c | 61 +++++++++++++++++++---------- 1 file changed, 40 insertions(+), 21 deletions(-) diff --git a/src/platforms/rcore_desktop_win32.c b/src/platforms/rcore_desktop_win32.c index fd10fca04..17d4fc530 100644 --- a/src/platforms/rcore_desktop_win32.c +++ b/src/platforms/rcore_desktop_win32.c @@ -156,8 +156,6 @@ static PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = NULL; // Flags that have no operations to perform during an update #define FLAG_MASK_NO_UPDATE (FLAG_WINDOW_HIGHDPI | FLAG_MSAA_4X_HINT) -#define WM_APP_UPDATE_WINDOW_SIZE (WM_APP + 1) - #define WGL_DRAW_TO_WINDOW_ARB 0x2001 #define WGL_ACCELERATION_ARB 0x2003 #define WGL_SUPPORT_OPENGL_ARB 0x2010 @@ -426,9 +424,7 @@ static bool UpdateWindowSize(int mode, HWND hwnd, int width, int height, unsigne else swpFlags |= SWP_NOMOVE; // WARNING: This code must be called after swInit() has been called, after InitPlatform() in [rcore] - //RECT rc = {0, 0, desired.cx, desired.cy}; - //AdjustWindowRectEx(&rc, WS_OVERLAPPEDWINDOW, FALSE, 0); - //SetWindowPos(hwnd, NULL, windowPos.x, windowPos.y, rc.right - rc.left, rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER); + SetWindowPos(hwnd, NULL, windowPos.x, windowPos.y, windowSize.cx, windowSize.cy, SWP_NOMOVE | SWP_NOZORDER); return true; } @@ -976,25 +972,40 @@ void SetWindowMonitor(int monitor) // Set window minimum dimensions (FLAG_WINDOW_RESIZABLE) void SetWindowMinSize(int width, int height) { - TRACELOG(LOG_WARNING, "SetWindowMinSize not implemented"); + if ((width > CORE.Window.screenMax.width) || (height > CORE.Window.screenMax.height)) + { + TRACELOG(LOG_WARNING, "WIN32: WINDOW: Cannot set minimum screen size higher than the maximum"); + return; + } CORE.Window.screenMin.width = width; CORE.Window.screenMin.height = height; + + SetWindowSize(platform.appScreenWidth, platform.appScreenHeight); } // Set window maximum dimensions (FLAG_WINDOW_RESIZABLE) void SetWindowMaxSize(int width, int height) { - TRACELOG(LOG_WARNING, "SetWindowMaxSize not implemented"); + if ((width < CORE.Window.screenMin.width) || (height < CORE.Window.screenMin.height)) + { + TRACELOG(LOG_WARNING, "WIN32: WINDOW: Cannot set maximum screen size lower than the minimum"); + return; + } CORE.Window.screenMax.width = width; CORE.Window.screenMax.height = height; + + SetWindowSize(platform.appScreenWidth, platform.appScreenHeight); } // Set window dimensions void SetWindowSize(int width, int height) { - TRACELOG(LOG_WARNING, "SetWindowSize not implemented"); + int screenWidth = fmaxf(CORE.Window.screenMin.width, fminf(CORE.Window.screenMax.width, width)); + int screenHeight = fmaxf(CORE.Window.screenMin.height, fminf(CORE.Window.screenMax.height, height)); + + UpdateWindowSize(1, platform.hwnd, screenWidth, screenHeight, platform.desiredFlags); } // Set window opacity, value opacity is between 0.0 and 1.0 @@ -1494,7 +1505,8 @@ int InitPlatform(void) // NOTE: From this point CORE.Window.flags should always reflect the actual state of the window CORE.Window.flags = FLAG_WINDOW_HIDDEN | (platform.desiredFlags & FLAG_MASK_NO_UPDATE); - + CORE.Window.screenMax.width = 9999; + CORE.Window.screenMax.height = 9999; /* // TODO: Review SetProcessDpiAwarenessContext() // NOTE: SetProcessDpiAwarenessContext() requires Windows 10, version 1703 and shcore.lib linkage @@ -1747,14 +1759,27 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara } break; case WM_SIZING: { - if (CORE.Window.flags & FLAG_WINDOW_RESIZABLE) - { - // TODO: Enforce min/max size - } - else TRACELOG(LOG_WARNING, "WIN32: WINDOW: Trying to resize a non-resizable window"); + if (!(CORE.Window.flags & FLAG_WINDOW_RESIZABLE)) + TRACELOG(LOG_WARNING, "WIN32: WINDOW: Trying to resize a non-resizable window"); result = TRUE; } break; + case WM_GETMINMAXINFO: + { + DWORD style = MakeWindowStyle(platform.desiredFlags); + SIZE maxClientSize = { CORE.Window.screenMax.width, CORE.Window.screenMax.height }; + SIZE maxWindowSize = CalcWindowSize(96, maxClientSize, style); + SIZE minClientSize = { CORE.Window.screenMin.width, CORE.Window.screenMin.height }; + SIZE minWindowSize = CalcWindowSize(96, minClientSize, style); + + LPMINMAXINFO lpmmi = (LPMINMAXINFO) lparam; + lpmmi->ptMaxSize.x = maxWindowSize.cx; + lpmmi->ptMaxSize.y = maxWindowSize.cy; + lpmmi->ptMaxTrackSize.x = maxWindowSize.cx; + lpmmi->ptMaxTrackSize.y = maxWindowSize.cy; + lpmmi->ptMinTrackSize.x = minWindowSize.cx; + lpmmi->ptMinTrackSize.y = minWindowSize.cy; + } break; case WM_STYLECHANGING: { if (wparam == GWL_STYLE) @@ -1960,10 +1985,6 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara } break; case WM_MOUSEWHEEL: CORE.Input.Mouse.currentWheelMove.y = ((float)GET_WHEEL_DELTA_WPARAM(wparam))/WHEEL_DELTA; break; case WM_MOUSEHWHEEL: CORE.Input.Mouse.currentWheelMove.x = ((float)GET_WHEEL_DELTA_WPARAM(wparam))/WHEEL_DELTA; break; - case WM_APP_UPDATE_WINDOW_SIZE: - { - //UpdateWindowSize(UPDATE_WINDOW_NORMAL, hwnd, platform.appScreenWidth, platform.appScreenHeight, CORE.Window.flags); - } break; default: result = DefWindowProcW(hwnd, msg, wparam, lparam); // Message passed directly for execution (default behaviour) } @@ -2045,12 +2066,10 @@ static void HandleWindowResize(HWND hwnd, int *width, int *height) GetClientRect(hwnd, &rect); SIZE clientSize = { rect.right, rect.bottom }; - // TODO: Update framebuffer on resize CORE.Window.currentFbo.width = (int)clientSize.cx; CORE.Window.currentFbo.height = (int)clientSize.cy; - //SetupViewport(0, 0, clientSize.cx, clientSize.cy); - SetupViewport(clientSize.cx, clientSize.cy); + CORE.Window.resizedLastFrame = true; float dpiScale = ((float)GetDpiForWindow(hwnd))/96.0f; bool highdpi = !!(CORE.Window.flags & FLAG_WINDOW_HIGHDPI); From c0829bc69e59a7fa92336b77e2fa2dd57df05840 Mon Sep 17 00:00:00 2001 From: LunaStev Date: Mon, 9 Feb 2026 21:27:51 +0900 Subject: [PATCH 158/232] Add raylib bindings for Wave language (#5539) * Bindings Wave * fix format --- BINDINGS.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/BINDINGS.md b/BINDINGS.md index e39602e4b..5ef67c98f 100644 --- a/BINDINGS.md +++ b/BINDINGS.md @@ -86,6 +86,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers | [raylib-v](https://github.com/vlang/raylib) | 5.5 | [V](https://vlang.io) | MIT/Unlicense | | [raylib.v](https://github.com/irishgreencitrus/raylib.v) | 4.2 | [V](https://vlang.io) | Zlib | | [raylib-vapi](https://github.com/lxmcf/raylib-vapi) | **5.0** | [Vala](https://vala.dev) | Zlib | +| [raylib-wave](https://github.com/wavefnd/raylib-wave) | **auto** |[Wave](http://wave-lang.dev) | Zlib | | [raylib-wren](https://github.com/TSnake41/raylib-wren) | 4.5 | [Wren](http://wren.io) | ISC | | [raylib-zig](https://github.com/raylib-zig/raylib-zig) | **5.6-dev** | [Zig](https://ziglang.org) | MIT | | [raylib.zig](https://github.com/ryupold/raylib.zig) | **5.1-dev** | [Zig](https://ziglang.org) | MIT | @@ -103,6 +104,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers | [fnl-raylib](https://github.com/0riginaln0/fnl-raylib) | **5.5** | [Fennel](https://fennel-lang.org/) | MIT | | [Rayua](https://github.com/uiua-lang/rayua) | **5.5** | [Uiua](https://www.uiua.org/) | **???** | + ### Utility Wrapers These are utility wrappers for specific languages, they are not required to use raylib in the language but may adapt the raylib API to be more inline with the language's paradigm. @@ -183,4 +185,4 @@ Missing some language or wrapper? Feel free to create a new one! :) Usually, raylib bindings follow the convention: `raylib-{language}` -Let me know if you're writing a new binding for raylib, I will list it here! +Let me know if you're writing a new binding for raylib, I will list it here! \ No newline at end of file From c4baa5b81d19051bfa3408cdd2cc1e59c863ad65 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 9 Feb 2026 22:23:23 +0100 Subject: [PATCH 159/232] REVIEWED: Comments --- src/rlgl.h | 87 +++++++++++++++++++++++++++--------------------------- 1 file changed, 43 insertions(+), 44 deletions(-) diff --git a/src/rlgl.h b/src/rlgl.h index d3e86cf1f..d05bc42cb 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -204,9 +204,9 @@ #define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 8192 #endif #if defined(GRAPHICS_API_OPENGL_ES2) - // We reduce memory sizes for embedded systems (RPI and HTML5) + // Reducing memory sizes for embedded systems (RPI and HTML5) // NOTE: On HTML5 (emscripten) this is allocated on heap, - // by default it's only 16MB!...just take care... + // by default heap is only 16MB!...just take care... #define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 2048 #endif #endif @@ -1277,7 +1277,7 @@ void rlTranslatef(float x, float y, float z) matTranslation.m13 = y; matTranslation.m14 = z; - // NOTE: We transpose matrix with multiplication order + // NOTE: Transposing matrix by multiplication order *RLGL.State.currentMatrix = rlMatrixMultiply(matTranslation, *RLGL.State.currentMatrix); } @@ -1322,7 +1322,7 @@ void rlRotatef(float angle, float x, float y, float z) matRotation.m14 = 0.0f; matRotation.m15 = 1.0f; - // NOTE: We transpose matrix with multiplication order + // NOTE: Transposing matrix by multiplication order *RLGL.State.currentMatrix = rlMatrixMultiply(matRotation, *RLGL.State.currentMatrix); } @@ -1336,7 +1336,7 @@ void rlScalef(float x, float y, float z) matScale.m5 = y; matScale.m10 = z; - // NOTE: We transpose matrix with multiplication order + // NOTE: Transposing matrix by multiplication order *RLGL.State.currentMatrix = rlMatrixMultiply(matScale, *RLGL.State.currentMatrix); } @@ -1418,7 +1418,6 @@ void rlOrtho(double left, double right, double bottom, double top, double znear, #endif // Set the viewport area (transformation from normalized device coordinates to window coordinates) -// NOTE: We store current viewport dimensions void rlViewport(int x, int y, int width, int height) { glViewport(x, y, width, height); @@ -1529,9 +1528,9 @@ void rlVertex3f(float x, float y, float z) tz = RLGL.State.transform.m2*x + RLGL.State.transform.m6*y + RLGL.State.transform.m10*z + RLGL.State.transform.m14; } - // WARNING: We can't break primitives when launching a new batch + // WARNING: Be careful with primitives breaking when launching a new batch! // RL_LINES comes in pairs, RL_TRIANGLES come in groups of 3 vertices and RL_QUADS come in groups of 4 vertices - // We must check current draw.mode when a new vertex is required and finish the batch only if the draw.mode draw.vertexCount is %2, %3 or %4 + // Checking current draw.mode when a new vertex is required and finish the batch only if the draw.mode draw.vertexCount is %2, %3 or %4 if (RLGL.State.vertexCounter > (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4 - 4)) { if ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_LINES) && @@ -1539,7 +1538,7 @@ void rlVertex3f(float x, float y, float z) { // Reached the maximum number of vertices for RL_LINES drawing // Launch a draw call but keep current state for next vertices comming - // NOTE: We add +1 vertex to the check for security + // NOTE: Adding +1 vertex to the check for some safety rlCheckRenderBatchLimit(2 + 1); } else if ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_TRIANGLES) && @@ -1659,7 +1658,7 @@ void rlSetTexture(unsigned int id) #if defined(GRAPHICS_API_OPENGL_11) rlDisableTexture(); #else - // NOTE: If quads batch limit is reached, we force a draw call and next batch starts + // NOTE: If quads batch limit is reached, force a draw call and next batch starts if (RLGL.State.vertexCounter >= RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4) { @@ -2485,7 +2484,7 @@ void rlLoadExtensions(void *loader) const char **extList = (const char **)RL_CALLOC(512, sizeof(const char *)); // Allocate 512 strings pointers (2 KB) const char *extensions = (const char *)glGetString(GL_EXTENSIONS); // One big const string - // NOTE: We have to duplicate string because glGetString() returns a const string + // NOTE: String duplication rquired because glGetString() returns a const string 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); @@ -2970,19 +2969,20 @@ void rlUnloadRenderBatch(rlRenderBatch batch) } // Draw render batch -// NOTE: We require a pointer to reset batch and increase current buffer (multi-buffer) +// NOTE: Batch is reseted and current buffer is updated (for multi-buffer config) void rlDrawRenderBatch(rlRenderBatch *batch) { #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) // Update batch vertex buffers //------------------------------------------------------------------------------------------------------------ // NOTE: If there is not vertex data, buffers doesn't need to be updated (vertexCount > 0) - // TODO: If no data changed on the CPU arrays there is no need to re-upload data to GPU, - // a flag can be used to detect changes but it would imply keeping a copy buffer and memcmp() both, does it worth it? if (RLGL.State.vertexCounter > 0) { // Activate elements VAO if (RLGL.ExtSupported.vao) glBindVertexArray(batch->vertexBuffer[batch->currentBuffer].vaoId); + + // TODO: If no data changed on the CPU arrays there is no need to re-upload data to GPU, + // a flag can be used to detect changes but it would imply keeping a copy buffer and memcmp() both, does it worth it? // Vertex positions buffer glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[0]); @@ -3006,18 +3006,17 @@ void rlDrawRenderBatch(rlRenderBatch *batch) // NOTE: glMapBuffer() causes sync issue // If GPU is working with this buffer, glMapBuffer() will wait(stall) until GPU to finish its job - // To avoid waiting (idle), you can call first glBufferData() with NULL pointer before glMapBuffer() - // If you do that, the previous data in PBO will be discarded and glMapBuffer() returns a new + // To avoid waiting (idle), glBufferData() can bee called first with NULL pointer before glMapBuffer() + // Doing that, the previous data in PBO will be discarded and glMapBuffer() returns a new // allocated pointer immediately even if GPU is still working with the previous data // Another option: map the buffer object into client's memory - // Probably this code could be moved somewhere else... - // batch->vertexBuffer[batch->currentBuffer].vertices = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE); - // if (batch->vertexBuffer[batch->currentBuffer].vertices) - // { - // Update vertex data - // } - // glUnmapBuffer(GL_ARRAY_BUFFER); + //batch->vertexBuffer[batch->currentBuffer].vertices = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE); + //if (batch->vertexBuffer[batch->currentBuffer].vertices) + //{ + // Update vertex data + //} + //glUnmapBuffer(GL_ARRAY_BUFFER); // Unbind the current VAO if (RLGL.ExtSupported.vao) glBindVertexArray(0); @@ -3132,7 +3131,7 @@ void rlDrawRenderBatch(rlRenderBatch *batch) else { #if defined(GRAPHICS_API_OPENGL_33) - // We need to define the number of indices to be processed: elementCount*6 + // The number of indices to be processed needs to be defined: elementCount*6 // NOTE: The final parameter tells the GPU the offset in bytes from the // start of the index buffer to the location of the first index to process glDrawElements(GL_TRIANGLES, batch->draws[i].vertexCount/4*6, GL_UNSIGNED_INT, (GLvoid *)(vertexOffset/4*6*sizeof(GLuint))); @@ -3233,7 +3232,7 @@ bool rlCheckRenderBatchLimit(int vCount) rlDrawRenderBatch(RLGL.currentBatch); // NOTE: Stereo rendering is checked inside - // Restore state of last batch so we can continue adding vertices + // Restore state of last batch so new vertices can be added RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode = currentMode; RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId = currentTexture; } @@ -3395,7 +3394,7 @@ unsigned int rlLoadTexture(const void *data, int width, int height, int format, } #endif - // At this point we have the texture loaded in GPU and texture parameters configured + // At this point texture is loaded in GPU and texture parameters configured // NOTE: If mipmaps were not in data, they are not generated automatically @@ -3416,10 +3415,10 @@ unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer) 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 + // In case depth textures were not supported, force renderbuffer usage if (!RLGL.ExtSupported.texDepth) useRenderBuffer = true; - // NOTE: We let the implementation to choose the best bit-depth + // NOTE: Letting the implementation to choose the best bit-depth // Possible formats: GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT32 and GL_DEPTH_COMPONENT32F unsigned int glInternalFormat = GL_DEPTH_COMPONENT; @@ -3565,7 +3564,7 @@ unsigned int rlLoadTextureCubemap(const void *data, int size, int format, int mi } // Update already loaded texture in GPU with new data -// NOTE: We don't know safely if internal texture format is the expected one... +// WARNING: Not possible to know safely if internal texture format is the expected one... void rlUpdateTexture(unsigned int id, int offsetX, int offsetY, int width, int height, int format, const void *data) { glBindTexture(GL_TEXTURE_2D, id); @@ -3699,7 +3698,7 @@ void *rlReadTexturePixels(unsigned int id, int width, int height, int format) #if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) glBindTexture(GL_TEXTURE_2D, id); - // NOTE: Using texture id, we can retrieve some texture info (but not on OpenGL ES 2.0) + // NOTE: Using texture id, some texture info can be retrieved (but not on OpenGL ES 2.0) // Possible texture info: GL_TEXTURE_RED_SIZE, GL_TEXTURE_GREEN_SIZE, GL_TEXTURE_BLUE_SIZE, GL_TEXTURE_ALPHA_SIZE //int width, height, format; //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); @@ -3742,7 +3741,7 @@ void *rlReadTexturePixels(unsigned int id, int width, int height, int format) // Attach our texture to FBO glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, id, 0); - // We read data as RGBA because FBO texture is configured as RGBA, despite binding another texture format + // Reading data as RGBA because FBO texture is configured as RGBA, despite binding another texture format pixels = RL_CALLOC(rlGetPixelDataSize(width, height, RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8), 1); glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); @@ -3778,12 +3777,12 @@ unsigned char *rlReadScreenPixels(int width, int height) { unsigned char *imgData = (unsigned char *)RL_CALLOC(width*height*4, sizeof(unsigned char)); - // NOTE 1: glReadPixels returns image flipped vertically -> (0,0) is the bottom left corner of the framebuffer - // NOTE 2: We are getting alpha channel! Be careful, it can be transparent if not cleared properly! + // NOTE: glReadPixels() returns image flipped vertically -> (0,0) is the bottom left corner of the framebuffer + // WARNING: Getting alpha channel! Be careful, it can be transparent if not cleared properly! glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, imgData); - // Flip image vertically! - // NOTE: Alpha value has already been applied to RGB in framebuffer, we don't need it! + // Flip image vertically + // NOTE: Alpha value has already been applied to RGB in framebuffer, not needed anymore for (int y = height - 1; y >= height/2; y--) { for (int x = 0; x < (width*4); x += 4) @@ -3904,13 +3903,13 @@ void rlUnloadFramebuffer(unsigned int id) { #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) // Query depth attachment to automatically delete texture/renderbuffer - int depthType = 0, depthId = 0; + int depthType = 0; glBindFramebuffer(GL_FRAMEBUFFER, id); // Bind framebuffer to query depth texture type glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &depthType); - // 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/ + int depthId = 0; glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &depthId); unsigned int depthIdU = (unsigned int)depthId; @@ -4190,15 +4189,15 @@ unsigned int rlLoadShaderCode(const char *vsCode, const char *fsCode) if (fsCode != NULL) fragmentShaderId = rlCompileShader(fsCode, GL_FRAGMENT_SHADER); else fragmentShaderId = RLGL.State.defaultFShaderId; - // In case vertex and fragment shader are the default ones, no need to recompile, we can just assign the default shader program id + // In case vertex and fragment shader are the default ones, no need to recompile, just assign the default shader program id if ((vertexShaderId == RLGL.State.defaultVShaderId) && (fragmentShaderId == RLGL.State.defaultFShaderId)) id = RLGL.State.defaultShaderId; else if ((vertexShaderId > 0) && (fragmentShaderId > 0)) { - // One of or both shader are new, we need to compile a new shader program + // One of or both shader are new, a new shader program needs to be compiled id = rlLoadShaderProgram(vertexShaderId, fragmentShaderId); - // We can detach and delete vertex/fragment shaders (if not default ones) - // NOTE: We detach shader before deletion to make sure memory is freed + // Detaching and deleting vertex/fragment shaders (if not default ones) + // WARNING: Detach shader before deletion to make sure memory is freed if (vertexShaderId != RLGL.State.defaultVShaderId) { // WARNING: Shader program linkage could fail and returned id is 0 @@ -4212,10 +4211,10 @@ unsigned int rlLoadShaderCode(const char *vsCode, const char *fsCode) glDeleteShader(fragmentShaderId); } - // In case shader program loading failed, we assign default shader + // In case shader program loading failed, assign default shader if (id == 0) { - // In case shader loading fails, we return the default shader + // In case shader loading fails, reassigning default shader TRACELOG(RL_LOG_WARNING, "SHADER: Failed to load custom shader code, using default shader"); id = RLGL.State.defaultShaderId; } @@ -4737,9 +4736,9 @@ Matrix rlGetMatrixTransform(void) Matrix mat = rlMatrixIdentity(); #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) // TODO: Consider possible transform matrices in the RLGL.State.stack - // Is this the right order? or should we start with the first stored matrix instead of the last one? //Matrix matStackTransform = rlMatrixIdentity(); //for (int i = RLGL.State.stackCounter; i > 0; i--) matStackTransform = rlMatrixMultiply(RLGL.State.stack[i], matStackTransform); + mat = RLGL.State.transform; #endif return mat; From 49cd2ddaa15efd1617efd142c74386a99a2f4d30 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 9 Feb 2026 22:24:07 +0100 Subject: [PATCH 160/232] Update rcore.c --- src/rcore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rcore.c b/src/rcore.c index 2d7b90b9a..6974314cc 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -277,7 +277,7 @@ #define FILE_FILTER_TAG_DIR_ONLY "DIR*" // Filter to include directories on directory scan #endif // NOTE: Used in ScanDirectoryFiles(), LoadDirectoryFilesEx() and GetDirectoryFileCountEx() -// Flags operation macros +// Flags bitwise operation macros #define FLAG_SET(n, f) ((n) |= (f)) #define FLAG_CLEAR(n, f) ((n) &= ~(f)) #define FLAG_TOGGLE(n, f) ((n) ^= (f)) From eba1fca93378bbccf2e7f6374bd6a5c474908665 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 9 Feb 2026 22:24:44 +0100 Subject: [PATCH 161/232] Update rcore.c --- src/rcore.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/rcore.c b/src/rcore.c index 6974314cc..e6338367c 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -18,18 +18,19 @@ * - macOS/OSX (x64, arm64) * - Others (not tested) * > PLATFORM_WEB_RGFW: +* > PLATFORM_WEB (GLFW + Emscripten): * - HTML5 (WebAssembly) -* > PLATFORM_WEB: +* > PLATFORM_WEB_EMSCRIPTEN (Emscripten): * - HTML5 (WebAssembly) -* > PLATFORM_DRM: +* > PLATFORM_DRM (native DRM): * - Raspberry Pi 0-5 (DRM/KMS) * - Linux DRM subsystem (KMS mode) -* > PLATFORM_ANDROID: +* - Embedded devices (with GPU) +* > PLATFORM_ANDROID (native NDK): * - Android (ARM, ARM64) -* > PLATFORM_DESKTOP_WIN32 (Native Win32): -* - Windows (Win32, Win64) * > PLATFORM_MEMORY * - Memory framebuffer output, using software renderer, no OS required +* * CONFIGURATION: * #define SUPPORT_DEFAULT_FONT (default) * Default font is loaded on window initialization to be available for the user to render simple text From a654beb5654bbb41a2e53e6a4005f3de560025e6 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 9 Feb 2026 22:25:20 +0100 Subject: [PATCH 162/232] REVIEWED: Comments --- src/raylib.h | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/raylib.h b/src/raylib.h index 8a0a14dad..66cfe4387 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -4,13 +4,12 @@ * * FEATURES: * - NO external dependencies, all required libraries included with raylib -* - Multiplatform: Windows, Linux, FreeBSD, OpenBSD, NetBSD, DragonFly, -* MacOS, Haiku, Android, Raspberry Pi, DRM native, HTML5 +* - Multiplatform: Windows, Linux, macOS, FreeBSD, Web, Android, Raspberry Pi, DRM native... * - Written in plain C code (C99) in PascalCase/camelCase notation * - Hardware accelerated with OpenGL (1.1, 2.1, 3.3, 4.3, ES2, ES3 - choose at compile) -* - Unique OpenGL abstraction layer (usable as standalone module): [rlgl] +* - Custom OpenGL abstraction layer (usable as standalone module): [rlgl] * - Multiple Fonts formats supported (TTF, OTF, FNT, BDF, Sprite fonts) -* - Outstanding texture formats support, including compressed formats (DXT, ETC, ASTC) +* - Many texture formats supportted, including compressed formats (DXT, ETC, ASTC) * - Full 3d support for 3d Shapes, Models, Billboards, Heightmaps and more! * - Flexible Materials system, supporting classic maps and PBR maps * - Animated 3D models supported (skeletal bones animation) (IQM, M3D, GLTF) @@ -26,10 +25,9 @@ * - One default Shader is loaded on rlglInit()->rlLoadShaderDefault() [rlgl] (OpenGL 3.3 or ES2) * - One default RenderBatch is loaded on rlglInit()->rlLoadRenderBatch() [rlgl] (OpenGL 3.3 or ES2) * -* DEPENDENCIES (included): -* [rcore][GLFW] rglfw (Camilla Löwy - github.com/glfw/glfw) for window/context management and input -* [rcore][RGFW] rgfw (ColleagueRiley - github.com/ColleagueRiley/RGFW) for window/context management and input -* [rlgl] glad/glad_gles2 (David Herberth - github.com/Dav1dde/glad) for OpenGL 3.3 extensions loading +* DEPENDENCIES: +* [rcore] Depends on the selected platform backend, check rcore.c header for details +* [rlgl] glad/glad_gles2 (David Herberth - github.com/Dav1dde/glad) for OpenGL extensions loading * [raudio] miniaudio (David Reid - github.com/mackron/miniaudio) for audio device/context management * * OPTIONAL DEPENDENCIES (included): @@ -41,6 +39,7 @@ * [rtextures] stb_image_write (Sean Barret) for image writing (BMP, TGA, PNG, JPG) * [rtextures] stb_image_resize2 (Sean Barret) for image resizing algorithms * [rtextures] stb_perlin (Sean Barret) for Perlin Noise image generation +* [rtextures] rl_gputex (Ramon Santamaria) for GPU-compressed texture formats * [rtext] stb_truetype (Sean Barret) for ttf fonts loading * [rtext] stb_rect_pack (Sean Barret) for rectangles packing * [rmodels] par_shapes (Philip Rideout) for parametric 3d shapes generation @@ -1102,7 +1101,7 @@ RLAPI void SetTraceLogLevel(int logLevel); // Set the curre RLAPI void TraceLog(int logLevel, const char *text, ...); // Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...) RLAPI void SetTraceLogCallback(TraceLogCallback callback); // Set custom trace log -// Memory management, using internal allocators +// Memory management, using internal allocators RLAPI void *MemAlloc(unsigned int size); // Internal memory allocator RLAPI void *MemRealloc(void *ptr, unsigned int size); // Internal memory reallocator RLAPI void MemFree(void *ptr); // Internal memory free From f6910bc1e0c413441d3176c8568d132eea160621 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 9 Feb 2026 22:25:52 +0100 Subject: [PATCH 163/232] Update rcore_drm.c --- src/platforms/rcore_drm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index 68431030b..6d3394f69 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -1469,7 +1469,7 @@ int InitPlatform(void) if (!eglChooseConfig(platform.device, framebufferAttribs, configs, numConfigs, &matchingNumConfigs)) { TRACELOG(LOG_WARNING, "DISPLAY: Failed to choose EGL config: 0x%x", eglGetError()); - free(configs); + RL_FREE(configs); return -1; } From e67dc15a52f404f811ab9064225f5dc77258d521 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 9 Feb 2026 22:25:55 +0100 Subject: [PATCH 164/232] Update rcore_desktop_glfw.c --- src/platforms/rcore_desktop_glfw.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index e3078dacf..b13018576 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -1049,14 +1049,14 @@ Image GetClipboardImage(void) #if defined(SUPPORT_CLIPBOARD_IMAGE) #if defined(_WIN32) unsigned long long int dataSize = 0; - void *fileData = NULL; + void *bmpData = NULL; int width = 0; int height = 0; - fileData = (void *)Win32GetClipboardImageData(&width, &height, &dataSize); + bmpData = (void *)Win32GetClipboardImageData(&width, &height, &dataSize); - if (fileData == NULL) TRACELOG(LOG_WARNING, "Clipboard image: Couldn't get clipboard data."); - else image = LoadImageFromMemory(".bmp", (const unsigned char *)fileData, (int)dataSize); + if (bmpData == NULL) TRACELOG(LOG_WARNING, "Clipboard image: Couldn't get clipboard data."); + else image = LoadImageFromMemory(".bmp", (const unsigned char *)bmpData, (int)dataSize); #else TRACELOG(LOG_WARNING, "GetClipboardImage() not implemented on target platform"); #endif From 9861baf4b7aa0b6061738c5a795890a2f9ae1ce5 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 9 Feb 2026 22:26:07 +0100 Subject: [PATCH 165/232] Update textures_framebuffer_rendering.c --- examples/textures/textures_framebuffer_rendering.c | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/textures/textures_framebuffer_rendering.c b/examples/textures/textures_framebuffer_rendering.c index 484192739..097ae1f2f 100644 --- a/examples/textures/textures_framebuffer_rendering.c +++ b/examples/textures/textures_framebuffer_rendering.c @@ -148,6 +148,7 @@ int main(void) //-------------------------------------------------------------------------------------- UnloadRenderTexture(observerTarget); UnloadRenderTexture(subjectTarget); + CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- From f190c6a4d479f6a8ee7ccf03cebe16848512b056 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 9 Feb 2026 22:27:16 +0100 Subject: [PATCH 166/232] Update rcore.c --- src/rcore.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rcore.c b/src/rcore.c index e6338367c..4568477d2 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -13,6 +13,7 @@ * - Linux (X11/Wayland desktop mode) * - Others (not tested) * > PLATFORM_DESKTOP_RGFW (RGFW backend): +* > PLATFORM_DESKTOP_WIN32 (native Win32): * - Windows (Win32, Win64) * - Linux (X11/Wayland desktop mode) * - macOS/OSX (x64, arm64) From 84f75785eeebc43a2c96cd4fcd3c21150027ebc3 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 9 Feb 2026 22:29:13 +0100 Subject: [PATCH 167/232] Update rcore.c --- src/rcore.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/rcore.c b/src/rcore.c index 4568477d2..49a928372 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -13,16 +13,18 @@ * - Linux (X11/Wayland desktop mode) * - Others (not tested) * > PLATFORM_DESKTOP_RGFW (RGFW backend): -* > PLATFORM_DESKTOP_WIN32 (native Win32): * - Windows (Win32, Win64) * - Linux (X11/Wayland desktop mode) * - macOS/OSX (x64, arm64) * - Others (not tested) -* > PLATFORM_WEB_RGFW: +* > PLATFORM_DESKTOP_WIN32 (native Win32): +* - Windows (Win32, Win64) * > PLATFORM_WEB (GLFW + Emscripten): * - HTML5 (WebAssembly) * > PLATFORM_WEB_EMSCRIPTEN (Emscripten): * - HTML5 (WebAssembly) +* > PLATFORM_WEB_RGFW (Emscripten): +* - HTML5 (WebAssembly) * > PLATFORM_DRM (native DRM): * - Raspberry Pi 0-5 (DRM/KMS) * - Linux DRM subsystem (KMS mode) From 7e59e1d93d602c9b71c0382d2c989167d5e432bb Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 9 Feb 2026 22:29:47 +0100 Subject: [PATCH 168/232] REVIEWED: Formating --- src/external/win32_clipboard.h | 103 +++++++++++++++------------------ 1 file changed, 47 insertions(+), 56 deletions(-) diff --git a/src/external/win32_clipboard.h b/src/external/win32_clipboard.h index 1f9a27521..75cd720a9 100644 --- a/src/external/win32_clipboard.h +++ b/src/external/win32_clipboard.h @@ -4,7 +4,7 @@ #ifndef WIN32_CLIPBOARD_ #define WIN32_CLIPBOARD_ -unsigned char* Win32GetClipboardImageData(int* width, int* height, unsigned long long int *dataSize); +unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned long long int *dataSize); #endif // WIN32_CLIPBOARD_ #ifdef WIN32_CLIPBOARD_IMPLEMENTATION @@ -92,7 +92,6 @@ unsigned char* Win32GetClipboardImageData(int* width, int* height, unsigned long typedef int WINBOOL; - #if !defined(_WINUSER_) || !defined(WINUSER_ALREADY_INCLUDED) WINUSERAPI WINBOOL WINAPI OpenClipboard(HWND hWndNewOwner); WINUSERAPI WINBOOL WINAPI CloseClipboard(VOID); @@ -170,8 +169,7 @@ typedef struct tagRGBQUAD { } RGBQUAD, *LPRGBQUAD; #endif - -// https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-wmf/4e588f70-bd92-4a6f-b77f-35d0feaf7a57 +// REF: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-wmf/4e588f70-bd92-4a6f-b77f-35d0feaf7a57 #define BI_RGB 0x0000 #define BI_RLE8 0x0001 #define BI_RLE4 0x0002 @@ -184,10 +182,10 @@ typedef struct tagRGBQUAD { #endif -// https://learn.microsoft.com/en-us/windows/win32/dataxchg/standard-clipboard-formats +// REF: https://learn.microsoft.com/en-us/windows/win32/dataxchg/standard-clipboard-formats #define CF_DIB 8 -// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setsystemcursor +// REF: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setsystemcursor // #define OCR_NORMAL 32512 // Normal select // #define OCR_IBEAM 32513 // Text select // #define OCR_WAIT 32514 // Busy @@ -202,36 +200,37 @@ typedef struct tagRGBQUAD { // #define OCR_HAND 32649 // Link select // #define OCR_APPSTARTING 32650 // +static BOOL OpenClipboardRetrying(HWND handle); // Open clipboard with a number of retries +static int GetPixelDataOffset(BITMAPINFOHEADER bih); //---------------------------------------------------------------------------------- // Module Internal Functions Declaration //---------------------------------------------------------------------------------- - - -static BOOL OpenClipboardRetrying(HWND handle); // Open clipboard with a number of retries -static int GetPixelDataOffset(BITMAPINFOHEADER bih); - -unsigned char* Win32GetClipboardImageData(int* width, int* height, unsigned long long int *dataSize) +unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned long long int *dataSize) { HWND win = NULL; // Get from somewhere but is doesnt seem to matter - const char* msgString = ""; + const char *msgString = ""; int severity = LOG_INFO; - BYTE* bmpData = NULL; - if (!OpenClipboardRetrying(win)) { + BYTE *bmpData = NULL; + + if (!OpenClipboardRetrying(win)) + { severity = LOG_ERROR; msgString = "Couldn't open clipboard"; goto end; } HGLOBAL clipHandle = (HGLOBAL)GetClipboardData(CF_DIB); - if (!clipHandle) { + if (!clipHandle) + { severity = LOG_ERROR; msgString = "Clipboard data is not an Image"; goto close; } BITMAPINFOHEADER *bmpInfoHeader = (BITMAPINFOHEADER *)GlobalLock(clipHandle); - if (!bmpInfoHeader) { + if (!bmpInfoHeader) + { // Mapping from HGLOBAL to our local *address space* failed severity = LOG_ERROR; msgString = "Clipboard data failed to be locked"; @@ -242,7 +241,8 @@ unsigned char* Win32GetClipboardImageData(int* width, int* height, unsigned long *height = bmpInfoHeader->biHeight; SIZE_T clipDataSize = GlobalSize(clipHandle); - if (clipDataSize < sizeof(BITMAPINFOHEADER)) { + if (clipDataSize < sizeof(BITMAPINFOHEADER)) + { // Format CF_DIB needs space for BITMAPINFOHEADER struct. msgString = "Clipboard has Malformed data"; severity = LOG_ERROR; @@ -259,31 +259,29 @@ unsigned char* Win32GetClipboardImageData(int* width, int* height, unsigned long // //--------------------------------------------------------------------------------// - BITMAPFILEHEADER bmpFileHeader = {0}; + BITMAPFILEHEADER bmpFileHeader = { 0 }; SIZE_T bmpFileSize = sizeof(bmpFileHeader) + clipDataSize; *dataSize = bmpFileSize; - bmpFileHeader.bfType = 0x4D42; //https://stackoverflow.com/questions/601430/multibyte-character-constants-and-bitmap-file-header-type-constants#601536 + bmpFileHeader.bfType = 0x4D42; // REF: https://stackoverflow.com/questions/601430/multibyte-character-constants-and-bitmap-file-header-type-constants#601536 bmpFileHeader.bfSize = (DWORD)bmpFileSize; // Up to 4GB works fine bmpFileHeader.bfOffBits = sizeof(bmpFileHeader) + pixelOffset; - // - // Each process has a default heap provided by the system + // WARNING: Each process has a default heap provided by the system // Memory objects allocated by GlobalAlloc and LocalAlloc are in private, - // committed pages with read/write access that cannot be accessed by other processes. + // committed pages with read/write access that cannot be accessed by other processes // // This may be wrong since we might be allocating in a DLL and freeing from another module, the main application // that may cause heap corruption. We could create a FreeImage function - // - bmpData = (BYTE *)malloc(sizeof(bmpFileHeader) + clipDataSize); + bmpData = (BYTE *)RL_MALLOC(sizeof(bmpFileHeader) + clipDataSize); // First we add the header for a bmp file - memcpy(bmpData, &bmpFileHeader, sizeof(bmpFileHeader)); + memcpy(bmpData, &bmpFileHeader, sizeof(bmpFileHeader)); // Add BMP file header data // Then we add the header for the bmp itself + the pixel data - memcpy(bmpData + sizeof(bmpFileHeader), bmpInfoHeader, clipDataSize); + memcpy(bmpData + sizeof(bmpFileHeader), bmpInfoHeader, clipDataSize); // Add BMP info header data + msgString = "Clipboad image acquired successfully"; - unlock: GlobalUnlock(clipHandle); close: @@ -291,6 +289,7 @@ close: end: TRACELOG(severity, msgString); + return bmpData; } @@ -298,65 +297,57 @@ static BOOL OpenClipboardRetrying(HWND hWnd) { static const int maxTries = 20; static const int sleepTimeMS = 60; - for (int _ = 0; _ < maxTries; ++_) + + for (int i = 0; i < maxTries; i++) { // Might be being hold by another process // Or yourself forgot to CloseClipboard - if (OpenClipboard(hWnd)) { - return true; - } + if (OpenClipboard(hWnd)) return true; + Sleep(sleepTimeMS); } + return false; } -// Based off of researching microsoft docs and reponses from this question https://stackoverflow.com/questions/30552255/how-to-read-a-bitmap-from-the-windows-clipboard#30552856 -// https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapinfoheader // Get the byte offset where does the pixels data start (from a packed DIB) +// REF: https://stackoverflow.com/questions/30552255/how-to-read-a-bitmap-from-the-windows-clipboard#30552856 +// REF: https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapinfoheader static int GetPixelDataOffset(BITMAPINFOHEADER bih) { int offset = 0; const unsigned int rgbaSize = sizeof(RGBQUAD); - // biSize Specifies the number of bytes required by the structure + // NOTE: biSize specifies the number of bytes required by the structure // We expect to always be 40 because it should be packed - if (40 == bih.biSize && 40 == sizeof(BITMAPINFOHEADER)) + if ((40 == bih.biSize) && (40 == sizeof(BITMAPINFOHEADER))) { - // - // biBitCount Specifies the number of bits per pixel. + // NOTE: biBitCount specifies the number of bits per pixel. // Might exist some bit masks *after* the header and *before* the pixel offset // we're looking, but only if we have more than // 8 bits per pixel, so we need to ajust for that - // if (bih.biBitCount > 8) { // if bih.biCompression is RBG we should NOT offset more - if (bih.biCompression == BI_BITFIELDS) + if (bih.biCompression == BI_BITFIELDS) offset += 3*rgbaSize; + else if (bih.biCompression == 6) // BI_ALPHABITFIELDS { - offset += 3 * rgbaSize; - } else if (bih.biCompression == 6 /* BI_ALPHABITFIELDS */) - { - // Not widely supported, but valid. - offset += 4 * rgbaSize; + // Not widely supported, but valid + offset += 4*rgbaSize; } } } - // - // biClrUsed Specifies the number of color indices in the color table that are actually used by the bitmap. + // NOTE: biClrUsed specifies the number of color indices in the color table that are actually used by the bitmap // If this value is zero, the bitmap uses the maximum number of colors - // corresponding to the value of the biBitCount member for the compression mode specified by biCompression. + // corresponding to the value of the biBitCount member for the compression mode specified by biCompression // If biClrUsed is nonzero and the biBitCount member is less than 16 // the biClrUsed member specifies the actual number of colors - // - if (bih.biClrUsed > 0) { - offset += bih.biClrUsed * rgbaSize; - } else { - if (bih.biBitCount < 16) - { - offset = offset + (rgbaSize << bih.biBitCount); - } + if (bih.biClrUsed > 0) offset += bih.biClrUsed*rgbaSize; + else + { + if (bih.biBitCount < 16) offset = offset + (rgbaSize << bih.biBitCount); } return bih.biSize + offset; From b39cc6bce70b78f0ba771c6b41a37db19e9169e8 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 9 Feb 2026 23:28:02 +0100 Subject: [PATCH 169/232] Update win32_clipboard.h --- src/external/win32_clipboard.h | 152 ++++++++++++++------------------- 1 file changed, 65 insertions(+), 87 deletions(-) diff --git a/src/external/win32_clipboard.h b/src/external/win32_clipboard.h index 75cd720a9..31caaf890 100644 --- a/src/external/win32_clipboard.h +++ b/src/external/win32_clipboard.h @@ -180,6 +180,10 @@ typedef struct tagRGBQUAD { #define BI_CMYKRLE8 0x000C #define BI_CMYKRLE4 0x000D +// Bitmap not compressed and that the color table consists of four DWORD color masks, +// that specify the red, green, blue, and alpha components of each pixel +#define BI_ALPHABITFIELDS 0x0006 + #endif // REF: https://learn.microsoft.com/en-us/windows/win32/dataxchg/standard-clipboard-formats @@ -208,91 +212,70 @@ static int GetPixelDataOffset(BITMAPINFOHEADER bih); //---------------------------------------------------------------------------------- unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned long long int *dataSize) { - HWND win = NULL; // Get from somewhere but is doesnt seem to matter - const char *msgString = ""; - int severity = LOG_INFO; - BYTE *bmpData = NULL; + unsigned char *bmpData = NULL; - if (!OpenClipboardRetrying(win)) + if (OpenClipboardRetrying(NULL)) { - severity = LOG_ERROR; - msgString = "Couldn't open clipboard"; - goto end; + HGLOBAL clipHandle = (HGLOBAL)GetClipboardData(CF_DIB); + if (clipHandle != NULL) + { + BITMAPINFOHEADER *bmpInfoHeader = (BITMAPINFOHEADER *)GlobalLock(clipHandle); + if (bmpInfoHeader) + { + *width = bmpInfoHeader->biWidth; + *height = bmpInfoHeader->biHeight; + SIZE_T clipDataSize = GlobalSize(clipHandle); + if (clipDataSize >= sizeof(BITMAPINFOHEADER)) + { + int pixelOffset = GetPixelDataOffset(*bmpInfoHeader); + + // Create the bytes for a correct BMP file and copy the data to a pointer + //------------------------------------------------------------------------ + BITMAPFILEHEADER bmpFileHeader = { 0 }; + SIZE_T bmpFileSize = sizeof(bmpFileHeader) + clipDataSize; + *dataSize = bmpFileSize; + + bmpFileHeader.bfType = 0x4D42; // BMP fil type constant + bmpFileHeader.bfSize = (DWORD)bmpFileSize; // Up to 4GB works fine + bmpFileHeader.bfOffBits = sizeof(bmpFileHeader) + pixelOffset; + + bmpData = (unsigned char *)RL_MALLOC(sizeof(bmpFileHeader) + clipDataSize); + memcpy(bmpData, &bmpFileHeader, sizeof(bmpFileHeader)); // Add BMP file header data + memcpy(bmpData + sizeof(bmpFileHeader), bmpInfoHeader, clipDataSize); // Add BMP info header data + + GlobalUnlock(clipHandle); + CloseClipboard(); + + TRACELOG(LOG_INFO, "Clipboad image acquired successfully"); + //------------------------------------------------------------------------ + } + else + { + TRACELOG(LOG_WARNING, "Clipboard data is malformed"); + GlobalUnlock(clipHandle); + CloseClipboard(); + } + } + else + { + TRACELOG(LOG_WARNING, "Clipboard data failed to be locked"); + GlobalUnlock(clipHandle); + CloseClipboard(); + } + } + else + { + TRACELOG(LOG_WARNING, "Clipboard data is not an image"); + CloseClipboard(); + } } + else TRACELOG(LOG_WARNING, "Clipboard can not be opened"); - HGLOBAL clipHandle = (HGLOBAL)GetClipboardData(CF_DIB); - if (!clipHandle) - { - severity = LOG_ERROR; - msgString = "Clipboard data is not an Image"; - goto close; - } - - BITMAPINFOHEADER *bmpInfoHeader = (BITMAPINFOHEADER *)GlobalLock(clipHandle); - if (!bmpInfoHeader) - { - // Mapping from HGLOBAL to our local *address space* failed - severity = LOG_ERROR; - msgString = "Clipboard data failed to be locked"; - goto unlock; - } - - *width = bmpInfoHeader->biWidth; - *height = bmpInfoHeader->biHeight; - - SIZE_T clipDataSize = GlobalSize(clipHandle); - if (clipDataSize < sizeof(BITMAPINFOHEADER)) - { - // Format CF_DIB needs space for BITMAPINFOHEADER struct. - msgString = "Clipboard has Malformed data"; - severity = LOG_ERROR; - goto unlock; - } - - // Denotes where the pixel data starts from the bmpInfoHeader pointer - int pixelOffset = GetPixelDataOffset(*bmpInfoHeader); - - //--------------------------------------------------------------------------------// - // - // The rest of the section is about create the bytes for a correct BMP file - // Then we copy the data and to a pointer - // - //--------------------------------------------------------------------------------// - - BITMAPFILEHEADER bmpFileHeader = { 0 }; - SIZE_T bmpFileSize = sizeof(bmpFileHeader) + clipDataSize; - *dataSize = bmpFileSize; - - bmpFileHeader.bfType = 0x4D42; // REF: https://stackoverflow.com/questions/601430/multibyte-character-constants-and-bitmap-file-header-type-constants#601536 - - bmpFileHeader.bfSize = (DWORD)bmpFileSize; // Up to 4GB works fine - bmpFileHeader.bfOffBits = sizeof(bmpFileHeader) + pixelOffset; - - // WARNING: Each process has a default heap provided by the system - // Memory objects allocated by GlobalAlloc and LocalAlloc are in private, - // committed pages with read/write access that cannot be accessed by other processes - // - // This may be wrong since we might be allocating in a DLL and freeing from another module, the main application - // that may cause heap corruption. We could create a FreeImage function - bmpData = (BYTE *)RL_MALLOC(sizeof(bmpFileHeader) + clipDataSize); - // First we add the header for a bmp file - memcpy(bmpData, &bmpFileHeader, sizeof(bmpFileHeader)); // Add BMP file header data - // Then we add the header for the bmp itself + the pixel data - memcpy(bmpData + sizeof(bmpFileHeader), bmpInfoHeader, clipDataSize); // Add BMP info header data - - msgString = "Clipboad image acquired successfully"; - -unlock: - GlobalUnlock(clipHandle); -close: - CloseClipboard(); -end: - - TRACELOG(severity, msgString); - return bmpData; } +// Open clipboard with several tries +// NOTE: If parameter is NULL, the open clipboard is associated with the current task static BOOL OpenClipboardRetrying(HWND hWnd) { static const int maxTries = 20; @@ -320,22 +303,18 @@ static int GetPixelDataOffset(BITMAPINFOHEADER bih) // NOTE: biSize specifies the number of bytes required by the structure // We expect to always be 40 because it should be packed - if ((40 == bih.biSize) && (40 == sizeof(BITMAPINFOHEADER))) + if ((bih.biSize == 40) && (sizeof(BITMAPINFOHEADER) == 40)) { - // NOTE: biBitCount specifies the number of bits per pixel. + // NOTE: biBitCount specifies the number of bits per pixel // Might exist some bit masks *after* the header and *before* the pixel offset // we're looking, but only if we have more than // 8 bits per pixel, so we need to ajust for that if (bih.biBitCount > 8) { - // if bih.biCompression is RBG we should NOT offset more + // If (bih.biCompression == BI_RGB) we should NOT offset more if (bih.biCompression == BI_BITFIELDS) offset += 3*rgbaSize; - else if (bih.biCompression == 6) // BI_ALPHABITFIELDS - { - // Not widely supported, but valid - offset += 4*rgbaSize; - } + else if (bih.biCompression == BI_ALPHABITFIELDS) offset += 4*rgbaSize; // Not widely supported, but valid } } @@ -353,4 +332,3 @@ static int GetPixelDataOffset(BITMAPINFOHEADER bih) return bih.biSize + offset; } #endif // WIN32_CLIPBOARD_IMPLEMENTATION -// EOF From 3b647c85e1749c8131e46387aa044cb009e60b10 Mon Sep 17 00:00:00 2001 From: "Nikolai S. Kiselev" Date: Tue, 10 Feb 2026 00:05:35 +0100 Subject: [PATCH 170/232] raymath: wrap float3 and float16 for consistency with other types (#5540) --- src/raymath.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/raymath.h b/src/raymath.h index 0f9cbc38b..214495a2c 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -164,13 +164,19 @@ typedef struct Matrix { #endif // NOTE: Helper types to be used instead of array return types for *ToFloat functions +#if !defined(RL_FLOAT3_TYPE) typedef struct float3 { float v[3]; } float3; +#define RL_FLOAT3_TYPE +#endif +#if !defined(RL_FLOAT16_TYPE) typedef struct float16 { float v[16]; } float16; +#define RL_FLOAT16_TYPE +#endif #include // Required for: sinf(), cosf(), tan(), atan2f(), sqrtf(), floor(), fminf(), fmaxf(), fabsf() From efda35b309e012dda56288072d4de57448f85fd0 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 10 Feb 2026 00:37:45 +0100 Subject: [PATCH 171/232] Update win32_clipboard.h --- src/external/win32_clipboard.h | 78 ++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/src/external/win32_clipboard.h b/src/external/win32_clipboard.h index 31caaf890..6845b0c2e 100644 --- a/src/external/win32_clipboard.h +++ b/src/external/win32_clipboard.h @@ -16,38 +16,38 @@ unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned long // NOTE: These search for architecture is taken from "Windows.h", and it's necessary if we really don't wanna import windows.h // and still make it compile on msvc, because import indirectly importing "winnt.h" (e.g. ) can cause problems is these are not defined. #if !defined(_X86_) && !defined(_68K_) && !defined(_MPPC_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64_) && !defined(_ARM64EC_) && defined(_M_IX86) -#define _X86_ -#if !defined(_CHPE_X86_ARM64_) && defined(_M_HYBRID) -#define _CHPE_X86_ARM64_ -#endif + #define _X86_ + #if !defined(_CHPE_X86_ARM64_) && defined(_M_HYBRID) + #define _CHPE_X86_ARM64_ + #endif #endif #if !defined(_AMD64_) && !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64_) && (defined(_M_AMD64) || defined(_M_ARM64EC)) -#define _AMD64_ + #define _AMD64_ #endif #if !defined(_ARM_) && !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM64_) && !defined(_ARM64EC_) && defined(_M_ARM) -#define _ARM_ + #define _ARM_ #endif #if !defined(_ARM64_) && !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64EC_) && defined(_M_ARM64) -#define _ARM64_ + #define _ARM64_ #endif #if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_ARM_) && !defined(_ARM64_) && !defined(_ARM64EC_) && defined(_M_ARM64EC) -#define _ARM64EC_ + #define _ARM64EC_ #endif #if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64_) && !defined(_ARM64EC_) && defined(_M_M68K) -#define _68K_ + #define _68K_ #endif #if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64_) && !defined(_ARM64EC_) && defined(_M_MPPC) -#define _MPPC_ + #define _MPPC_ #endif #if !defined(_IA64_) && !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_M_IX86) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64_) && !defined(_ARM64EC_) && defined(_M_IA64) -#define _IA64_ + #define _IA64_ #endif @@ -59,35 +59,35 @@ unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned long // #include #ifndef WINAPI -#if defined(_ARM_) -#define WINAPI -#else -#define WINAPI __stdcall -#endif + #if defined(_ARM_) + #define WINAPI + #else + #define WINAPI __stdcall + #endif #endif #ifndef WINAPI -#if defined(_ARM_) -#define WINAPI -#else -#define WINAPI __stdcall -#endif + #if defined(_ARM_) + #define WINAPI + #else + #define WINAPI __stdcall + #endif #endif #ifndef WINBASEAPI -#ifndef _KERNEL32_ -#define WINBASEAPI DECLSPEC_IMPORT -#else -#define WINBASEAPI -#endif + #ifndef _KERNEL32_ + #define WINBASEAPI DECLSPEC_IMPORT + #else + #define WINBASEAPI + #endif #endif #ifndef WINUSERAPI -#ifndef _USER32_ -#define WINUSERAPI __declspec (dllimport) -#else -#define WINUSERAPI -#endif + #ifndef _USER32_ + #define WINUSERAPI __declspec (dllimport) + #else + #define WINUSERAPI + #endif #endif typedef int WINBOOL; @@ -115,7 +115,7 @@ WINUSERAPI HWND WINAPI GetOpenClipboardWindow(VOID); #endif #ifndef HGLOBAL -#define HGLOBAL void* + #define HGLOBAL void* #endif #if !defined(_WINBASE_) || !defined(WINBASE_ALREADY_INCLUDED) @@ -124,7 +124,6 @@ WINBASEAPI LPVOID WINAPI GlobalLock (HGLOBAL hMem); WINBASEAPI WINBOOL WINAPI GlobalUnlock (HGLOBAL hMem); #endif - #if !defined(_WINGDI_) || !defined(WINGDI_ALREADY_INCLUDED) #ifndef BITMAPINFOHEADER_ALREADY_DEFINED #define BITMAPINFOHEADER_ALREADY_DEFINED @@ -183,7 +182,6 @@ typedef struct tagRGBQUAD { // Bitmap not compressed and that the color table consists of four DWORD color masks, // that specify the red, green, blue, and alpha components of each pixel #define BI_ALPHABITFIELDS 0x0006 - #endif // REF: https://learn.microsoft.com/en-us/windows/win32/dataxchg/standard-clipboard-formats @@ -204,12 +202,15 @@ typedef struct tagRGBQUAD { // #define OCR_HAND 32649 // Link select // #define OCR_APPSTARTING 32650 // -static BOOL OpenClipboardRetrying(HWND handle); // Open clipboard with a number of retries -static int GetPixelDataOffset(BITMAPINFOHEADER bih); - //---------------------------------------------------------------------------------- // Module Internal Functions Declaration //---------------------------------------------------------------------------------- +static BOOL OpenClipboardRetrying(HWND handle); // Open clipboard with a number of retries +static int GetPixelDataOffset(BITMAPINFOHEADER bih); // Get pixel data offset from DIB image + +//---------------------------------------------------------------------------------- +// Module Functions Definition +//---------------------------------------------------------------------------------- unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned long long int *dataSize) { unsigned char *bmpData = NULL; @@ -274,6 +275,9 @@ unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned long return bmpData; } +//---------------------------------------------------------------------------------- +// Module Internal Functions Definition +//---------------------------------------------------------------------------------- // Open clipboard with several tries // NOTE: If parameter is NULL, the open clipboard is associated with the current task static BOOL OpenClipboardRetrying(HWND hWnd) From 4b01c23ba678d4c1243fcc6ecc4672df9fe71872 Mon Sep 17 00:00:00 2001 From: dtasada <83500532+dtasada@users.noreply.github.com> Date: Tue, 10 Feb 2026 08:33:31 +0100 Subject: [PATCH 172/232] [build] Zig master branch compatibility for `build.zig`. (#5520) * fixed build errors with zig. now compatible with zig master 0.16.0-dev.1593+c13857e50. still backwards compatible with 0.15.1 * [build] building with zig-master 0.16.0-dev.2349+204fa8959. * [build] building with zig-master 0.16.0-dev.2349+204fa8959, now compatible with zig 0.15 * build: removed compatibility with zig 0.15.2. * inlined processExample function to minimize diffs --- build.zig | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/build.zig b/build.zig index ab98bbe98..7eb46699e 100644 --- a/build.zig +++ b/build.zig @@ -2,7 +2,7 @@ const std = @import("std"); const builtin = @import("builtin"); /// Minimum supported version of Zig -const min_ver = "0.15.1"; +const min_ver = "0.16.0-dev.2349+204fa8959"; const emccOutputDir = "zig-out" ++ std.fs.path.sep_str ++ "htmlout" ++ std.fs.path.sep_str; const emccOutputFile = "index.html"; @@ -197,7 +197,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std. } var c_source_files: std.ArrayList([]const u8) = try .initCapacity(b.allocator, 2); - c_source_files.appendSliceAssumeCapacity(&.{ "src/rcore.c" }); + c_source_files.appendSliceAssumeCapacity(&.{"src/rcore.c"}); if (options.rshapes) { try c_source_files.append(b.allocator, "src/rshapes.c"); @@ -448,7 +448,7 @@ pub const Options = struct { .linux_display_backend = b.option(LinuxDisplayBackend, "linux_display_backend", "Linux display backend to use") orelse defaults.linux_display_backend, .opengl_version = b.option(OpenglVersion, "opengl_version", "OpenGL version to use") orelse defaults.opengl_version, .config = b.option([]const u8, "config", "Compile with custom define macros overriding config.h") orelse &.{}, - .android_ndk = b.option([]const u8, "android_ndk", "specify path to android ndk") orelse std.process.getEnvVarOwned(b.allocator, "ANDROID_NDK_HOME") catch "", + .android_ndk = b.option([]const u8, "android_ndk", "specify path to android ndk") orelse b.graph.environ_map.get("ANDROID_NDK_HOME") orelse "", .android_api_version = b.option([]const u8, "android_api_version", "specify target android API level") orelse defaults.android_api_version, }; } @@ -523,15 +523,17 @@ fn addExamples( ) !*std.Build.Step { const all = b.step(module, "All " ++ module ++ " examples"); const module_subpath = b.pathJoin(&.{ "examples", module }); - var dir = try std.fs.cwd().openDir(b.pathFromRoot(module_subpath), .{ .iterate = true }); - defer dir.close(); + + var dir = try std.Io.Dir.cwd().openDir(b.graph.io, b.pathFromRoot(module_subpath), .{ .iterate = true }); + defer dir.close(b.graph.io); var iter = dir.iterate(); - while (try iter.next()) |entry| { + while (try iter.next(b.graph.io)) |entry| { if (entry.kind != .file) continue; const extension_idx = std.mem.lastIndexOf(u8, entry.name, ".c") orelse continue; const name = entry.name[0..extension_idx]; - const path = b.pathJoin(&.{ module_subpath, entry.name }); + const filename = try std.fmt.allocPrint(b.allocator, "{s}.c", .{name}); + const path = b.pathJoin(&.{ module_subpath, filename }); // zig's mingw headers do not include pthread.h if (std.mem.eql(u8, "core_loading_thread", name) and target.result.os.tag == .windows) continue; @@ -553,12 +555,11 @@ fn addExamples( }); if (std.mem.eql(u8, name, "rlgl_standalone")) { - //TODO: Make rlgl_standalone example work - continue; + exe_mod.addIncludePath(b.path("src")); + exe_mod.addIncludePath(b.path("src/external/glfw/include")); } if (std.mem.eql(u8, name, "raylib_opengl_interop")) { - //TODO: Make raylib_opengl_interop example work - continue; + exe_mod.addIncludePath(b.path("src/external")); } const emcc_flags = emsdk.emccDefaultFlags(b.allocator, .{ .optimize = optimize }); @@ -650,6 +651,7 @@ fn addExamples( all.dependOn(&install_cmd.step); } } + return all; } From 48ec41f0ec2d2ed26c917c5d88d8e25e57c37db2 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 10 Feb 2026 18:02:36 +0100 Subject: [PATCH 173/232] Update raylib.h --- src/raylib.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/raylib.h b/src/raylib.h index 66cfe4387..b4b175919 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -417,11 +417,11 @@ typedef struct Model { // ModelAnimation typedef struct ModelAnimation { + char name[32]; // Animation name int boneCount; // Number of bones int frameCount; // Number of animation frames BoneInfo *bones; // Bones information (skeleton) Transform **framePoses; // Poses array by frame - char name[32]; // Animation name } ModelAnimation; // Ray, ray for raycasting From 3aced1fd7c44c5089c1d8d79d2b37adfa094039d Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 10 Feb 2026 18:02:42 +0100 Subject: [PATCH 174/232] Update rmodels.c --- src/rmodels.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/rmodels.c b/src/rmodels.c index 6f3ae995f..755d0437d 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -2358,11 +2358,12 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, int frame) Mesh mesh = model.meshes[m]; Vector3 animVertex = { 0 }; Vector3 animNormal = { 0 }; + const int vValues = mesh.vertexCount*3; + int boneId = 0; int boneCounter = 0; - float boneWeight = 0.0; + float boneWeight = 0.0f; bool updated = false; // Flag to check when anim vertex information is updated - const int vValues = mesh.vertexCount*3; // Skip if missing bone data, causes segfault without on some models if ((mesh.boneWeights == NULL) || (mesh.boneIds == NULL)) continue; @@ -2388,7 +2389,7 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, int frame) // Early stop when no transformation will be applied if (boneWeight == 0.0f) continue; animVertex = (Vector3){ mesh.vertices[vCounter], mesh.vertices[vCounter + 1], mesh.vertices[vCounter + 2] }; - animVertex = Vector3Transform(animVertex,model.meshes[m].boneMatrices[boneId]); + animVertex = Vector3Transform(animVertex, model.meshes[m].boneMatrices[boneId]); mesh.animVertices[vCounter] += animVertex.x*boneWeight; mesh.animVertices[vCounter+1] += animVertex.y*boneWeight; mesh.animVertices[vCounter+2] += animVertex.z*boneWeight; From 919ad68ca71fc2f4c173694e163f3df21edefca0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 17:02:58 +0000 Subject: [PATCH 175/232] rlparser: update raylib_api.* by CI --- tools/rlparser/output/raylib_api.json | 10 +++++----- tools/rlparser/output/raylib_api.lua | 10 +++++----- tools/rlparser/output/raylib_api.txt | 10 +++++----- tools/rlparser/output/raylib_api.xml | 2 +- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tools/rlparser/output/raylib_api.json b/tools/rlparser/output/raylib_api.json index d4c059c50..96875fe87 100644 --- a/tools/rlparser/output/raylib_api.json +++ b/tools/rlparser/output/raylib_api.json @@ -1029,6 +1029,11 @@ "name": "ModelAnimation", "description": "ModelAnimation", "fields": [ + { + "type": "char[32]", + "name": "name", + "description": "Animation name" + }, { "type": "int", "name": "boneCount", @@ -1048,11 +1053,6 @@ "type": "Transform **", "name": "framePoses", "description": "Poses array by frame" - }, - { - "type": "char[32]", - "name": "name", - "description": "Animation name" } ] }, diff --git a/tools/rlparser/output/raylib_api.lua b/tools/rlparser/output/raylib_api.lua index 2de69f69c..a1f79cbe6 100644 --- a/tools/rlparser/output/raylib_api.lua +++ b/tools/rlparser/output/raylib_api.lua @@ -1029,6 +1029,11 @@ return { name = "ModelAnimation", description = "ModelAnimation", fields = { + { + type = "char[32]", + name = "name", + description = "Animation name" + }, { type = "int", name = "boneCount", @@ -1048,11 +1053,6 @@ return { type = "Transform **", name = "framePoses", description = "Poses array by frame" - }, - { - type = "char[32]", - name = "name", - description = "Animation name" } } }, diff --git a/tools/rlparser/output/raylib_api.txt b/tools/rlparser/output/raylib_api.txt index 53dbf8813..e7ff4c98b 100644 --- a/tools/rlparser/output/raylib_api.txt +++ b/tools/rlparser/output/raylib_api.txt @@ -466,11 +466,11 @@ Struct 21: Model (9 fields) Struct 22: ModelAnimation (5 fields) Name: ModelAnimation Description: ModelAnimation - Field[1]: int boneCount // Number of bones - Field[2]: int frameCount // Number of animation frames - Field[3]: BoneInfo * bones // Bones information (skeleton) - Field[4]: Transform ** framePoses // Poses array by frame - Field[5]: char[32] name // Animation name + Field[1]: char[32] name // Animation name + Field[2]: int boneCount // Number of bones + Field[3]: int frameCount // Number of animation frames + Field[4]: BoneInfo * bones // Bones information (skeleton) + Field[5]: Transform ** framePoses // Poses array by frame Struct 23: Ray (2 fields) Name: Ray Description: Ray, ray for raycasting diff --git a/tools/rlparser/output/raylib_api.xml b/tools/rlparser/output/raylib_api.xml index c1f9bc818..8734f405d 100644 --- a/tools/rlparser/output/raylib_api.xml +++ b/tools/rlparser/output/raylib_api.xml @@ -214,11 +214,11 @@ + - From 64848bbd4cbf7ef7f8b0a95336e9cbcc308ce3aa Mon Sep 17 00:00:00 2001 From: Vadim Gunko Date: Wed, 11 Feb 2026 23:12:15 +0500 Subject: [PATCH 176/232] Update BINDINGS.md (#5546) added support for Delphi --- BINDINGS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BINDINGS.md b/BINDINGS.md index 5ef67c98f..6c405ab66 100644 --- a/BINDINGS.md +++ b/BINDINGS.md @@ -63,7 +63,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers | [raylib_odin_bindings](https://github.com/Deathbat2190/raylib_odin_bindings) | 4.0-dev | [Odin](https://odin-lang.org) | MIT | | [raylib-ocaml](https://github.com/tjammer/raylib-ocaml) | **5.0** | [OCaml](https://ocaml.org) | MIT | | [TurboRaylib](https://github.com/turborium/TurboRaylib) | 4.5 | [Object Pascal](https://en.wikipedia.org/wiki/Object_Pascal) | MIT | -| [Ray4Laz](https://github.com/GuvaCode/Ray4Laz) | **5.5** | [Free Pascal](https://en.wikipedia.org/wiki/Free_Pascal) | Zlib | +| [Ray4Laz](https://github.com/GuvaCode/Ray4Laz) | **5.5** | [Free Pascal](https://en.wikipedia.org/wiki/Free_Pascal)/[Delphi](https://en.wikipedia.org/wiki/Delphi_(software)) | Zlib | | [Raylib.4.0.Pascal](https://github.com/sysrpl/Raylib.4.0.Pascal) | 4.0 | [Free Pascal](https://en.wikipedia.org/wiki/Free_Pascal) | Zlib | | [pyraylib](https://github.com/Ho011/pyraylib) | 3.7 | [Python](https://www.python.org) | Zlib | | [raylib-python-cffi](https://github.com/electronstudio/raylib-python-cffi) | **5.5** | [Python](https://www.python.org) | EPL-2.0 | @@ -185,4 +185,4 @@ Missing some language or wrapper? Feel free to create a new one! :) Usually, raylib bindings follow the convention: `raylib-{language}` -Let me know if you're writing a new binding for raylib, I will list it here! \ No newline at end of file +Let me know if you're writing a new binding for raylib, I will list it here! From 85de580527e96f327d474cd865afba5b68ed4f72 Mon Sep 17 00:00:00 2001 From: Max Coplan Date: Thu, 12 Feb 2026 07:15:47 -0800 Subject: [PATCH 177/232] fix(examples): don't bleed fog when on edge (#5547) Steps to reproduce: 1. play textures_fog_of_war example 2. Move player to edge of screen 3. Note the light bleeds to the other side of the screen --- examples/textures/textures_fog_of_war.c | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/textures/textures_fog_of_war.c b/examples/textures/textures_fog_of_war.c index ea98b03ce..1354d7124 100644 --- a/examples/textures/textures_fog_of_war.c +++ b/examples/textures/textures_fog_of_war.c @@ -68,6 +68,7 @@ int main(void) // at a smaller size (one pixel per tile) and scale it on drawing with bilinear filtering RenderTexture2D fogOfWar = LoadRenderTexture(map.tilesX, map.tilesY); SetTextureFilter(fogOfWar.texture, TEXTURE_FILTER_BILINEAR); + SetTextureWrap(fogOfWar.texture, TEXTURE_WRAP_CLAMP); SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- From 4e7c38ac43a23a96aec7f96ed4fef2b0cf12e981 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yui=20Kinomoto=20/=20=E3=81=8D=E3=81=AE=E3=82=82=E3=81=A8?= =?UTF-8?q?=20=E7=B5=90=E8=A1=A3?= Date: Fri, 13 Feb 2026 01:04:22 +0900 Subject: [PATCH 178/232] fix SDL SetGamepadMappings (#5548) --- src/platforms/rcore_desktop_sdl.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index 66a917da2..ae44728c4 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -1287,7 +1287,25 @@ void OpenURL(const char *url) // Set internal gamepad mappings int SetGamepadMappings(const char *mappings) { - return SDL_GameControllerAddMapping(mappings); + const int mappingsLength = strlen(mappings); + char *buffer = (char *)RL_CALLOC(mappingsLength + 1, sizeof(char)); + memcpy(buffer, mappings, mappingsLength); + char *p = strtok(buffer, "\n"); + bool succeed = true; + + while (p != NULL) + { + if (SDL_GameControllerAddMapping(p) == -1) + { + succeed = false; + } + p = strtok(NULL, "\n"); + } + + RL_FREE(buffer); + + // To make return value is consistent with the GLFW version. + return (succeed)? 1 : 0; } // Set gamepad vibration From 070082f8c950ef83708253a64d5a5e89fdbed705 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 12 Feb 2026 18:55:40 +0100 Subject: [PATCH 179/232] REVIEWED: Comments to impersonal format --- src/platforms/rcore_android.c | 32 ++++++++++++++-------------- src/platforms/rcore_desktop_sdl.c | 18 ++++++++-------- src/platforms/rcore_desktop_win32.c | 18 ++++++++-------- src/platforms/rcore_drm.c | 14 +++++------- src/platforms/rcore_web.c | 24 ++++++++++----------- src/platforms/rcore_web_emscripten.c | 4 ++-- src/raudio.c | 4 ++-- src/rtext.c | 2 +- src/rtextures.c | 31 ++++++++++++--------------- 9 files changed, 70 insertions(+), 77 deletions(-) diff --git a/src/platforms/rcore_android.c b/src/platforms/rcore_android.c index 65236be0f..74c7b3792 100644 --- a/src/platforms/rcore_android.c +++ b/src/platforms/rcore_android.c @@ -290,8 +290,8 @@ FILE *funopen(const void *cookie, int (*readfn)(void *, char *, int), int (*writ // Module Functions Definition: Application //---------------------------------------------------------------------------------- -// To allow easier porting to android, we allow the user to define a -// main function which we call from android_main, defined by ourselves +// To allow easier porting to android, allow the user to define a +// custom main function which is called from android_main extern int main(int argc, char *argv[]); // Android main function @@ -313,7 +313,7 @@ void android_main(struct android_app *app) // Waiting for application events before complete finishing while (!app->destroyRequested) { - // Poll all events until we reach return value TIMEOUT, meaning no events left to process + // Poll all events until return value TIMEOUT is reached, meaning no events left to process while ((pollResult = ALooper_pollOnce(0, NULL, &pollEvents, (void **)&platform.source)) > ALOOPER_POLL_TIMEOUT) { if (platform.source != NULL) platform.source->process(app, platform.source); @@ -640,9 +640,9 @@ double GetTime(void) } // Open URL with default system browser (if available) -// NOTE: This function is only safe to use if you control the URL given +// NOTE: This function is only safe to use if the provided URL is safe // 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 +// Avoid calling this function with user input non-validated strings void OpenURL(const char *url) { // Security check to (partially) avoid malicious code @@ -757,7 +757,7 @@ void PollInputEvents(void) int pollResult = 0; int pollEvents = 0; - // Poll Events (registered events) until we reach TIMEOUT which indicates there are no events left to poll + // Poll Events (registered events) until TIMEOUT is reached which indicates there are no events left to poll // 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)) { @@ -843,7 +843,7 @@ int InitPlatform(void) // Wait for window to be initialized (display and context) while (!CORE.Window.ready) { - // Process events until we reach TIMEOUT, which indicates no more events queued + // Process events until TIMEOUT is reached, which indicates no more events queued while ((pollResult = ALooper_pollOnce(0, NULL, &pollEvents, ((void **)&platform.source)) > ALOOPER_POLL_TIMEOUT)) { // Process this event @@ -964,10 +964,10 @@ static int InitGraphicsDevice(void) 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 + // As soon as an EGLConfig is picked, it's safe to reconfigure the ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID eglGetConfigAttrib(platform.device, platform.config, EGL_NATIVE_VISUAL_ID, &displayFormat); - // At this point we need to manage render size vs screen size + // At this point render size vs screen size needs to be managed // NOTE: This function use and modify global module variables: // -> CORE.Window.screen.width/CORE.Window.screen.height // -> CORE.Window.render.width/CORE.Window.render.height @@ -1075,12 +1075,12 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd) Rectangle rec = GetFontDefault().recs[95]; if (FLAG_IS_SET(CORE.Window.flags, FLAG_MSAA_4X_HINT)) { - // NOTE: We try to maxime rec padding to avoid pixel bleeding on MSAA filtering + // NOTE: Trying to maxime rec padding to avoid pixel bleeding on MSAA filtering SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 2, rec.y + 2, 1, 1 }); } else { - // NOTE: We set up a 1px padding on char rectangle to avoid pixel bleeding + // NOTE: Setting up a 1px padding on char rectangle to avoid pixel bleeding SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2 }); } #endif @@ -1450,7 +1450,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) // NOTE: Global variables CORE.Window.render.width/CORE.Window.render.height and CORE.Window.renderOffset.x/CORE.Window.renderOffset.y can be modified static void SetupFramebuffer(int width, int height) { - // Calculate CORE.Window.render.width and CORE.Window.render.height, we have the display size (input params) and the desired screen size (global var) + // Calculate CORE.Window.render.width and CORE.Window.render.height, having the display size (input params) and the desired screen size (global var) if ((CORE.Window.screen.width > CORE.Window.display.width) || (CORE.Window.screen.height > CORE.Window.display.height)) { TRACELOG(LOG_WARNING, "DISPLAY: Downscaling required: Screen size (%ix%i) is bigger than display size (%ix%i)", CORE.Window.screen.width, CORE.Window.screen.height, CORE.Window.display.width, CORE.Window.display.height); @@ -1478,8 +1478,8 @@ static void SetupFramebuffer(int width, int height) float scaleRatio = (float)CORE.Window.render.width/(float)CORE.Window.screen.width; CORE.Window.screenScale = MatrixScale(scaleRatio, scaleRatio, 1.0f); - // NOTE: We render to full display resolution! - // We just need to calculate above parameters for downscale matrix and offsets + // NOTE: Rendering to full display resolution + // Above parameters need to be calculate for downscale matrix and offsets CORE.Window.render.width = CORE.Window.display.width; CORE.Window.render.height = CORE.Window.display.height; @@ -1533,8 +1533,8 @@ FILE *android_fopen(const char *fileName, const char *mode) if (mode[0] == 'w') { // NOTE: fopen() is mapped to android_fopen() that only grants read access to - // assets directory through AAssetManager but we want to also be able to - // write data when required using the standard stdio FILE access functions + // assets directory through AAssetManager but it could be required to write data + // using the standard stdio FILE access functions // REF: https://stackoverflow.com/questions/11294487/android-writing-saving-files-from-native-code-only #undef fopen file = fopen(TextFormat("%s/%s", platform.app->activity->internalDataPath, fileName), mode); diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index ae44728c4..ca49e6a8e 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -255,9 +255,9 @@ static const int CursorsLUT[] = { // SDL3 Migration: // SDL_WINDOW_FULLSCREEN_DESKTOP has been removed, -// and you can call SDL_GetWindowFullscreenMode() +// SDL_GetWindowFullscreenMode() can be called // to see whether an exclusive fullscreen mode will be used -// or the borderless fullscreen desktop mode will be used +// or the borderless fullscreen desktop mode #define SDL_WINDOW_FULLSCREEN_DESKTOP SDL_WINDOW_FULLSCREEN #define SDL_IGNORE false @@ -1269,9 +1269,9 @@ double GetTime(void) } // Open URL with default system browser (if available) -// NOTE: This function is only safe to use if you control the URL given +// NOTE: This function is only safe to use if the provided URL is safe // 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 +// Avoid calling this function with user input non-validated strings // REF: https://github.com/raysan5/raylib/issues/686 void OpenURL(const char *url) { @@ -1437,9 +1437,9 @@ void PollInputEvents(void) #if defined(USING_VERSION_SDL3) // const char *data; // The text for SDL_EVENT_DROP_TEXT and the file name for SDL_EVENT_DROP_FILE, NULL for other events - // Event memory is now managed by SDL, so you should not free the data in SDL_EVENT_DROP_FILE, - // and if you want to hold onto the text in SDL_EVENT_TEXT_EDITING and SDL_EVENT_TEXT_INPUT events, - // you should make a copy of it. SDL_TEXTINPUTEVENT_TEXT_SIZE is no longer necessary and has been removed + // Event memory is now managed by SDL, so it should not be freed in SDL_EVENT_DROP_FILE, + // in case data needs to be hold onto the text in SDL_EVENT_TEXT_EDITING and SDL_EVENT_TEXT_INPUT events, + // a copy is required, SDL_TEXTINPUTEVENT_TEXT_SIZE is no longer necessary and has been removed strncpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.data, MAX_FILEPATH_LENGTH - 1); #else strncpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file, MAX_FILEPATH_LENGTH - 1); @@ -1468,10 +1468,10 @@ void PollInputEvents(void) // Window events are also polled (minimized, maximized, close...) #ifndef USING_VERSION_SDL3 - // SDL3 states: // The SDL_WINDOWEVENT_* events have been moved to top level events, and SDL_WINDOWEVENT has been removed // In general, handling this change just means checking for the individual events instead of first checking for SDL_WINDOWEVENT - // and then checking for window events. You can compare the event >= SDL_EVENT_WINDOW_FIRST and <= SDL_EVENT_WINDOW_LAST if you need to see whether it's a window event + // and then checking for window events; Events >= SDL_EVENT_WINDOW_FIRST and <= SDL_EVENT_WINDOW_LAST can be compared + // to see whether it's a window event case SDL_WINDOWEVENT: { switch (event.window.event) diff --git a/src/platforms/rcore_desktop_win32.c b/src/platforms/rcore_desktop_win32.c index 17d4fc530..8cb9645d2 100644 --- a/src/platforms/rcore_desktop_win32.c +++ b/src/platforms/rcore_desktop_win32.c @@ -1244,9 +1244,9 @@ double GetTime(void) } // Open URL with default system browser (if available) -// NOTE: This function is only safe to use if you control the URL given +// NOTE: This function is only safe to use if the provided URL is safe // 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 +// Avoid calling this function with user input non-validated strings // REF: https://github.com/raysan5/raylib/issues/686 void OpenURL(const char *url) { @@ -1864,9 +1864,9 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara } break; case WM_SIZE: { - // WARNING: Don't trust the docs, they say you won't get this message if you don't call DefWindowProc - // in response to WM_WINDOWPOSCHANGED but looks like when a window is created you'll get this - // message without getting WM_WINDOWPOSCHANGED + // WARNING: Don't trust the docs, they say this message can not be obtained if not calling DefWindowProc() + // in response to WM_WINDOWPOSCHANGED but looks like when a window is created, + // this message can be obtained without getting WM_WINDOWPOSCHANGED HandleWindowResize(hwnd, &platform.appScreenWidth, &platform.appScreenHeight); } break; //case WM_MOVE @@ -2187,10 +2187,10 @@ static unsigned SanitizeFlags(int mode, unsigned flags) // window. This function will continue to perform these update operations so long as // the state continues to change // -// This design takes care of many odd corner cases. For example, if you want to restore -// a window that was previously maximized AND minimized and you want to remove both these -// flags, you actually need to call ShowWindow with SW_RESTORE twice. Another example is -// if you have a maximized window, if the undecorated flag is modified then the window style +// This design takes care of many odd corner cases. For example, in case of restoring +// a window that was previously maximized AND minimized and those two flags need to be removed, +// ShowWindow with SW_RESTORE twice need to bee actually calleed. Another example is +// wheen having a maximized window, if the undecorated flag is modified then the window style // needs to be updated, but updating the style would mean the window size would change // causing the window to lose its Maximized state which would mean the window size // needs to be updated, followed by the update of window style, a second time, to restore that maximized diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index 6d3394f69..85db9b4e1 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -1017,10 +1017,9 @@ double GetTime(void) } // Open URL with default system browser (if available) -// NOTE: This function is only safe to use if you control the URL given +// NOTE: This function is only safe to use if the provided URL is safe // 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 +// Avoid calling this function with user input non-validated strings void OpenURL(const char *url) { TRACELOG(LOG_WARNING, "OpenURL() not implemented on target platform"); @@ -2149,14 +2148,11 @@ static void ConfigureEvdevDevice(char *device) if (absAxisCount > 0) { - // TODO / NOTE + // TODO: Review GamepadAxis enum matching // So gamepad axes (as in the actual linux joydev.c) are just simply enumerated // and (at least for some input drivers like xpat) it's convention to use - // ABS_X, ABX_Y for one joystick ABS_RX, ABS_RY for the other and the Z axes for the - // shoulder buttons - // If these are now enumerated you get LJOY_X, LJOY_Y, LEFT_SHOULDERB, RJOY_X, ... - // That means they don't match the GamepadAxis enum - // This could be fixed + // ABS_X, ABX_Y for one joystick ABS_RX, ABS_RY for the other and the Z axes for the shoulder buttons + // If these are now enumerated, it results to LJOY_X, LJOY_Y, LEFT_SHOULDERB, RJOY_X, ... int axisIndex = 0; for (int axis = ABS_X; axis < ABS_PRESSURE; axis++) { diff --git a/src/platforms/rcore_web.c b/src/platforms/rcore_web.c index 3dd3eb9df..5430cf5a9 100644 --- a/src/platforms/rcore_web.c +++ b/src/platforms/rcore_web.c @@ -173,7 +173,7 @@ bool WindowShouldClose(void) // and encapsulating one frame execution on a UpdateDrawFrame() function, // allowing the browser to manage execution asynchronously - // Optionally we can manage the time we give-control-back-to-browser if required, + // Optionally, time to give-control-back-to-browser can be managed here, // but it seems below line could generate stuttering on some browsers emscripten_sleep(12); @@ -921,9 +921,9 @@ double GetTime(void) } // Open URL with default system browser (if available) -// NOTE: This function is only safe to use if you control the URL given +// NOTE: This function is only safe to use if the provided URL is safe // 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 +// Avoid calling this function with user input non-validated strings void OpenURL(const char *url) { // Security check to (partially) avoid malicious code on target platform @@ -1252,11 +1252,11 @@ int InitPlatform(void) #else if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) { - // remember center for switchinging from fullscreen to window + // Remember center for switchinging from fullscreen to window if ((CORE.Window.screen.height == CORE.Window.display.height) && (CORE.Window.screen.width == CORE.Window.display.width)) { - // If screen width/height equal to the display, we can't calculate the window pos for toggling full-screened/windowed - // Toggling full-screened/windowed with pos(0, 0) can cause problems in some platforms, such as X11 + // If screen width/height equal to the display, it's not possible to + // calculate the window position for toggling full-screened/windowed CORE.Window.position.x = CORE.Window.display.width/4; CORE.Window.position.y = CORE.Window.display.height/4; } @@ -1367,7 +1367,7 @@ int InitPlatform(void) if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)) MinimizeWindow(); - // If graphic device is no properly initialized, we end program + // If graphic device is no properly initialized, end program if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return -1; } // Load OpenGL extensions @@ -1491,7 +1491,7 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths { if (count > 0) { - // In case previous dropped filepaths have not been freed, we free them + // In case previous dropped filepaths have not been freed, free them if (CORE.Window.dropFileCount > 0) { for (unsigned int i = 0; i < CORE.Window.dropFileCount; i++) RL_FREE(CORE.Window.dropFilepaths[i]); @@ -1502,7 +1502,7 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths CORE.Window.dropFilepaths = NULL; } - // WARNING: Paths are freed by GLFW when the callback returns, we must keep an internal copy + // WARNING: Paths are freed by GLFW when the callback returns, an internal copy must freed CORE.Window.dropFileCount = count; CORE.Window.dropFilepaths = (char **)RL_CALLOC(CORE.Window.dropFileCount, sizeof(char *)); @@ -1519,7 +1519,7 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i { if (key < 0) return; // Security check, macOS fn key generates -1 - // WARNING: GLFW could return GLFW_REPEAT, we need to consider it as 1 + // WARNING: GLFW could return GLFW_REPEAT, it needs to be considered as 1 // to work properly with our implementation (IsKeyDown/IsKeyUp checks) if (action == GLFW_RELEASE) CORE.Input.Keyboard.currentKeyState[key] = 0; else if (action == GLFW_PRESS) CORE.Input.Keyboard.currentKeyState[key] = 1; @@ -1721,7 +1721,7 @@ static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent double canvasWidth = 0.0; double canvasHeight = 0.0; // 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 + // actual CSS size needs to be considered: canvas.style.width and canvas.style.height // EMSCRIPTEN_RESULT res = emscripten_get_canvas_element_size("#canvas", &canvasWidth, &canvasHeight); emscripten_get_element_css_size(platform.canvasId, &canvasWidth, &canvasHeight); @@ -1741,7 +1741,7 @@ static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent else if (eventType == EMSCRIPTEN_EVENT_TOUCHEND) CORE.Input.Touch.currentTouchState[i] = 0; } - // Update mouse position if we detect a single touch + // Update mouse position when single touch detected if (CORE.Input.Touch.pointCount == 1) { CORE.Input.Mouse.currentPosition.x = CORE.Input.Touch.position[0].x; diff --git a/src/platforms/rcore_web_emscripten.c b/src/platforms/rcore_web_emscripten.c index 92caae99f..13e685939 100644 --- a/src/platforms/rcore_web_emscripten.c +++ b/src/platforms/rcore_web_emscripten.c @@ -908,9 +908,9 @@ double GetTime(void) } // Open URL with default system browser (if available) -// NOTE: This function is only safe to use if you control the URL given +// NOTE: This function is only safe to use if the provided URL is safe // 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 +// Avoid calling this function with user input non-validated strings void OpenURL(const char *url) { // Security check to (partially) avoid malicious code on target platform diff --git a/src/raudio.c b/src/raudio.c index 2e087205e..75547d285 100644 --- a/src/raudio.c +++ b/src/raudio.c @@ -2015,7 +2015,7 @@ void UpdateMusicStream(Music music) #if defined(SUPPORT_FILEFORMAT_MOD) case MUSIC_MODULE_MOD: { - // NOTE: 3rd parameter (nbsample) specify the number of stereo 16bits samples you want, so sampleCount/2 + // NOTE: 3rd parameter (nbsample) specify the number of stereo 16bits samples desired, so sampleCount/2 jar_mod_fillbuffer((jar_mod_context_t *)music.ctxData, (short *)AUDIO.System.pcmBuffer, framesToStream, 0); //jar_mod_seek_start((jar_mod_context_t *)music.ctxData); @@ -2504,7 +2504,7 @@ static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const memset(pFramesOut, 0, frameCount*pDevice->playback.channels*ma_get_bytes_per_sample(pDevice->playback.format)); // Using a mutex here for thread-safety which makes things not real-time - // This is unlikely to be necessary for this project, but may want to consider how you might want to avoid this + // This is unlikely to be necessary for this project, but it can be reconsidered ma_mutex_lock(&AUDIO.System.lock); { for (AudioBuffer *audioBuffer = AUDIO.Buffer.first; audioBuffer != NULL; audioBuffer = audioBuffer->next) diff --git a/src/rtext.c b/src/rtext.c index 2c871cc49..8e7fafec2 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -682,7 +682,7 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz // Render a unicode codepoint to a bitmap // stbtt_GetCodepointBitmap() -- allocates and returns a bitmap // stbtt_GetCodepointBitmapBox() -- how big the bitmap must be - // stbtt_MakeCodepointBitmap() -- renders into bitmap you provide + // stbtt_MakeCodepointBitmap() -- renders into a provided bitmap // Check if a glyph is available in the font // WARNING: if (index == 0), glyph not found, it could fallback to default .notdef glyph (if defined in font) diff --git a/src/rtextures.c b/src/rtextures.c index 1aced0533..c49ca1359 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -883,7 +883,7 @@ Image GenImageGradientRadial(int width, int height, float density, Color inner, float factor = (dist - radius*density)/(radius*(1.0f - density)); factor = (float)fmax(factor, 0.0f); - factor = (float)fmin(factor, 1.f); // dist can be bigger than radius, so we have to check + factor = (float)fmin(factor, 1.f); // Distance can be bigger than radius, so it needs to be checked pixels[y*width + x].r = (int)((float)outer.r*factor + (float)inner.r*(1.0f - factor)); pixels[y*width + x].g = (int)((float)outer.g*factor + (float)inner.g*(1.0f - factor)); @@ -1032,7 +1032,7 @@ Image GenImagePerlinNoise(int width, int height, int offsetX, int offsetY, float if (p < -1.0f) p = -1.0f; if (p > 1.0f) p = 1.0f; - // We need to normalize the data from [-1..1] to [0..1] + // Data needs to be normalized from [-1..1] to [0..1] float np = (p + 1.0f)/2.0f; unsigned char intensity = (unsigned char)(np*255.0f); @@ -1264,7 +1264,7 @@ void ImageFormat(Image *image, int newFormat) { Vector4 *pixels = LoadImageDataNormalized(*image); // Supports 8 to 32 bit per channel - RL_FREE(image->data); // WARNING! We loose mipmaps data --> Regenerated at the end... + RL_FREE(image->data); // WARNING! Loosing mipmaps data --> Regenerated at the end image->data = NULL; image->format = newFormat; @@ -1759,7 +1759,7 @@ void ImageResize(Image *image, int newWidth, int newHeight) // Security check to avoid program crash if ((image->data == NULL) || (image->width == 0) || (image->height == 0)) return; - // Check if we can use a fast path on image scaling + // Check if a fast path can be used on image scaling // It can be for 8 bit per channel images with 1 to 4 channels per pixel if ((image->format == PIXELFORMAT_UNCOMPRESSED_GRAYSCALE) || (image->format == PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA) || @@ -2026,7 +2026,7 @@ void ImageAlphaMask(Image *image, Image alphaMask) Image mask = ImageCopy(alphaMask); if (mask.format != PIXELFORMAT_UNCOMPRESSED_GRAYSCALE) ImageFormat(&mask, PIXELFORMAT_UNCOMPRESSED_GRAYSCALE); - // In case image is only grayscale, we just add alpha channel + // In case image is only grayscale, just add alpha channel if (image->format == PIXELFORMAT_UNCOMPRESSED_GRAYSCALE) { unsigned char *data = (unsigned char *)RL_MALLOC(image->width*image->height*2); @@ -2479,7 +2479,7 @@ void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp) TRACELOG(LOG_WARNING, "IMAGE: Unsupported dithered OpenGL internal format: %ibpp (R%iG%iB%iA%i)", (rBpp+gBpp+bBpp+aBpp), rBpp, gBpp, bBpp, aBpp); } - // NOTE: We will store the dithered data as unsigned short (16bpp) + // NOTE: Storing the dithered data as unsigned short (16bpp) image->data = (unsigned short *)RL_MALLOC(image->width*image->height*sizeof(unsigned short)); Color oldPixel = WHITE; @@ -2507,8 +2507,8 @@ void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp) newPixel.b = oldPixel.b >> (8 - bBpp); // B bits newPixel.a = oldPixel.a >> (8 - aBpp); // A bits (not used on dithering) - // NOTE: Error must be computed between new and old pixel but using same number of bits! - // We want to know how much color precision we have lost... + // NOTE: Error must be computed between new and old pixel but using same number of bits, + // to know how much color precision has been lost rError = (int)oldPixel.r - (int)(newPixel.r << (8 - rBpp)); gError = (int)oldPixel.g - (int)(newPixel.g << (8 - gBpp)); bError = (int)oldPixel.b - (int)(newPixel.b << (8 - bBpp)); @@ -3134,7 +3134,7 @@ Color *LoadImagePalette(Image image, int maxPaletteSize, int *colorCount) palette[palCount] = pixels[i]; // Add pixels[i] to palette palCount++; - // We reached the limit of colors supported by palette + // Reached the limit of colors supported by palette if (palCount >= maxPaletteSize) { i = image.width*image.height; // Finish palette get @@ -3806,7 +3806,7 @@ void ImageDrawTriangle(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color col for (int x = xMin; x <= xMax; x++) { // Check if the pixel is inside the triangle using barycentric coordinates - // If it is then we can draw the pixel with the given color + // If it is, the pixel can be drawn with the given color if ((w1 | w2 | w3) >= 0) ImageDrawPixel(dst, x, y, color); // Increment the barycentric coordinates for the next pixel @@ -3863,9 +3863,6 @@ void ImageDrawTriangleEx(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color c int w3Row = (int)((xMin - v1.x)*w3XStep + w3YStep*(yMin - v1.y)); // Calculate the inverse of the sum of the barycentric coordinates for normalization - // NOTE 1: Here, we act as if we multiply by 255 the reciprocal, which avoids additional - // calculations in the loop. This is acceptable because we are only interpolating colors - // NOTE 2: This sum remains constant throughout the triangle float wInvSum = 255.0f/(w1Row + w2Row + w3Row); // Rasterization loop @@ -3965,11 +3962,11 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color if ((srcRec.y + srcRec.height) > src.height) srcRec.height = src.height - srcRec.y; // Check if source rectangle needs to be resized to destination rectangle - // In that case, we make a copy of source, and we apply all required transform + // In that case, make a copy of source, and apply all required transform if (((int)srcRec.width != (int)dstRec.width) || ((int)srcRec.height != (int)dstRec.height)) { - srcMod = ImageFromImage(src, srcRec); // Create image from another image - ImageResize(&srcMod, (int)dstRec.width, (int)dstRec.height); // Resize to destination rectangle + srcMod = ImageFromImage(src, srcRec); // Create image from another image + ImageResize(&srcMod, (int)dstRec.width, (int)dstRec.height); // Resize to destination rectangle srcRec = (Rectangle){ 0, 0, (float)srcMod.width, (float)srcMod.height }; srcPtr = &srcMod; @@ -5126,7 +5123,7 @@ Color ColorAlphaBlend(Color dst, Color src, Color tint) else if (src.a == 255) out = src; else { - unsigned int alpha = (unsigned int)src.a + 1; // We are shifting by 8 (dividing by 256), so we need to take that excess into account + unsigned int alpha = (unsigned int)src.a + 1; // Shifting by 8 (dividing by 256), so need to take that excess into account out.a = (unsigned char)(((unsigned int)alpha*256 + (unsigned int)dst.a*(256 - alpha)) >> 8); if (out.a > 0) From dcd813068b832ae7536eea523fec9c980440098f Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 12 Feb 2026 18:55:42 +0100 Subject: [PATCH 180/232] Update raylib.h --- src/raylib.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/raylib.h b/src/raylib.h index b4b175919..f9c504680 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -350,8 +350,8 @@ typedef struct Mesh { float *texcoords2; // Vertex texture second coordinates (UV - 2 components per vertex) (shader-location = 5) float *normals; // Vertex normals (XYZ - 3 components per vertex) (shader-location = 2) float *tangents; // Vertex tangents (XYZW - 4 components per vertex) (shader-location = 4) - unsigned char *colors; // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3) - unsigned short *indices; // Vertex indices (in case vertex data comes indexed) + unsigned char *colors; // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3) + unsigned short *indices; // Vertex indices (in case vertex data comes indexed) // Animation vertex data float *animVertices; // Animated vertex positions (after bones transformations) From 8e81ca0e60e2ce5f76b8fc3ddee4b4212f032ec2 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 12 Feb 2026 19:08:48 +0100 Subject: [PATCH 181/232] Update win32_clipboard.h --- src/external/win32_clipboard.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/external/win32_clipboard.h b/src/external/win32_clipboard.h index 6845b0c2e..1cb05457d 100644 --- a/src/external/win32_clipboard.h +++ b/src/external/win32_clipboard.h @@ -13,7 +13,7 @@ unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned long #include #include -// NOTE: These search for architecture is taken from "Windows.h", and it's necessary if we really don't wanna import windows.h +// NOTE: These search for architecture is taken from "windows.h", and it's necessary to avoid including windows.h // and still make it compile on msvc, because import indirectly importing "winnt.h" (e.g. ) can cause problems is these are not defined. #if !defined(_X86_) && !defined(_68K_) && !defined(_MPPC_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64_) && !defined(_ARM64EC_) && defined(_M_IX86) #define _X86_ @@ -306,16 +306,15 @@ static int GetPixelDataOffset(BITMAPINFOHEADER bih) const unsigned int rgbaSize = sizeof(RGBQUAD); // NOTE: biSize specifies the number of bytes required by the structure - // We expect to always be 40 because it should be packed + // It's expected to be always 40 because it should be packed if ((bih.biSize == 40) && (sizeof(BITMAPINFOHEADER) == 40)) { // NOTE: biBitCount specifies the number of bits per pixel // Might exist some bit masks *after* the header and *before* the pixel offset - // we're looking, but only if we have more than - // 8 bits per pixel, so we need to ajust for that + // we're looking, but only if more than 8 bits per pixel, so it needs to be ajusted for that if (bih.biBitCount > 8) { - // If (bih.biCompression == BI_RGB) we should NOT offset more + // If (bih.biCompression == BI_RGB) no need to be offset more if (bih.biCompression == BI_BITFIELDS) offset += 3*rgbaSize; else if (bih.biCompression == BI_ALPHABITFIELDS) offset += 4*rgbaSize; // Not widely supported, but valid From debbb90479d70335c2999df82c8fbd61fcf33e0c Mon Sep 17 00:00:00 2001 From: Thomas Anderson <5776225+CrackedPixel@users.noreply.github.com> Date: Sat, 14 Feb 2026 15:09:52 -0600 Subject: [PATCH 182/232] fix extra drawtext() (#5551) --- examples/core/core_random_sequence.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/core/core_random_sequence.c b/examples/core/core_random_sequence.c index 580c2bb26..19d44461e 100644 --- a/examples/core/core_random_sequence.c +++ b/examples/core/core_random_sequence.c @@ -96,8 +96,6 @@ int main(void) { DrawRectangleRec(rectangles[i].rect, rectangles[i].color); - DrawText("Press SPACE to shuffle the sequence", 10, screenHeight - 96, 20, BLACK); - DrawText("Press SPACE to shuffle the current sequence", 10, screenHeight - 96, 20, BLACK); DrawText("Press UP to add a rectangle and generate a new sequence", 10, screenHeight - 64, 20, BLACK); DrawText("Press DOWN to remove a rectangle and generate a new sequence", 10, screenHeight - 32, 20, BLACK); From 8f1421ee5dec1b9e7ad7ea081ac3ed6b36102510 Mon Sep 17 00:00:00 2001 From: Thomas Anderson <5776225+CrackedPixel@users.noreply.github.com> Date: Sat, 14 Feb 2026 15:10:31 -0600 Subject: [PATCH 183/232] fix wrong name (#5552) --- examples/core/core_input_actions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/core/core_input_actions.c b/examples/core/core_input_actions.c index f4b1156d8..d5fd74e84 100644 --- a/examples/core/core_input_actions.c +++ b/examples/core/core_input_actions.c @@ -117,7 +117,7 @@ int main(void) DrawRectangleV(position, size, releaseAction? BLUE : RED); - DrawText((actionSet == 0)? "Current input set: WASD (default)" : "Current input set: Cursor", 10, 10, 20, WHITE); + DrawText((actionSet == 0)? "Current input set: WASD (default)" : "Current input set: Arrow keys", 10, 10, 20, WHITE); DrawText("Use TAB key to toggles Actions keyset", 10, 50, 20, GREEN); EndDrawing(); From a78d575f752bc26338fce9fffc243e5983da8a8c Mon Sep 17 00:00:00 2001 From: Thomas Anderson <5776225+CrackedPixel@users.noreply.github.com> Date: Sat, 14 Feb 2026 15:11:18 -0600 Subject: [PATCH 184/232] change attenuation distance (#5555) --- examples/audio/audio_sound_positioning.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/audio/audio_sound_positioning.c b/examples/audio/audio_sound_positioning.c index 34b15c07b..41ea4cb74 100644 --- a/examples/audio/audio_sound_positioning.c +++ b/examples/audio/audio_sound_positioning.c @@ -68,7 +68,7 @@ int main(void) .z = 5.0f*sinf(th) }; - SetSoundPosition(camera, sound, spherePos, 20.0f); + SetSoundPosition(camera, sound, spherePos, 1.0f); if (!IsSoundPlaying(sound)) PlaySound(sound); //---------------------------------------------------------------------------------- From fd40d2b374c29feaa1aca956d68460fd28ef7cb9 Mon Sep 17 00:00:00 2001 From: Thomas Anderson <5776225+CrackedPixel@users.noreply.github.com> Date: Sat, 14 Feb 2026 15:11:47 -0600 Subject: [PATCH 185/232] fix missing alias for PS (#5559) --- examples/core/core_input_gamepad.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/core/core_input_gamepad.c b/examples/core/core_input_gamepad.c index a9e0660e0..7291c6d78 100644 --- a/examples/core/core_input_gamepad.c +++ b/examples/core/core_input_gamepad.c @@ -24,7 +24,8 @@ // NOTE: Gamepad name ID depends on drivers and OS #define XBOX_ALIAS_1 "xbox" #define XBOX_ALIAS_2 "x-box" -#define PS_ALIAS "playstation" +#define PS_ALIAS_1 "playstation" +#define PS_ALIAS_2 "sony" //------------------------------------------------------------------------------------ // Program main entry point @@ -148,7 +149,8 @@ int main(void) //DrawText(TextFormat("Xbox axis LT: %02.02f", GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_LEFT_TRIGGER)), 10, 40, 10, BLACK); //DrawText(TextFormat("Xbox axis RT: %02.02f", GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_RIGHT_TRIGGER)), 10, 60, 10, BLACK); } - else if (TextFindIndex(TextToLower(GetGamepadName(gamepad)), PS_ALIAS) > -1) + else if ((TextFindIndex(TextToLower(GetGamepadName(gamepad)), PS_ALIAS_1) > -1) || + (TextFindIndex(TextToLower(GetGamepadName(gamepad)), PS_ALIAS_2) > -1)) { DrawTexture(texPs3Pad, 0, 0, DARKGRAY); From 4d6ef19fcc53cd2459ce53cdcf791454c7c201d1 Mon Sep 17 00:00:00 2001 From: Thomas Anderson <5776225+CrackedPixel@users.noreply.github.com> Date: Sat, 14 Feb 2026 15:12:11 -0600 Subject: [PATCH 186/232] change on-screen text (#5553) --- examples/core/core_2d_camera_platformer.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/core/core_2d_camera_platformer.c b/examples/core/core_2d_camera_platformer.c index 49d0a940c..8f443acba 100644 --- a/examples/core/core_2d_camera_platformer.c +++ b/examples/core/core_2d_camera_platformer.c @@ -148,10 +148,11 @@ int main(void) DrawText("Controls:", 20, 20, 10, BLACK); DrawText("- Right/Left to move", 40, 40, 10, DARKGRAY); DrawText("- Space to jump", 40, 60, 10, DARKGRAY); - DrawText("- Mouse Wheel to Zoom in-out, R to reset zoom", 40, 80, 10, DARKGRAY); - DrawText("- C to change camera mode", 40, 100, 10, DARKGRAY); - DrawText("Current camera mode:", 20, 120, 10, BLACK); - DrawText(cameraDescriptions[cameraOption], 40, 140, 10, DARKGRAY); + DrawText("- Mouse Wheel to Zoom in-out", 40, 80, 10, DARKGRAY); + DrawText("- R to reset position + zoom", 40, 100, 10, DARKGRAY); + DrawText("- C to change camera mode", 40, 120, 10, DARKGRAY); + DrawText("Current camera mode:", 20, 140, 10, BLACK); + DrawText(cameraDescriptions[cameraOption], 40, 160, 10, DARKGRAY); EndDrawing(); //---------------------------------------------------------------------------------- From b210d165978b9b29651f99aa2770c323d21cfe44 Mon Sep 17 00:00:00 2001 From: Thomas Anderson <5776225+CrackedPixel@users.noreply.github.com> Date: Sat, 14 Feb 2026 15:12:44 -0600 Subject: [PATCH 187/232] fix y-offset casting (#5556) --- examples/shapes/shapes_colors_palette.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/shapes/shapes_colors_palette.c b/examples/shapes/shapes_colors_palette.c index 44da323eb..aa287df53 100644 --- a/examples/shapes/shapes_colors_palette.c +++ b/examples/shapes/shapes_colors_palette.c @@ -45,7 +45,7 @@ int main(void) for (int i = 0; i < MAX_COLORS_COUNT; i++) { colorsRecs[i].x = 20.0f + 100.0f *(i%7) + 10.0f *(i%7); - colorsRecs[i].y = 80.0f + 100.0f *((float)i/7) + 10.0f *((float)i/7); + colorsRecs[i].y = 80.0f + 100.0f *((int)i/7) + 10.0f *((float)i/7); colorsRecs[i].width = 100.0f; colorsRecs[i].height = 100.0f; } From b04d2a22689cbd53baabac7919462b46104b3791 Mon Sep 17 00:00:00 2001 From: Thomas Anderson <5776225+CrackedPixel@users.noreply.github.com> Date: Sat, 14 Feb 2026 15:13:22 -0600 Subject: [PATCH 188/232] change d-pad text to shapes (#5557) --- examples/core/core_input_virtual_controls.c | 39 ++++++++++++++++----- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/examples/core/core_input_virtual_controls.c b/examples/core/core_input_virtual_controls.c index db293b993..de4ac7ead 100644 --- a/examples/core/core_input_virtual_controls.c +++ b/examples/core/core_input_virtual_controls.c @@ -51,11 +51,31 @@ int main(void) { padPosition.x, padPosition.y + buttonRadius*1.5f } // Down }; - const char *buttonLabels[BUTTON_MAX] = { - "Y", // Up - "X", // Left - "B", // Right - "A" // Down + Vector2 arrowTris[4][3] = { + // Up + { + { buttonPositions[0].x, buttonPositions[0].y - 12 }, + { buttonPositions[0].x - 9, buttonPositions[0].y + 9 }, + { buttonPositions[0].x + 9, buttonPositions[0].y + 9 } + }, + // Left + { + { buttonPositions[1].x + 9, buttonPositions[1].y - 9 }, + { buttonPositions[1].x - 12, buttonPositions[1].y }, + { buttonPositions[1].x + 9, buttonPositions[1].y + 9 } + }, + // Right + { + { buttonPositions[2].x + 12, buttonPositions[2].y }, + { buttonPositions[2].x - 9, buttonPositions[2].y - 9 }, + { buttonPositions[2].x - 9, buttonPositions[2].y + 9 } + }, + // Down + { + { buttonPositions[3].x - 9, buttonPositions[3].y - 9 }, + { buttonPositions[3].x, buttonPositions[3].y + 12 }, + { buttonPositions[3].x + 9, buttonPositions[3].y - 9 } + } }; Color buttonLabelColors[BUTTON_MAX] = { @@ -128,9 +148,12 @@ int main(void) { DrawCircleV(buttonPositions[i], buttonRadius, (i == pressedButton)? DARKGRAY : BLACK); - DrawText(buttonLabels[i], - (int)buttonPositions[i].x - 7, (int)buttonPositions[i].y - 8, - 20, buttonLabelColors[i]); + DrawTriangle( + arrowTris[i][0], + arrowTris[i][1], + arrowTris[i][2], + buttonLabelColors[i] + ); } DrawText("move the player with D-Pad buttons", 10, 10, 20, DARKGRAY); From fb5bc42190cceb38e51066a399f10fc5217d4773 Mon Sep 17 00:00:00 2001 From: Thomas Anderson <5776225+CrackedPixel@users.noreply.github.com> Date: Sat, 14 Feb 2026 15:16:09 -0600 Subject: [PATCH 189/232] update camera pan speed (#5554) --- src/rcamera.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rcamera.h b/src/rcamera.h index 82f14fecd..3c880bab7 100644 --- a/src/rcamera.h +++ b/src/rcamera.h @@ -199,7 +199,7 @@ RLAPI Matrix GetCameraProjectionMatrix(Camera *camera, float aspect); //---------------------------------------------------------------------------------- #define CAMERA_MOVE_SPEED 5.4f // Units per second #define CAMERA_ROTATION_SPEED 0.03f -#define CAMERA_PAN_SPEED 0.2f +#define CAMERA_PAN_SPEED 2.0f // Camera mouse movement sensitivity #define CAMERA_MOUSE_MOVE_SENSITIVITY 0.003f From 1061daf197d1984c913af22ba57c419d5e604d49 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 14 Feb 2026 22:17:49 +0100 Subject: [PATCH 190/232] REVIEWED: Installed libraries #5550 --- src/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Makefile b/src/Makefile index 459b79f83..b4ea8f0a9 100644 --- a/src/Makefile +++ b/src/Makefile @@ -841,6 +841,7 @@ ifeq ($(ROOT),root) # Copying raylib development files to $(RAYLIB_H_INSTALL_PATH). cp --update raylib.h $(RAYLIB_H_INSTALL_PATH)/raylib.h cp --update raymath.h $(RAYLIB_H_INSTALL_PATH)/raymath.h + cp --update rcamera.h $(RAYLIB_H_INSTALL_PATH)/rcamera.h cp --update rlgl.h $(RAYLIB_H_INSTALL_PATH)/rlgl.h @echo "raylib development files installed/updated!" else From 180c3c13ba3ab6ca10b43ced8464aed0db7df566 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 14 Feb 2026 22:22:31 +0100 Subject: [PATCH 191/232] REVIEWED: `GetImageColor()` #5560 --- src/rtextures.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/rtextures.c b/src/rtextures.c index c49ca1359..1b147796e 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -3295,9 +3295,9 @@ Color GetImageColor(Image image, int x, int y) case PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: { color.r = (unsigned char)(((float *)image.data)[(y*image.width + x)*4]*255.0f); - color.g = (unsigned char)(((float *)image.data)[(y*image.width + x)*4]*255.0f); - color.b = (unsigned char)(((float *)image.data)[(y*image.width + x)*4]*255.0f); - color.a = (unsigned char)(((float *)image.data)[(y*image.width + x)*4]*255.0f); + color.g = (unsigned char)(((float *)image.data)[(y*image.width + x)*4 + 1]*255.0f); + color.b = (unsigned char)(((float *)image.data)[(y*image.width + x)*4 + 2]*255.0f); + color.a = (unsigned char)(((float *)image.data)[(y*image.width + x)*4 + 3]*255.0f); } break; case PIXELFORMAT_UNCOMPRESSED_R16: @@ -3319,9 +3319,9 @@ Color GetImageColor(Image image, int x, int y) case PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: { color.r = (unsigned char)(HalfToFloat(((unsigned short *)image.data)[(y*image.width + x)*4])*255.0f); - color.g = (unsigned char)(HalfToFloat(((unsigned short *)image.data)[(y*image.width + x)*4])*255.0f); - color.b = (unsigned char)(HalfToFloat(((unsigned short *)image.data)[(y*image.width + x)*4])*255.0f); - color.a = (unsigned char)(HalfToFloat(((unsigned short *)image.data)[(y*image.width + x)*4])*255.0f); + color.g = (unsigned char)(HalfToFloat(((unsigned short *)image.data)[(y*image.width + x)*4 + 1])*255.0f); + color.b = (unsigned char)(HalfToFloat(((unsigned short *)image.data)[(y*image.width + x)*4 + 2])*255.0f); + color.a = (unsigned char)(HalfToFloat(((unsigned short *)image.data)[(y*image.width + x)*4 + 3])*255.0f); } break; default: TRACELOG(LOG_WARNING, "Compressed image format does not support color reading"); break; From d01f158bd54d70458ee6e40e78154f04d6d45502 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 15 Feb 2026 13:21:08 +0100 Subject: [PATCH 192/232] REVIEWED: Window initialization on HighDPI monitor (Windows) #5549 --- examples/core/core_highdpi_testbed.c | 2 +- src/platforms/rcore_desktop_glfw.c | 29 +++++++++++++++------------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/examples/core/core_highdpi_testbed.c b/examples/core/core_highdpi_testbed.c index a925527db..1c39a9d2c 100644 --- a/examples/core/core_highdpi_testbed.c +++ b/examples/core/core_highdpi_testbed.c @@ -78,7 +78,7 @@ int main(void) DrawText(TextFormat("WINDOW POSITION: %ix%i", (int)windowPos.x, (int)windowPos.y), 50, 90, 20, DARKGRAY); DrawText(TextFormat("SCREEN SIZE: %ix%i", GetScreenWidth(), GetScreenHeight()), 50, 130, 20, DARKGRAY); DrawText(TextFormat("RENDER SIZE: %ix%i", GetRenderWidth(), GetRenderHeight()), 50, 170, 20, DARKGRAY); - DrawText(TextFormat("SCALE FACTOR: %.1fx%.1f", scaleDpi.x, scaleDpi.y), 50, 210, 20, GRAY); + DrawText(TextFormat("SCALE FACTOR: %.2fx%.2f", scaleDpi.x, scaleDpi.y), 50, 210, 20, GRAY); // Draw reference rectangles, top-left and bottom-right corners DrawRectangle(0, 0, 30, 60, RED); diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index b13018576..42b5a002f 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -1649,31 +1649,34 @@ int InitPlatform(void) TRACELOG(LOG_INFO, "DISPLAY: Trying to enable VSYNC"); } - int fbWidth = CORE.Window.screen.width; - int fbHeight = CORE.Window.screen.height; - if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) { + // Set screen size to logical pixel size, considering content scaling + Vector2 scaleDpi = GetWindowScaleDPI(); + CORE.Window.render.width = (int)(CORE.Window.screen.width*scaleDpi.x); + CORE.Window.render.height = (int)(CORE.Window.screen.height*scaleDpi.y); + // 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); - // Get current framebuffer size, on high-dpi it could be bigger than screen size - glfwGetFramebufferSize(platform.handle, &fbWidth, &fbHeight); + //glfwGetFramebufferSize(platform.handle, &fbWidth, &fbHeight); // Screen scaling matrix is required in case desired screen area is different from display area - CORE.Window.screenScale = MatrixScale((float)fbWidth/CORE.Window.screen.width, (float)fbHeight/CORE.Window.screen.height, 1.0f); + CORE.Window.screenScale = MatrixScale(scaleDpi.x, scaleDpi.y, 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); + SetMouseScale(1.0f/scaleDpi.x, 1.0f/scaleDpi.y); #endif + glfwSetWindowSize(platform.handle, CORE.Window.render.width, CORE.Window.render.height); + } + else + { + CORE.Window.render = CORE.Window.screen; + CORE.Window.currentFbo = CORE.Window.render; } - CORE.Window.render.width = fbWidth; - CORE.Window.render.height = fbHeight; - CORE.Window.currentFbo.width = fbWidth; - CORE.Window.currentFbo.height = fbHeight; - - TRACELOG(LOG_INFO, "DISPLAY: Device initialized successfully"); + TRACELOG(LOG_INFO, "DISPLAY: Device initialized successfully %s", + FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)? "(HighDPI)" : ""); TRACELOG(LOG_INFO, " > Display size: %i x %i", CORE.Window.display.width, CORE.Window.display.height); TRACELOG(LOG_INFO, " > Screen size: %i x %i", CORE.Window.screen.width, CORE.Window.screen.height); TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height); From 059ebaa6ada3228e2334c68b9b7adee3aa8f4a10 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 15 Feb 2026 15:02:04 +0100 Subject: [PATCH 193/232] REVIEWED: HIghDPI content scaling on macOS --- src/platforms/rcore_desktop_glfw.c | 57 +++++++++++++++++------------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index 42b5a002f..68a321ffd 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -1655,25 +1655,29 @@ int InitPlatform(void) Vector2 scaleDpi = GetWindowScaleDPI(); CORE.Window.render.width = (int)(CORE.Window.screen.width*scaleDpi.x); CORE.Window.render.height = (int)(CORE.Window.screen.height*scaleDpi.y); - - // 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); - // Get current framebuffer size, on high-dpi it could be bigger than screen size - //glfwGetFramebufferSize(platform.handle, &fbWidth, &fbHeight); + //TRACELOG(LOG_INFO, "DPI SCALING: %.2f, %.2f", scaleDpi.x, scaleDpi.y); // Screen scaling matrix is required in case desired screen area is different from display area CORE.Window.screenScale = MatrixScale(scaleDpi.x, scaleDpi.y, 1.0f); + + // NOTE: On APPLE platforms system manage window and input scaling + // Framebuffer scaling is activated with: glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_TRUE); + + // Screen scaling matrix is required in case desired screen area is different from display area + CORE.Window.screenScale = MatrixScale(scaleDpi.x, scaleDpi.y, 1.0f); + #if !defined(__APPLE__) // Mouse input scaling for the new screen size SetMouseScale(1.0f/scaleDpi.x, 1.0f/scaleDpi.y); -#endif + + // Force window size (and framebuffer) refresh glfwSetWindowSize(platform.handle, CORE.Window.render.width, CORE.Window.render.height); +#endif } - else - { - CORE.Window.render = CORE.Window.screen; - CORE.Window.currentFbo = CORE.Window.render; - } + else CORE.Window.render = CORE.Window.screen; + + // Current active framebuffer size is main framebuffer size + CORE.Window.currentFbo = CORE.Window.render; TRACELOG(LOG_INFO, "DISPLAY: Device initialized successfully %s", FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)? "(HighDPI)" : ""); @@ -1681,6 +1685,7 @@ int InitPlatform(void) TRACELOG(LOG_INFO, " > Screen size: %i x %i", CORE.Window.screen.width, CORE.Window.screen.height); TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height); TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y); + //TRACELOG(LOG_INFO, " > Content Scaling: %.2f, %.2f", scaleDpi.x, scaleDpi.y); // Try to center window on screen but avoiding window-bar outside of screen int monitorCount = 0; @@ -1694,13 +1699,17 @@ int InitPlatform(void) int monitorHeight = 0; glfwGetMonitorWorkarea(monitor, &monitorX, &monitorY, &monitorWidth, &monitorHeight); - // TODO: Here CORE.Window.render.width/height should be used instead of - // CORE.Window.screen.width/height to center the window correctly when the high dpi flag is enabled - CORE.Window.position.x = monitorX + (monitorWidth - (int)CORE.Window.screen.width)/2; - CORE.Window.position.y = monitorY + (monitorHeight - (int)CORE.Window.screen.height)/2; - //if (CORE.Window.position.x < monitorX) CORE.Window.position.x = monitorX; - //if (CORE.Window.position.y < monitorY) CORE.Window.position.y = monitorY; + // NOTE: It seems on macOS monitor size is not correct + //TRACELOG(LOG_WARNING, "Monitor info: [%i, %i, %i, %i]", monitorX, monitorY, monitorWidth, monitorHeight); + // Center window into current monitor + #if defined(__APPLE__) + CORE.Window.position.x = monitorX + (monitorWidth - CORE.Window.screen.width)/2; + CORE.Window.position.y = monitorY + (monitorHeight - CORE.Window.screen.height)/2; + #else + CORE.Window.position.x = monitorX + (monitorWidth - CORE.Window.render.width)/2; + CORE.Window.position.y = monitorY + (monitorHeight - CORE.Window.render.height)/2; + #endif SetWindowPosition(CORE.Window.position.x, CORE.Window.position.y); if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)) MinimizeWindow(); @@ -1831,8 +1840,9 @@ static void FramebufferSizeCallback(GLFWwindow *window, int width, int height) SetupViewport(width, height); // Set render size - CORE.Window.currentFbo.width = width; - CORE.Window.currentFbo.height = height; + CORE.Window.render.width = width; + CORE.Window.render.height = height; + CORE.Window.currentFbo = CORE.Window.render; CORE.Window.resizedLastFrame = true; if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) @@ -1878,8 +1888,9 @@ static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float s { //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; + CORE.Window.render.width = (int)((float)CORE.Window.screen.width*scalex); + CORE.Window.render.height = (int)((float)CORE.Window.screen.height*scaley); + CORE.Window.currentFbo = CORE.Window.render; // 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); @@ -1889,10 +1900,6 @@ static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float s // Mouse input scaling for the new screen size SetMouseScale(1.0f/scalex, 1.0f/scaley); #endif - - CORE.Window.render.width = (int)fbWidth; - CORE.Window.render.height = (int)fbHeight; - CORE.Window.currentFbo = CORE.Window.render; } // GLFW3: Window position callback, runs when window position changes From 6564cea6a31109e9f2fe1a6349c8dd12840098cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yui=20Kinomoto=20/=20=E3=81=8D=E3=81=AE=E3=82=82=E3=81=A8?= =?UTF-8?q?=20=E7=B5=90=E8=A1=A3?= Date: Mon, 16 Feb 2026 04:15:25 +0900 Subject: [PATCH 194/232] Fixed doesn't property load when 1 frame animation. (#5561) --- src/rmodels.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/rmodels.c b/src/rmodels.c index 755d0437d..eadc16f07 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -6244,7 +6244,10 @@ static bool GetPoseAtTimeGLTF(cgltf_interpolation_type interpolationType, cgltf_ } // Constant animation, no need to interpolate - if (FloatEquals(tend, tstart)) return true; + if (FloatEquals(tend, tstart)) + { + interpolationType = cgltf_interpolation_type_step; + } float duration = fmaxf((tend - tstart), EPSILON); float t = (time - tstart)/duration; From 7c48fa9ac9d6cacfa8a1fe5e8a5107380eccc7dd Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 15 Feb 2026 20:20:53 +0100 Subject: [PATCH 195/232] Update Makefile --- examples/Makefile | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/examples/Makefile b/examples/Makefile index acfcb0857..4f86ad5c0 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -393,14 +393,14 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW) # NOTE: Required packages: libegl1-mesa-dev LDLIBS = -lraylib -lGL -lm -lpthread -ldl -lrt - # On X11 requires also below libraries - LDLIBS += -lX11 - # NOTE: It seems additional libraries are not required any more, latest GLFW just dlopen them - #LDLIBS += -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor - - # On Wayland windowing system, additional libraries requires + # On Wayland, additional libraries requires ifeq ($(USE_WAYLAND_DISPLAY),TRUE) LDLIBS += -lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon + else + # On X11, additional libraries required + LDLIBS += -lX11 + # NOTE: It seems additional libraries are not required any more, latest GLFW just dlopen them + #LDLIBS += -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor endif # Explicit link to libc ifeq ($(RAYLIB_LIBTYPE),SHARED) @@ -439,15 +439,16 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_SDL) # NOTE: Required packages: libegl1-mesa-dev LDLIBS = -lraylib $(SDL_LIBRARIES) -lGL -lm -lpthread -ldl -lrt - # On X11 requires also below libraries + # On X11, addition libraries required LDLIBS += -lX11 # NOTE: It seems additional libraries are not required any more, latest GLFW just dlopen them #LDLIBS += -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor - # On Wayland windowing system, additional libraries requires + # On Wayland, additional libraries requires ifeq ($(USE_WAYLAND_DISPLAY),TRUE) LDLIBS += -lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon endif + # Explicit link to libc ifeq ($(RAYLIB_LIBTYPE),SHARED) LDLIBS += -lc From b871a556d7a2b3086e2e70ca254bb742e4f99021 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 17 Feb 2026 12:13:04 +0100 Subject: [PATCH 196/232] Init framebuffer using render size (should be same as currentFbo) --- src/rcore.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/rcore.c b/src/rcore.c index 49a928372..97a6cce0e 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -682,8 +682,6 @@ void InitWindow(int width, int height, const char *title) // Initialize window data CORE.Window.screen.width = width; CORE.Window.screen.height = height; - CORE.Window.currentFbo.width = CORE.Window.screen.width; - CORE.Window.currentFbo.height = CORE.Window.screen.height; CORE.Window.eventWaiting = false; CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default @@ -709,10 +707,10 @@ 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); + rlglInit(CORE.Window.render.width, CORE.Window.render.height); // Setup default viewport - SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height); + SetupViewport(CORE.Window.render.width, CORE.Window.render.height); #if defined(SUPPORT_MODULE_RTEXT) #if defined(SUPPORT_DEFAULT_FONT) From 4678a544b6f74753755c09291c63215bb37fc535 Mon Sep 17 00:00:00 2001 From: paddy <0xPD33@proton.me> Date: Tue, 17 Feb 2026 12:43:52 +0100 Subject: [PATCH 197/232] [rcore][glfw] Fix window scaling on Wayland with GLFW 3.4+ (#5564) * Fix window scaling on Wayland with GLFW 3.4+ display scaling GLFW 3.4 defaults GLFW_SCALE_FRAMEBUFFER to TRUE on all platforms, causing framebuffer/window size mismatch on Wayland with display scaling (content renders in a subset of the window, mouse coordinates are wrong). Three fixes: - Disable GLFW_SCALE_FRAMEBUFFER on Wayland when FLAG_WINDOW_HIGHDPI is not set, restoring 1:1 window-to-framebuffer mapping - With FLAG_WINDOW_HIGHDPI, read actual framebuffer size from GLFW instead of resizing the window (which double-scales on Wayland where GLFW_SCALE_TO_MONITOR has no effect) - Skip mouse coordinate scaling on Wayland since GLFW already reports coordinates in logical (window) space Tested on NixOS/Niri with GLFW 3.4 at 1x, 1.5x, and 2x scaling. Fixes #5504 * Fix fullscreen and borderless windowed scaling on Wayland with HiDPI ToggleFullscreen and ToggleBorderlessWindowed exit paths manually scale screen size by DPI before passing to glfwSetWindowMonitor, which double-scales on Wayland where GLFW_SCALE_FRAMEBUFFER already handles it. Skip the manual resize on Wayland. Also fix FramebufferSizeCallback fullscreen branch: on Wayland with GLFW_SCALE_FRAMEBUFFER the framebuffer is still scaled in fullscreen, so use the logical window size as screen size and derive screenScale from the framebuffer/window ratio. Fixes #5504 * Apply style fixes from code review: remove duplicate screenScale assignment, collapse single-statement ifs to one line, remove trailing periods from comments --- src/platforms/rcore_desktop_glfw.c | 56 +++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index 68a321ffd..4cb3726e1 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -221,7 +221,9 @@ void ToggleFullscreen(void) #if !defined(__APPLE__) // Make sure to restore render size considering HighDPI scaling - if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) + // NOTE: On Wayland, GLFW_SCALE_FRAMEBUFFER handles scaling, skip manual resize + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI) && + (glfwGetPlatform() != GLFW_PLATFORM_WAYLAND)) { Vector2 scaleDpi = GetWindowScaleDPI(); CORE.Window.screen.width = (unsigned int)(CORE.Window.screen.width*scaleDpi.x); @@ -300,7 +302,9 @@ void ToggleBorderlessWindowed(void) #if !defined(__APPLE__) // Make sure to restore size considering HighDPI scaling - if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) + // NOTE: On Wayland, GLFW_SCALE_FRAMEBUFFER handles scaling, skip manual resize + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI) && + (glfwGetPlatform() != GLFW_PLATFORM_WAYLAND)) { Vector2 scaleDpi = GetWindowScaleDPI(); CORE.Window.screen.width = (unsigned int)(CORE.Window.screen.width*scaleDpi.x); @@ -1465,6 +1469,8 @@ int InitPlatform(void) #if defined(__APPLE__) glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_FALSE); #endif + // GLFW 3.4+ defaults GLFW_SCALE_FRAMEBUFFER to TRUE, causing framebuffer/window size mismatch on Wayland with display scaling + if (glfwGetPlatform() == GLFW_PLATFORM_WAYLAND) glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_FALSE); } // Mouse passthrough @@ -1663,15 +1669,23 @@ int InitPlatform(void) // NOTE: On APPLE platforms system manage window and input scaling // Framebuffer scaling is activated with: glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_TRUE); - // Screen scaling matrix is required in case desired screen area is different from display area - CORE.Window.screenScale = MatrixScale(scaleDpi.x, scaleDpi.y, 1.0f); - #if !defined(__APPLE__) - // Mouse input scaling for the new screen size - SetMouseScale(1.0f/scaleDpi.x, 1.0f/scaleDpi.y); + if (glfwGetPlatform() == GLFW_PLATFORM_WAYLAND) + { + // On Wayland, GLFW_SCALE_FRAMEBUFFER handles scaling; read actual framebuffer size instead of resizing the window (which would double-scale) + int fbWidth, fbHeight; + glfwGetFramebufferSize(platform.handle, &fbWidth, &fbHeight); + CORE.Window.render.width = fbWidth; + CORE.Window.render.height = fbHeight; + } + else + { + // Mouse input scaling for the new screen size + SetMouseScale(1.0f/scaleDpi.x, 1.0f/scaleDpi.y); - // Force window size (and framebuffer) refresh - glfwSetWindowSize(platform.handle, CORE.Window.render.width, CORE.Window.render.height); + // Force window size (and framebuffer) refresh + glfwSetWindowSize(platform.handle, CORE.Window.render.width, CORE.Window.render.height); + } #endif } else CORE.Window.render = CORE.Window.screen; @@ -1855,6 +1869,22 @@ static void FramebufferSizeCallback(GLFWwindow *window, int width, int height) CORE.Window.screen.height = height; CORE.Window.screenScale = MatrixScale(1.0f, 1.0f, 1.0f); SetMouseScale(1.0f, 1.0f); + + // On Wayland with GLFW_SCALE_FRAMEBUFFER, the framebuffer is still scaled in fullscreen, use logical window size as screen and apply screenScale + if ((glfwGetPlatform() == GLFW_PLATFORM_WAYLAND) && + FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) + { + int winWidth, winHeight; + glfwGetWindowSize(platform.handle, &winWidth, &winHeight); + if ((winWidth != width) || (winHeight != height)) + { + CORE.Window.screen.width = winWidth; + CORE.Window.screen.height = winHeight; + float scaleX = (float)width/winWidth; + float scaleY = (float)height/winHeight; + CORE.Window.screenScale = MatrixScale(scaleX, scaleY, 1.0f); + } + } } else // Window mode (including borderless window) { @@ -1867,8 +1897,8 @@ static void FramebufferSizeCallback(GLFWwindow *window, int width, int height) CORE.Window.screen.height = (int)((float)height/scaleDpi.y); CORE.Window.screenScale = MatrixScale(scaleDpi.x, scaleDpi.y, 1.0f); #if !defined(__APPLE__) - // Mouse input scaling for the new screen size - SetMouseScale(1.0f/scaleDpi.x, 1.0f/scaleDpi.y); + // On Wayland, mouse coords are already in logical space + if (glfwGetPlatform() != GLFW_PLATFORM_WAYLAND) SetMouseScale(1.0f/scaleDpi.x, 1.0f/scaleDpi.y); #endif } else @@ -1897,8 +1927,8 @@ static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float s CORE.Window.screenScale = MatrixScale(scalex, scaley, 1.0f); #if !defined(__APPLE__) - // Mouse input scaling for the new screen size - SetMouseScale(1.0f/scalex, 1.0f/scaley); + // On Wayland, mouse coords are already in logical space + if (glfwGetPlatform() != GLFW_PLATFORM_WAYLAND) SetMouseScale(1.0f/scalex, 1.0f/scaley); #endif } From 5bbb2fc1df612d48f53e23c586779ae383b8725d Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 17 Feb 2026 13:22:11 +0100 Subject: [PATCH 198/232] REVIEWED: Wayland checks, using compilation flags when possible #5564 --- src/platforms/rcore_desktop_glfw.c | 46 ++++++++++++++++++------------ 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index 4cb3726e1..af3e6b6c1 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -219,11 +219,10 @@ void ToggleFullscreen(void) // and considered by GetWindowScaleDPI() FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); -#if !defined(__APPLE__) +#if !defined(__APPLE__) && !defined(_GLFW_WAYLAND) // Make sure to restore render size considering HighDPI scaling // NOTE: On Wayland, GLFW_SCALE_FRAMEBUFFER handles scaling, skip manual resize - if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI) && - (glfwGetPlatform() != GLFW_PLATFORM_WAYLAND)) + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) { Vector2 scaleDpi = GetWindowScaleDPI(); CORE.Window.screen.width = (unsigned int)(CORE.Window.screen.width*scaleDpi.x); @@ -300,11 +299,10 @@ void ToggleBorderlessWindowed(void) glfwSetWindowAttrib(platform.handle, GLFW_DECORATED, GLFW_TRUE); FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNDECORATED); - #if !defined(__APPLE__) + #if !defined(__APPLE__) && !defined(_GLFW_WAYLAND) // Make sure to restore size considering HighDPI scaling // NOTE: On Wayland, GLFW_SCALE_FRAMEBUFFER handles scaling, skip manual resize - if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI) && - (glfwGetPlatform() != GLFW_PLATFORM_WAYLAND)) + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) { Vector2 scaleDpi = GetWindowScaleDPI(); CORE.Window.screen.width = (unsigned int)(CORE.Window.screen.width*scaleDpi.x); @@ -1469,8 +1467,11 @@ int InitPlatform(void) #if defined(__APPLE__) glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_FALSE); #endif - // GLFW 3.4+ defaults GLFW_SCALE_FRAMEBUFFER to TRUE, causing framebuffer/window size mismatch on Wayland with display scaling - if (glfwGetPlatform() == GLFW_PLATFORM_WAYLAND) glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_FALSE); +#if defined(_GLFW_WAYLAND) && !defined(_GLFW_X11) + // GLFW 3.4+ defaults GLFW_SCALE_FRAMEBUFFER to TRUE, + // causing framebuffer/window size mismatch on Wayland with display scaling + glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_FALSE); +#endif } // Mouse passthrough @@ -1672,9 +1673,12 @@ int InitPlatform(void) #if !defined(__APPLE__) if (glfwGetPlatform() == GLFW_PLATFORM_WAYLAND) { - // On Wayland, GLFW_SCALE_FRAMEBUFFER handles scaling; read actual framebuffer size instead of resizing the window (which would double-scale) - int fbWidth, fbHeight; + // On Wayland, GLFW_SCALE_FRAMEBUFFER handles scaling; read actual framebuffer size + // instead of resizing the window (which would double-scale) + int fbWidth = 0; + int fbHeight = 0; glfwGetFramebufferSize(platform.handle, &fbWidth, &fbHeight); + CORE.Window.render.width = fbWidth; CORE.Window.render.height = fbHeight; } @@ -1871,20 +1875,24 @@ static void FramebufferSizeCallback(GLFWwindow *window, int width, int height) SetMouseScale(1.0f, 1.0f); // On Wayland with GLFW_SCALE_FRAMEBUFFER, the framebuffer is still scaled in fullscreen, use logical window size as screen and apply screenScale - if ((glfwGetPlatform() == GLFW_PLATFORM_WAYLAND) && - FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) +#if defined(_GLFW_WAYLAND) && !defined(_GLFW_X11) + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) { - int winWidth, winHeight; + int winWidth = 0; + int winHeight = 0; glfwGetWindowSize(platform.handle, &winWidth, &winHeight); + if ((winWidth != width) || (winHeight != height)) { CORE.Window.screen.width = winWidth; CORE.Window.screen.height = winHeight; float scaleX = (float)width/winWidth; float scaleY = (float)height/winHeight; + CORE.Window.screenScale = MatrixScale(scaleX, scaleY, 1.0f); } } +#endif } else // Window mode (including borderless window) { @@ -1896,9 +1904,9 @@ static void FramebufferSizeCallback(GLFWwindow *window, int width, int height) CORE.Window.screen.width = (int)((float)width/scaleDpi.x); CORE.Window.screen.height = (int)((float)height/scaleDpi.y); CORE.Window.screenScale = MatrixScale(scaleDpi.x, scaleDpi.y, 1.0f); -#if !defined(__APPLE__) - // On Wayland, mouse coords are already in logical space - if (glfwGetPlatform() != GLFW_PLATFORM_WAYLAND) SetMouseScale(1.0f/scaleDpi.x, 1.0f/scaleDpi.y); +#if !defined(__APPLE__) && !defined(_GLFW_WAYLAND) + // On macOS and Linux-Wayland, mouse coords are already in logical space + SetMouseScale(1.0f/scaleDpi.x, 1.0f/scaleDpi.y); #endif } else @@ -1926,9 +1934,9 @@ static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float s // Framebuffer scaling is activated with: glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_TRUE); CORE.Window.screenScale = MatrixScale(scalex, scaley, 1.0f); -#if !defined(__APPLE__) - // On Wayland, mouse coords are already in logical space - if (glfwGetPlatform() != GLFW_PLATFORM_WAYLAND) SetMouseScale(1.0f/scalex, 1.0f/scaley); +#if !defined(__APPLE__) && !defined(_GLFW_WAYLAND) + // On macOS and Linux-Wayland, mouse coords are already in logical space + SetMouseScale(1.0f/scalex, 1.0f/scaley); #endif } From 4311df1e6d5632d718fb6b14f5d4b72ce6b7744f Mon Sep 17 00:00:00 2001 From: dmitrii-brand <114125495+dmitrii-brand@users.noreply.github.com> Date: Tue, 17 Feb 2026 14:43:46 +0000 Subject: [PATCH 199/232] Add bone blending animation example (#5543) - Demonstrates per-bone animation blending for smooth transitions - Supports upper/lower body selective blending (walk + attack) - Includes uniform blending mode for comparison - Uses GPU skinning for performance - Follows raylib example conventions --- examples/examples_list.txt | 1 + .../models/models_animation_bone_blending.c | 291 ++++++++++++++++++ 2 files changed, 292 insertions(+) create mode 100644 examples/models/models_animation_bone_blending.c diff --git a/examples/examples_list.txt b/examples/examples_list.txt index eda62ee13..f4cfa0e47 100644 --- a/examples/examples_list.txt +++ b/examples/examples_list.txt @@ -163,6 +163,7 @@ models;models_heightmap_rendering;★☆☆☆;1.8;3.5;2015;2025;"Ramon Santamar models;models_skybox_rendering;★★☆☆;1.8;4.0;2017;2025;"Ramon Santamaria";@raysan5 models;models_textured_cube;★★☆☆;4.5;4.5;2022;2025;"Ramon Santamaria";@raysan5 models;models_animation_gpu_skinning;★★★☆;4.5;4.5;2024;2025;"Daniel Holden";@orangeduck +models;models_animation_bone_blending;★★★★;5.5;5.5;2025;2025;"[Your Name]";@[your_github] models;models_bone_socket;★★★★;4.5;4.5;2024;2025;"iP";@ipzaur models;models_tesseract_view;★★☆☆;5.6-dev;5.6-dev;2024;2025;"Timothy van der Valk";@arceryz models;models_basic_voxel;★★☆☆;5.5;5.5;2025;2025;"Tim Little";@timlittle diff --git a/examples/models/models_animation_bone_blending.c b/examples/models/models_animation_bone_blending.c new file mode 100644 index 000000000..ea6827762 --- /dev/null +++ b/examples/models/models_animation_bone_blending.c @@ -0,0 +1,291 @@ +/******************************************************************************************* +* +* raylib [models] example - animation bone blending +* +* Example complexity rating: [★★★★] 4/4 +* +* Example originally created with raylib 5.5, last time updated with raylib 5.5 +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* This example demonstrates per-bone animation blending, allowing smooth transitions +* between two animations by interpolating bone transforms. This is useful for: +* - Blending movement animations (walk/run) with action animations (jump/attack) +* - Creating smooth animation transitions +* - Layering animations (e.g., upper body attack while lower body walks) +* +* Note: Due to limitations in the Apple OpenGL driver, GPU skinning does not work on MacOS +* +********************************************************************************************/ + +#include "raylib.h" +#include "raymath.h" +#include // For memcpy +#include // For NULL + +#if defined(PLATFORM_DESKTOP) + #define GLSL_VERSION 330 +#else // PLATFORM_ANDROID, PLATFORM_WEB + #define GLSL_VERSION 100 +#endif + +//------------------------------------------------------------------------------------ +// Check if a bone is part of upper body (for selective blending) +//------------------------------------------------------------------------------------ +bool IsUpperBodyBone(const char *boneName) +{ + // Common upper body bone names (adjust based on your model) + if (TextIsEqual(boneName, "spine") || TextIsEqual(boneName, "spine1") || TextIsEqual(boneName, "spine2") || + TextIsEqual(boneName, "chest") || TextIsEqual(boneName, "upperChest") || + TextIsEqual(boneName, "neck") || TextIsEqual(boneName, "head") || + TextIsEqual(boneName, "shoulder") || TextIsEqual(boneName, "shoulder_L") || TextIsEqual(boneName, "shoulder_R") || + TextIsEqual(boneName, "upperArm") || TextIsEqual(boneName, "upperArm_L") || TextIsEqual(boneName, "upperArm_R") || + TextIsEqual(boneName, "lowerArm") || TextIsEqual(boneName, "lowerArm_L") || TextIsEqual(boneName, "lowerArm_R") || + TextIsEqual(boneName, "hand") || TextIsEqual(boneName, "hand_L") || TextIsEqual(boneName, "hand_R") || + TextIsEqual(boneName, "clavicle") || TextIsEqual(boneName, "clavicle_L") || TextIsEqual(boneName, "clavicle_R")) + { + return true; + } + + // Check if bone name contains upper body keywords + if (strstr(boneName, "spine") != NULL || strstr(boneName, "chest") != NULL || + strstr(boneName, "neck") != NULL || strstr(boneName, "head") != NULL || + strstr(boneName, "shoulder") != NULL || strstr(boneName, "arm") != NULL || + strstr(boneName, "hand") != NULL || strstr(boneName, "clavicle") != NULL) + { + return true; + } + + return false; +} + +//------------------------------------------------------------------------------------ +// Blend two animations per-bone with selective upper/lower body blending +//------------------------------------------------------------------------------------ +void BlendModelAnimationsBones(Model *model, ModelAnimation *anim1, int frame1, + ModelAnimation *anim2, int frame2, float blendFactor, bool upperBodyBlend) +{ + // Clamp blend factor to [0, 1] + blendFactor = fminf(1.0f, fmaxf(0.0f, blendFactor)); + + // Validate inputs + if (anim1->boneCount == 0 || anim1->framePoses == NULL || + anim2->boneCount == 0 || anim2->framePoses == NULL || + model->boneCount == 0 || model->bindPose == NULL) + { + return; + } + + // Ensure frame indices are valid + if (frame1 >= anim1->frameCount) frame1 = anim1->frameCount - 1; + if (frame2 >= anim2->frameCount) frame2 = anim2->frameCount - 1; + if (frame1 < 0) frame1 = 0; + if (frame2 < 0) frame2 = 0; + + // Find first mesh with bones + int firstMeshWithBones = -1; + for (int i = 0; i < model->meshCount; i++) + { + if (model->meshes[i].boneMatrices) + { + firstMeshWithBones = i; + break; + } + } + + if (firstMeshWithBones == -1) return; + + // Get bone count (use minimum of all to be safe) + int boneCount = model->boneCount; + if (anim1->boneCount < boneCount) boneCount = anim1->boneCount; + if (anim2->boneCount < boneCount) boneCount = anim2->boneCount; + + // Blend each bone + for (int boneId = 0; boneId < boneCount; boneId++) + { + // Determine blend factor for this bone + float boneBlendFactor = blendFactor; + + // If upper body blending is enabled, use different blend factors for upper vs lower body + if (upperBodyBlend) + { + const char *boneName = model->bones[boneId].name; + bool isUpperBody = IsUpperBodyBone(boneName); + + // Upper body: use anim2 (attack), Lower body: use anim1 (walk) + // blendFactor = 0.0 means full anim1 (walk), 1.0 means full anim2 (attack) + if (isUpperBody) + { + // Upper body: blend towards anim2 (attack) + boneBlendFactor = blendFactor; + } + else + { + // Lower body: blend towards anim1 (walk) - invert the blend + boneBlendFactor = 1.0f - blendFactor; + } + } + + // Get transforms from both animations + Transform *bindTransform = &model->bindPose[boneId]; + Transform *anim1Transform = &anim1->framePoses[frame1][boneId]; + Transform *anim2Transform = &anim2->framePoses[frame2][boneId]; + + // Blend the transforms + Transform blended; + blended.translation = Vector3Lerp(anim1Transform->translation, anim2Transform->translation, boneBlendFactor); + blended.rotation = QuaternionSlerp(anim1Transform->rotation, anim2Transform->rotation, boneBlendFactor); + blended.scale = Vector3Lerp(anim1Transform->scale, anim2Transform->scale, boneBlendFactor); + + // Convert bind pose to matrix + Matrix bindMatrix = MatrixMultiply(MatrixMultiply( + MatrixScale(bindTransform->scale.x, bindTransform->scale.y, bindTransform->scale.z), + QuaternionToMatrix(bindTransform->rotation)), + MatrixTranslate(bindTransform->translation.x, bindTransform->translation.y, bindTransform->translation.z)); + + // Convert blended transform to matrix + Matrix blendedMatrix = MatrixMultiply(MatrixMultiply( + MatrixScale(blended.scale.x, blended.scale.y, blended.scale.z), + QuaternionToMatrix(blended.rotation)), + MatrixTranslate(blended.translation.x, blended.translation.y, blended.translation.z)); + + // Calculate final bone matrix (similar to UpdateModelAnimationBones) + model->meshes[firstMeshWithBones].boneMatrices[boneId] = MatrixMultiply(MatrixInvert(bindMatrix), blendedMatrix); + } + + // Copy bone matrices to remaining meshes + for (int i = firstMeshWithBones + 1; i < model->meshCount; i++) + { + if (model->meshes[i].boneMatrices) + { + memcpy(model->meshes[i].boneMatrices, + model->meshes[firstMeshWithBones].boneMatrices, + model->meshes[i].boneCount * sizeof(model->meshes[i].boneMatrices[0])); + } + } +} + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [models] example - animation bone blending"); + + // Define the camera to look into our 3d world + Camera camera = { 0 }; + camera.position = (Vector3){ 5.0f, 5.0f, 5.0f }; // Camera position + camera.target = (Vector3){ 0.0f, 2.0f, 0.0f }; // Camera looking at point + camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target) + camera.fovy = 45.0f; // Camera field-of-view Y + camera.projection = CAMERA_PERSPECTIVE; // Camera projection type + + // Load gltf model + Model characterModel = LoadModel("resources/models/gltf/greenman.glb"); + + // Load skinning shader + Shader skinningShader = LoadShader(TextFormat("resources/shaders/glsl%i/skinning.vs", GLSL_VERSION), + TextFormat("resources/shaders/glsl%i/skinning.fs", GLSL_VERSION)); + + characterModel.materials[1].shader = skinningShader; + + // Load gltf model animations + int animsCount = 0; + ModelAnimation *modelAnimations = LoadModelAnimations("resources/models/gltf/greenman.glb", &animsCount); + + // Log all available animations for debugging + TraceLog(LOG_INFO, "Found %d animations:", animsCount); + for (int i = 0; i < animsCount; i++) + { + TraceLog(LOG_INFO, " Animation %d: %s (%d frames)", i, modelAnimations[i].name, modelAnimations[i].frameCount); + } + + // Use specific indices: walk/move = 2, attack = 3 + unsigned int animIndex1 = 2; // Walk/Move animation (index 2) + unsigned int animIndex2 = 3; // Attack animation (index 3) + unsigned int animCurrentFrame1 = 0; + unsigned int animCurrentFrame2 = 0; + + // Validate indices + if (animIndex1 >= animsCount) animIndex1 = 0; + if (animIndex2 >= animsCount) animIndex2 = (animsCount > 1) ? 1 : 0; + + TraceLog(LOG_INFO, "Using Walk (index %d): %s", animIndex1, modelAnimations[animIndex1].name); + TraceLog(LOG_INFO, "Using Attack (index %d): %s", animIndex2, modelAnimations[animIndex2].name); + + Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position + bool upperBodyBlend = true; // Toggle: true = upper/lower body blending, false = uniform blending (50/50) + + DisableCursor(); // Limit cursor to relative movement inside the window + + SetTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + UpdateCamera(&camera, CAMERA_THIRD_PERSON); + + // Toggle upper/lower body blending mode (SPACE key) + if (IsKeyPressed(KEY_SPACE)) upperBodyBlend = !upperBodyBlend; + + // Update animation frames + ModelAnimation anim1 = modelAnimations[animIndex1]; + ModelAnimation anim2 = modelAnimations[animIndex2]; + + animCurrentFrame1 = (animCurrentFrame1 + 1) % anim1.frameCount; + animCurrentFrame2 = (animCurrentFrame2 + 1) % anim2.frameCount; + + // Blend the two animations + characterModel.transform = MatrixTranslate(position.x, position.y, position.z); + // When upperBodyBlend is ON: upper body = attack (1.0), lower body = walk (0.0) + // When upperBodyBlend is OFF: uniform blend at 0.5 (50% walk, 50% attack) + float blendFactor = upperBodyBlend ? 1.0f : 0.5f; + BlendModelAnimationsBones(&characterModel, &anim1, animCurrentFrame1, &anim2, animCurrentFrame2, blendFactor, upperBodyBlend); + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + BeginMode3D(camera); + + // Draw character mesh, pose calculation is done in shader (GPU skinning) + DrawMesh(characterModel.meshes[0], characterModel.materials[1], characterModel.transform); + + DrawGrid(10, 1.0f); + + EndMode3D(); + + // Draw UI + DrawText("BONE BLENDING EXAMPLE", 10, 10, 20, DARKGRAY); + DrawText(TextFormat("Walk (Animation 2): %s", anim1.name), 10, 35, 10, GRAY); + DrawText(TextFormat("Attack (Animation 3): %s", anim2.name), 10, 50, 10, GRAY); + DrawText(TextFormat("Mode: %s", upperBodyBlend ? "Upper/Lower Body Blending" : "Uniform Blending"), 10, 65, 10, GRAY); + DrawText("SPACE - Toggle blending mode", 10, GetScreenHeight() - 20, 10, DARKGRAY); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadModelAnimations(modelAnimations, animsCount); // Unload model animation + UnloadModel(characterModel); // Unload model and meshes/material + UnloadShader(skinningShader); // Unload GPU skinning shader + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} From 95edeeccd27c1cafb2241237415da28cc6dce6f0 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 17 Feb 2026 16:17:14 +0100 Subject: [PATCH 200/232] REVIEWED: example: `models_animation_bone_blending` --- examples/examples_list.txt | 1 - .../models/models_animation_bone_blending.c | 297 +++++++++--------- 2 files changed, 151 insertions(+), 147 deletions(-) diff --git a/examples/examples_list.txt b/examples/examples_list.txt index f4cfa0e47..eda62ee13 100644 --- a/examples/examples_list.txt +++ b/examples/examples_list.txt @@ -163,7 +163,6 @@ models;models_heightmap_rendering;★☆☆☆;1.8;3.5;2015;2025;"Ramon Santamar models;models_skybox_rendering;★★☆☆;1.8;4.0;2017;2025;"Ramon Santamaria";@raysan5 models;models_textured_cube;★★☆☆;4.5;4.5;2022;2025;"Ramon Santamaria";@raysan5 models;models_animation_gpu_skinning;★★★☆;4.5;4.5;2024;2025;"Daniel Holden";@orangeduck -models;models_animation_bone_blending;★★★★;5.5;5.5;2025;2025;"[Your Name]";@[your_github] models;models_bone_socket;★★★★;4.5;4.5;2024;2025;"iP";@ipzaur models;models_tesseract_view;★★☆☆;5.6-dev;5.6-dev;2024;2025;"Timothy van der Valk";@arceryz models;models_basic_voxel;★★☆☆;5.5;5.5;2025;2025;"Tim Little";@timlittle diff --git a/examples/models/models_animation_bone_blending.c b/examples/models/models_animation_bone_blending.c index ea6827762..11e05a305 100644 --- a/examples/models/models_animation_bone_blending.c +++ b/examples/models/models_animation_bone_blending.c @@ -6,23 +6,29 @@ * * Example originally created with raylib 5.5, last time updated with raylib 5.5 * +* This example demonstrates per-bone animation blending, allowing smooth transitions +* between two animations by interpolating bone transforms. This is useful for: +* - Blending movement animations (walk/run) with action animations (jump/attack) +* - Creating smooth animation transitions +* - Layering animations (e.g., upper body attack while lower body walks) +* +* Example contributed by dmitrii-brand (@dmitrii-brand) and reviewed by Ramon Santamaria (@raysan5) +* +* NOTE: Due to limitations in the Apple OpenGL driver, this feature does not work on MacOS +* * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software * -* This example demonstrates per-bone animation blending, allowing smooth transitions -* between two animations by interpolating bone transforms. This is useful for: -* - Blending movement animations (walk/run) with action animations (jump/attack) -* - Creating smooth animation transitions -* - Layering animations (e.g., upper body attack while lower body walks) -* -* Note: Due to limitations in the Apple OpenGL driver, GPU skinning does not work on MacOS +* Copyright (c) 2026 dmitrii-brand (@dmitrii-brand) * ********************************************************************************************/ #include "raylib.h" + #include "raymath.h" -#include // For memcpy -#include // For NULL + +#include // Required for: memcpy() +#include // Required for: NULL #if defined(PLATFORM_DESKTOP) #define GLSL_VERSION 330 @@ -31,140 +37,11 @@ #endif //------------------------------------------------------------------------------------ -// Check if a bone is part of upper body (for selective blending) +// Module Functions Declaration //------------------------------------------------------------------------------------ -bool IsUpperBodyBone(const char *boneName) -{ - // Common upper body bone names (adjust based on your model) - if (TextIsEqual(boneName, "spine") || TextIsEqual(boneName, "spine1") || TextIsEqual(boneName, "spine2") || - TextIsEqual(boneName, "chest") || TextIsEqual(boneName, "upperChest") || - TextIsEqual(boneName, "neck") || TextIsEqual(boneName, "head") || - TextIsEqual(boneName, "shoulder") || TextIsEqual(boneName, "shoulder_L") || TextIsEqual(boneName, "shoulder_R") || - TextIsEqual(boneName, "upperArm") || TextIsEqual(boneName, "upperArm_L") || TextIsEqual(boneName, "upperArm_R") || - TextIsEqual(boneName, "lowerArm") || TextIsEqual(boneName, "lowerArm_L") || TextIsEqual(boneName, "lowerArm_R") || - TextIsEqual(boneName, "hand") || TextIsEqual(boneName, "hand_L") || TextIsEqual(boneName, "hand_R") || - TextIsEqual(boneName, "clavicle") || TextIsEqual(boneName, "clavicle_L") || TextIsEqual(boneName, "clavicle_R")) - { - return true; - } - - // Check if bone name contains upper body keywords - if (strstr(boneName, "spine") != NULL || strstr(boneName, "chest") != NULL || - strstr(boneName, "neck") != NULL || strstr(boneName, "head") != NULL || - strstr(boneName, "shoulder") != NULL || strstr(boneName, "arm") != NULL || - strstr(boneName, "hand") != NULL || strstr(boneName, "clavicle") != NULL) - { - return true; - } - - return false; -} - -//------------------------------------------------------------------------------------ -// Blend two animations per-bone with selective upper/lower body blending -//------------------------------------------------------------------------------------ -void BlendModelAnimationsBones(Model *model, ModelAnimation *anim1, int frame1, - ModelAnimation *anim2, int frame2, float blendFactor, bool upperBodyBlend) -{ - // Clamp blend factor to [0, 1] - blendFactor = fminf(1.0f, fmaxf(0.0f, blendFactor)); - - // Validate inputs - if (anim1->boneCount == 0 || anim1->framePoses == NULL || - anim2->boneCount == 0 || anim2->framePoses == NULL || - model->boneCount == 0 || model->bindPose == NULL) - { - return; - } - - // Ensure frame indices are valid - if (frame1 >= anim1->frameCount) frame1 = anim1->frameCount - 1; - if (frame2 >= anim2->frameCount) frame2 = anim2->frameCount - 1; - if (frame1 < 0) frame1 = 0; - if (frame2 < 0) frame2 = 0; - - // Find first mesh with bones - int firstMeshWithBones = -1; - for (int i = 0; i < model->meshCount; i++) - { - if (model->meshes[i].boneMatrices) - { - firstMeshWithBones = i; - break; - } - } - - if (firstMeshWithBones == -1) return; - - // Get bone count (use minimum of all to be safe) - int boneCount = model->boneCount; - if (anim1->boneCount < boneCount) boneCount = anim1->boneCount; - if (anim2->boneCount < boneCount) boneCount = anim2->boneCount; - - // Blend each bone - for (int boneId = 0; boneId < boneCount; boneId++) - { - // Determine blend factor for this bone - float boneBlendFactor = blendFactor; - - // If upper body blending is enabled, use different blend factors for upper vs lower body - if (upperBodyBlend) - { - const char *boneName = model->bones[boneId].name; - bool isUpperBody = IsUpperBodyBone(boneName); - - // Upper body: use anim2 (attack), Lower body: use anim1 (walk) - // blendFactor = 0.0 means full anim1 (walk), 1.0 means full anim2 (attack) - if (isUpperBody) - { - // Upper body: blend towards anim2 (attack) - boneBlendFactor = blendFactor; - } - else - { - // Lower body: blend towards anim1 (walk) - invert the blend - boneBlendFactor = 1.0f - blendFactor; - } - } - - // Get transforms from both animations - Transform *bindTransform = &model->bindPose[boneId]; - Transform *anim1Transform = &anim1->framePoses[frame1][boneId]; - Transform *anim2Transform = &anim2->framePoses[frame2][boneId]; - - // Blend the transforms - Transform blended; - blended.translation = Vector3Lerp(anim1Transform->translation, anim2Transform->translation, boneBlendFactor); - blended.rotation = QuaternionSlerp(anim1Transform->rotation, anim2Transform->rotation, boneBlendFactor); - blended.scale = Vector3Lerp(anim1Transform->scale, anim2Transform->scale, boneBlendFactor); - - // Convert bind pose to matrix - Matrix bindMatrix = MatrixMultiply(MatrixMultiply( - MatrixScale(bindTransform->scale.x, bindTransform->scale.y, bindTransform->scale.z), - QuaternionToMatrix(bindTransform->rotation)), - MatrixTranslate(bindTransform->translation.x, bindTransform->translation.y, bindTransform->translation.z)); - - // Convert blended transform to matrix - Matrix blendedMatrix = MatrixMultiply(MatrixMultiply( - MatrixScale(blended.scale.x, blended.scale.y, blended.scale.z), - QuaternionToMatrix(blended.rotation)), - MatrixTranslate(blended.translation.x, blended.translation.y, blended.translation.z)); - - // Calculate final bone matrix (similar to UpdateModelAnimationBones) - model->meshes[firstMeshWithBones].boneMatrices[boneId] = MatrixMultiply(MatrixInvert(bindMatrix), blendedMatrix); - } - - // Copy bone matrices to remaining meshes - for (int i = firstMeshWithBones + 1; i < model->meshCount; i++) - { - if (model->meshes[i].boneMatrices) - { - memcpy(model->meshes[i].boneMatrices, - model->meshes[firstMeshWithBones].boneMatrices, - model->meshes[i].boneCount * sizeof(model->meshes[i].boneMatrices[0])); - } - } -} +static bool IsUpperBodyBone(const char *boneName); +static void BlendModelAnimationsBones(Model *model, ModelAnimation *anim1, int frame1, + ModelAnimation *anim2, int frame2, float blendFactor, bool upperBodyBlend); //------------------------------------------------------------------------------------ // Program main entry point @@ -207,8 +84,8 @@ int main(void) } // Use specific indices: walk/move = 2, attack = 3 - unsigned int animIndex1 = 2; // Walk/Move animation (index 2) - unsigned int animIndex2 = 3; // Attack animation (index 3) + unsigned int animIndex1 = 2; // Walk/Move animation (index 2) + unsigned int animIndex2 = 3; // Attack animation (index 3) unsigned int animCurrentFrame1 = 0; unsigned int animCurrentFrame2 = 0; @@ -241,8 +118,8 @@ int main(void) ModelAnimation anim1 = modelAnimations[animIndex1]; ModelAnimation anim2 = modelAnimations[animIndex2]; - animCurrentFrame1 = (animCurrentFrame1 + 1) % anim1.frameCount; - animCurrentFrame2 = (animCurrentFrame2 + 1) % anim2.frameCount; + animCurrentFrame1 = (animCurrentFrame1 + 1)%anim1.frameCount; + animCurrentFrame2 = (animCurrentFrame2 + 1)%anim2.frameCount; // Blend the two animations characterModel.transform = MatrixTranslate(position.x, position.y, position.z); @@ -289,3 +166,131 @@ int main(void) return 0; } + +//---------------------------------------------------------------------------------- +// Module Functions Definition +//---------------------------------------------------------------------------------- +// Check if a bone is part of upper body (for selective blending) +static bool IsUpperBodyBone(const char *boneName) +{ + // Common upper body bone names (adjust based on your model) + if (TextIsEqual(boneName, "spine") || TextIsEqual(boneName, "spine1") || TextIsEqual(boneName, "spine2") || + TextIsEqual(boneName, "chest") || TextIsEqual(boneName, "upperChest") || + TextIsEqual(boneName, "neck") || TextIsEqual(boneName, "head") || + TextIsEqual(boneName, "shoulder") || TextIsEqual(boneName, "shoulder_L") || TextIsEqual(boneName, "shoulder_R") || + TextIsEqual(boneName, "upperArm") || TextIsEqual(boneName, "upperArm_L") || TextIsEqual(boneName, "upperArm_R") || + TextIsEqual(boneName, "lowerArm") || TextIsEqual(boneName, "lowerArm_L") || TextIsEqual(boneName, "lowerArm_R") || + TextIsEqual(boneName, "hand") || TextIsEqual(boneName, "hand_L") || TextIsEqual(boneName, "hand_R") || + TextIsEqual(boneName, "clavicle") || TextIsEqual(boneName, "clavicle_L") || TextIsEqual(boneName, "clavicle_R")) + { + return true; + } + + // Check if bone name contains upper body keywords + if (strstr(boneName, "spine") != NULL || strstr(boneName, "chest") != NULL || + strstr(boneName, "neck") != NULL || strstr(boneName, "head") != NULL || + strstr(boneName, "shoulder") != NULL || strstr(boneName, "arm") != NULL || + strstr(boneName, "hand") != NULL || strstr(boneName, "clavicle") != NULL) + { + return true; + } + + return false; +} + +// Blend two animations per-bone with selective upper/lower body blending +static void BlendModelAnimationsBones(Model *model, ModelAnimation *anim1, int frame1, + ModelAnimation *anim2, int frame2, float blendFactor, bool upperBodyBlend) +{ + // Validate inputs + if (anim1->boneCount == 0 || anim1->framePoses == NULL || + anim2->boneCount == 0 || anim2->framePoses == NULL || + model->boneCount == 0 || model->bindPose == NULL) + { + return; + } + + // Clamp blend factor to [0, 1] + blendFactor = fminf(1.0f, fmaxf(0.0f, blendFactor)); + + // Ensure frame indices are valid + if (frame1 >= anim1->frameCount) frame1 = anim1->frameCount - 1; + if (frame2 >= anim2->frameCount) frame2 = anim2->frameCount - 1; + if (frame1 < 0) frame1 = 0; + if (frame2 < 0) frame2 = 0; + + // Find first mesh with bones + int firstMeshWithBones = -1; + for (int i = 0; i < model->meshCount; i++) + { + if (model->meshes[i].boneMatrices) + { + firstMeshWithBones = i; + break; + } + } + + if (firstMeshWithBones == -1) return; + + // Get bone count (use minimum of all to be safe) + int boneCount = model->boneCount; + if (anim1->boneCount < boneCount) boneCount = anim1->boneCount; + if (anim2->boneCount < boneCount) boneCount = anim2->boneCount; + + // Blend each bone + for (int boneId = 0; boneId < boneCount; boneId++) + { + // Determine blend factor for this bone + float boneBlendFactor = blendFactor; + + // If upper body blending is enabled, use different blend factors for upper vs lower body + if (upperBodyBlend) + { + const char *boneName = model->bones[boneId].name; + bool isUpperBody = IsUpperBodyBone(boneName); + + // Upper body: use anim2 (attack), Lower body: use anim1 (walk) + // blendFactor = 0.0 means full anim1 (walk), 1.0 means full anim2 (attack) + if (isUpperBody) boneBlendFactor = blendFactor; // Upper body: blend towards anim2 (attack) + else boneBlendFactor = 1.0f - blendFactor; // Lower body: blend towards anim1 (walk) - invert the blend + } + + // Get transforms from both animations + Transform *bindTransform = &model->bindPose[boneId]; + Transform *anim1Transform = &anim1->framePoses[frame1][boneId]; + Transform *anim2Transform = &anim2->framePoses[frame2][boneId]; + + // Blend the transforms + Transform blended; + blended.translation = Vector3Lerp(anim1Transform->translation, anim2Transform->translation, boneBlendFactor); + blended.rotation = QuaternionSlerp(anim1Transform->rotation, anim2Transform->rotation, boneBlendFactor); + blended.scale = Vector3Lerp(anim1Transform->scale, anim2Transform->scale, boneBlendFactor); + + // Convert bind pose to matrix + Matrix bindMatrix = MatrixMultiply(MatrixMultiply( + MatrixScale(bindTransform->scale.x, bindTransform->scale.y, bindTransform->scale.z), + QuaternionToMatrix(bindTransform->rotation)), + MatrixTranslate(bindTransform->translation.x, bindTransform->translation.y, bindTransform->translation.z)); + + // Convert blended transform to matrix + Matrix blendedMatrix = MatrixMultiply(MatrixMultiply( + MatrixScale(blended.scale.x, blended.scale.y, blended.scale.z), + QuaternionToMatrix(blended.rotation)), + MatrixTranslate(blended.translation.x, blended.translation.y, blended.translation.z)); + + // Calculate final bone matrix (similar to UpdateModelAnimationBones) + model->meshes[firstMeshWithBones].boneMatrices[boneId] = MatrixMultiply(MatrixInvert(bindMatrix), blendedMatrix); + } + + // Copy bone matrices to remaining meshes + for (int i = firstMeshWithBones + 1; i < model->meshCount; i++) + { + if (model->meshes[i].boneMatrices) + { + memcpy(model->meshes[i].boneMatrices, + model->meshes[firstMeshWithBones].boneMatrices, + model->meshes[i].boneCount*sizeof(model->meshes[i].boneMatrices[0])); + } + } +} + From 1955516f54585c6a4418866fbaf96cb62eec91ed Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 17 Feb 2026 16:39:02 +0100 Subject: [PATCH 201/232] Updated raygui for examples --- examples/core/core_directory_files.c | 20 +- examples/core/raygui.h | 390 +- .../models/models_directional_billboard.c | 2 + examples/models/raygui.h | 6043 +++++++++++++++++ examples/shaders/raygui.h | 390 +- examples/shapes/raygui.h | 390 +- 6 files changed, 6732 insertions(+), 503 deletions(-) create mode 100644 examples/models/raygui.h diff --git a/examples/core/core_directory_files.c b/examples/core/core_directory_files.c index a98c950f6..5bc7b7e57 100644 --- a/examples/core/core_directory_files.c +++ b/examples/core/core_directory_files.c @@ -37,10 +37,17 @@ int main(void) char directory[MAX_FILEPATH_SIZE] = { 0 }; strcpy(directory, GetWorkingDirectory()); + // Load file-paths on current working directory + // NOTE: LoadDirectoryFiles() loads files and directories by default, + // use LoadDirectoryFilesEx() for custom filters and recursive directories loading FilePathList files = LoadDirectoryFiles(directory); int btnBackPressed = false; + int listScrollIndex = 0; + int listItemActive = -1; + int listItemFocused = -1; + SetTargetFPS(60); //-------------------------------------------------------------------------------------- @@ -62,10 +69,18 @@ int main(void) BeginDrawing(); ClearBackground(RAYWHITE); - DrawText(directory, 100, 40, 20, DARKGRAY); + btnBackPressed = GuiButton((Rectangle){ 40.0f, 10.0f, 48, 28 }, "<"); - btnBackPressed = GuiButton((Rectangle){ 40.0f, 38.0f, 48, 24 }, "<"); + GuiSetStyle(DEFAULT, TEXT_SIZE, GuiGetFont().baseSize*2); + GuiLabel((Rectangle){ 40 + 48 + 10, 10, 700, 28 }, directory); + GuiSetStyle(DEFAULT, TEXT_SIZE, GuiGetFont().baseSize); + GuiSetStyle(LISTVIEW, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); + GuiSetStyle(LISTVIEW, TEXT_PADDING, 40); + GuiListViewEx((Rectangle){ 0, 50, GetScreenWidth(), GetScreenHeight() - 40 }, + files.paths, files.count, &listScrollIndex, &listItemActive, &listItemFocused); + + /* for (int i = 0; i < (int)files.count; i++) { Color color = Fade(LIGHTGRAY, 0.3f); @@ -84,6 +99,7 @@ int main(void) DrawRectangle(0, 85 + 40*i, screenWidth, 40, color); DrawText(GetFileName(files.paths[i]), 120, 100 + 40*i, 10, GRAY); } + */ EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/examples/core/raygui.h b/examples/core/raygui.h index 88fe5cc5b..67c16be45 100644 --- a/examples/core/raygui.h +++ b/examples/core/raygui.h @@ -1,6 +1,6 @@ /******************************************************************************************* * -* raygui v4.5-dev - A simple and easy-to-use immediate-mode gui library +* raygui v5.0-dev - A simple and easy-to-use immediate-mode gui library * * DESCRIPTION: * raygui is a tools-dev-focused immediate-mode-gui library based on raylib but also @@ -83,8 +83,8 @@ * used for all controls, when any of those base values is set, it is automatically populated to all * controls, so, specific control values overwriting generic style should be set after base values * -* After the first BASE set we have the EXTENDED properties (by default guiStyle[16..23]), those -* properties are actually common to all controls and can not be overwritten individually (like BASE ones) +* After the first BASE properties set, the EXTENDED properties set is defined (by default guiStyle[16..23]), +* those properties are actually common to all controls and can not be overwritten individually (like BASE ones) * Some of those properties are: TEXT_SIZE, TEXT_SPACING, LINE_COLOR, BACKGROUND_COLOR * * Custom control properties can be defined using the EXTENDED properties for each independent control. @@ -141,13 +141,14 @@ * Draw text bounds rectangles for debug * * VERSIONS HISTORY: -* 5.0 (xx-Nov-2025) ADDED: Support up to 32 controls (v500) +* 5.0 (xx-Mar-2026) ADDED: Support up to 32 controls (v500) * ADDED: guiControlExclusiveMode and guiControlExclusiveRec for exclusive modes * ADDED: GuiValueBoxFloat() * ADDED: GuiDropdonwBox() properties: DROPDOWN_ARROW_HIDDEN, DROPDOWN_ROLL_UP * ADDED: GuiListView() property: LIST_ITEMS_BORDER_WIDTH * ADDED: GuiLoadIconsFromMemory() * ADDED: Multiple new icons +* ADDED: Macros for inputs customization, raylib decoupling * REMOVED: GuiSpinner() from controls list, using BUTTON + VALUEBOX properties * REMOVED: GuiSliderPro(), functionality was redundant * REVIEWED: Controls using text labels to use LABEL properties @@ -165,6 +166,7 @@ * REVIEWED: GuiTextBox(), multiple improvements: autocursor and more * REVIEWED: Functions descriptions, removed wrong return value reference * REDESIGNED: GuiColorPanel(), improved HSV <-> RGBA convertion +* REDESIGNED: WARNING: TEXT_LINE_SPACING does not consider text height, only lines spacing * * 4.0 (12-Sep-2023) ADDED: GuiToggleSlider() * ADDED: GuiColorPickerHSV() and GuiColorPanelHSV() @@ -316,7 +318,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2014-2025 Ramon Santamaria (@raysan5) +* Copyright (c) 2014-2026 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -351,10 +353,11 @@ // NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll #if defined(_WIN32) #if defined(BUILD_LIBTYPE_SHARED) - #define RAYGUIAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll) + #define RAYGUIAPI __declspec(dllexport) // Building the library as a Win32 shared library (.dll) #elif defined(USE_LIBTYPE_SHARED) - #define RAYGUIAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll) + #define RAYGUIAPI __declspec(dllimport) // Using the library as a Win32 shared library (.dll) #endif + #define _CRT_SECURE_NO_WARNINGS // Disable unsafe warnings on scanf() functions in MSVC #endif // Function specifiers definition @@ -369,9 +372,48 @@ // NOTE: Avoiding those calls, also avoids const strings memory usage #define RAYGUI_SUPPORT_LOG_INFO #if defined(RAYGUI_SUPPORT_LOG_INFO) - #define RAYGUI_LOG(...) printf(__VA_ARGS__) + #define RAYGUI_LOG(...) printf(__VA_ARGS__) #else - #define RAYGUI_LOG(...) + #define RAYGUI_LOG(...) +#endif + +// Macros to define required UI inputs, including mapping to gamepad controls +// TODO: Define additionally required macros for missing inputs +#if !defined(GUI_BUTTON_DOWN) + #define GUI_BUTTON_DOWN (IsMouseButtonDown(MOUSE_LEFT_BUTTON) || IsGamepadButtonDown(0, GAMEPAD_BUTTON_RIGHT_FACE_DOWN)) +#endif +#if !defined(GUI_BUTTON_DOWN_ALT) + // Mapping to alternative button down pressed + #define GUI_BUTTON_DOWN_ALT (IsMouseButtonDown(MOUSE_RIGHT_BUTTON) || IsGamepadButtonDown(0, GAMEPAD_BUTTON_RIGHT_FACE_RIGHT)) +#endif +#if !defined(GUI_BUTTON_PRESSED) + #define GUI_BUTTON_PRESSED (IsMouseButtonPressed(MOUSE_LEFT_BUTTON) || IsGamepadButtonPressed(0, GAMEPAD_BUTTON_RIGHT_FACE_DOWN)) +#endif +// TODO: WARNING: GuiTabBar() still requires IsMouseButtonPressed(MOUSE_MIDDLE_BUTTON) +#if !defined(GUI_BUTTON_RELEASED) + #define GUI_BUTTON_RELEASED (IsMouseButtonReleased(MOUSE_LEFT_BUTTON) || IsGamepadButtonReleased(0, GAMEPAD_BUTTON_RIGHT_FACE_DOWN)) +#endif +#if !defined(GUI_SCROLL_DELTA) + // Mapping to scroll delta changes + // TODO: Review inconsistencies between platforms + #if defined(PLATFORM_WEB) + // NOTE: Gamepad axis triggers not detected on web platform + #define GUI_SCROLL_DELTA ((float)IsGamepadButtonDown(0, GAMEPAD_BUTTON_RIGHT_TRIGGER_2) - (float)IsGamepadButtonDown(0, GAMEPAD_BUTTON_LEFT_TRIGGER_2)) + #else + #define GUI_SCROLL_DELTA (GetMouseWheelMove() + (GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_TRIGGER) + 1) - (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_TRIGGER) + 1)) + #endif +#endif +#if !defined(GUI_POINTER_POSITION) + #define GUI_POINTER_POSITION GetMousePosition() +#endif +#if !defined(GUI_KEY_DOWN) + #define GUI_KEY_DOWN(key) IsKeyDown(key) +#endif +#if !defined(GUI_KEY_PRESSED) + #define GUI_KEY_PRESSED(key) IsKeyPressed(key) +#endif +#if !defined(GUI_INPUT_KEY) + #define GUI_INPUT_KEY GetCharPressed() #endif //---------------------------------------------------------------------------------- @@ -567,7 +609,7 @@ typedef enum { //---------------------------------------------------------------------------------- // DEFAULT extended properties // NOTE: Those properties are common to all controls or global -// WARNING: We only have 8 slots for those properties by default!!! -> New global control: TEXT? +// WARNING: Only 8 slots vailable for those properties by default typedef enum { TEXT_SIZE = 16, // Text size (glyphs max height) TEXT_SPACING, // Text spacing between glyphs @@ -1091,7 +1133,7 @@ typedef enum { // Icons data is defined by bit array (every bit represents one pixel) // Those arrays are stored as unsigned int data arrays, so, // every array element defines 32 pixels (bits) of information -// One icon is defined by 8 int, (8 int * 32 bit = 256 bit = 16*16 pixels) +// One icon is defined by 8 int, (8 int*32 bit = 256 bit = 16*16 pixels) // NOTE: Number of elemens depend on RAYGUI_ICON_SIZE (by default 16x16 pixels) #define RAYGUI_ICON_DATA_ELEMENTS (RAYGUI_ICON_SIZE*RAYGUI_ICON_SIZE/32) @@ -1450,12 +1492,12 @@ static bool IsMouseButtonReleased(int button); static bool IsKeyDown(int key); static bool IsKeyPressed(int key); -static int GetCharPressed(void); // -- GuiTextBox(), GuiValueBox() +static int GetCharPressed(void); // -- GuiTextBox(), GuiValueBox() //------------------------------------------------------------------------------- // Drawing required functions //------------------------------------------------------------------------------- -static void DrawRectangle(int x, int y, int width, int height, Color color); // -- GuiDrawRectangle() +static void DrawRectangle(int x, int y, int width, int height, Color color); // -- GuiDrawRectangle() static void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4); // -- GuiColorPicker() //------------------------------------------------------------------------------- @@ -1520,11 +1562,11 @@ static Color GuiFade(Color color, float alpha); // Fade color by an alph // Gui Setup Functions Definition //---------------------------------------------------------------------------------- // Enable gui global state -// NOTE: We check for STATE_DISABLED to avoid messing custom global state setups +// NOTE: Checking for STATE_DISABLED to avoid messing custom global state setups void GuiEnable(void) { if (guiState == STATE_DISABLED) guiState = STATE_NORMAL; } // Disable gui global state -// NOTE: We check for STATE_NORMAL to avoid messing custom global state setups +// NOTE: Checking for STATE_NORMAL to avoid messing custom global state setups void GuiDisable(void) { if (guiState == STATE_NORMAL) guiState = STATE_DISABLED; } // Lock gui global state @@ -1557,9 +1599,8 @@ void GuiSetFont(Font font) { if (font.texture.id > 0) { - // NOTE: If we try to setup a font but default style has not been - // lazily loaded before, it will be overwritten, so we need to force - // default style loading first + // NOTE: If a font is tried to be set but default style has not been lazily loaded first, + // it will be overwritten, so default style loading needs to be forced first if (!guiStyleLoaded) GuiLoadStyleDefault(); guiFont = font; @@ -1613,13 +1654,14 @@ int GuiWindowBox(Rectangle bounds, const char *title) //GuiState state = guiState; int statusBarHeight = RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT; + int statusBorderWidth = GuiGetStyle(STATUSBAR, BORDER_WIDTH); Rectangle statusBar = { bounds.x, bounds.y, bounds.width, (float)statusBarHeight }; if (bounds.height < statusBarHeight*2.0f) bounds.height = statusBarHeight*2.0f; const float vPadding = statusBarHeight/2.0f - RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT/2.0f; - Rectangle windowPanel = { bounds.x, bounds.y + (float)statusBarHeight - 1, bounds.width, bounds.height - (float)statusBarHeight + 1 }; - Rectangle closeButtonRec = { statusBar.x + statusBar.width - GuiGetStyle(STATUSBAR, BORDER_WIDTH) - RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT - vPadding, + Rectangle windowPanel = { bounds.x, bounds.y + (float)statusBarHeight - (float)statusBorderWidth, bounds.width, bounds.height - (float)statusBarHeight + (float)statusBorderWidth }; + Rectangle closeButtonRec = { statusBar.x + statusBar.width - (float)statusBorderWidth - RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT - vPadding, statusBar.y + vPadding, RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT, RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT }; // Update control @@ -1629,8 +1671,8 @@ int GuiWindowBox(Rectangle bounds, const char *title) // Draw control //-------------------------------------------------------------------- - GuiStatusBar(statusBar, title); // Draw window header as status bar GuiPanel(windowPanel, NULL); // Draw window base + GuiStatusBar(statusBar, title); // Draw window header as status bar // Draw window close button int tempBorderWidth = GuiGetStyle(BUTTON, BORDER_WIDTH); @@ -1786,7 +1828,7 @@ int GuiTabBar(Rectangle bounds, const char **text, int count, int *active) } // Close tab with middle mouse button pressed - if (CheckCollisionPointRec(GetMousePosition(), tabBounds) && IsMouseButtonPressed(MOUSE_MIDDLE_BUTTON)) result = i; + if (CheckCollisionPointRec(GUI_POINTER_POSITION, tabBounds) && IsMouseButtonPressed(MOUSE_MIDDLE_BUTTON)) result = i; GuiSetStyle(TOGGLE, TEXT_PADDING, textPadding); GuiSetStyle(TOGGLE, TEXT_ALIGNMENT, textAlignment); @@ -1885,37 +1927,37 @@ int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; // Check button state if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; else state = STATE_FOCUSED; #if defined(SUPPORT_SCROLLBAR_KEY_INPUT) if (hasHorizontalScrollBar) { - if (IsKeyDown(KEY_RIGHT)) scrollPos.x -= GuiGetStyle(SCROLLBAR, SCROLL_SPEED); - if (IsKeyDown(KEY_LEFT)) scrollPos.x += GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + if (GUI_KEY_DOWN(KEY_RIGHT)) scrollPos.x -= GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + if (GUI_KEY_DOWN(KEY_LEFT)) scrollPos.x += GuiGetStyle(SCROLLBAR, SCROLL_SPEED); } if (hasVerticalScrollBar) { - if (IsKeyDown(KEY_DOWN)) scrollPos.y -= GuiGetStyle(SCROLLBAR, SCROLL_SPEED); - if (IsKeyDown(KEY_UP)) scrollPos.y += GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + if (GUI_KEY_DOWN(KEY_DOWN)) scrollPos.y -= GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + if (GUI_KEY_DOWN(KEY_UP)) scrollPos.y += GuiGetStyle(SCROLLBAR, SCROLL_SPEED); } #endif - float wheelMove = GetMouseWheelMove(); + float scrollDelta = GUI_SCROLL_DELTA; // Set scrolling speed with mouse wheel based on ratio between bounds and content - Vector2 mouseWheelSpeed = { content.width/bounds.width, content.height/bounds.height }; - if (mouseWheelSpeed.x < RAYGUI_MIN_MOUSE_WHEEL_SPEED) mouseWheelSpeed.x = RAYGUI_MIN_MOUSE_WHEEL_SPEED; - if (mouseWheelSpeed.y < RAYGUI_MIN_MOUSE_WHEEL_SPEED) mouseWheelSpeed.y = RAYGUI_MIN_MOUSE_WHEEL_SPEED; + Vector2 scrollSpeed = { content.width/bounds.width, content.height/bounds.height }; + if (scrollSpeed.x < RAYGUI_MIN_MOUSE_WHEEL_SPEED) scrollSpeed.x = RAYGUI_MIN_MOUSE_WHEEL_SPEED; + if (scrollSpeed.y < RAYGUI_MIN_MOUSE_WHEEL_SPEED) scrollSpeed.y = RAYGUI_MIN_MOUSE_WHEEL_SPEED; // Horizontal and vertical scrolling with mouse wheel - if (hasHorizontalScrollBar && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_LEFT_SHIFT))) scrollPos.x += wheelMove*mouseWheelSpeed.x; - else scrollPos.y += wheelMove*mouseWheelSpeed.y; // Vertical scroll + if (hasHorizontalScrollBar && (GUI_KEY_DOWN(KEY_LEFT_CONTROL) || GUI_KEY_DOWN(KEY_LEFT_SHIFT))) scrollPos.x += scrollDelta*scrollSpeed.x; + else scrollPos.y += scrollDelta*scrollSpeed.y; // Vertical scroll } } @@ -2001,15 +2043,15 @@ int GuiButton(Rectangle bounds, const char *text) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; // Check button state if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; else state = STATE_FOCUSED; - if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) result = 1; + if (GUI_BUTTON_RELEASED) result = 1; } } //-------------------------------------------------------------------- @@ -2031,7 +2073,7 @@ int GuiLabelButton(Rectangle bounds, const char *text) GuiState state = guiState; bool pressed = false; - // NOTE: We force bounds.width to be all text + // NOTE: Force bounds.width to be all text float textWidth = (float)GuiGetTextWidth(text); if ((bounds.width - 2*GuiGetStyle(LABEL, BORDER_WIDTH) - 2*GuiGetStyle(LABEL, TEXT_PADDING)) < textWidth) bounds.width = textWidth + 2*GuiGetStyle(LABEL, BORDER_WIDTH) + 2*GuiGetStyle(LABEL, TEXT_PADDING) + 2; @@ -2039,15 +2081,15 @@ int GuiLabelButton(Rectangle bounds, const char *text) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; // Check checkbox state if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; else state = STATE_FOCUSED; - if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) pressed = true; + if (GUI_BUTTON_RELEASED) pressed = true; } } //-------------------------------------------------------------------- @@ -2073,13 +2115,13 @@ int GuiToggle(Rectangle bounds, const char *text, bool *active) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; // Check toggle button state if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; - else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; + else if (GUI_BUTTON_RELEASED) { state = STATE_NORMAL; *active = !(*active); @@ -2184,12 +2226,12 @@ int GuiToggleSlider(Rectangle bounds, const char *text, int *active) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; - else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; + else if (GUI_BUTTON_RELEASED) { state = STATE_PRESSED; (*active)++; @@ -2255,7 +2297,7 @@ int GuiCheckBox(Rectangle bounds, const char *text, bool *checked) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; Rectangle totalBounds = { (GuiGetStyle(CHECKBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT)? textBounds.x : bounds.x, @@ -2267,10 +2309,10 @@ int GuiCheckBox(Rectangle bounds, const char *text, bool *checked) // Check checkbox state if (CheckCollisionPointRec(mousePoint, totalBounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; else state = STATE_FOCUSED; - if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_RELEASED) { *checked = !(*checked); result = 1; @@ -2323,18 +2365,18 @@ int GuiComboBox(Rectangle bounds, const char *text, int *active) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && (itemCount > 1) && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; if (CheckCollisionPointRec(mousePoint, bounds) || CheckCollisionPointRec(mousePoint, selector)) { - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_PRESSED) { *active += 1; if (*active >= itemCount) *active = 0; // Cyclic combobox } - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; else state = STATE_FOCUSED; } } @@ -2392,7 +2434,7 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && (editMode || !guiLocked) && (itemCount > 1) && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; if (editMode) { @@ -2401,11 +2443,11 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod // Check if mouse has been pressed or released outside limits if (!CheckCollisionPointRec(mousePoint, boundsOpen)) { - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON) || IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) result = 1; + if (GUI_BUTTON_PRESSED || GUI_BUTTON_RELEASED) result = 1; } // Check if already selected item has been pressed again - if (CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) result = 1; + if (CheckCollisionPointRec(mousePoint, bounds) && GUI_BUTTON_PRESSED) result = 1; // Check focused and selected item for (int i = 0; i < itemCount; i++) @@ -2417,7 +2459,7 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod if (CheckCollisionPointRec(mousePoint, itemBounds)) { itemFocused = i; - if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_RELEASED) { itemSelected = i; result = 1; // Item selected @@ -2432,7 +2474,7 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod { if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_PRESSED) { result = 1; state = STATE_PRESSED; @@ -2506,7 +2548,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) int result = 0; GuiState state = guiState; - bool multiline = false; // TODO: Consider multiline text input + bool multiline = false; // TODO: Consider multiline text input int wrapMode = GuiGetStyle(DEFAULT, TEXT_WRAP_MODE); Rectangle textBounds = GetTextBounds(TEXTBOX, bounds); @@ -2514,7 +2556,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) int thisCursorIndex = textBoxCursorIndex; if (thisCursorIndex > textLength) thisCursorIndex = textLength; int textWidth = GuiGetTextWidth(text) - GuiGetTextWidth(text + thisCursorIndex); - int textIndexOffset = 0; // Text index offset to start drawing in the box + int textIndexOffset = 0; // Text index offset to start drawing in the box // Cursor rectangle // NOTE: Position X value should be updated @@ -2547,13 +2589,13 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) !guiControlExclusiveMode && // No gui slider on dragging (wrapMode == TEXT_WRAP_NONE)) // No wrap mode { - Vector2 mousePosition = GetMousePosition(); + Vector2 mousePosition = GUI_POINTER_POSITION; if (editMode) { // GLOBAL: Auto-cursor movement logic // NOTE: Keystrokes are handled repeatedly when button is held down for some time - if (IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_UP) || IsKeyDown(KEY_DOWN) || IsKeyDown(KEY_BACKSPACE) || IsKeyDown(KEY_DELETE)) autoCursorCounter++; + if (GUI_KEY_DOWN(KEY_LEFT) || GUI_KEY_DOWN(KEY_RIGHT) || GUI_KEY_DOWN(KEY_UP) || GUI_KEY_DOWN(KEY_DOWN) || GUI_KEY_DOWN(KEY_BACKSPACE) || GUI_KEY_DOWN(KEY_DELETE)) autoCursorCounter++; else autoCursorCounter = 0; bool autoCursorShouldTrigger = (autoCursorCounter > RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN) && ((autoCursorCounter % RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY) == 0); @@ -2563,7 +2605,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) if (textBoxCursorIndex > textLength) textBoxCursorIndex = textLength; // If text does not fit in the textbox and current cursor position is out of bounds, - // we add an index offset to text for drawing only what requires depending on cursor + // adding an index offset to text for drawing only what requires depending on cursor while (textWidth >= textBounds.width) { int nextCodepointSize = 0; @@ -2574,15 +2616,15 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) textWidth = GuiGetTextWidth(text + textIndexOffset) - GuiGetTextWidth(text + textBoxCursorIndex); } - int codepoint = GetCharPressed(); // Get Unicode codepoint - if (multiline && IsKeyPressed(KEY_ENTER)) codepoint = (int)'\n'; + int codepoint = GUI_INPUT_KEY; // Get Unicode codepoint + if (multiline && GUI_KEY_PRESSED(KEY_ENTER)) codepoint = (int)'\n'; // Encode codepoint as UTF-8 int codepointSize = 0; const char *charEncoded = CodepointToUTF8(codepoint, &codepointSize); // Handle text paste action - if (IsKeyPressed(KEY_V) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))) + if (GUI_KEY_PRESSED(KEY_V) && (GUI_KEY_DOWN(KEY_LEFT_CONTROL) || GUI_KEY_DOWN(KEY_RIGHT_CONTROL))) { const char *pasteText = GetClipboardText(); if (pasteText != NULL) @@ -2632,13 +2674,13 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) } // Move cursor to start - if ((textLength > 0) && IsKeyPressed(KEY_HOME)) textBoxCursorIndex = 0; + if ((textLength > 0) && GUI_KEY_PRESSED(KEY_HOME)) textBoxCursorIndex = 0; // Move cursor to end - if ((textLength > textBoxCursorIndex) && IsKeyPressed(KEY_END)) textBoxCursorIndex = textLength; + if ((textLength > textBoxCursorIndex) && GUI_KEY_PRESSED(KEY_END)) textBoxCursorIndex = textLength; // Delete related codepoints from text, after current cursor position - if ((textLength > textBoxCursorIndex) && IsKeyPressed(KEY_DELETE) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))) + if ((textLength > textBoxCursorIndex) && GUI_KEY_PRESSED(KEY_DELETE) && (GUI_KEY_DOWN(KEY_LEFT_CONTROL) || GUI_KEY_DOWN(KEY_RIGHT_CONTROL))) { int offset = textBoxCursorIndex; int accCodepointSize = 0; @@ -2674,7 +2716,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) textLength -= accCodepointSize; } - else if ((textLength > textBoxCursorIndex) && (IsKeyPressed(KEY_DELETE) || (IsKeyDown(KEY_DELETE) && autoCursorShouldTrigger))) + else if ((textLength > textBoxCursorIndex) && (GUI_KEY_PRESSED(KEY_DELETE) || (GUI_KEY_DOWN(KEY_DELETE) && autoCursorShouldTrigger))) { // Delete single codepoint from text, after current cursor position @@ -2688,12 +2730,12 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) } // Delete related codepoints from text, before current cursor position - if ((textBoxCursorIndex > 0) && IsKeyPressed(KEY_BACKSPACE) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))) + if ((textBoxCursorIndex > 0) && GUI_KEY_PRESSED(KEY_BACKSPACE) && (GUI_KEY_DOWN(KEY_LEFT_CONTROL) || GUI_KEY_DOWN(KEY_RIGHT_CONTROL))) { int offset = textBoxCursorIndex; int accCodepointSize = 0; - int prevCodepointSize; - int prevCodepoint; + int prevCodepointSize = 0; + int prevCodepoint = 0; // Check whitespace to delete (ASCII only) while (offset > 0) @@ -2724,7 +2766,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) textBoxCursorIndex -= accCodepointSize; } - else if ((textBoxCursorIndex > 0) && (IsKeyPressed(KEY_BACKSPACE) || (IsKeyDown(KEY_BACKSPACE) && autoCursorShouldTrigger))) + else if ((textBoxCursorIndex > 0) && (GUI_KEY_PRESSED(KEY_BACKSPACE) || (GUI_KEY_DOWN(KEY_BACKSPACE) && autoCursorShouldTrigger))) { // Delete single codepoint from text, before current cursor position @@ -2740,12 +2782,12 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) } // Move cursor position with keys - if ((textBoxCursorIndex > 0) && IsKeyPressed(KEY_LEFT) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))) + if ((textBoxCursorIndex > 0) && GUI_KEY_PRESSED(KEY_LEFT) && (GUI_KEY_DOWN(KEY_LEFT_CONTROL) || GUI_KEY_DOWN(KEY_RIGHT_CONTROL))) { int offset = textBoxCursorIndex; //int accCodepointSize = 0; - int prevCodepointSize; - int prevCodepoint; + int prevCodepointSize = 0; + int prevCodepoint = 0; // Check whitespace to skip (ASCII only) while (offset > 0) @@ -2771,14 +2813,14 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) textBoxCursorIndex = offset; } - else if ((textBoxCursorIndex > 0) && (IsKeyPressed(KEY_LEFT) || (IsKeyDown(KEY_LEFT) && autoCursorShouldTrigger))) + else if ((textBoxCursorIndex > 0) && (GUI_KEY_PRESSED(KEY_LEFT) || (GUI_KEY_DOWN(KEY_LEFT) && autoCursorShouldTrigger))) { int prevCodepointSize = 0; GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize); textBoxCursorIndex -= prevCodepointSize; } - else if ((textLength > textBoxCursorIndex) && IsKeyPressed(KEY_RIGHT) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))) + else if ((textLength > textBoxCursorIndex) && GUI_KEY_PRESSED(KEY_RIGHT) && (GUI_KEY_DOWN(KEY_LEFT_CONTROL) || GUI_KEY_DOWN(KEY_RIGHT_CONTROL))) { int offset = textBoxCursorIndex; //int accCodepointSize = 0; @@ -2810,7 +2852,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) textBoxCursorIndex = offset; } - else if ((textLength > textBoxCursorIndex) && (IsKeyPressed(KEY_RIGHT) || (IsKeyDown(KEY_RIGHT) && autoCursorShouldTrigger))) + else if ((textLength > textBoxCursorIndex) && (GUI_KEY_PRESSED(KEY_RIGHT) || (GUI_KEY_DOWN(KEY_RIGHT) && autoCursorShouldTrigger))) { int nextCodepointSize = 0; GetCodepointNext(text + textBoxCursorIndex, &nextCodepointSize); @@ -2847,14 +2889,14 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) // Check if mouse cursor is at the last position int textEndWidth = GuiGetTextWidth(text + textIndexOffset); - if (GetMousePosition().x >= (textBounds.x + textEndWidth - glyphWidth/2)) + if (GUI_POINTER_POSITION.x >= (textBounds.x + textEndWidth - glyphWidth/2)) { mouseCursor.x = textBounds.x + textEndWidth; mouseCursorIndex = textLength; } // Place cursor at required index on mouse click - if ((mouseCursor.x >= 0) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + if ((mouseCursor.x >= 0) && GUI_BUTTON_PRESSED) { cursor.x = mouseCursor.x; textBoxCursorIndex = mouseCursorIndex; @@ -2867,8 +2909,8 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) //if (multiline) cursor.y = GetTextLines() // Finish text editing on ENTER or mouse click outside bounds - if ((!multiline && IsKeyPressed(KEY_ENTER)) || - (!CheckCollisionPointRec(mousePosition, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) + if ((!multiline && GUI_KEY_PRESSED(KEY_ENTER)) || + (!CheckCollisionPointRec(mousePosition, bounds) && GUI_BUTTON_PRESSED)) { textBoxCursorIndex = 0; // GLOBAL: Reset the shared cursor index autoCursorCounter = 0; // GLOBAL: Reset counter for repeated keystrokes @@ -2881,7 +2923,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) { state = STATE_FOCUSED; - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_PRESSED) { textBoxCursorIndex = textLength; // GLOBAL: Place cursor index to the end of current text autoCursorCounter = 0; // GLOBAL: Reset counter for repeated keystrokes @@ -2975,12 +3017,12 @@ int GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; // Check spinner state if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; else state = STATE_FOCUSED; } } @@ -3050,7 +3092,7 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; bool valueHasChanged = false; if (editMode) @@ -3060,7 +3102,7 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in int keyCount = (int)strlen(textValue); // Add or remove minus symbol - if (IsKeyPressed(KEY_MINUS)) + if (GUI_KEY_PRESSED(KEY_MINUS)) { if (textValue[0] == '-') { @@ -3089,8 +3131,8 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in // Add new digit to text value if ((keyCount >= 0) && (keyCount < RAYGUI_VALUEBOX_MAX_CHARS) && (GuiGetTextWidth(textValue) < bounds.width)) { - int key = GetCharPressed(); - + int key = GUI_INPUT_KEY; + // Only allow keys in range [48..57] if ((key >= 48) && (key <= 57)) { @@ -3101,7 +3143,7 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in } // Delete text - if ((keyCount > 0) && IsKeyPressed(KEY_BACKSPACE)) + if ((keyCount > 0) && GUI_KEY_PRESSED(KEY_BACKSPACE)) { keyCount--; textValue[keyCount] = '\0'; @@ -3110,11 +3152,11 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in if (valueHasChanged) *value = TextToInteger(textValue); - // NOTE: We are not clamp values until user input finishes + // NOTE: Values are not clamped until user input finishes //if (*value > maxValue) *value = maxValue; //else if (*value < minValue) *value = minValue; - if ((IsKeyPressed(KEY_ENTER) || IsKeyPressed(KEY_KP_ENTER)) || (!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) + if ((GUI_KEY_PRESSED(KEY_ENTER) || GUI_KEY_PRESSED(KEY_KP_ENTER)) || (!CheckCollisionPointRec(mousePoint, bounds) && GUI_BUTTON_PRESSED)) { if (*value > maxValue) *value = maxValue; else if (*value < minValue) *value = minValue; @@ -3130,7 +3172,7 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in if (CheckCollisionPointRec(mousePoint, bounds)) { state = STATE_FOCUSED; - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) result = 1; + if (GUI_BUTTON_PRESSED) result = 1; } } } @@ -3191,7 +3233,7 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; bool valueHasChanged = false; @@ -3202,7 +3244,7 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float int keyCount = (int)strlen(textValue); // Add or remove minus symbol - if (IsKeyPressed(KEY_MINUS)) + if (GUI_KEY_PRESSED(KEY_MINUS)) { if (textValue[0] == '-') { @@ -3233,7 +3275,7 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float { if (GuiGetTextWidth(textValue) < bounds.width) { - int key = GetCharPressed(); + int key = GUI_INPUT_KEY; if (((key >= 48) && (key <= 57)) || (key == '.') || ((keyCount == 0) && (key == '+')) || // NOTE: Sign can only be in first position @@ -3248,7 +3290,7 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float } // Pressed backspace - if (IsKeyPressed(KEY_BACKSPACE)) + if (GUI_KEY_PRESSED(KEY_BACKSPACE)) { if (keyCount > 0) { @@ -3260,14 +3302,14 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float if (valueHasChanged) *value = TextToFloat(textValue); - if ((IsKeyPressed(KEY_ENTER) || IsKeyPressed(KEY_KP_ENTER)) || (!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) result = 1; + if ((GUI_KEY_PRESSED(KEY_ENTER) || GUI_KEY_PRESSED(KEY_KP_ENTER)) || (!CheckCollisionPointRec(mousePoint, bounds) && GUI_BUTTON_PRESSED)) result = 1; } else { if (CheckCollisionPointRec(mousePoint, bounds)) { state = STATE_FOCUSED; - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) result = 1; + if (GUI_BUTTON_PRESSED) result = 1; } } } @@ -3321,11 +3363,11 @@ int GuiSlider(Rectangle bounds, const char *textLeft, const char *textRight, flo //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) { if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) { @@ -3342,7 +3384,7 @@ int GuiSlider(Rectangle bounds, const char *textLeft, const char *textRight, flo } else if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) { state = STATE_PRESSED; guiControlExclusiveMode = true; @@ -3535,12 +3577,12 @@ int GuiDummyRec(Rectangle bounds, const char *text) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; // Check button state if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; else state = STATE_FOCUSED; } } @@ -3578,7 +3620,7 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd int itemFocused = (focus == NULL)? -1 : *focus; int itemSelected = (active == NULL)? -1 : *active; - // Check if we need a scroll bar + // Check if scroll bar is needed bool useScrollBar = false; if ((GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT) + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING))*count > bounds.height) useScrollBar = true; @@ -3602,7 +3644,7 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; // Check mouse inside list view if (CheckCollisionPointRec(mousePoint, bounds)) @@ -3615,7 +3657,7 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd if (CheckCollisionPointRec(mousePoint, itemBounds)) { itemFocused = startIndex + i; - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_PRESSED) { if (itemSelected == (startIndex + i)) itemSelected = -1; else itemSelected = startIndex + i; @@ -3629,8 +3671,8 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd if (useScrollBar) { - int wheelMove = (int)GetMouseWheelMove(); - startIndex -= wheelMove; + float scrollDelta = GUI_SCROLL_DELTA; + startIndex -= (int)scrollDelta; if (startIndex < 0) startIndex = 0; else if (startIndex > (count - visibleItems)) startIndex = count - visibleItems; @@ -3659,7 +3701,7 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd { if ((startIndex + i) == itemSelected) GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, LIST_ITEMS_BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_DISABLED)), GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_DISABLED))); - GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_DISABLED))); + GuiDrawText(text[startIndex + i], GetTextBounds(LISTVIEW, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_DISABLED))); } else { @@ -3667,18 +3709,18 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd { // Draw item selected GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, LIST_ITEMS_BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_PRESSED)), GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_PRESSED))); - GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_PRESSED))); + GuiDrawText(text[startIndex + i], GetTextBounds(LISTVIEW, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_PRESSED))); } - else if (((startIndex + i) == itemFocused)) // && (focus != NULL)) // NOTE: We want items focused, despite not returned! + else if (((startIndex + i) == itemFocused)) // && (focus != NULL)) // NOTE: Items focused, despite not returned { // Draw item focused GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, LIST_ITEMS_BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_FOCUSED)), GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_FOCUSED))); - GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_FOCUSED))); + GuiDrawText(text[startIndex + i], GetTextBounds(LISTVIEW, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_FOCUSED))); } else { // Draw item normal (no rectangle) - GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_NORMAL))); + GuiDrawText(text[startIndex + i], GetTextBounds(LISTVIEW, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_NORMAL))); } } @@ -3765,11 +3807,11 @@ int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) { if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) { @@ -3788,7 +3830,7 @@ int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha) } else if (CheckCollisionPointRec(mousePoint, bounds) || CheckCollisionPointRec(mousePoint, selector)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) { state = STATE_PRESSED; guiControlExclusiveMode = true; @@ -3850,11 +3892,11 @@ int GuiColorBarHue(Rectangle bounds, const char *text, float *hue) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) { if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) { @@ -3873,7 +3915,7 @@ int GuiColorBarHue(Rectangle bounds, const char *text, float *hue) } else if (CheckCollisionPointRec(mousePoint, bounds) || CheckCollisionPointRec(mousePoint, selector)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) { state = STATE_PRESSED; guiControlExclusiveMode = true; @@ -3886,12 +3928,12 @@ int GuiColorBarHue(Rectangle bounds, const char *text, float *hue) } else state = STATE_FOCUSED; - /*if (IsKeyDown(KEY_UP)) + /*if (GUI_KEY_DOWN(KEY_UP)) { hue -= 2.0f; if (hue <= 0.0f) hue = 0.0f; } - else if (IsKeyDown(KEY_DOWN)) + else if (GUI_KEY_DOWN(KEY_DOWN)) { hue += 2.0f; if (hue >= 360.0f) hue = 360.0f; @@ -4008,11 +4050,11 @@ int GuiColorPanelHSV(Rectangle bounds, const char *text, Vector3 *colorHsv) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) { if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) { @@ -4042,7 +4084,7 @@ int GuiColorPanelHSV(Rectangle bounds, const char *text, Vector3 *colorHsv) } else if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) { state = STATE_PRESSED; guiControlExclusiveMode = true; @@ -4198,6 +4240,9 @@ int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, co GuiSetStyle(LABEL, TEXT_ALIGNMENT, prevTextAlignment); } + int prevTextBoxAlignment = GuiGetStyle(TEXTBOX, TEXT_ALIGNMENT); + GuiSetStyle(TEXTBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); + if (secretViewActive != NULL) { static char stars[] = "****************"; @@ -4211,6 +4256,8 @@ int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, co if (GuiTextBox(textBoxBounds, text, textMaxSize, textEditMode)) textEditMode = !textEditMode; } + GuiSetStyle(TEXTBOX, TEXT_ALIGNMENT, prevTextBoxAlignment); + int prevBtnTextAlignment = GuiGetStyle(BUTTON, TEXT_ALIGNMENT); GuiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); @@ -4231,7 +4278,7 @@ int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, co // Grid control // NOTE: Returns grid mouse-hover selected cell // About drawing lines at subpixel spacing, simple put, not easy solution: -// https://stackoverflow.com/questions/4435450/2d-opengl-drawing-lines-that-dont-exactly-fit-pixel-raster +// REF: https://stackoverflow.com/questions/4435450/2d-opengl-drawing-lines-that-dont-exactly-fit-pixel-raster int GuiGrid(Rectangle bounds, const char *text, float spacing, int subdivs, Vector2 *mouseCell) { // Grid lines alpha amount @@ -4242,7 +4289,7 @@ int GuiGrid(Rectangle bounds, const char *text, float spacing, int subdivs, Vect int result = 0; GuiState state = guiState; - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; Vector2 currentMouseCell = { -1, -1 }; float spaceWidth = spacing/(float)subdivs; @@ -4410,11 +4457,14 @@ void GuiLoadStyle(const char *fileName) if (fileDataSize > 0) { unsigned char *fileData = (unsigned char *)RAYGUI_CALLOC(fileDataSize, sizeof(unsigned char)); - fread(fileData, sizeof(unsigned char), fileDataSize, rgsFile); + if (fileData != NULL) + { + fread(fileData, sizeof(unsigned char), fileDataSize, rgsFile); - GuiLoadStyleFromMemory(fileData, fileDataSize); + GuiLoadStyleFromMemory(fileData, fileDataSize); - RAYGUI_FREE(fileData); + RAYGUI_FREE(fileData); + } } fclose(rgsFile); @@ -4425,7 +4475,7 @@ void GuiLoadStyle(const char *fileName) // Load style default over global style void GuiLoadStyleDefault(void) { - // We set this variable first to avoid cyclic function calls + // Setting this flag first to avoid cyclic function calls // when calling GuiSetStyle() and GuiGetStyle() guiStyleLoaded = true; @@ -4454,7 +4504,7 @@ void GuiLoadStyleDefault(void) GuiSetStyle(DEFAULT, TEXT_SPACING, 1); // DEFAULT, shared by all controls GuiSetStyle(DEFAULT, LINE_COLOR, 0x90abb5ff); // DEFAULT specific property GuiSetStyle(DEFAULT, BACKGROUND_COLOR, 0xf5f5f5ff); // DEFAULT specific property - GuiSetStyle(DEFAULT, TEXT_LINE_SPACING, 15); // DEFAULT, 15 pixels between lines + GuiSetStyle(DEFAULT, TEXT_LINE_SPACING, 5); // DEFAULT, pixels between lines, from bottom of first line to top of second GuiSetStyle(DEFAULT, TEXT_ALIGNMENT_VERTICAL, TEXT_ALIGN_MIDDLE); // DEFAULT, text aligned vertically to middle of text-bounds // Initialize control-specific property values @@ -4520,7 +4570,7 @@ void GuiLoadStyleDefault(void) // NOTE: Default raylib font character 95 is a white square Rectangle whiteChar = guiFont.recs[95]; - // NOTE: We set up a 1px padding on char rectangle to avoid pixel bleeding on MSAA filtering + // NOTE: Setting up a 1px padding on char rectangle to avoid pixel bleeding on MSAA filtering SetShapesTexture(guiFont.texture, RAYGUI_CLITERAL(Rectangle){ whiteChar.x + 1, whiteChar.y + 1, whiteChar.width - 2, whiteChar.height - 2 }); } } @@ -5037,14 +5087,14 @@ static Rectangle GetTextBounds(int control, Rectangle bounds) } // Get text icon if provided and move text cursor -// NOTE: We support up to 999 values for iconId +// NOTE: Up to #999# values supported for iconId static const char *GetTextIcon(const char *text, int *iconId) { #if !defined(RAYGUI_NO_ICONS) *iconId = -1; - if (text[0] == '#') // Maybe we have an icon! + if (text[0] == '#') // Maybe it is stars with an icon, ending # must be found { - char iconValue[4] = { 0 }; // Maximum length for icon value: 3 digits + '\0' + char iconValue[4] = { 0 }; // Maximum length for icon value: 3 digits + '\0' int pos = 1; while ((pos < 4) && (text[pos] >= '0') && (text[pos] <= '9')) @@ -5076,12 +5126,12 @@ static const char **GetTextLines(const char *text, int *count) static const char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 }; for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings - int textSize = (int)strlen(text); + int textLength = (int)strlen(text); lines[0] = text; *count = 1; - for (int i = 0, k = 0; (i < textSize) && (*count < RAYGUI_MAX_TEXT_LINES); i++) + for (int i = 0, k = 0; (i < textLength) && (*count < RAYGUI_MAX_TEXT_LINES); i++) { if (text[i] == '\n') { @@ -5141,7 +5191,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C // - For every line, wordwrap mode is checked (useful for GuitextBox(), read-only) // Get text lines (using '\n' as delimiter) to be processed individually - // WARNING: We can't use GuiTextSplit() function because it can be already used + // WARNING: GuiTextSplit() function can't be used now because it can have already been used // before the GuiDrawText() call and its buffer is static, it would be overriden :( int lineCount = 0; const char **lines = GetTextLines(text, &lineCount); @@ -5152,7 +5202,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C int wrapMode = GuiGetStyle(DEFAULT, TEXT_WRAP_MODE); // Wrap-mode only available in read-only mode, no for text editing // TODO: WARNING: This totalHeight is not valid for vertical alignment in case of word-wrap - float totalHeight = (float)(lineCount*GuiGetStyle(DEFAULT, TEXT_SIZE) + (lineCount - 1)*GuiGetStyle(DEFAULT, TEXT_SIZE)/2); + float totalHeight = (float)(lineCount*GuiGetStyle(DEFAULT, TEXT_SIZE) + (lineCount - 1)*GuiGetStyle(DEFAULT, TEXT_LINE_SPACING)); float posOffsetY = 0.0f; for (int i = 0; i < lineCount; i++) @@ -5165,7 +5215,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C Vector2 textBoundsPosition = { textBounds.x, textBounds.y }; float textBoundsWidthOffset = 0.0f; - // NOTE: We get text size after icon has been processed + // NOTE: Get text size after icon has been processed // WARNING: GuiGetTextWidth() also processes text icon to get width! -> Really needed? int textSizeX = GuiGetTextWidth(lines[i]); @@ -5200,8 +5250,8 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C default: break; } - // NOTE: Make sure we get pixel-perfect coordinates, - // In case of decimals we got weird text positioning + // NOTE: Make sure getting pixel-perfect coordinates, + // In case of decimals, it could result in text positioning artifacts textBoundsPosition.x = (float)((int)textBoundsPosition.x); textBoundsPosition.y = (float)((int)textBoundsPosition.y); //--------------------------------------------------------------------------------- @@ -5211,7 +5261,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C #if !defined(RAYGUI_NO_ICONS) if (iconId >= 0) { - // NOTE: We consider icon height, probably different than text size + // NOTE: Considering icon height, probably different than text size GuiDrawIcon(iconId, (int)textBoundsPosition.x, (int)(textBounds.y + textBounds.height/2 - RAYGUI_ICON_SIZE*guiIconScale/2 + TEXT_VALIGN_PIXEL_OFFSET(textBounds.height)), guiIconScale, tint); textBoundsPosition.x += (float)(RAYGUI_ICON_SIZE*guiIconScale + ICON_TEXT_PADDING); textBoundsWidthOffset = (float)(RAYGUI_ICON_SIZE*guiIconScale + ICON_TEXT_PADDING); @@ -5237,8 +5287,8 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C int codepoint = GetCodepointNext(&lines[i][c], &codepointSize); int index = GetGlyphIndex(guiFont, codepoint); - // NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f) - // but we need to draw all of the bad bytes using the '?' symbol moving one byte + // NOTE: Normally, exiting the decoding sequence as soon as a bad byte is found (and return 0x3f) + // but all of the bad bytes need to be drawn using the '?' symbol, moving one byte if (codepoint == 0x3f) codepointSize = 1; // TODO: Review not recognized codepoints size // Get glyph width to check if it goes out of bounds @@ -5253,7 +5303,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C if ((textOffsetX + glyphWidth) > textBounds.width - textBoundsWidthOffset) { textOffsetX = 0.0f; - textOffsetY += GuiGetStyle(DEFAULT, TEXT_LINE_SPACING); + textOffsetY += (GuiGetStyle(DEFAULT, TEXT_SIZE) + GuiGetStyle(DEFAULT, TEXT_LINE_SPACING)); if (tempWrapCharMode) // Wrap at char level when too long words { @@ -5282,7 +5332,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C else if ((textOffsetX + nextSpaceWidth) > textBounds.width - textBoundsWidthOffset) { textOffsetX = 0.0f; - textOffsetY += GuiGetStyle(DEFAULT, TEXT_LINE_SPACING); + textOffsetY += (GuiGetStyle(DEFAULT, TEXT_SIZE) + GuiGetStyle(DEFAULT, TEXT_LINE_SPACING)); } } @@ -5332,7 +5382,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C } } - if (wrapMode == TEXT_WRAP_NONE) posOffsetY += (float)GuiGetStyle(DEFAULT, TEXT_LINE_SPACING); + if (wrapMode == TEXT_WRAP_NONE) posOffsetY += (float)(GuiGetStyle(DEFAULT, TEXT_SIZE) + GuiGetStyle(DEFAULT, TEXT_LINE_SPACING)); else if ((wrapMode == TEXT_WRAP_CHAR) || (wrapMode == TEXT_WRAP_WORD)) posOffsetY += (textOffsetY + (float)GuiGetStyle(DEFAULT, TEXT_LINE_SPACING)); //--------------------------------------------------------------------------------- } @@ -5374,13 +5424,19 @@ static void GuiTooltip(Rectangle controlRec) if ((controlRec.x + textSize.x + 16) > GetScreenWidth()) controlRec.x -= (textSize.x + 16 - controlRec.width); - GuiPanel(RAYGUI_CLITERAL(Rectangle){ controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, GuiGetStyle(DEFAULT, TEXT_SIZE) + 8.0f }, NULL); + int lineCount = 0; + GetTextLines(guiTooltipPtr, &lineCount); // Only using the line count + if ((controlRec.y + controlRec.height + textSize.y + 4 + 8*lineCount) > GetScreenHeight()) + controlRec.y -= (controlRec.height + textSize.y + 4 + 8*lineCount); + + // TODO: Probably TEXT_LINE_SPACING should be considered on panel size instead of hardcoding 8.0f + GuiPanel(RAYGUI_CLITERAL(Rectangle){ controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, textSize.y + 8.0f*lineCount }, NULL); int textPadding = GuiGetStyle(LABEL, TEXT_PADDING); int textAlignment = GuiGetStyle(LABEL, TEXT_ALIGNMENT); GuiSetStyle(LABEL, TEXT_PADDING, 0); GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); - GuiLabel(RAYGUI_CLITERAL(Rectangle){ controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, GuiGetStyle(DEFAULT, TEXT_SIZE) + 8.0f }, guiTooltipPtr); + GuiLabel(RAYGUI_CLITERAL(Rectangle){ controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, textSize.y + 8.0f*lineCount }, guiTooltipPtr); GuiSetStyle(LABEL, TEXT_ALIGNMENT, textAlignment); GuiSetStyle(LABEL, TEXT_PADDING, textPadding); } @@ -5416,7 +5472,7 @@ static const char **GuiTextSplit(const char *text, char delimiter, int *count, i if (textRow != NULL) textRow[0] = 0; - // Count how many substrings we have on text and point to every one + // Count how many substrings text contains and point to every one of them for (int i = 0; i < RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE; i++) { buffer[i] = text[i]; @@ -5637,11 +5693,11 @@ static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON) && + if (GUI_BUTTON_DOWN && !CheckCollisionPointRec(mousePoint, arrowUpLeft) && !CheckCollisionPointRec(mousePoint, arrowDownRight)) { @@ -5664,11 +5720,11 @@ static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue) state = STATE_FOCUSED; // Handle mouse wheel - int wheel = (int)GetMouseWheelMove(); - if (wheel != 0) value += wheel; + float scrollDelta = GUI_SCROLL_DELTA; + if (scrollDelta != 0) value += (int)scrollDelta; // Handle mouse button down - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_PRESSED) { guiControlExclusiveMode = true; guiControlExclusiveRec = bounds; // Store bounds as an identifier when dragging starts @@ -5690,13 +5746,13 @@ static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue) /* if (isVertical) { - if (IsKeyDown(KEY_DOWN)) value += 5; - else if (IsKeyDown(KEY_UP)) value -= 5; + if (GUI_KEY_DOWN(KEY_DOWN)) value += 5; + else if (GUI_KEY_DOWN(KEY_UP)) value -= 5; } else { - if (IsKeyDown(KEY_RIGHT)) value += 5; - else if (IsKeyDown(KEY_LEFT)) value -= 5; + if (GUI_KEY_DOWN(KEY_RIGHT)) value += 5; + else if (GUI_KEY_DOWN(KEY_LEFT)) value -= 5; } */ } @@ -5833,7 +5889,7 @@ const char **TextSplit(const char *text, char delimiter, int *count) { counter = 1; - // Count how many substrings we have on text and point to every one + // Count how many substrings text contains and point to every one of them for (int i = 0; i < RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE; i++) { buffer[i] = text[i]; @@ -5866,7 +5922,7 @@ static int TextToInteger(const char *text) 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; } @@ -5941,9 +5997,9 @@ static const char *CodepointToUTF8(int codepoint, int *byteSize) } // Get next codepoint in a UTF-8 encoded text, scanning until '\0' is found -// When a invalid UTF-8 byte is encountered we exit as soon as possible and a '?'(0x3f) codepoint is returned +// When a invalid UTF-8 byte is encountered, exiting as soon as possible and returning a '?'(0x3f) codepoint // Total number of bytes processed are returned as a parameter -// NOTE: the standard says U+FFFD should be returned in case of errors +// NOTE: The standard says U+FFFD should be returned in case of errors // but that character is not supported by the default font in raylib static int GetCodepointNext(const char *text, int *codepointSize) { diff --git a/examples/models/models_directional_billboard.c b/examples/models/models_directional_billboard.c index e2c75c15a..caab94afb 100644 --- a/examples/models/models_directional_billboard.c +++ b/examples/models/models_directional_billboard.c @@ -17,7 +17,9 @@ ********************************************************************************************/ #include "raylib.h" + #include "raymath.h" + #include //------------------------------------------------------------------------------------ diff --git a/examples/models/raygui.h b/examples/models/raygui.h new file mode 100644 index 000000000..67c16be45 --- /dev/null +++ b/examples/models/raygui.h @@ -0,0 +1,6043 @@ +/******************************************************************************************* +* +* raygui v5.0-dev - A simple and easy-to-use immediate-mode gui library +* +* DESCRIPTION: +* raygui is a tools-dev-focused immediate-mode-gui library based on raylib but also +* available as a standalone library, as long as input and drawing functions are provided +* +* FEATURES: +* - Immediate-mode gui, minimal retained data +* - +25 controls provided (basic and advanced) +* - Styling system for colors, font and metrics +* - Icons supported, embedded as a 1-bit icons pack +* - Standalone mode option (custom input/graphics backend) +* - Multiple support tools provided for raygui development +* +* POSSIBLE IMPROVEMENTS: +* - Better standalone mode API for easy plug of custom backends +* - Externalize required inputs, allow user easier customization +* +* LIMITATIONS: +* - No editable multi-line word-wraped text box supported +* - No auto-layout mechanism, up to the user to define controls position and size +* - Standalone mode requires library modification and some user work to plug another backend +* +* NOTES: +* - WARNING: GuiLoadStyle() and GuiLoadStyle{Custom}() functions, allocate memory for +* font atlas recs and glyphs, freeing that memory is (usually) up to the user, +* no unload function is explicitly provided... but note that GuiLoadStyleDefault() unloads +* by default any previously loaded font (texture, recs, glyphs) +* - Global UI alpha (guiAlpha) is applied inside GuiDrawRectangle() and GuiDrawText() functions +* +* CONTROLS PROVIDED: +* # Container/separators Controls +* - WindowBox --> StatusBar, Panel +* - GroupBox --> Line +* - Line +* - Panel --> StatusBar +* - ScrollPanel --> StatusBar +* - TabBar --> Button +* +* # Basic Controls +* - Label +* - LabelButton --> Label +* - Button +* - Toggle +* - ToggleGroup --> Toggle +* - ToggleSlider +* - CheckBox +* - ComboBox +* - DropdownBox +* - TextBox +* - ValueBox --> TextBox +* - Spinner --> Button, ValueBox +* - Slider +* - SliderBar --> Slider +* - ProgressBar +* - StatusBar +* - DummyRec +* - Grid +* +* # Advance Controls +* - ListView +* - ColorPicker --> ColorPanel, ColorBarHue +* - MessageBox --> Window, Label, Button +* - TextInputBox --> Window, Label, TextBox, Button +* +* It also provides a set of functions for styling the controls based on its properties (size, color) +* +* +* RAYGUI STYLE (guiStyle): +* raygui uses a global data array for all gui style properties (allocated on data segment by default), +* when a new style is loaded, it is loaded over the global style... but a default gui style could always be +* recovered with GuiLoadStyleDefault() function, that overwrites the current style to the default one +* +* The global style array size is fixed and depends on the number of controls and properties: +* +* static unsigned int guiStyle[RAYGUI_MAX_CONTROLS*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED)]; +* +* guiStyle size is by default: 16*(16 + 8) = 384 int = 384*4 bytes = 1536 bytes = 1.5 KB +* +* Note that the first set of BASE properties (by default guiStyle[0..15]) belong to the generic style +* used for all controls, when any of those base values is set, it is automatically populated to all +* controls, so, specific control values overwriting generic style should be set after base values +* +* After the first BASE properties set, the EXTENDED properties set is defined (by default guiStyle[16..23]), +* those properties are actually common to all controls and can not be overwritten individually (like BASE ones) +* Some of those properties are: TEXT_SIZE, TEXT_SPACING, LINE_COLOR, BACKGROUND_COLOR +* +* Custom control properties can be defined using the EXTENDED properties for each independent control. +* +* TOOL: rGuiStyler is a visual tool to customize raygui style: github.com/raysan5/rguistyler +* +* +* RAYGUI ICONS (guiIcons): +* raygui could use a global array containing icons data (allocated on data segment by default), +* a custom icons set could be loaded over this array using GuiLoadIcons(), but loaded icons set +* must be same RAYGUI_ICON_SIZE and no more than RAYGUI_ICON_MAX_ICONS will be loaded +* +* Every icon is codified in binary form, using 1 bit per pixel, so, every 16x16 icon +* requires 8 integers (16*16/32) to be stored in memory. +* +* When the icon is draw, actually one quad per pixel is drawn if the bit for that pixel is set +* +* The global icons array size is fixed and depends on the number of icons and size: +* +* static unsigned int guiIcons[RAYGUI_ICON_MAX_ICONS*RAYGUI_ICON_DATA_ELEMENTS]; +* +* guiIcons size is by default: 256*(16*16/32) = 2048*4 = 8192 bytes = 8 KB +* +* TOOL: rGuiIcons is a visual tool to customize/create raygui icons: github.com/raysan5/rguiicons +* +* RAYGUI LAYOUT: +* raygui currently does not provide an auto-layout mechanism like other libraries, +* layouts must be defined manually on controls drawing, providing the right bounds Rectangle for it +* +* TOOL: rGuiLayout is a visual tool to create raygui layouts: github.com/raysan5/rguilayout +* +* CONFIGURATION: +* #define RAYGUI_IMPLEMENTATION +* Generates the implementation of the library into the included file +* If not defined, the library is in header only mode and can be included in other headers +* or source files without problems. But only ONE file should hold the implementation +* +* #define RAYGUI_STANDALONE +* Avoid raylib.h header inclusion in this file. Data types defined on raylib are defined +* internally in the library and input management and drawing functions must be provided by +* the user (check library implementation for further details) +* +* #define RAYGUI_NO_ICONS +* Avoid including embedded ricons data (256 icons, 16x16 pixels, 1-bit per pixel, 2KB) +* +* #define RAYGUI_CUSTOM_ICONS +* Includes custom ricons.h header defining a set of custom icons, +* this file can be generated using rGuiIcons tool +* +* #define RAYGUI_DEBUG_RECS_BOUNDS +* Draw control bounds rectangles for debug +* +* #define RAYGUI_DEBUG_TEXT_BOUNDS +* Draw text bounds rectangles for debug +* +* VERSIONS HISTORY: +* 5.0 (xx-Mar-2026) ADDED: Support up to 32 controls (v500) +* ADDED: guiControlExclusiveMode and guiControlExclusiveRec for exclusive modes +* ADDED: GuiValueBoxFloat() +* ADDED: GuiDropdonwBox() properties: DROPDOWN_ARROW_HIDDEN, DROPDOWN_ROLL_UP +* ADDED: GuiListView() property: LIST_ITEMS_BORDER_WIDTH +* ADDED: GuiLoadIconsFromMemory() +* ADDED: Multiple new icons +* ADDED: Macros for inputs customization, raylib decoupling +* REMOVED: GuiSpinner() from controls list, using BUTTON + VALUEBOX properties +* REMOVED: GuiSliderPro(), functionality was redundant +* REVIEWED: Controls using text labels to use LABEL properties +* REVIEWED: Replaced sprintf() by snprintf() for more safety +* REVIEWED: GuiTabBar(), close tab with mouse middle button +* REVIEWED: GuiScrollPanel(), scroll speed proportional to content +* REVIEWED: GuiDropdownBox(), support roll up and hidden arrow +* REVIEWED: GuiTextBox(), cursor position initialization +* REVIEWED: GuiSliderPro(), control value change check +* REVIEWED: GuiGrid(), simplified implementation +* REVIEWED: GuiIconText(), increase buffer size and reviewed padding +* REVIEWED: GuiDrawText(), improved wrap mode drawing +* REVIEWED: GuiScrollBar(), minor tweaks +* REVIEWED: GuiProgressBar(), improved borders computing +* REVIEWED: GuiTextBox(), multiple improvements: autocursor and more +* REVIEWED: Functions descriptions, removed wrong return value reference +* REDESIGNED: GuiColorPanel(), improved HSV <-> RGBA convertion +* REDESIGNED: WARNING: TEXT_LINE_SPACING does not consider text height, only lines spacing +* +* 4.0 (12-Sep-2023) ADDED: GuiToggleSlider() +* ADDED: GuiColorPickerHSV() and GuiColorPanelHSV() +* ADDED: Multiple new icons, mostly compiler related +* ADDED: New DEFAULT properties: TEXT_LINE_SPACING, TEXT_ALIGNMENT_VERTICAL, TEXT_WRAP_MODE +* ADDED: New enum values: GuiTextAlignment, GuiTextAlignmentVertical, GuiTextWrapMode +* ADDED: Support loading styles with custom font charset from external file +* REDESIGNED: GuiTextBox(), support mouse cursor positioning +* REDESIGNED: GuiDrawText(), support multiline and word-wrap modes (read only) +* REDESIGNED: GuiProgressBar() to be more visual, progress affects border color +* REDESIGNED: Global alpha consideration moved to GuiDrawRectangle() and GuiDrawText() +* REDESIGNED: GuiScrollPanel(), get parameters by reference and return result value +* REDESIGNED: GuiToggleGroup(), get parameters by reference and return result value +* REDESIGNED: GuiComboBox(), get parameters by reference and return result value +* REDESIGNED: GuiCheckBox(), get parameters by reference and return result value +* REDESIGNED: GuiSlider(), get parameters by reference and return result value +* REDESIGNED: GuiSliderBar(), get parameters by reference and return result value +* REDESIGNED: GuiProgressBar(), get parameters by reference and return result value +* REDESIGNED: GuiListView(), get parameters by reference and return result value +* REDESIGNED: GuiColorPicker(), get parameters by reference and return result value +* REDESIGNED: GuiColorPanel(), get parameters by reference and return result value +* REDESIGNED: GuiColorBarAlpha(), get parameters by reference and return result value +* REDESIGNED: GuiColorBarHue(), get parameters by reference and return result value +* REDESIGNED: GuiGrid(), get parameters by reference and return result value +* REDESIGNED: GuiGrid(), added extra parameter +* REDESIGNED: GuiListViewEx(), change parameters order +* REDESIGNED: All controls return result as int value +* REVIEWED: GuiScrollPanel() to avoid smallish scroll-bars +* REVIEWED: All examples and specially controls_test_suite +* RENAMED: gui_file_dialog module to gui_window_file_dialog +* UPDATED: All styles to include ISO-8859-15 charset (as much as possible) +* +* 3.6 (10-May-2023) ADDED: New icon: SAND_TIMER +* ADDED: GuiLoadStyleFromMemory() (binary only) +* REVIEWED: GuiScrollBar() horizontal movement key +* REVIEWED: GuiTextBox() crash on cursor movement +* REVIEWED: GuiTextBox(), additional inputs support +* REVIEWED: GuiLabelButton(), avoid text cut +* REVIEWED: GuiTextInputBox(), password input +* REVIEWED: Local GetCodepointNext(), aligned with raylib +* REDESIGNED: GuiSlider*()/GuiScrollBar() to support out-of-bounds +* +* 3.5 (20-Apr-2023) ADDED: GuiTabBar(), based on GuiToggle() +* ADDED: Helper functions to split text in separate lines +* ADDED: Multiple new icons, useful for code editing tools +* REMOVED: Unneeded icon editing functions +* REMOVED: GuiTextBoxMulti(), very limited and broken +* REMOVED: MeasureTextEx() dependency, logic directly implemented +* REMOVED: DrawTextEx() dependency, logic directly implemented +* REVIEWED: GuiScrollBar(), improve mouse-click behaviour +* REVIEWED: Library header info, more info, better organized +* REDESIGNED: GuiTextBox() to support cursor movement +* REDESIGNED: GuiDrawText() to divide drawing by lines +* +* 3.2 (22-May-2022) RENAMED: Some enum values, for unification, avoiding prefixes +* REMOVED: GuiScrollBar(), only internal +* REDESIGNED: GuiPanel() to support text parameter +* REDESIGNED: GuiScrollPanel() to support text parameter +* REDESIGNED: GuiColorPicker() to support text parameter +* REDESIGNED: GuiColorPanel() to support text parameter +* REDESIGNED: GuiColorBarAlpha() to support text parameter +* REDESIGNED: GuiColorBarHue() to support text parameter +* REDESIGNED: GuiTextInputBox() to support password +* +* 3.1 (12-Jan-2022) REVIEWED: Default style for consistency (aligned with rGuiLayout v2.5 tool) +* REVIEWED: GuiLoadStyle() to support compressed font atlas image data and unload previous textures +* REVIEWED: External icons usage logic +* REVIEWED: GuiLine() for centered alignment when including text +* RENAMED: Multiple controls properties definitions to prepend RAYGUI_ +* RENAMED: RICON_ references to RAYGUI_ICON_ for library consistency +* Projects updated and multiple tweaks +* +* 3.0 (04-Nov-2021) Integrated ricons data to avoid external file +* REDESIGNED: GuiTextBoxMulti() +* REMOVED: GuiImageButton*() +* Multiple minor tweaks and bugs corrected +* +* 2.9 (17-Mar-2021) REMOVED: Tooltip API +* 2.8 (03-May-2020) Centralized rectangles drawing to GuiDrawRectangle() +* 2.7 (20-Feb-2020) ADDED: Possible tooltips API +* 2.6 (09-Sep-2019) ADDED: GuiTextInputBox() +* REDESIGNED: GuiListView*(), GuiDropdownBox(), GuiSlider*(), GuiProgressBar(), GuiMessageBox() +* REVIEWED: GuiTextBox(), GuiSpinner(), GuiValueBox(), GuiLoadStyle() +* Replaced property INNER_PADDING by TEXT_PADDING, renamed some properties +* ADDED: 8 new custom styles ready to use +* Multiple minor tweaks and bugs corrected +* +* 2.5 (28-May-2019) Implemented extended GuiTextBox(), GuiValueBox(), GuiSpinner() +* 2.3 (29-Apr-2019) ADDED: rIcons auxiliar library and support for it, multiple controls reviewed +* Refactor all controls drawing mechanism to use control state +* 2.2 (05-Feb-2019) ADDED: GuiScrollBar(), GuiScrollPanel(), reviewed GuiListView(), removed Gui*Ex() controls +* 2.1 (26-Dec-2018) REDESIGNED: GuiCheckBox(), GuiComboBox(), GuiDropdownBox(), GuiToggleGroup() > Use combined text string +* REDESIGNED: Style system (breaking change) +* 2.0 (08-Nov-2018) ADDED: Support controls guiLock and custom fonts +* REVIEWED: GuiComboBox(), GuiListView()... +* 1.9 (09-Oct-2018) REVIEWED: GuiGrid(), GuiTextBox(), GuiTextBoxMulti(), GuiValueBox()... +* 1.8 (01-May-2018) Lot of rework and redesign to align with rGuiStyler and rGuiLayout +* 1.5 (21-Jun-2017) Working in an improved styles system +* 1.4 (15-Jun-2017) Rewritten all GUI functions (removed useless ones) +* 1.3 (12-Jun-2017) Complete redesign of style system +* 1.1 (01-Jun-2017) Complete review of the library +* 1.0 (07-Jun-2016) Converted to header-only by Ramon Santamaria +* 0.9 (07-Mar-2016) Reviewed and tested by Albert Martos, Ian Eito, Sergio Martinez and Ramon Santamaria +* 0.8 (27-Aug-2015) Initial release. Implemented by Kevin Gato, Daniel Nicolás and Ramon Santamaria +* +* DEPENDENCIES: +* raylib 5.6-dev - Inputs reading (keyboard/mouse), shapes drawing, font loading and text drawing +* +* STANDALONE MODE: +* By default raygui depends on raylib mostly for the inputs and the drawing functionality but that dependency can be disabled +* with the config flag RAYGUI_STANDALONE. In that case is up to the user to provide another backend to cover library needs +* +* The following functions should be redefined for a custom backend: +* +* - Vector2 GetMousePosition(void); +* - float GetMouseWheelMove(void); +* - bool IsMouseButtonDown(int button); +* - bool IsMouseButtonPressed(int button); +* - bool IsMouseButtonReleased(int button); +* - bool IsKeyDown(int key); +* - bool IsKeyPressed(int key); +* - int GetCharPressed(void); // -- GuiTextBox(), GuiValueBox() +* +* - void DrawRectangle(int x, int y, int width, int height, Color color); // -- GuiDrawRectangle() +* - void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4); // -- GuiColorPicker() +* +* - Font GetFontDefault(void); // -- GuiLoadStyleDefault() +* - Font LoadFontEx(const char *fileName, int fontSize, int *codepoints, int codepointCount); // -- GuiLoadStyle() +* - Texture2D LoadTextureFromImage(Image image); // -- GuiLoadStyle(), required to load texture from embedded font atlas image +* - void SetShapesTexture(Texture2D tex, Rectangle rec); // -- GuiLoadStyle(), required to set shapes rec to font white rec (optimization) +* - char *LoadFileText(const char *fileName); // -- GuiLoadStyle(), required to load charset data +* - void UnloadFileText(char *text); // -- GuiLoadStyle(), required to unload charset data +* - const char *GetDirectoryPath(const char *filePath); // -- GuiLoadStyle(), required to find charset/font file from text .rgs +* - int *LoadCodepoints(const char *text, int *count); // -- GuiLoadStyle(), required to load required font codepoints list +* - void UnloadCodepoints(int *codepoints); // -- GuiLoadStyle(), required to unload codepoints list +* - unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize); // -- GuiLoadStyle() +* +* CONTRIBUTORS: +* Ramon Santamaria: Supervision, review, redesign, update and maintenance +* Vlad Adrian: Complete rewrite of GuiTextBox() to support extended features (2019) +* Sergio Martinez: Review, testing (2015) and redesign of multiple controls (2018) +* Adria Arranz: Testing and implementation of additional controls (2018) +* Jordi Jorba: Testing and implementation of additional controls (2018) +* Albert Martos: Review and testing of the library (2015) +* Ian Eito: Review and testing of the library (2015) +* Kevin Gato: Initial implementation of basic components (2014) +* Daniel Nicolas: Initial implementation of basic components (2014) +* +* +* LICENSE: zlib/libpng +* +* Copyright (c) 2014-2026 Ramon Santamaria (@raysan5) +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +#ifndef RAYGUI_H +#define RAYGUI_H + +#define RAYGUI_VERSION_MAJOR 4 +#define RAYGUI_VERSION_MINOR 5 +#define RAYGUI_VERSION_PATCH 0 +#define RAYGUI_VERSION "5.0-dev" + +#if !defined(RAYGUI_STANDALONE) + #include "raylib.h" +#endif + +// Function specifiers in case library is build/used as a shared library (Windows) +// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll +#if defined(_WIN32) + #if defined(BUILD_LIBTYPE_SHARED) + #define RAYGUIAPI __declspec(dllexport) // Building the library as a Win32 shared library (.dll) + #elif defined(USE_LIBTYPE_SHARED) + #define RAYGUIAPI __declspec(dllimport) // Using the library as a Win32 shared library (.dll) + #endif + #define _CRT_SECURE_NO_WARNINGS // Disable unsafe warnings on scanf() functions in MSVC +#endif + +// Function specifiers definition +#ifndef RAYGUIAPI + #define RAYGUIAPI // Functions defined as 'extern' by default (implicit specifiers) +#endif + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- +// Simple log system to avoid printf() calls if required +// NOTE: Avoiding those calls, also avoids const strings memory usage +#define RAYGUI_SUPPORT_LOG_INFO +#if defined(RAYGUI_SUPPORT_LOG_INFO) + #define RAYGUI_LOG(...) printf(__VA_ARGS__) +#else + #define RAYGUI_LOG(...) +#endif + +// Macros to define required UI inputs, including mapping to gamepad controls +// TODO: Define additionally required macros for missing inputs +#if !defined(GUI_BUTTON_DOWN) + #define GUI_BUTTON_DOWN (IsMouseButtonDown(MOUSE_LEFT_BUTTON) || IsGamepadButtonDown(0, GAMEPAD_BUTTON_RIGHT_FACE_DOWN)) +#endif +#if !defined(GUI_BUTTON_DOWN_ALT) + // Mapping to alternative button down pressed + #define GUI_BUTTON_DOWN_ALT (IsMouseButtonDown(MOUSE_RIGHT_BUTTON) || IsGamepadButtonDown(0, GAMEPAD_BUTTON_RIGHT_FACE_RIGHT)) +#endif +#if !defined(GUI_BUTTON_PRESSED) + #define GUI_BUTTON_PRESSED (IsMouseButtonPressed(MOUSE_LEFT_BUTTON) || IsGamepadButtonPressed(0, GAMEPAD_BUTTON_RIGHT_FACE_DOWN)) +#endif +// TODO: WARNING: GuiTabBar() still requires IsMouseButtonPressed(MOUSE_MIDDLE_BUTTON) +#if !defined(GUI_BUTTON_RELEASED) + #define GUI_BUTTON_RELEASED (IsMouseButtonReleased(MOUSE_LEFT_BUTTON) || IsGamepadButtonReleased(0, GAMEPAD_BUTTON_RIGHT_FACE_DOWN)) +#endif +#if !defined(GUI_SCROLL_DELTA) + // Mapping to scroll delta changes + // TODO: Review inconsistencies between platforms + #if defined(PLATFORM_WEB) + // NOTE: Gamepad axis triggers not detected on web platform + #define GUI_SCROLL_DELTA ((float)IsGamepadButtonDown(0, GAMEPAD_BUTTON_RIGHT_TRIGGER_2) - (float)IsGamepadButtonDown(0, GAMEPAD_BUTTON_LEFT_TRIGGER_2)) + #else + #define GUI_SCROLL_DELTA (GetMouseWheelMove() + (GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_TRIGGER) + 1) - (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_TRIGGER) + 1)) + #endif +#endif +#if !defined(GUI_POINTER_POSITION) + #define GUI_POINTER_POSITION GetMousePosition() +#endif +#if !defined(GUI_KEY_DOWN) + #define GUI_KEY_DOWN(key) IsKeyDown(key) +#endif +#if !defined(GUI_KEY_PRESSED) + #define GUI_KEY_PRESSED(key) IsKeyPressed(key) +#endif +#if !defined(GUI_INPUT_KEY) + #define GUI_INPUT_KEY GetCharPressed() +#endif + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +// NOTE: Some types are required for RAYGUI_STANDALONE usage +//---------------------------------------------------------------------------------- +#if defined(RAYGUI_STANDALONE) + #ifndef __cplusplus + // Boolean type + #ifndef true + typedef enum { false, true } bool; + #endif + #endif + + // Vector2 type + typedef struct Vector2 { + float x; + float y; + } Vector2; + + // Vector3 type // -- ConvertHSVtoRGB(), ConvertRGBtoHSV() + typedef struct Vector3 { + float x; + float y; + float z; + } Vector3; + + // Color type, RGBA (32bit) + typedef struct Color { + unsigned char r; + unsigned char g; + unsigned char b; + unsigned char a; + } Color; + + // Rectangle type + typedef struct Rectangle { + float x; + float y; + float width; + float height; + } Rectangle; + + // TODO: Texture2D type is very coupled to raylib, required by Font type + // It should be redesigned to be provided by user + typedef struct Texture { + unsigned int id; // OpenGL texture id + int width; // Texture base width + int height; // Texture base height + int mipmaps; // Mipmap levels, 1 by default + int format; // Data format (PixelFormat type) + } Texture; + + // Texture2D, same as Texture + typedef Texture Texture2D; + + // Image, pixel data stored in CPU memory (RAM) + typedef struct Image { + void *data; // Image raw data + int width; // Image base width + int height; // Image base height + int mipmaps; // Mipmap levels, 1 by default + int format; // Data format (PixelFormat type) + } Image; + + // GlyphInfo, font characters glyphs info + typedef struct GlyphInfo { + int value; // Character value (Unicode) + int offsetX; // Character offset X when drawing + int offsetY; // Character offset Y when drawing + int advanceX; // Character advance position X + Image image; // Character image data + } GlyphInfo; + + // TODO: Font type is very coupled to raylib, mostly required by GuiLoadStyle() + // It should be redesigned to be provided by user + typedef struct Font { + int baseSize; // Base size (default chars height) + int glyphCount; // Number of glyph characters + int glyphPadding; // Padding around the glyph characters + Texture2D texture; // Texture atlas containing the glyphs + Rectangle *recs; // Rectangles in texture for the glyphs + GlyphInfo *glyphs; // Glyphs info data + } Font; +#endif + +// Style property +// NOTE: Used when exporting style as code for convenience +typedef struct GuiStyleProp { + unsigned short controlId; // Control identifier + unsigned short propertyId; // Property identifier + int propertyValue; // Property value +} GuiStyleProp; + +/* +// Controls text style -NOT USED- +// NOTE: Text style is defined by control +typedef struct GuiTextStyle { + unsigned int size; + int charSpacing; + int lineSpacing; + int alignmentH; + int alignmentV; + int padding; +} GuiTextStyle; +*/ + +// Gui control state +typedef enum { + STATE_NORMAL = 0, + STATE_FOCUSED, + STATE_PRESSED, + STATE_DISABLED +} GuiState; + +// Gui control text alignment +typedef enum { + TEXT_ALIGN_LEFT = 0, + TEXT_ALIGN_CENTER, + TEXT_ALIGN_RIGHT +} GuiTextAlignment; + +// Gui control text alignment vertical +// NOTE: Text vertical position inside the text bounds +typedef enum { + TEXT_ALIGN_TOP = 0, + TEXT_ALIGN_MIDDLE, + TEXT_ALIGN_BOTTOM +} GuiTextAlignmentVertical; + +// Gui control text wrap mode +// NOTE: Useful for multiline text +typedef enum { + TEXT_WRAP_NONE = 0, + TEXT_WRAP_CHAR, + TEXT_WRAP_WORD +} GuiTextWrapMode; + +// Gui controls +typedef enum { + // Default -> populates to all controls when set + DEFAULT = 0, + + // Basic controls + LABEL, // Used also for: LABELBUTTON + BUTTON, + TOGGLE, // Used also for: TOGGLEGROUP + SLIDER, // Used also for: SLIDERBAR, TOGGLESLIDER + PROGRESSBAR, + CHECKBOX, + COMBOBOX, + DROPDOWNBOX, + TEXTBOX, // Used also for: TEXTBOXMULTI + VALUEBOX, + CONTROL11, + LISTVIEW, + COLORPICKER, + SCROLLBAR, + STATUSBAR +} GuiControl; + +// Gui base properties for every control +// NOTE: RAYGUI_MAX_PROPS_BASE properties (by default 16 properties) +typedef enum { + BORDER_COLOR_NORMAL = 0, // Control border color in STATE_NORMAL + BASE_COLOR_NORMAL, // Control base color in STATE_NORMAL + TEXT_COLOR_NORMAL, // Control text color in STATE_NORMAL + BORDER_COLOR_FOCUSED, // Control border color in STATE_FOCUSED + BASE_COLOR_FOCUSED, // Control base color in STATE_FOCUSED + TEXT_COLOR_FOCUSED, // Control text color in STATE_FOCUSED + BORDER_COLOR_PRESSED, // Control border color in STATE_PRESSED + BASE_COLOR_PRESSED, // Control base color in STATE_PRESSED + TEXT_COLOR_PRESSED, // Control text color in STATE_PRESSED + BORDER_COLOR_DISABLED, // Control border color in STATE_DISABLED + BASE_COLOR_DISABLED, // Control base color in STATE_DISABLED + TEXT_COLOR_DISABLED, // Control text color in STATE_DISABLED + BORDER_WIDTH = 12, // Control border size, 0 for no border + //TEXT_SIZE, // Control text size (glyphs max height) -> GLOBAL for all controls + //TEXT_SPACING, // Control text spacing between glyphs -> GLOBAL for all controls + //TEXT_LINE_SPACING, // Control text spacing between lines -> GLOBAL for all controls + TEXT_PADDING = 13, // Control text padding, not considering border + TEXT_ALIGNMENT = 14, // Control text horizontal alignment inside control text bound (after border and padding) + //TEXT_WRAP_MODE // Control text wrap-mode inside text bounds -> GLOBAL for all controls +} GuiControlProperty; + +// TODO: Which text styling properties should be global or per-control? +// At this moment TEXT_PADDING and TEXT_ALIGNMENT is configured and saved per control while +// TEXT_SIZE, TEXT_SPACING, TEXT_LINE_SPACING, TEXT_ALIGNMENT_VERTICAL, TEXT_WRAP_MODE are global and +// should be configured by user as needed while defining the UI layout + +// Gui extended properties depend on control +// NOTE: RAYGUI_MAX_PROPS_EXTENDED properties (by default, max 8 properties) +//---------------------------------------------------------------------------------- +// DEFAULT extended properties +// NOTE: Those properties are common to all controls or global +// WARNING: Only 8 slots vailable for those properties by default +typedef enum { + TEXT_SIZE = 16, // Text size (glyphs max height) + TEXT_SPACING, // Text spacing between glyphs + LINE_COLOR, // Line control color + BACKGROUND_COLOR, // Background color + TEXT_LINE_SPACING, // Text spacing between lines + TEXT_ALIGNMENT_VERTICAL, // Text vertical alignment inside text bounds (after border and padding) + TEXT_WRAP_MODE // Text wrap-mode inside text bounds + //TEXT_DECORATION // Text decoration: 0-None, 1-Underline, 2-Line-through, 3-Overline + //TEXT_DECORATION_THICK // Text decoration line thickness +} GuiDefaultProperty; + +// Other possible text properties: +// TEXT_WEIGHT // Normal, Italic, Bold -> Requires specific font change +// TEXT_INDENT // Text indentation -> Now using TEXT_PADDING... + +// Label +//typedef enum { } GuiLabelProperty; + +// Button/Spinner +//typedef enum { } GuiButtonProperty; + +// Toggle/ToggleGroup +typedef enum { + GROUP_PADDING = 16, // ToggleGroup separation between toggles +} GuiToggleProperty; + +// Slider/SliderBar +typedef enum { + SLIDER_WIDTH = 16, // Slider size of internal bar + SLIDER_PADDING // Slider/SliderBar internal bar padding +} GuiSliderProperty; + +// ProgressBar +typedef enum { + PROGRESS_PADDING = 16, // ProgressBar internal padding +} GuiProgressBarProperty; + +// ScrollBar +typedef enum { + ARROWS_SIZE = 16, // ScrollBar arrows size + ARROWS_VISIBLE, // ScrollBar arrows visible + SCROLL_SLIDER_PADDING, // ScrollBar slider internal padding + SCROLL_SLIDER_SIZE, // ScrollBar slider size + SCROLL_PADDING, // ScrollBar scroll padding from arrows + SCROLL_SPEED, // ScrollBar scrolling speed +} GuiScrollBarProperty; + +// CheckBox +typedef enum { + CHECK_PADDING = 16 // CheckBox internal check padding +} GuiCheckBoxProperty; + +// ComboBox +typedef enum { + COMBO_BUTTON_WIDTH = 16, // ComboBox right button width + COMBO_BUTTON_SPACING // ComboBox button separation +} GuiComboBoxProperty; + +// DropdownBox +typedef enum { + ARROW_PADDING = 16, // DropdownBox arrow separation from border and items + DROPDOWN_ITEMS_SPACING, // DropdownBox items separation + DROPDOWN_ARROW_HIDDEN, // DropdownBox arrow hidden + DROPDOWN_ROLL_UP // DropdownBox roll up flag (default rolls down) +} GuiDropdownBoxProperty; + +// TextBox/TextBoxMulti/ValueBox/Spinner +typedef enum { + TEXT_READONLY = 16, // TextBox in read-only mode: 0-text editable, 1-text no-editable +} GuiTextBoxProperty; + +// ValueBox/Spinner +typedef enum { + SPINNER_BUTTON_WIDTH = 16, // Spinner left/right buttons width + SPINNER_BUTTON_SPACING, // Spinner buttons separation +} GuiValueBoxProperty; + +// Control11 +//typedef enum { } GuiControl11Property; + +// ListView +typedef enum { + LIST_ITEMS_HEIGHT = 16, // ListView items height + LIST_ITEMS_SPACING, // ListView items separation + SCROLLBAR_WIDTH, // ListView scrollbar size (usually width) + SCROLLBAR_SIDE, // ListView scrollbar side (0-SCROLLBAR_LEFT_SIDE, 1-SCROLLBAR_RIGHT_SIDE) + LIST_ITEMS_BORDER_NORMAL, // ListView items border enabled in normal state + LIST_ITEMS_BORDER_WIDTH // ListView items border width +} GuiListViewProperty; + +// ColorPicker +typedef enum { + COLOR_SELECTOR_SIZE = 16, + HUEBAR_WIDTH, // ColorPicker right hue bar width + HUEBAR_PADDING, // ColorPicker right hue bar separation from panel + HUEBAR_SELECTOR_HEIGHT, // ColorPicker right hue bar selector height + HUEBAR_SELECTOR_OVERFLOW // ColorPicker right hue bar selector overflow +} GuiColorPickerProperty; + +#define SCROLLBAR_LEFT_SIDE 0 +#define SCROLLBAR_RIGHT_SIDE 1 + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +// ... + +//---------------------------------------------------------------------------------- +// Module Functions Declaration +//---------------------------------------------------------------------------------- + +#if defined(__cplusplus) +extern "C" { // Prevents name mangling of functions +#endif + +// Global gui state control functions +RAYGUIAPI void GuiEnable(void); // Enable gui controls (global state) +RAYGUIAPI void GuiDisable(void); // Disable gui controls (global state) +RAYGUIAPI void GuiLock(void); // Lock gui controls (global state) +RAYGUIAPI void GuiUnlock(void); // Unlock gui controls (global state) +RAYGUIAPI bool GuiIsLocked(void); // Check if gui is locked (global state) +RAYGUIAPI void GuiSetAlpha(float alpha); // Set gui controls alpha (global state), alpha goes from 0.0f to 1.0f +RAYGUIAPI void GuiSetState(int state); // Set gui state (global state) +RAYGUIAPI int GuiGetState(void); // Get gui state (global state) + +// Font set/get functions +RAYGUIAPI void GuiSetFont(Font font); // Set gui custom font (global state) +RAYGUIAPI Font GuiGetFont(void); // Get gui custom font (global state) + +// Style set/get functions +RAYGUIAPI void GuiSetStyle(int control, int property, int value); // Set one style property +RAYGUIAPI int GuiGetStyle(int control, int property); // Get one style property + +// Styles loading functions +RAYGUIAPI void GuiLoadStyle(const char *fileName); // Load style file over global style variable (.rgs) +RAYGUIAPI void GuiLoadStyleDefault(void); // Load style default over global style + +// Tooltips management functions +RAYGUIAPI void GuiEnableTooltip(void); // Enable gui tooltips (global state) +RAYGUIAPI void GuiDisableTooltip(void); // Disable gui tooltips (global state) +RAYGUIAPI void GuiSetTooltip(const char *tooltip); // Set tooltip string + +// Icons functionality +RAYGUIAPI const char *GuiIconText(int iconId, const char *text); // Get text with icon id prepended (if supported) +#if !defined(RAYGUI_NO_ICONS) +RAYGUIAPI void GuiSetIconScale(int scale); // Set default icon drawing size +RAYGUIAPI unsigned int *GuiGetIcons(void); // Get raygui icons data pointer +RAYGUIAPI char **GuiLoadIcons(const char *fileName, bool loadIconsName); // Load raygui icons file (.rgi) into internal icons data +RAYGUIAPI void GuiDrawIcon(int iconId, int posX, int posY, int pixelSize, Color color); // Draw icon using pixel size at specified position +#endif + +// Utility functions +RAYGUIAPI int GuiGetTextWidth(const char *text); // Get text width considering gui style and icon size (if required) + +// Controls +//---------------------------------------------------------------------------------------------------------- +// Container/separator controls, useful for controls organization +RAYGUIAPI int GuiWindowBox(Rectangle bounds, const char *title); // Window Box control, shows a window that can be closed +RAYGUIAPI int GuiGroupBox(Rectangle bounds, const char *text); // Group Box control with text name +RAYGUIAPI int GuiLine(Rectangle bounds, const char *text); // Line separator control, could contain text +RAYGUIAPI int GuiPanel(Rectangle bounds, const char *text); // Panel control, useful to group controls +RAYGUIAPI int GuiTabBar(Rectangle bounds, const char **text, int count, int *active); // Tab Bar control, returns TAB to be closed or -1 +RAYGUIAPI int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector2 *scroll, Rectangle *view); // Scroll Panel control + +// Basic controls set +RAYGUIAPI int GuiLabel(Rectangle bounds, const char *text); // Label control +RAYGUIAPI int GuiButton(Rectangle bounds, const char *text); // Button control, returns true when clicked +RAYGUIAPI int GuiLabelButton(Rectangle bounds, const char *text); // Label button control, returns true when clicked +RAYGUIAPI int GuiToggle(Rectangle bounds, const char *text, bool *active); // Toggle Button control +RAYGUIAPI int GuiToggleGroup(Rectangle bounds, const char *text, int *active); // Toggle Group control +RAYGUIAPI int GuiToggleSlider(Rectangle bounds, const char *text, int *active); // Toggle Slider control +RAYGUIAPI int GuiCheckBox(Rectangle bounds, const char *text, bool *checked); // Check Box control, returns true when active +RAYGUIAPI int GuiComboBox(Rectangle bounds, const char *text, int *active); // Combo Box control + +RAYGUIAPI int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMode); // Dropdown Box control +RAYGUIAPI int GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode); // Spinner control +RAYGUIAPI int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode); // Value Box control, updates input text with numbers +RAYGUIAPI int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float *value, bool editMode); // Value box control for float values +RAYGUIAPI int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode); // Text Box control, updates input text + +RAYGUIAPI int GuiSlider(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue); // Slider control +RAYGUIAPI int GuiSliderBar(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue); // Slider Bar control +RAYGUIAPI int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue); // Progress Bar control +RAYGUIAPI int GuiStatusBar(Rectangle bounds, const char *text); // Status Bar control, shows info text +RAYGUIAPI int GuiDummyRec(Rectangle bounds, const char *text); // Dummy control for placeholders +RAYGUIAPI int GuiGrid(Rectangle bounds, const char *text, float spacing, int subdivs, Vector2 *mouseCell); // Grid control + +// Advance controls set +RAYGUIAPI int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *active); // List View control +RAYGUIAPI int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus); // List View with extended parameters +RAYGUIAPI int GuiMessageBox(Rectangle bounds, const char *title, const char *message, const char *buttons); // Message Box control, displays a message +RAYGUIAPI int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, const char *buttons, char *text, int textMaxSize, bool *secretViewActive); // Text Input Box control, ask for text, supports secret +RAYGUIAPI int GuiColorPicker(Rectangle bounds, const char *text, Color *color); // Color Picker control (multiple color controls) +RAYGUIAPI int GuiColorPanel(Rectangle bounds, const char *text, Color *color); // Color Panel control +RAYGUIAPI int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha); // Color Bar Alpha control +RAYGUIAPI int GuiColorBarHue(Rectangle bounds, const char *text, float *value); // Color Bar Hue control +RAYGUIAPI int GuiColorPickerHSV(Rectangle bounds, const char *text, Vector3 *colorHsv); // Color Picker control that avoids conversion to RGB on each call (multiple color controls) +RAYGUIAPI int GuiColorPanelHSV(Rectangle bounds, const char *text, Vector3 *colorHsv); // Color Panel control that updates Hue-Saturation-Value color value, used by GuiColorPickerHSV() +//---------------------------------------------------------------------------------------------------------- + +#if !defined(RAYGUI_NO_ICONS) + +#if !defined(RAYGUI_CUSTOM_ICONS) +//---------------------------------------------------------------------------------- +// Icons enumeration +//---------------------------------------------------------------------------------- +typedef enum { + ICON_NONE = 0, + ICON_FOLDER_FILE_OPEN = 1, + ICON_FILE_SAVE_CLASSIC = 2, + ICON_FOLDER_OPEN = 3, + ICON_FOLDER_SAVE = 4, + ICON_FILE_OPEN = 5, + ICON_FILE_SAVE = 6, + ICON_FILE_EXPORT = 7, + ICON_FILE_ADD = 8, + ICON_FILE_DELETE = 9, + ICON_FILETYPE_TEXT = 10, + ICON_FILETYPE_AUDIO = 11, + ICON_FILETYPE_IMAGE = 12, + ICON_FILETYPE_PLAY = 13, + ICON_FILETYPE_VIDEO = 14, + ICON_FILETYPE_INFO = 15, + ICON_FILE_COPY = 16, + ICON_FILE_CUT = 17, + ICON_FILE_PASTE = 18, + ICON_CURSOR_HAND = 19, + ICON_CURSOR_POINTER = 20, + ICON_CURSOR_CLASSIC = 21, + ICON_PENCIL = 22, + ICON_PENCIL_BIG = 23, + ICON_BRUSH_CLASSIC = 24, + ICON_BRUSH_PAINTER = 25, + ICON_WATER_DROP = 26, + ICON_COLOR_PICKER = 27, + ICON_RUBBER = 28, + ICON_COLOR_BUCKET = 29, + ICON_TEXT_T = 30, + ICON_TEXT_A = 31, + ICON_SCALE = 32, + ICON_RESIZE = 33, + ICON_FILTER_POINT = 34, + ICON_FILTER_BILINEAR = 35, + ICON_CROP = 36, + ICON_CROP_ALPHA = 37, + ICON_SQUARE_TOGGLE = 38, + ICON_SYMMETRY = 39, + ICON_SYMMETRY_HORIZONTAL = 40, + ICON_SYMMETRY_VERTICAL = 41, + ICON_LENS = 42, + ICON_LENS_BIG = 43, + ICON_EYE_ON = 44, + ICON_EYE_OFF = 45, + ICON_FILTER_TOP = 46, + ICON_FILTER = 47, + ICON_TARGET_POINT = 48, + ICON_TARGET_SMALL = 49, + ICON_TARGET_BIG = 50, + ICON_TARGET_MOVE = 51, + ICON_CURSOR_MOVE = 52, + ICON_CURSOR_SCALE = 53, + ICON_CURSOR_SCALE_RIGHT = 54, + ICON_CURSOR_SCALE_LEFT = 55, + ICON_UNDO = 56, + ICON_REDO = 57, + ICON_REREDO = 58, + ICON_MUTATE = 59, + ICON_ROTATE = 60, + ICON_REPEAT = 61, + ICON_SHUFFLE = 62, + ICON_EMPTYBOX = 63, + ICON_TARGET = 64, + ICON_TARGET_SMALL_FILL = 65, + ICON_TARGET_BIG_FILL = 66, + ICON_TARGET_MOVE_FILL = 67, + ICON_CURSOR_MOVE_FILL = 68, + ICON_CURSOR_SCALE_FILL = 69, + ICON_CURSOR_SCALE_RIGHT_FILL = 70, + ICON_CURSOR_SCALE_LEFT_FILL = 71, + ICON_UNDO_FILL = 72, + ICON_REDO_FILL = 73, + ICON_REREDO_FILL = 74, + ICON_MUTATE_FILL = 75, + ICON_ROTATE_FILL = 76, + ICON_REPEAT_FILL = 77, + ICON_SHUFFLE_FILL = 78, + ICON_EMPTYBOX_SMALL = 79, + ICON_BOX = 80, + ICON_BOX_TOP = 81, + ICON_BOX_TOP_RIGHT = 82, + ICON_BOX_RIGHT = 83, + ICON_BOX_BOTTOM_RIGHT = 84, + ICON_BOX_BOTTOM = 85, + ICON_BOX_BOTTOM_LEFT = 86, + ICON_BOX_LEFT = 87, + ICON_BOX_TOP_LEFT = 88, + ICON_BOX_CENTER = 89, + ICON_BOX_CIRCLE_MASK = 90, + ICON_POT = 91, + ICON_ALPHA_MULTIPLY = 92, + ICON_ALPHA_CLEAR = 93, + ICON_DITHERING = 94, + ICON_MIPMAPS = 95, + ICON_BOX_GRID = 96, + ICON_GRID = 97, + ICON_BOX_CORNERS_SMALL = 98, + ICON_BOX_CORNERS_BIG = 99, + ICON_FOUR_BOXES = 100, + ICON_GRID_FILL = 101, + ICON_BOX_MULTISIZE = 102, + ICON_ZOOM_SMALL = 103, + ICON_ZOOM_MEDIUM = 104, + ICON_ZOOM_BIG = 105, + ICON_ZOOM_ALL = 106, + ICON_ZOOM_CENTER = 107, + ICON_BOX_DOTS_SMALL = 108, + ICON_BOX_DOTS_BIG = 109, + ICON_BOX_CONCENTRIC = 110, + ICON_BOX_GRID_BIG = 111, + ICON_OK_TICK = 112, + ICON_CROSS = 113, + ICON_ARROW_LEFT = 114, + ICON_ARROW_RIGHT = 115, + ICON_ARROW_DOWN = 116, + ICON_ARROW_UP = 117, + ICON_ARROW_LEFT_FILL = 118, + ICON_ARROW_RIGHT_FILL = 119, + ICON_ARROW_DOWN_FILL = 120, + ICON_ARROW_UP_FILL = 121, + ICON_AUDIO = 122, + ICON_FX = 123, + ICON_WAVE = 124, + ICON_WAVE_SINUS = 125, + ICON_WAVE_SQUARE = 126, + ICON_WAVE_TRIANGULAR = 127, + ICON_CROSS_SMALL = 128, + ICON_PLAYER_PREVIOUS = 129, + ICON_PLAYER_PLAY_BACK = 130, + ICON_PLAYER_PLAY = 131, + ICON_PLAYER_PAUSE = 132, + ICON_PLAYER_STOP = 133, + ICON_PLAYER_NEXT = 134, + ICON_PLAYER_RECORD = 135, + ICON_MAGNET = 136, + ICON_LOCK_CLOSE = 137, + ICON_LOCK_OPEN = 138, + ICON_CLOCK = 139, + ICON_TOOLS = 140, + ICON_GEAR = 141, + ICON_GEAR_BIG = 142, + ICON_BIN = 143, + ICON_HAND_POINTER = 144, + ICON_LASER = 145, + ICON_COIN = 146, + ICON_EXPLOSION = 147, + ICON_1UP = 148, + ICON_PLAYER = 149, + ICON_PLAYER_JUMP = 150, + ICON_KEY = 151, + ICON_DEMON = 152, + ICON_TEXT_POPUP = 153, + ICON_GEAR_EX = 154, + ICON_CRACK = 155, + ICON_CRACK_POINTS = 156, + ICON_STAR = 157, + ICON_DOOR = 158, + ICON_EXIT = 159, + ICON_MODE_2D = 160, + ICON_MODE_3D = 161, + ICON_CUBE = 162, + ICON_CUBE_FACE_TOP = 163, + ICON_CUBE_FACE_LEFT = 164, + ICON_CUBE_FACE_FRONT = 165, + ICON_CUBE_FACE_BOTTOM = 166, + ICON_CUBE_FACE_RIGHT = 167, + ICON_CUBE_FACE_BACK = 168, + ICON_CAMERA = 169, + ICON_SPECIAL = 170, + ICON_LINK_NET = 171, + ICON_LINK_BOXES = 172, + ICON_LINK_MULTI = 173, + ICON_LINK = 174, + ICON_LINK_BROKE = 175, + ICON_TEXT_NOTES = 176, + ICON_NOTEBOOK = 177, + ICON_SUITCASE = 178, + ICON_SUITCASE_ZIP = 179, + ICON_MAILBOX = 180, + ICON_MONITOR = 181, + ICON_PRINTER = 182, + ICON_PHOTO_CAMERA = 183, + ICON_PHOTO_CAMERA_FLASH = 184, + ICON_HOUSE = 185, + ICON_HEART = 186, + ICON_CORNER = 187, + ICON_VERTICAL_BARS = 188, + ICON_VERTICAL_BARS_FILL = 189, + ICON_LIFE_BARS = 190, + ICON_INFO = 191, + ICON_CROSSLINE = 192, + ICON_HELP = 193, + ICON_FILETYPE_ALPHA = 194, + ICON_FILETYPE_HOME = 195, + ICON_LAYERS_VISIBLE = 196, + ICON_LAYERS = 197, + ICON_WINDOW = 198, + ICON_HIDPI = 199, + ICON_FILETYPE_BINARY = 200, + ICON_HEX = 201, + ICON_SHIELD = 202, + ICON_FILE_NEW = 203, + ICON_FOLDER_ADD = 204, + ICON_ALARM = 205, + ICON_CPU = 206, + ICON_ROM = 207, + ICON_STEP_OVER = 208, + ICON_STEP_INTO = 209, + ICON_STEP_OUT = 210, + ICON_RESTART = 211, + ICON_BREAKPOINT_ON = 212, + ICON_BREAKPOINT_OFF = 213, + ICON_BURGER_MENU = 214, + ICON_CASE_SENSITIVE = 215, + ICON_REG_EXP = 216, + ICON_FOLDER = 217, + ICON_FILE = 218, + ICON_SAND_TIMER = 219, + ICON_WARNING = 220, + ICON_HELP_BOX = 221, + ICON_INFO_BOX = 222, + ICON_PRIORITY = 223, + ICON_LAYERS_ISO = 224, + ICON_LAYERS2 = 225, + ICON_MLAYERS = 226, + ICON_MAPS = 227, + ICON_HOT = 228, + ICON_LABEL = 229, + ICON_NAME_ID = 230, + ICON_SLICING = 231, + ICON_MANUAL_CONTROL = 232, + ICON_COLLISION = 233, + ICON_CIRCLE_ADD = 234, + ICON_CIRCLE_ADD_FILL = 235, + ICON_CIRCLE_WARNING = 236, + ICON_CIRCLE_WARNING_FILL = 237, + ICON_BOX_MORE = 238, + ICON_BOX_MORE_FILL = 239, + ICON_BOX_MINUS = 240, + ICON_BOX_MINUS_FILL = 241, + ICON_UNION = 242, + ICON_INTERSECTION = 243, + ICON_DIFFERENCE = 244, + ICON_SPHERE = 245, + ICON_CYLINDER = 246, + ICON_CONE = 247, + ICON_ELLIPSOID = 248, + ICON_CAPSULE = 249, + ICON_250 = 250, + ICON_251 = 251, + ICON_252 = 252, + ICON_253 = 253, + ICON_254 = 254, + ICON_255 = 255 +} GuiIconName; +#endif + +#endif + +#if defined(__cplusplus) +} // Prevents name mangling of functions +#endif + +#endif // RAYGUI_H + +/*********************************************************************************** +* +* RAYGUI IMPLEMENTATION +* +************************************************************************************/ + +#if defined(RAYGUI_IMPLEMENTATION) + +#include // required for: isspace() [GuiTextBox()] +#include // Required for: FILE, fopen(), fclose(), fprintf(), feof(), fscanf(), snprintf(), vsprintf() [GuiLoadStyle(), GuiLoadIcons()] +#include // Required for: strlen() [GuiTextBox(), GuiValueBox()], memset(), memcpy() +#include // Required for: va_list, va_start(), vfprintf(), va_end() [TextFormat()] +#include // Required for: roundf() [GuiColorPicker()] + +// Allow custom memory allocators +#if defined(RAYGUI_MALLOC) || defined(RAYGUI_CALLOC) || defined(RAYGUI_FREE) + #if !defined(RAYGUI_MALLOC) || !defined(RAYGUI_CALLOC) || !defined(RAYGUI_FREE) + #error "RAYGUI: if RAYGUI_MALLOC, RAYGUI_CALLOC, or RAYGUI_FREE is customized, all three must be customized" + #endif +#else + #include // Required for: malloc(), calloc(), free() [GuiLoadStyle(), GuiLoadIcons()] + + #define RAYGUI_MALLOC(sz) malloc(sz) + #define RAYGUI_CALLOC(n,sz) calloc(n,sz) + #define RAYGUI_FREE(p) free(p) +#endif + +#ifdef __cplusplus + #define RAYGUI_CLITERAL(name) name +#else + #define RAYGUI_CLITERAL(name) (name) +#endif + +// Check if two rectangles are equal, used to validate a slider bounds as an id +#ifndef CHECK_BOUNDS_ID + #define CHECK_BOUNDS_ID(src, dst) (((int)src.x == (int)dst.x) && ((int)src.y == (int)dst.y) && ((int)src.width == (int)dst.width) && ((int)src.height == (int)dst.height)) +#endif + +#if !defined(RAYGUI_NO_ICONS) && !defined(RAYGUI_CUSTOM_ICONS) + +// Embedded icons, no external file provided +#define RAYGUI_ICON_SIZE 16 // Size of icons in pixels (squared) +#define RAYGUI_ICON_MAX_ICONS 256 // Maximum number of icons +#define RAYGUI_ICON_MAX_NAME_LENGTH 32 // Maximum length of icon name id + +// Icons data is defined by bit array (every bit represents one pixel) +// Those arrays are stored as unsigned int data arrays, so, +// every array element defines 32 pixels (bits) of information +// One icon is defined by 8 int, (8 int*32 bit = 256 bit = 16*16 pixels) +// NOTE: Number of elemens depend on RAYGUI_ICON_SIZE (by default 16x16 pixels) +#define RAYGUI_ICON_DATA_ELEMENTS (RAYGUI_ICON_SIZE*RAYGUI_ICON_SIZE/32) + +//---------------------------------------------------------------------------------- +// Icons data for all gui possible icons (allocated on data segment by default) +// +// NOTE 1: Every icon is codified in binary form, using 1 bit per pixel, so, +// every 16x16 icon requires 8 integers (16*16/32) to be stored +// +// NOTE 2: A different icon set could be loaded over this array using GuiLoadIcons(), +// but loaded icons set must be same RAYGUI_ICON_SIZE and no more than RAYGUI_ICON_MAX_ICONS +// +// guiIcons size is by default: 256*(16*16/32) = 2048*4 = 8192 bytes = 8 KB +//---------------------------------------------------------------------------------- +static unsigned int guiIcons[RAYGUI_ICON_MAX_ICONS*RAYGUI_ICON_DATA_ELEMENTS] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_NONE + 0x3ff80000, 0x2f082008, 0x2042207e, 0x40027fc2, 0x40024002, 0x40024002, 0x40024002, 0x00007ffe, // ICON_FOLDER_FILE_OPEN + 0x3ffe0000, 0x44226422, 0x400247e2, 0x5ffa4002, 0x57ea500a, 0x500a500a, 0x40025ffa, 0x00007ffe, // ICON_FILE_SAVE_CLASSIC + 0x00000000, 0x0042007e, 0x40027fc2, 0x40024002, 0x41024002, 0x44424282, 0x793e4102, 0x00000100, // ICON_FOLDER_OPEN + 0x00000000, 0x0042007e, 0x40027fc2, 0x40024002, 0x41024102, 0x44424102, 0x793e4282, 0x00000000, // ICON_FOLDER_SAVE + 0x3ff00000, 0x201c2010, 0x20042004, 0x21042004, 0x24442284, 0x21042104, 0x20042104, 0x00003ffc, // ICON_FILE_OPEN + 0x3ff00000, 0x201c2010, 0x20042004, 0x21042004, 0x21042104, 0x22842444, 0x20042104, 0x00003ffc, // ICON_FILE_SAVE + 0x3ff00000, 0x201c2010, 0x00042004, 0x20041004, 0x20844784, 0x00841384, 0x20042784, 0x00003ffc, // ICON_FILE_EXPORT + 0x3ff00000, 0x201c2010, 0x20042004, 0x20042004, 0x22042204, 0x22042f84, 0x20042204, 0x00003ffc, // ICON_FILE_ADD + 0x3ff00000, 0x201c2010, 0x20042004, 0x20042004, 0x25042884, 0x25042204, 0x20042884, 0x00003ffc, // ICON_FILE_DELETE + 0x3ff00000, 0x201c2010, 0x20042004, 0x20042ff4, 0x20042ff4, 0x20042ff4, 0x20042004, 0x00003ffc, // ICON_FILETYPE_TEXT + 0x3ff00000, 0x201c2010, 0x27042004, 0x244424c4, 0x26442444, 0x20642664, 0x20042004, 0x00003ffc, // ICON_FILETYPE_AUDIO + 0x3ff00000, 0x201c2010, 0x26042604, 0x20042004, 0x35442884, 0x2414222c, 0x20042004, 0x00003ffc, // ICON_FILETYPE_IMAGE + 0x3ff00000, 0x201c2010, 0x20c42004, 0x22442144, 0x22442444, 0x20c42144, 0x20042004, 0x00003ffc, // ICON_FILETYPE_PLAY + 0x3ff00000, 0x3ffc2ff0, 0x3f3c2ff4, 0x3dbc2eb4, 0x3dbc2bb4, 0x3f3c2eb4, 0x3ffc2ff4, 0x00002ff4, // ICON_FILETYPE_VIDEO + 0x3ff00000, 0x201c2010, 0x21842184, 0x21842004, 0x21842184, 0x21842184, 0x20042184, 0x00003ffc, // ICON_FILETYPE_INFO + 0x0ff00000, 0x381c0810, 0x28042804, 0x28042804, 0x28042804, 0x28042804, 0x20102ffc, 0x00003ff0, // ICON_FILE_COPY + 0x00000000, 0x701c0000, 0x079c1e14, 0x55a000f0, 0x079c00f0, 0x701c1e14, 0x00000000, 0x00000000, // ICON_FILE_CUT + 0x01c00000, 0x13e41bec, 0x3f841004, 0x204420c4, 0x20442044, 0x20442044, 0x207c2044, 0x00003fc0, // ICON_FILE_PASTE + 0x00000000, 0x3aa00fe0, 0x2abc2aa0, 0x2aa42aa4, 0x20042aa4, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_CURSOR_HAND + 0x00000000, 0x003c000c, 0x030800c8, 0x30100c10, 0x10202020, 0x04400840, 0x01800280, 0x00000000, // ICON_CURSOR_POINTER + 0x00000000, 0x00180000, 0x01f00078, 0x03e007f0, 0x07c003e0, 0x04000e40, 0x00000000, 0x00000000, // ICON_CURSOR_CLASSIC + 0x00000000, 0x04000000, 0x11000a00, 0x04400a80, 0x01100220, 0x00580088, 0x00000038, 0x00000000, // ICON_PENCIL + 0x04000000, 0x15000a00, 0x50402880, 0x14102820, 0x05040a08, 0x015c028c, 0x007c00bc, 0x00000000, // ICON_PENCIL_BIG + 0x01c00000, 0x01400140, 0x01400140, 0x0ff80140, 0x0ff80808, 0x0aa80808, 0x0aa80aa8, 0x00000ff8, // ICON_BRUSH_CLASSIC + 0x1ffc0000, 0x5ffc7ffe, 0x40004000, 0x00807f80, 0x01c001c0, 0x01c001c0, 0x01c001c0, 0x00000080, // ICON_BRUSH_PAINTER + 0x00000000, 0x00800000, 0x01c00080, 0x03e001c0, 0x07f003e0, 0x036006f0, 0x000001c0, 0x00000000, // ICON_WATER_DROP + 0x00000000, 0x3e003800, 0x1f803f80, 0x0c201e40, 0x02080c10, 0x00840104, 0x00380044, 0x00000000, // ICON_COLOR_PICKER + 0x00000000, 0x07800300, 0x1fe00fc0, 0x3f883fd0, 0x0e021f04, 0x02040402, 0x00f00108, 0x00000000, // ICON_RUBBER + 0x00c00000, 0x02800140, 0x08200440, 0x20081010, 0x2ffe3004, 0x03f807fc, 0x00e001f0, 0x00000040, // ICON_COLOR_BUCKET + 0x00000000, 0x21843ffc, 0x01800180, 0x01800180, 0x01800180, 0x01800180, 0x03c00180, 0x00000000, // ICON_TEXT_T + 0x00800000, 0x01400180, 0x06200340, 0x0c100620, 0x1ff80c10, 0x380c1808, 0x70067004, 0x0000f80f, // ICON_TEXT_A + 0x78000000, 0x50004000, 0x00004800, 0x03c003c0, 0x03c003c0, 0x00100000, 0x0002000a, 0x0000000e, // ICON_SCALE + 0x75560000, 0x5e004002, 0x54001002, 0x41001202, 0x408200fe, 0x40820082, 0x40820082, 0x00006afe, // ICON_RESIZE + 0x00000000, 0x3f003f00, 0x3f003f00, 0x3f003f00, 0x00400080, 0x001c0020, 0x001c001c, 0x00000000, // ICON_FILTER_POINT + 0x6d800000, 0x00004080, 0x40804080, 0x40800000, 0x00406d80, 0x001c0020, 0x001c001c, 0x00000000, // ICON_FILTER_BILINEAR + 0x40080000, 0x1ffe2008, 0x14081008, 0x11081208, 0x10481088, 0x10081028, 0x10047ff8, 0x00001002, // ICON_CROP + 0x00100000, 0x3ffc0010, 0x2ab03550, 0x22b02550, 0x20b02150, 0x20302050, 0x2000fff0, 0x00002000, // ICON_CROP_ALPHA + 0x40000000, 0x1ff82000, 0x04082808, 0x01082208, 0x00482088, 0x00182028, 0x35542008, 0x00000002, // ICON_SQUARE_TOGGLE + 0x00000000, 0x02800280, 0x06c006c0, 0x0ea00ee0, 0x1e901eb0, 0x3e883e98, 0x7efc7e8c, 0x00000000, // ICON_SYMMETRY + 0x01000000, 0x05600100, 0x1d480d50, 0x7d423d44, 0x3d447d42, 0x0d501d48, 0x01000560, 0x00000100, // ICON_SYMMETRY_HORIZONTAL + 0x01800000, 0x04200240, 0x10080810, 0x00001ff8, 0x00007ffe, 0x0ff01ff8, 0x03c007e0, 0x00000180, // ICON_SYMMETRY_VERTICAL + 0x00000000, 0x010800f0, 0x02040204, 0x02040204, 0x07f00308, 0x1c000e00, 0x30003800, 0x00000000, // ICON_LENS + 0x00000000, 0x061803f0, 0x08240c0c, 0x08040814, 0x0c0c0804, 0x23f01618, 0x18002400, 0x00000000, // ICON_LENS_BIG + 0x00000000, 0x00000000, 0x1c7007c0, 0x638e3398, 0x1c703398, 0x000007c0, 0x00000000, 0x00000000, // ICON_EYE_ON + 0x00000000, 0x10002000, 0x04700fc0, 0x610e3218, 0x1c703098, 0x001007a0, 0x00000008, 0x00000000, // ICON_EYE_OFF + 0x00000000, 0x00007ffc, 0x40047ffc, 0x10102008, 0x04400820, 0x02800280, 0x02800280, 0x00000100, // ICON_FILTER_TOP + 0x00000000, 0x40027ffe, 0x10082004, 0x04200810, 0x02400240, 0x02400240, 0x01400240, 0x000000c0, // ICON_FILTER + 0x00800000, 0x00800080, 0x00000080, 0x3c9e0000, 0x00000000, 0x00800080, 0x00800080, 0x00000000, // ICON_TARGET_POINT + 0x00800000, 0x00800080, 0x00800080, 0x3f7e01c0, 0x008001c0, 0x00800080, 0x00800080, 0x00000000, // ICON_TARGET_SMALL + 0x00800000, 0x00800080, 0x03e00080, 0x3e3e0220, 0x03e00220, 0x00800080, 0x00800080, 0x00000000, // ICON_TARGET_BIG + 0x01000000, 0x04400280, 0x01000100, 0x43842008, 0x43849ab2, 0x01002008, 0x04400100, 0x01000280, // ICON_TARGET_MOVE + 0x01000000, 0x04400280, 0x01000100, 0x41042108, 0x41049ff2, 0x01002108, 0x04400100, 0x01000280, // ICON_CURSOR_MOVE + 0x781e0000, 0x500a4002, 0x04204812, 0x00000240, 0x02400000, 0x48120420, 0x4002500a, 0x0000781e, // ICON_CURSOR_SCALE + 0x00000000, 0x20003c00, 0x24002800, 0x01000200, 0x00400080, 0x00140024, 0x003c0004, 0x00000000, // ICON_CURSOR_SCALE_RIGHT + 0x00000000, 0x0004003c, 0x00240014, 0x00800040, 0x02000100, 0x28002400, 0x3c002000, 0x00000000, // ICON_CURSOR_SCALE_LEFT + 0x00000000, 0x00100020, 0x10101fc8, 0x10001020, 0x10001000, 0x10001000, 0x00001fc0, 0x00000000, // ICON_UNDO + 0x00000000, 0x08000400, 0x080813f8, 0x00080408, 0x00080008, 0x00080008, 0x000003f8, 0x00000000, // ICON_REDO + 0x00000000, 0x3ffc0000, 0x20042004, 0x20002000, 0x20402000, 0x3f902020, 0x00400020, 0x00000000, // ICON_REREDO + 0x00000000, 0x3ffc0000, 0x20042004, 0x27fc2004, 0x20202000, 0x3fc82010, 0x00200010, 0x00000000, // ICON_MUTATE + 0x00000000, 0x0ff00000, 0x10081818, 0x11801008, 0x10001180, 0x18101020, 0x00100fc8, 0x00000020, // ICON_ROTATE + 0x00000000, 0x04000200, 0x240429fc, 0x20042204, 0x20442004, 0x3f942024, 0x00400020, 0x00000000, // ICON_REPEAT + 0x00000000, 0x20001000, 0x22104c0e, 0x00801120, 0x11200040, 0x4c0e2210, 0x10002000, 0x00000000, // ICON_SHUFFLE + 0x7ffe0000, 0x50024002, 0x44024802, 0x41024202, 0x40424082, 0x40124022, 0x4002400a, 0x00007ffe, // ICON_EMPTYBOX + 0x00800000, 0x03e00080, 0x08080490, 0x3c9e0808, 0x08080808, 0x03e00490, 0x00800080, 0x00000000, // ICON_TARGET + 0x00800000, 0x00800080, 0x00800080, 0x3ffe01c0, 0x008001c0, 0x00800080, 0x00800080, 0x00000000, // ICON_TARGET_SMALL_FILL + 0x00800000, 0x00800080, 0x03e00080, 0x3ffe03e0, 0x03e003e0, 0x00800080, 0x00800080, 0x00000000, // ICON_TARGET_BIG_FILL + 0x01000000, 0x07c00380, 0x01000100, 0x638c2008, 0x638cfbbe, 0x01002008, 0x07c00100, 0x01000380, // ICON_TARGET_MOVE_FILL + 0x01000000, 0x07c00380, 0x01000100, 0x610c2108, 0x610cfffe, 0x01002108, 0x07c00100, 0x01000380, // ICON_CURSOR_MOVE_FILL + 0x781e0000, 0x6006700e, 0x04204812, 0x00000240, 0x02400000, 0x48120420, 0x700e6006, 0x0000781e, // ICON_CURSOR_SCALE_FILL + 0x00000000, 0x38003c00, 0x24003000, 0x01000200, 0x00400080, 0x000c0024, 0x003c001c, 0x00000000, // ICON_CURSOR_SCALE_RIGHT_FILL + 0x00000000, 0x001c003c, 0x0024000c, 0x00800040, 0x02000100, 0x30002400, 0x3c003800, 0x00000000, // ICON_CURSOR_SCALE_LEFT_FILL + 0x00000000, 0x00300020, 0x10301ff8, 0x10001020, 0x10001000, 0x10001000, 0x00001fc0, 0x00000000, // ICON_UNDO_FILL + 0x00000000, 0x0c000400, 0x0c081ff8, 0x00080408, 0x00080008, 0x00080008, 0x000003f8, 0x00000000, // ICON_REDO_FILL + 0x00000000, 0x3ffc0000, 0x20042004, 0x20002000, 0x20402000, 0x3ff02060, 0x00400060, 0x00000000, // ICON_REREDO_FILL + 0x00000000, 0x3ffc0000, 0x20042004, 0x27fc2004, 0x20202000, 0x3ff82030, 0x00200030, 0x00000000, // ICON_MUTATE_FILL + 0x00000000, 0x0ff00000, 0x10081818, 0x11801008, 0x10001180, 0x18301020, 0x00300ff8, 0x00000020, // ICON_ROTATE_FILL + 0x00000000, 0x06000200, 0x26042ffc, 0x20042204, 0x20442004, 0x3ff42064, 0x00400060, 0x00000000, // ICON_REPEAT_FILL + 0x00000000, 0x30001000, 0x32107c0e, 0x00801120, 0x11200040, 0x7c0e3210, 0x10003000, 0x00000000, // ICON_SHUFFLE_FILL + 0x00000000, 0x30043ffc, 0x24042804, 0x21042204, 0x20442084, 0x20142024, 0x3ffc200c, 0x00000000, // ICON_EMPTYBOX_SMALL + 0x00000000, 0x20043ffc, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_BOX + 0x00000000, 0x23c43ffc, 0x23c423c4, 0x200423c4, 0x20042004, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_BOX_TOP + 0x00000000, 0x3e043ffc, 0x3e043e04, 0x20043e04, 0x20042004, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_BOX_TOP_RIGHT + 0x00000000, 0x20043ffc, 0x20042004, 0x3e043e04, 0x3e043e04, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_BOX_RIGHT + 0x00000000, 0x20043ffc, 0x20042004, 0x20042004, 0x3e042004, 0x3e043e04, 0x3ffc3e04, 0x00000000, // ICON_BOX_BOTTOM_RIGHT + 0x00000000, 0x20043ffc, 0x20042004, 0x20042004, 0x23c42004, 0x23c423c4, 0x3ffc23c4, 0x00000000, // ICON_BOX_BOTTOM + 0x00000000, 0x20043ffc, 0x20042004, 0x20042004, 0x207c2004, 0x207c207c, 0x3ffc207c, 0x00000000, // ICON_BOX_BOTTOM_LEFT + 0x00000000, 0x20043ffc, 0x20042004, 0x207c207c, 0x207c207c, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_BOX_LEFT + 0x00000000, 0x207c3ffc, 0x207c207c, 0x2004207c, 0x20042004, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_BOX_TOP_LEFT + 0x00000000, 0x20043ffc, 0x20042004, 0x23c423c4, 0x23c423c4, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_BOX_CENTER + 0x7ffe0000, 0x40024002, 0x47e24182, 0x4ff247e2, 0x47e24ff2, 0x418247e2, 0x40024002, 0x00007ffe, // ICON_BOX_CIRCLE_MASK + 0x7fff0000, 0x40014001, 0x40014001, 0x49555ddd, 0x4945495d, 0x400149c5, 0x40014001, 0x00007fff, // ICON_POT + 0x7ffe0000, 0x53327332, 0x44ce4cce, 0x41324332, 0x404e40ce, 0x48125432, 0x4006540e, 0x00007ffe, // ICON_ALPHA_MULTIPLY + 0x7ffe0000, 0x53327332, 0x44ce4cce, 0x41324332, 0x5c4e40ce, 0x44124432, 0x40065c0e, 0x00007ffe, // ICON_ALPHA_CLEAR + 0x7ffe0000, 0x42fe417e, 0x42fe417e, 0x42fe417e, 0x42fe417e, 0x42fe417e, 0x42fe417e, 0x00007ffe, // ICON_DITHERING + 0x07fe0000, 0x1ffa0002, 0x7fea000a, 0x402a402a, 0x5b2a512a, 0x5128552a, 0x40205128, 0x00007fe0, // ICON_MIPMAPS + 0x00000000, 0x1ff80000, 0x12481248, 0x12481ff8, 0x1ff81248, 0x12481248, 0x00001ff8, 0x00000000, // ICON_BOX_GRID + 0x12480000, 0x7ffe1248, 0x12481248, 0x12487ffe, 0x7ffe1248, 0x12481248, 0x12487ffe, 0x00001248, // ICON_GRID + 0x00000000, 0x1c380000, 0x1c3817e8, 0x08100810, 0x08100810, 0x17e81c38, 0x00001c38, 0x00000000, // ICON_BOX_CORNERS_SMALL + 0x700e0000, 0x700e5ffa, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x5ffa700e, 0x0000700e, // ICON_BOX_CORNERS_BIG + 0x3f7e0000, 0x21422142, 0x21422142, 0x00003f7e, 0x21423f7e, 0x21422142, 0x3f7e2142, 0x00000000, // ICON_FOUR_BOXES + 0x00000000, 0x3bb80000, 0x3bb83bb8, 0x3bb80000, 0x3bb83bb8, 0x3bb80000, 0x3bb83bb8, 0x00000000, // ICON_GRID_FILL + 0x7ffe0000, 0x7ffe7ffe, 0x77fe7000, 0x77fe77fe, 0x777e7700, 0x777e777e, 0x777e777e, 0x0000777e, // ICON_BOX_MULTISIZE + 0x781e0000, 0x40024002, 0x00004002, 0x01800000, 0x00000180, 0x40020000, 0x40024002, 0x0000781e, // ICON_ZOOM_SMALL + 0x781e0000, 0x40024002, 0x00004002, 0x03c003c0, 0x03c003c0, 0x40020000, 0x40024002, 0x0000781e, // ICON_ZOOM_MEDIUM + 0x781e0000, 0x40024002, 0x07e04002, 0x07e007e0, 0x07e007e0, 0x400207e0, 0x40024002, 0x0000781e, // ICON_ZOOM_BIG + 0x781e0000, 0x5ffa4002, 0x1ff85ffa, 0x1ff81ff8, 0x1ff81ff8, 0x5ffa1ff8, 0x40025ffa, 0x0000781e, // ICON_ZOOM_ALL + 0x00000000, 0x2004381c, 0x00002004, 0x00000000, 0x00000000, 0x20040000, 0x381c2004, 0x00000000, // ICON_ZOOM_CENTER + 0x00000000, 0x1db80000, 0x10081008, 0x10080000, 0x00001008, 0x10081008, 0x00001db8, 0x00000000, // ICON_BOX_DOTS_SMALL + 0x35560000, 0x00002002, 0x00002002, 0x00002002, 0x00002002, 0x00002002, 0x35562002, 0x00000000, // ICON_BOX_DOTS_BIG + 0x7ffe0000, 0x40024002, 0x48124ff2, 0x49924812, 0x48124992, 0x4ff24812, 0x40024002, 0x00007ffe, // ICON_BOX_CONCENTRIC + 0x00000000, 0x10841ffc, 0x10841084, 0x1ffc1084, 0x10841084, 0x10841084, 0x00001ffc, 0x00000000, // ICON_BOX_GRID_BIG + 0x00000000, 0x00000000, 0x10000000, 0x04000800, 0x01040200, 0x00500088, 0x00000020, 0x00000000, // ICON_OK_TICK + 0x00000000, 0x10080000, 0x04200810, 0x01800240, 0x02400180, 0x08100420, 0x00001008, 0x00000000, // ICON_CROSS + 0x00000000, 0x02000000, 0x00800100, 0x00200040, 0x00200010, 0x00800040, 0x02000100, 0x00000000, // ICON_ARROW_LEFT + 0x00000000, 0x00400000, 0x01000080, 0x04000200, 0x04000800, 0x01000200, 0x00400080, 0x00000000, // ICON_ARROW_RIGHT + 0x00000000, 0x00000000, 0x00000000, 0x08081004, 0x02200410, 0x00800140, 0x00000000, 0x00000000, // ICON_ARROW_DOWN + 0x00000000, 0x00000000, 0x01400080, 0x04100220, 0x10040808, 0x00000000, 0x00000000, 0x00000000, // ICON_ARROW_UP + 0x00000000, 0x02000000, 0x03800300, 0x03e003c0, 0x03e003f0, 0x038003c0, 0x02000300, 0x00000000, // ICON_ARROW_LEFT_FILL + 0x00000000, 0x00400000, 0x01c000c0, 0x07c003c0, 0x07c00fc0, 0x01c003c0, 0x004000c0, 0x00000000, // ICON_ARROW_RIGHT_FILL + 0x00000000, 0x00000000, 0x00000000, 0x0ff81ffc, 0x03e007f0, 0x008001c0, 0x00000000, 0x00000000, // ICON_ARROW_DOWN_FILL + 0x00000000, 0x00000000, 0x01c00080, 0x07f003e0, 0x1ffc0ff8, 0x00000000, 0x00000000, 0x00000000, // ICON_ARROW_UP_FILL + 0x00000000, 0x18a008c0, 0x32881290, 0x24822686, 0x26862482, 0x12903288, 0x08c018a0, 0x00000000, // ICON_AUDIO + 0x00000000, 0x04800780, 0x004000c0, 0x662000f0, 0x08103c30, 0x130a0e18, 0x0000318e, 0x00000000, // ICON_FX + 0x00000000, 0x00800000, 0x08880888, 0x2aaa0a8a, 0x0a8a2aaa, 0x08880888, 0x00000080, 0x00000000, // ICON_WAVE + 0x00000000, 0x00600000, 0x01080090, 0x02040108, 0x42044204, 0x24022402, 0x00001800, 0x00000000, // ICON_WAVE_SINUS + 0x00000000, 0x07f80000, 0x04080408, 0x04080408, 0x04080408, 0x7c0e0408, 0x00000000, 0x00000000, // ICON_WAVE_SQUARE + 0x00000000, 0x00000000, 0x00a00040, 0x22084110, 0x08021404, 0x00000000, 0x00000000, 0x00000000, // ICON_WAVE_TRIANGULAR + 0x00000000, 0x00000000, 0x04200000, 0x01800240, 0x02400180, 0x00000420, 0x00000000, 0x00000000, // ICON_CROSS_SMALL + 0x00000000, 0x18380000, 0x12281428, 0x10a81128, 0x112810a8, 0x14281228, 0x00001838, 0x00000000, // ICON_PLAYER_PREVIOUS + 0x00000000, 0x18000000, 0x11801600, 0x10181060, 0x10601018, 0x16001180, 0x00001800, 0x00000000, // ICON_PLAYER_PLAY_BACK + 0x00000000, 0x00180000, 0x01880068, 0x18080608, 0x06081808, 0x00680188, 0x00000018, 0x00000000, // ICON_PLAYER_PLAY + 0x00000000, 0x1e780000, 0x12481248, 0x12481248, 0x12481248, 0x12481248, 0x00001e78, 0x00000000, // ICON_PLAYER_PAUSE + 0x00000000, 0x1ff80000, 0x10081008, 0x10081008, 0x10081008, 0x10081008, 0x00001ff8, 0x00000000, // ICON_PLAYER_STOP + 0x00000000, 0x1c180000, 0x14481428, 0x15081488, 0x14881508, 0x14281448, 0x00001c18, 0x00000000, // ICON_PLAYER_NEXT + 0x00000000, 0x03c00000, 0x08100420, 0x10081008, 0x10081008, 0x04200810, 0x000003c0, 0x00000000, // ICON_PLAYER_RECORD + 0x00000000, 0x0c3007e0, 0x13c81818, 0x14281668, 0x14281428, 0x1c381c38, 0x08102244, 0x00000000, // ICON_MAGNET + 0x07c00000, 0x08200820, 0x3ff80820, 0x23882008, 0x21082388, 0x20082108, 0x1ff02008, 0x00000000, // ICON_LOCK_CLOSE + 0x07c00000, 0x08000800, 0x3ff80800, 0x23882008, 0x21082388, 0x20082108, 0x1ff02008, 0x00000000, // ICON_LOCK_OPEN + 0x01c00000, 0x0c180770, 0x3086188c, 0x60832082, 0x60034781, 0x30062002, 0x0c18180c, 0x01c00770, // ICON_CLOCK + 0x0a200000, 0x1b201b20, 0x04200e20, 0x04200420, 0x04700420, 0x0e700e70, 0x0e700e70, 0x04200e70, // ICON_TOOLS + 0x01800000, 0x3bdc318c, 0x0ff01ff8, 0x7c3e1e78, 0x1e787c3e, 0x1ff80ff0, 0x318c3bdc, 0x00000180, // ICON_GEAR + 0x01800000, 0x3ffc318c, 0x1c381ff8, 0x781e1818, 0x1818781e, 0x1ff81c38, 0x318c3ffc, 0x00000180, // ICON_GEAR_BIG + 0x00000000, 0x08080ff8, 0x08081ffc, 0x0aa80aa8, 0x0aa80aa8, 0x0aa80aa8, 0x08080aa8, 0x00000ff8, // ICON_BIN + 0x00000000, 0x00000000, 0x20043ffc, 0x08043f84, 0x04040f84, 0x04040784, 0x000007fc, 0x00000000, // ICON_HAND_POINTER + 0x00000000, 0x24400400, 0x00001480, 0x6efe0e00, 0x00000e00, 0x24401480, 0x00000400, 0x00000000, // ICON_LASER + 0x00000000, 0x03c00000, 0x08300460, 0x11181118, 0x11181118, 0x04600830, 0x000003c0, 0x00000000, // ICON_COIN + 0x00000000, 0x10880080, 0x06c00810, 0x366c07e0, 0x07e00240, 0x00001768, 0x04200240, 0x00000000, // ICON_EXPLOSION + 0x00000000, 0x3d280000, 0x2528252c, 0x3d282528, 0x05280528, 0x05e80528, 0x00000000, 0x00000000, // ICON_1UP + 0x01800000, 0x03c003c0, 0x018003c0, 0x0ff007e0, 0x0bd00bd0, 0x0a500bd0, 0x02400240, 0x02400240, // ICON_PLAYER + 0x01800000, 0x03c003c0, 0x118013c0, 0x03c81ff8, 0x07c003c8, 0x04400440, 0x0c080478, 0x00000000, // ICON_PLAYER_JUMP + 0x3ff80000, 0x30183ff8, 0x30183018, 0x3ff83ff8, 0x03000300, 0x03c003c0, 0x03e00300, 0x000003e0, // ICON_KEY + 0x3ff80000, 0x3ff83ff8, 0x33983ff8, 0x3ff83398, 0x3ff83ff8, 0x00000540, 0x0fe00aa0, 0x00000fe0, // ICON_DEMON + 0x00000000, 0x0ff00000, 0x20041008, 0x25442004, 0x10082004, 0x06000bf0, 0x00000300, 0x00000000, // ICON_TEXT_POPUP + 0x00000000, 0x11440000, 0x07f00be8, 0x1c1c0e38, 0x1c1c0c18, 0x07f00e38, 0x11440be8, 0x00000000, // ICON_GEAR_EX + 0x00000000, 0x20080000, 0x0c601010, 0x07c00fe0, 0x07c007c0, 0x0c600fe0, 0x20081010, 0x00000000, // ICON_CRACK + 0x00000000, 0x20080000, 0x0c601010, 0x04400fe0, 0x04405554, 0x0c600fe0, 0x20081010, 0x00000000, // ICON_CRACK_POINTS + 0x00000000, 0x00800080, 0x01c001c0, 0x1ffc3ffe, 0x03e007f0, 0x07f003e0, 0x0c180770, 0x00000808, // ICON_STAR + 0x0ff00000, 0x08180810, 0x08100818, 0x0a100810, 0x08180810, 0x08100818, 0x08100810, 0x00001ff8, // ICON_DOOR + 0x0ff00000, 0x08100810, 0x08100810, 0x10100010, 0x4f902010, 0x10102010, 0x08100010, 0x00000ff0, // ICON_EXIT + 0x00040000, 0x001f000e, 0x0ef40004, 0x12f41284, 0x0ef41214, 0x10040004, 0x7ffc3004, 0x10003000, // ICON_MODE_2D + 0x78040000, 0x501f600e, 0x0ef44004, 0x12f41284, 0x0ef41284, 0x10140004, 0x7ffc300c, 0x10003000, // ICON_MODE_3D + 0x7fe00000, 0x50286030, 0x47fe4804, 0x44224402, 0x44224422, 0x241275e2, 0x0c06140a, 0x000007fe, // ICON_CUBE + 0x7fe00000, 0x5ff87ff0, 0x47fe4ffc, 0x44224402, 0x44224422, 0x241275e2, 0x0c06140a, 0x000007fe, // ICON_CUBE_FACE_TOP + 0x7fe00000, 0x50386030, 0x47c2483c, 0x443e443e, 0x443e443e, 0x241e75fe, 0x0c06140e, 0x000007fe, // ICON_CUBE_FACE_LEFT + 0x7fe00000, 0x50286030, 0x47fe4804, 0x47fe47fe, 0x47fe47fe, 0x27fe77fe, 0x0ffe17fe, 0x000007fe, // ICON_CUBE_FACE_FRONT + 0x7fe00000, 0x50286030, 0x47fe4804, 0x44224402, 0x44224422, 0x3bf27be2, 0x0bfe1bfa, 0x000007fe, // ICON_CUBE_FACE_BOTTOM + 0x7fe00000, 0x70286030, 0x7ffe7804, 0x7c227c02, 0x7c227c22, 0x3c127de2, 0x0c061c0a, 0x000007fe, // ICON_CUBE_FACE_RIGHT + 0x7fe00000, 0x6fe85ff0, 0x781e77e4, 0x7be27be2, 0x7be27be2, 0x24127be2, 0x0c06140a, 0x000007fe, // ICON_CUBE_FACE_BACK + 0x00000000, 0x2a0233fe, 0x22022602, 0x22022202, 0x2a022602, 0x00a033fe, 0x02080110, 0x00000000, // ICON_CAMERA + 0x00000000, 0x200c3ffc, 0x000c000c, 0x3ffc000c, 0x30003000, 0x30003000, 0x3ffc3004, 0x00000000, // ICON_SPECIAL + 0x00000000, 0x0022003e, 0x012201e2, 0x0100013e, 0x01000100, 0x79000100, 0x4f004900, 0x00007800, // ICON_LINK_NET + 0x00000000, 0x44007c00, 0x45004600, 0x00627cbe, 0x00620022, 0x45007cbe, 0x44004600, 0x00007c00, // ICON_LINK_BOXES + 0x00000000, 0x0044007c, 0x0010007c, 0x3f100010, 0x3f1021f0, 0x3f100010, 0x3f0021f0, 0x00000000, // ICON_LINK_MULTI + 0x00000000, 0x0044007c, 0x00440044, 0x0010007c, 0x00100010, 0x44107c10, 0x440047f0, 0x00007c00, // ICON_LINK + 0x00000000, 0x0044007c, 0x00440044, 0x0000007c, 0x00000010, 0x44007c10, 0x44004550, 0x00007c00, // ICON_LINK_BROKE + 0x02a00000, 0x22a43ffc, 0x20042004, 0x20042ff4, 0x20042ff4, 0x20042ff4, 0x20042004, 0x00003ffc, // ICON_TEXT_NOTES + 0x3ffc0000, 0x20042004, 0x245e27c4, 0x27c42444, 0x2004201e, 0x201e2004, 0x20042004, 0x00003ffc, // ICON_NOTEBOOK + 0x00000000, 0x07e00000, 0x04200420, 0x24243ffc, 0x24242424, 0x24242424, 0x3ffc2424, 0x00000000, // ICON_SUITCASE + 0x00000000, 0x0fe00000, 0x08200820, 0x40047ffc, 0x7ffc5554, 0x40045554, 0x7ffc4004, 0x00000000, // ICON_SUITCASE_ZIP + 0x00000000, 0x20043ffc, 0x3ffc2004, 0x13c81008, 0x100813c8, 0x10081008, 0x1ff81008, 0x00000000, // ICON_MAILBOX + 0x00000000, 0x40027ffe, 0x5ffa5ffa, 0x5ffa5ffa, 0x40025ffa, 0x03c07ffe, 0x1ff81ff8, 0x00000000, // ICON_MONITOR + 0x0ff00000, 0x6bfe7ffe, 0x7ffe7ffe, 0x68167ffe, 0x08106816, 0x08100810, 0x0ff00810, 0x00000000, // ICON_PRINTER + 0x3ff80000, 0xfffe2008, 0x870a8002, 0x904a888a, 0x904a904a, 0x870a888a, 0xfffe8002, 0x00000000, // ICON_PHOTO_CAMERA + 0x0fc00000, 0xfcfe0cd8, 0x8002fffe, 0x84428382, 0x84428442, 0x80028382, 0xfffe8002, 0x00000000, // ICON_PHOTO_CAMERA_FLASH + 0x00000000, 0x02400180, 0x08100420, 0x20041008, 0x23c42004, 0x22442244, 0x3ffc2244, 0x00000000, // ICON_HOUSE + 0x00000000, 0x1c700000, 0x3ff83ef8, 0x3ff83ff8, 0x0fe01ff0, 0x038007c0, 0x00000100, 0x00000000, // ICON_HEART + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0xe000c000, // ICON_CORNER + 0x00000000, 0x14001c00, 0x15c01400, 0x15401540, 0x155c1540, 0x15541554, 0x1ddc1554, 0x00000000, // ICON_VERTICAL_BARS + 0x00000000, 0x03000300, 0x1b001b00, 0x1b601b60, 0x1b6c1b60, 0x1b6c1b6c, 0x1b6c1b6c, 0x00000000, // ICON_VERTICAL_BARS_FILL + 0x00000000, 0x00000000, 0x403e7ffe, 0x7ffe403e, 0x7ffe0000, 0x43fe43fe, 0x00007ffe, 0x00000000, // ICON_LIFE_BARS + 0x7ffc0000, 0x43844004, 0x43844284, 0x43844004, 0x42844284, 0x42844284, 0x40044384, 0x00007ffc, // ICON_INFO + 0x40008000, 0x10002000, 0x04000800, 0x01000200, 0x00400080, 0x00100020, 0x00040008, 0x00010002, // ICON_CROSSLINE + 0x00000000, 0x1ff01ff0, 0x18301830, 0x1f001830, 0x03001f00, 0x00000300, 0x03000300, 0x00000000, // ICON_HELP + 0x3ff00000, 0x2abc3550, 0x2aac3554, 0x2aac3554, 0x2aac3554, 0x2aac3554, 0x2aac3554, 0x00003ffc, // ICON_FILETYPE_ALPHA + 0x3ff00000, 0x201c2010, 0x22442184, 0x28142424, 0x29942814, 0x2ff42994, 0x20042004, 0x00003ffc, // ICON_FILETYPE_HOME + 0x07fe0000, 0x04020402, 0x7fe20402, 0x44224422, 0x44224422, 0x402047fe, 0x40204020, 0x00007fe0, // ICON_LAYERS_VISIBLE + 0x07fe0000, 0x04020402, 0x7c020402, 0x44024402, 0x44024402, 0x402047fe, 0x40204020, 0x00007fe0, // ICON_LAYERS + 0x00000000, 0x40027ffe, 0x7ffe4002, 0x40024002, 0x40024002, 0x40024002, 0x7ffe4002, 0x00000000, // ICON_WINDOW + 0x09100000, 0x09f00910, 0x09100910, 0x00000910, 0x24a2779e, 0x27a224a2, 0x709e20a2, 0x00000000, // ICON_HIDPI + 0x3ff00000, 0x201c2010, 0x2a842e84, 0x2e842a84, 0x2ba42004, 0x2aa42aa4, 0x20042ba4, 0x00003ffc, // ICON_FILETYPE_BINARY + 0x00000000, 0x00000000, 0x00120012, 0x4a5e4bd2, 0x485233d2, 0x00004bd2, 0x00000000, 0x00000000, // ICON_HEX + 0x01800000, 0x381c0660, 0x23c42004, 0x23c42044, 0x13c82204, 0x08101008, 0x02400420, 0x00000180, // ICON_SHIELD + 0x007e0000, 0x20023fc2, 0x40227fe2, 0x400a403a, 0x400a400a, 0x400a400a, 0x4008400e, 0x00007ff8, // ICON_FILE_NEW + 0x00000000, 0x0042007e, 0x40027fc2, 0x44024002, 0x5f024402, 0x44024402, 0x7ffe4002, 0x00000000, // ICON_FOLDER_ADD + 0x44220000, 0x12482244, 0xf3cf0000, 0x14280420, 0x48122424, 0x08100810, 0x1ff81008, 0x03c00420, // ICON_ALARM + 0x0aa00000, 0x1ff80aa0, 0x1068700e, 0x1008706e, 0x1008700e, 0x1008700e, 0x0aa01ff8, 0x00000aa0, // ICON_CPU + 0x07e00000, 0x04201db8, 0x04a01c38, 0x04a01d38, 0x04a01d38, 0x04a01d38, 0x04201d38, 0x000007e0, // ICON_ROM + 0x00000000, 0x03c00000, 0x3c382ff0, 0x3c04380c, 0x01800000, 0x03c003c0, 0x00000180, 0x00000000, // ICON_STEP_OVER + 0x01800000, 0x01800180, 0x01800180, 0x03c007e0, 0x00000180, 0x01800000, 0x03c003c0, 0x00000180, // ICON_STEP_INTO + 0x01800000, 0x07e003c0, 0x01800180, 0x01800180, 0x00000180, 0x01800000, 0x03c003c0, 0x00000180, // ICON_STEP_OUT + 0x00000000, 0x0ff003c0, 0x181c1c34, 0x303c301c, 0x30003000, 0x1c301800, 0x03c00ff0, 0x00000000, // ICON_RESTART + 0x00000000, 0x00000000, 0x07e003c0, 0x0ff00ff0, 0x0ff00ff0, 0x03c007e0, 0x00000000, 0x00000000, // ICON_BREAKPOINT_ON + 0x00000000, 0x00000000, 0x042003c0, 0x08100810, 0x08100810, 0x03c00420, 0x00000000, 0x00000000, // ICON_BREAKPOINT_OFF + 0x00000000, 0x00000000, 0x1ff81ff8, 0x1ff80000, 0x00001ff8, 0x1ff81ff8, 0x00000000, 0x00000000, // ICON_BURGER_MENU + 0x00000000, 0x00000000, 0x00880070, 0x0c880088, 0x1e8810f8, 0x3e881288, 0x00000000, 0x00000000, // ICON_CASE_SENSITIVE + 0x00000000, 0x02000000, 0x07000a80, 0x07001fc0, 0x02000a80, 0x00300030, 0x00000000, 0x00000000, // ICON_REG_EXP + 0x00000000, 0x0042007e, 0x40027fc2, 0x40024002, 0x40024002, 0x40024002, 0x7ffe4002, 0x00000000, // ICON_FOLDER + 0x3ff00000, 0x201c2010, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x00003ffc, // ICON_FILE + 0x1ff00000, 0x20082008, 0x17d02fe8, 0x05400ba0, 0x09200540, 0x23881010, 0x2fe827c8, 0x00001ff0, // ICON_SAND_TIMER + 0x01800000, 0x02400240, 0x05a00420, 0x09900990, 0x11881188, 0x21842004, 0x40024182, 0x00003ffc, // ICON_WARNING + 0x7ffe0000, 0x4ff24002, 0x4c324ff2, 0x4f824c02, 0x41824f82, 0x41824002, 0x40024182, 0x00007ffe, // ICON_HELP_BOX + 0x7ffe0000, 0x41824002, 0x40024182, 0x41824182, 0x41824182, 0x41824182, 0x40024182, 0x00007ffe, // ICON_INFO_BOX + 0x01800000, 0x04200240, 0x10080810, 0x7bde2004, 0x0a500a50, 0x08500bd0, 0x08100850, 0x00000ff0, // ICON_PRIORITY + 0x01800000, 0x18180660, 0x80016006, 0x98196006, 0x99996666, 0x19986666, 0x01800660, 0x00000000, // ICON_LAYERS_ISO + 0x07fe0000, 0x1c020402, 0x74021402, 0x54025402, 0x54025402, 0x500857fe, 0x40205ff8, 0x00007fe0, // ICON_LAYERS2 + 0x0ffe0000, 0x3ffa0802, 0x7fea200a, 0x402a402a, 0x422a422a, 0x422e422a, 0x40384e28, 0x00007fe0, // ICON_MLAYERS + 0x0ffe0000, 0x3ffa0802, 0x7fea200a, 0x402a402a, 0x5b2a512a, 0x512e552a, 0x40385128, 0x00007fe0, // ICON_MAPS + 0x04200000, 0x1cf00c60, 0x11f019f0, 0x0f3807b8, 0x1e3c0f3c, 0x1c1c1e1c, 0x1e3c1c1c, 0x00000f70, // ICON_HOT + 0x00000000, 0x20803f00, 0x2a202e40, 0x20082e10, 0x08021004, 0x02040402, 0x00900108, 0x00000060, // ICON_LABEL + 0x00000000, 0x042007e0, 0x47e27c3e, 0x4ffa4002, 0x47fa4002, 0x4ffa4002, 0x7ffe4002, 0x00000000, // ICON_NAME_ID + 0x7fe00000, 0x402e4020, 0x43ce5e0a, 0x40504078, 0x438e4078, 0x402e5e0a, 0x7fe04020, 0x00000000, // ICON_SLICING + 0x00000000, 0x40027ffe, 0x47c24002, 0x55425d42, 0x55725542, 0x50125552, 0x10105016, 0x00001ff0, // ICON_MANUAL_CONTROL + 0x7ffe0000, 0x43c24002, 0x48124422, 0x500a500a, 0x500a500a, 0x44224812, 0x400243c2, 0x00007ffe, // ICON_COLLISION + 0x03c00000, 0x10080c30, 0x21842184, 0x4ff24182, 0x41824ff2, 0x21842184, 0x0c301008, 0x000003c0, // ICON_CIRCLE_ADD + 0x03c00000, 0x1ff80ff0, 0x3e7c3e7c, 0x700e7e7e, 0x7e7e700e, 0x3e7c3e7c, 0x0ff01ff8, 0x000003c0, // ICON_CIRCLE_ADD_FILL + 0x03c00000, 0x10080c30, 0x21842184, 0x41824182, 0x40024182, 0x21842184, 0x0c301008, 0x000003c0, // ICON_CIRCLE_WARNING + 0x03c00000, 0x1ff80ff0, 0x3e7c3e7c, 0x7e7e7e7e, 0x7ffe7e7e, 0x3e7c3e7c, 0x0ff01ff8, 0x000003c0, // ICON_CIRCLE_WARNING_FILL + 0x00000000, 0x10041ffc, 0x10841004, 0x13e41084, 0x10841084, 0x10041004, 0x00001ffc, 0x00000000, // ICON_BOX_MORE + 0x00000000, 0x1ffc1ffc, 0x1f7c1ffc, 0x1c1c1f7c, 0x1f7c1f7c, 0x1ffc1ffc, 0x00001ffc, 0x00000000, // ICON_BOX_MORE_FILL + 0x00000000, 0x1ffc1ffc, 0x1ffc1ffc, 0x1c1c1ffc, 0x1ffc1ffc, 0x1ffc1ffc, 0x00001ffc, 0x00000000, // ICON_BOX_MINUS + 0x00000000, 0x10041ffc, 0x10041004, 0x13e41004, 0x10041004, 0x10041004, 0x00001ffc, 0x00000000, // ICON_BOX_MINUS_FILL + 0x07fe0000, 0x055606aa, 0x7ff606aa, 0x55766eba, 0x55766eaa, 0x55606ffe, 0x55606aa0, 0x00007fe0, // ICON_UNION + 0x07fe0000, 0x04020402, 0x7fe20402, 0x456246a2, 0x456246a2, 0x402047fe, 0x40204020, 0x00007fe0, // ICON_INTERSECTION + 0x07fe0000, 0x055606aa, 0x7ff606aa, 0x4436442a, 0x4436442a, 0x402047fe, 0x40204020, 0x00007fe0, // ICON_DIFFERENCE + 0x03c00000, 0x10080c30, 0x20042004, 0x60064002, 0x47e2581a, 0x20042004, 0x0c301008, 0x000003c0, // ICON_SPHERE + 0x03e00000, 0x08080410, 0x0c180808, 0x08080be8, 0x08080808, 0x08080808, 0x04100808, 0x000003e0, // ICON_CYLINDER + 0x00800000, 0x01400140, 0x02200220, 0x04100410, 0x08080808, 0x1c1c13e4, 0x08081004, 0x000007f0, // ICON_CONE + 0x00000000, 0x07e00000, 0x20841918, 0x40824082, 0x40824082, 0x19182084, 0x000007e0, 0x00000000, // ICON_ELLIPSOID + 0x00000000, 0x00000000, 0x20041ff8, 0x40024002, 0x40024002, 0x1ff82004, 0x00000000, 0x00000000, // ICON_CAPSULE + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_250 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_251 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_252 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_253 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_254 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_255 +}; + +// NOTE: A pointer to current icons array should be defined +static unsigned int *guiIconsPtr = guiIcons; + +#endif // !RAYGUI_NO_ICONS && !RAYGUI_CUSTOM_ICONS + +#ifndef RAYGUI_ICON_SIZE + #define RAYGUI_ICON_SIZE 0 +#endif + +// WARNING: Those values define the total size of the style data array, +// if changed, previous saved styles could become incompatible +#define RAYGUI_MAX_CONTROLS 16 // Maximum number of controls +#define RAYGUI_MAX_PROPS_BASE 16 // Maximum number of base properties +#define RAYGUI_MAX_PROPS_EXTENDED 8 // Maximum number of extended properties + +//---------------------------------------------------------------------------------- +// Module Types and Structures Definition +//---------------------------------------------------------------------------------- +// Gui control property style color element +typedef enum { BORDER = 0, BASE, TEXT, OTHER } GuiPropertyElement; + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +static GuiState guiState = STATE_NORMAL; // Gui global state, if !STATE_NORMAL, forces defined state + +static Font guiFont = { 0 }; // Gui current font (WARNING: highly coupled to raylib) +static bool guiLocked = false; // Gui lock state (no inputs processed) +static float guiAlpha = 1.0f; // Gui controls transparency + +static unsigned int guiIconScale = 1; // Gui icon default scale (if icons enabled) + +static bool guiTooltip = false; // Tooltip enabled/disabled +static const char *guiTooltipPtr = NULL; // Tooltip string pointer (string provided by user) + +static bool guiControlExclusiveMode = false; // Gui control exclusive mode (no inputs processed except current control) +static Rectangle guiControlExclusiveRec = { 0 }; // Gui control exclusive bounds rectangle, used as an unique identifier + +static int textBoxCursorIndex = 0; // Cursor index, shared by all GuiTextBox*() +//static int blinkCursorFrameCounter = 0; // Frame counter for cursor blinking +static int autoCursorCounter = 0; // Frame counter for automatic repeated cursor movement on key-down (cooldown and delay) + +//---------------------------------------------------------------------------------- +// Style data array for all gui style properties (allocated on data segment by default) +// +// NOTE 1: First set of BASE properties are generic to all controls but could be individually +// overwritten per control, first set of EXTENDED properties are generic to all controls and +// can not be overwritten individually but custom EXTENDED properties can be used by control +// +// NOTE 2: A new style set could be loaded over this array using GuiLoadStyle(), +// but default gui style could always be recovered with GuiLoadStyleDefault() +// +// guiStyle size is by default: 16*(16 + 8) = 384*4 = 1536 bytes = 1.5 KB +//---------------------------------------------------------------------------------- +static unsigned int guiStyle[RAYGUI_MAX_CONTROLS*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED)] = { 0 }; + +static bool guiStyleLoaded = false; // Style loaded flag for lazy style initialization + +//---------------------------------------------------------------------------------- +// Standalone Mode Functions Declaration +// +// NOTE: raygui depend on some raylib input and drawing functions +// To use raygui as standalone library, below functions must be defined by the user +//---------------------------------------------------------------------------------- +#if defined(RAYGUI_STANDALONE) + +#define KEY_RIGHT 262 +#define KEY_LEFT 263 +#define KEY_DOWN 264 +#define KEY_UP 265 +#define KEY_BACKSPACE 259 +#define KEY_ENTER 257 + +#define MOUSE_LEFT_BUTTON 0 + +// Input required functions +//------------------------------------------------------------------------------- +static Vector2 GetMousePosition(void); +static float GetMouseWheelMove(void); +static bool IsMouseButtonDown(int button); +static bool IsMouseButtonPressed(int button); +static bool IsMouseButtonReleased(int button); + +static bool IsKeyDown(int key); +static bool IsKeyPressed(int key); +static int GetCharPressed(void); // -- GuiTextBox(), GuiValueBox() +//------------------------------------------------------------------------------- + +// Drawing required functions +//------------------------------------------------------------------------------- +static void DrawRectangle(int x, int y, int width, int height, Color color); // -- GuiDrawRectangle() +static void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4); // -- GuiColorPicker() +//------------------------------------------------------------------------------- + +// Text required functions +//------------------------------------------------------------------------------- +static Font GetFontDefault(void); // -- GuiLoadStyleDefault() +static Font LoadFontEx(const char *fileName, int fontSize, int *codepoints, int codepointCount); // -- GuiLoadStyle(), load font + +static Texture2D LoadTextureFromImage(Image image); // -- GuiLoadStyle(), required to load texture from embedded font atlas image +static void SetShapesTexture(Texture2D tex, Rectangle rec); // -- GuiLoadStyle(), required to set shapes rec to font white rec (optimization) + +static char *LoadFileText(const char *fileName); // -- GuiLoadStyle(), required to load charset data +static void UnloadFileText(char *text); // -- GuiLoadStyle(), required to unload charset data + +static const char *GetDirectoryPath(const char *filePath); // -- GuiLoadStyle(), required to find charset/font file from text .rgs + +static int *LoadCodepoints(const char *text, int *count); // -- GuiLoadStyle(), required to load required font codepoints list +static void UnloadCodepoints(int *codepoints); // -- GuiLoadStyle(), required to unload codepoints list + +static unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize); // -- GuiLoadStyle() +//------------------------------------------------------------------------------- + +// raylib functions already implemented in raygui +//------------------------------------------------------------------------------- +static Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value +static int ColorToInt(Color color); // Returns hexadecimal value for a Color +static bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle +static const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed' +static const char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings +static int TextToInteger(const char *text); // Get integer value from text +static float TextToFloat(const char *text); // Get float value from text + +static int GetCodepointNext(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded text +static const char *CodepointToUTF8(int codepoint, int *byteSize); // Encode codepoint into UTF-8 text (char array size returned as parameter) + +static void DrawRectangleGradientV(int posX, int posY, int width, int height, Color color1, Color color2); // Draw rectangle vertical gradient +//------------------------------------------------------------------------------- + +#endif // RAYGUI_STANDALONE + +//---------------------------------------------------------------------------------- +// Module Internal Functions Declaration +//---------------------------------------------------------------------------------- +static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize); // Load style from memory (binary only) + +static Rectangle GetTextBounds(int control, Rectangle bounds); // Get text bounds considering control bounds +static const char *GetTextIcon(const char *text, int *iconId); // Get text icon if provided and move text cursor + +static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, Color tint); // Gui draw text using default font +static void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor, Color color); // Gui draw rectangle using default raygui style + +static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow); // Split controls text into multiple strings +static Vector3 ConvertHSVtoRGB(Vector3 hsv); // Convert color data from HSV to RGB +static Vector3 ConvertRGBtoHSV(Vector3 rgb); // Convert color data from RGB to HSV + +static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue); // Scroll bar control, used by GuiScrollPanel() +static void GuiTooltip(Rectangle controlRec); // Draw tooltip using control rec position + +static Color GuiFade(Color color, float alpha); // Fade color by an alpha factor + +//---------------------------------------------------------------------------------- +// Gui Setup Functions Definition +//---------------------------------------------------------------------------------- +// Enable gui global state +// NOTE: Checking for STATE_DISABLED to avoid messing custom global state setups +void GuiEnable(void) { if (guiState == STATE_DISABLED) guiState = STATE_NORMAL; } + +// Disable gui global state +// NOTE: Checking for STATE_NORMAL to avoid messing custom global state setups +void GuiDisable(void) { if (guiState == STATE_NORMAL) guiState = STATE_DISABLED; } + +// Lock gui global state +void GuiLock(void) { guiLocked = true; } + +// Unlock gui global state +void GuiUnlock(void) { guiLocked = false; } + +// Check if gui is locked (global state) +bool GuiIsLocked(void) { return guiLocked; } + +// Set gui controls alpha global state +void GuiSetAlpha(float alpha) +{ + if (alpha < 0.0f) alpha = 0.0f; + else if (alpha > 1.0f) alpha = 1.0f; + + guiAlpha = alpha; +} + +// Set gui state (global state) +void GuiSetState(int state) { guiState = (GuiState)state; } + +// Get gui state (global state) +int GuiGetState(void) { return guiState; } + +// Set custom gui font +// NOTE: Font loading/unloading is external to raygui +void GuiSetFont(Font font) +{ + if (font.texture.id > 0) + { + // NOTE: If a font is tried to be set but default style has not been lazily loaded first, + // it will be overwritten, so default style loading needs to be forced first + if (!guiStyleLoaded) GuiLoadStyleDefault(); + + guiFont = font; + } +} + +// Get custom gui font +Font GuiGetFont(void) +{ + return guiFont; +} + +// Set control style property value +void GuiSetStyle(int control, int property, int value) +{ + if (!guiStyleLoaded) GuiLoadStyleDefault(); + guiStyle[control*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED) + property] = value; + + // Default properties are propagated to all controls + if ((control == 0) && (property < RAYGUI_MAX_PROPS_BASE)) + { + for (int i = 1; i < RAYGUI_MAX_CONTROLS; i++) guiStyle[i*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED) + property] = value; + } +} + +// Get control style property value +int GuiGetStyle(int control, int property) +{ + if (!guiStyleLoaded) GuiLoadStyleDefault(); + return guiStyle[control*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED) + property]; +} + +//---------------------------------------------------------------------------------- +// Gui Controls Functions Definition +//---------------------------------------------------------------------------------- + +// Window Box control +int GuiWindowBox(Rectangle bounds, const char *title) +{ + // Window title bar height (including borders) + // NOTE: This define is also used by GuiMessageBox() and GuiTextInputBox() + #if !defined(RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT) + #define RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT 24 + #endif + + #if !defined(RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT) + #define RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT 18 + #endif + + int result = 0; + //GuiState state = guiState; + + int statusBarHeight = RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT; + int statusBorderWidth = GuiGetStyle(STATUSBAR, BORDER_WIDTH); + + Rectangle statusBar = { bounds.x, bounds.y, bounds.width, (float)statusBarHeight }; + if (bounds.height < statusBarHeight*2.0f) bounds.height = statusBarHeight*2.0f; + + const float vPadding = statusBarHeight/2.0f - RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT/2.0f; + Rectangle windowPanel = { bounds.x, bounds.y + (float)statusBarHeight - (float)statusBorderWidth, bounds.width, bounds.height - (float)statusBarHeight + (float)statusBorderWidth }; + Rectangle closeButtonRec = { statusBar.x + statusBar.width - (float)statusBorderWidth - RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT - vPadding, + statusBar.y + vPadding, RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT, RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT }; + + // Update control + //-------------------------------------------------------------------- + // NOTE: Logic is directly managed by button + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + GuiPanel(windowPanel, NULL); // Draw window base + GuiStatusBar(statusBar, title); // Draw window header as status bar + + // Draw window close button + int tempBorderWidth = GuiGetStyle(BUTTON, BORDER_WIDTH); + int tempTextAlignment = GuiGetStyle(BUTTON, TEXT_ALIGNMENT); + GuiSetStyle(BUTTON, BORDER_WIDTH, 1); + GuiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); +#if defined(RAYGUI_NO_ICONS) + result = GuiButton(closeButtonRec, "x"); +#else + result = GuiButton(closeButtonRec, GuiIconText(ICON_CROSS_SMALL, NULL)); +#endif + GuiSetStyle(BUTTON, BORDER_WIDTH, tempBorderWidth); + GuiSetStyle(BUTTON, TEXT_ALIGNMENT, tempTextAlignment); + //-------------------------------------------------------------------- + + return result; // Window close button clicked: result = 1 +} + +// Group Box control with text name +int GuiGroupBox(Rectangle bounds, const char *text) +{ + #if !defined(RAYGUI_GROUPBOX_LINE_THICK) + #define RAYGUI_GROUPBOX_LINE_THICK 1 + #endif + + int result = 0; + GuiState state = guiState; + + // Draw control + //-------------------------------------------------------------------- + GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y, RAYGUI_GROUPBOX_LINE_THICK, bounds.height }, 0, BLANK, GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? (int)BORDER_COLOR_DISABLED : (int)LINE_COLOR))); + GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + bounds.height - 1, bounds.width, RAYGUI_GROUPBOX_LINE_THICK }, 0, BLANK, GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? (int)BORDER_COLOR_DISABLED : (int)LINE_COLOR))); + GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x + bounds.width - 1, bounds.y, RAYGUI_GROUPBOX_LINE_THICK, bounds.height }, 0, BLANK, GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? (int)BORDER_COLOR_DISABLED : (int)LINE_COLOR))); + + GuiLine(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y - GuiGetStyle(DEFAULT, TEXT_SIZE)/2, bounds.width, (float)GuiGetStyle(DEFAULT, TEXT_SIZE) }, text); + //-------------------------------------------------------------------- + + return result; +} + +// Line control +int GuiLine(Rectangle bounds, const char *text) +{ + #if !defined(RAYGUI_LINE_MARGIN_TEXT) + #define RAYGUI_LINE_MARGIN_TEXT 12 + #endif + #if !defined(RAYGUI_LINE_TEXT_PADDING) + #define RAYGUI_LINE_TEXT_PADDING 4 + #endif + + int result = 0; + GuiState state = guiState; + + Color color = GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? (int)BORDER_COLOR_DISABLED : (int)LINE_COLOR)); + + // Draw control + //-------------------------------------------------------------------- + if (text == NULL) GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + bounds.height/2, bounds.width, 1 }, 0, BLANK, color); + else + { + Rectangle textBounds = { 0 }; + textBounds.width = (float)GuiGetTextWidth(text) + 2; + textBounds.height = bounds.height; + textBounds.x = bounds.x + RAYGUI_LINE_MARGIN_TEXT; + textBounds.y = bounds.y; + + // Draw line with embedded text label: "--- text --------------" + GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + bounds.height/2, RAYGUI_LINE_MARGIN_TEXT - RAYGUI_LINE_TEXT_PADDING, 1 }, 0, BLANK, color); + GuiDrawText(text, textBounds, TEXT_ALIGN_LEFT, color); + GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x + 12 + textBounds.width + 4, bounds.y + bounds.height/2, bounds.width - textBounds.width - RAYGUI_LINE_MARGIN_TEXT - RAYGUI_LINE_TEXT_PADDING, 1 }, 0, BLANK, color); + } + //-------------------------------------------------------------------- + + return result; +} + +// Panel control +int GuiPanel(Rectangle bounds, const char *text) +{ + #if !defined(RAYGUI_PANEL_BORDER_WIDTH) + #define RAYGUI_PANEL_BORDER_WIDTH 1 + #endif + + int result = 0; + GuiState state = guiState; + + // Text will be drawn as a header bar (if provided) + Rectangle statusBar = { bounds.x, bounds.y, bounds.width, (float)RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT }; + if ((text != NULL) && (bounds.height < RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT*2.0f)) bounds.height = RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT*2.0f; + + if (text != NULL) + { + // Move panel bounds after the header bar + bounds.y += (float)RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - 1; + bounds.height -= (float)RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - 1; + } + + // Draw control + //-------------------------------------------------------------------- + if (text != NULL) GuiStatusBar(statusBar, text); // Draw panel header as status bar + + GuiDrawRectangle(bounds, RAYGUI_PANEL_BORDER_WIDTH, GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? (int)BORDER_COLOR_DISABLED : (int)LINE_COLOR)), + GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? (int)BASE_COLOR_DISABLED : (int)BACKGROUND_COLOR))); + //-------------------------------------------------------------------- + + return result; +} + +// Tab Bar control +// NOTE: Using GuiToggle() for the TABS +int GuiTabBar(Rectangle bounds, const char **text, int count, int *active) +{ + #define RAYGUI_TABBAR_ITEM_WIDTH 148 + + int result = -1; + //GuiState state = guiState; + + Rectangle tabBounds = { bounds.x, bounds.y, RAYGUI_TABBAR_ITEM_WIDTH, bounds.height }; + + if (*active < 0) *active = 0; + else if (*active > count - 1) *active = count - 1; + + int offsetX = 0; // Required in case tabs go out of screen + offsetX = (*active + 2)*RAYGUI_TABBAR_ITEM_WIDTH - GetScreenWidth(); + if (offsetX < 0) offsetX = 0; + + bool toggle = false; // Required for individual toggles + + // Draw control + //-------------------------------------------------------------------- + for (int i = 0; i < count; i++) + { + tabBounds.x = bounds.x + (RAYGUI_TABBAR_ITEM_WIDTH + 4)*i - offsetX; + + if (tabBounds.x < GetScreenWidth()) + { + // Draw tabs as toggle controls + int textAlignment = GuiGetStyle(TOGGLE, TEXT_ALIGNMENT); + int textPadding = GuiGetStyle(TOGGLE, TEXT_PADDING); + GuiSetStyle(TOGGLE, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); + GuiSetStyle(TOGGLE, TEXT_PADDING, 8); + + if (i == (*active)) + { + toggle = true; + GuiToggle(tabBounds, text[i], &toggle); + } + else + { + toggle = false; + GuiToggle(tabBounds, text[i], &toggle); + if (toggle) *active = i; + } + + // Close tab with middle mouse button pressed + if (CheckCollisionPointRec(GUI_POINTER_POSITION, tabBounds) && IsMouseButtonPressed(MOUSE_MIDDLE_BUTTON)) result = i; + + GuiSetStyle(TOGGLE, TEXT_PADDING, textPadding); + GuiSetStyle(TOGGLE, TEXT_ALIGNMENT, textAlignment); + + // Draw tab close button + // NOTE: Only draw close button for current tab: if (CheckCollisionPointRec(mousePosition, tabBounds)) + int tempBorderWidth = GuiGetStyle(BUTTON, BORDER_WIDTH); + int tempTextAlignment = GuiGetStyle(BUTTON, TEXT_ALIGNMENT); + GuiSetStyle(BUTTON, BORDER_WIDTH, 1); + GuiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); +#if defined(RAYGUI_NO_ICONS) + if (GuiButton(RAYGUI_CLITERAL(Rectangle){ tabBounds.x + tabBounds.width - 14 - 5, tabBounds.y + 5, 14, 14 }, "x")) result = i; +#else + if (GuiButton(RAYGUI_CLITERAL(Rectangle){ tabBounds.x + tabBounds.width - 14 - 5, tabBounds.y + 5, 14, 14 }, GuiIconText(ICON_CROSS_SMALL, NULL))) result = i; +#endif + GuiSetStyle(BUTTON, BORDER_WIDTH, tempBorderWidth); + GuiSetStyle(BUTTON, TEXT_ALIGNMENT, tempTextAlignment); + } + } + + // Draw tab-bar bottom line + GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + bounds.height - 1, bounds.width, 1 }, 0, BLANK, GetColor(GuiGetStyle(TOGGLE, BORDER_COLOR_NORMAL))); + //-------------------------------------------------------------------- + + return result; // Return as result the current TAB closing requested +} + +// Scroll Panel control +int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector2 *scroll, Rectangle *view) +{ + #define RAYGUI_MIN_SCROLLBAR_WIDTH 40 + #define RAYGUI_MIN_SCROLLBAR_HEIGHT 40 + #define RAYGUI_MIN_MOUSE_WHEEL_SPEED 20 + + int result = 0; + GuiState state = guiState; + + Rectangle temp = { 0 }; + if (view == NULL) view = &temp; + + Vector2 scrollPos = { 0.0f, 0.0f }; + if (scroll != NULL) scrollPos = *scroll; + + // Text will be drawn as a header bar (if provided) + Rectangle statusBar = { bounds.x, bounds.y, bounds.width, (float)RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT }; + if (bounds.height < RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT*2.0f) bounds.height = RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT*2.0f; + + if (text != NULL) + { + // Move panel bounds after the header bar + bounds.y += (float)RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - 1; + bounds.height -= (float)RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT + 1; + } + + bool hasHorizontalScrollBar = (content.width > bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH))? true : false; + bool hasVerticalScrollBar = (content.height > bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH))? true : false; + + // Recheck to account for the other scrollbar being visible + if (!hasHorizontalScrollBar) hasHorizontalScrollBar = (hasVerticalScrollBar && (content.width > (bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH))))? true : false; + if (!hasVerticalScrollBar) hasVerticalScrollBar = (hasHorizontalScrollBar && (content.height > (bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH))))? true : false; + + int horizontalScrollBarWidth = hasHorizontalScrollBar? GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH) : 0; + int verticalScrollBarWidth = hasVerticalScrollBar? GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH) : 0; + Rectangle horizontalScrollBar = { + (float)((GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)bounds.x + verticalScrollBarWidth : (float)bounds.x) + GuiGetStyle(DEFAULT, BORDER_WIDTH), + (float)bounds.y + bounds.height - horizontalScrollBarWidth - GuiGetStyle(DEFAULT, BORDER_WIDTH), + (float)bounds.width - verticalScrollBarWidth - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH), + (float)horizontalScrollBarWidth + }; + Rectangle verticalScrollBar = { + (float)((GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)bounds.x + GuiGetStyle(DEFAULT, BORDER_WIDTH) : (float)bounds.x + bounds.width - verticalScrollBarWidth - GuiGetStyle(DEFAULT, BORDER_WIDTH)), + (float)bounds.y + GuiGetStyle(DEFAULT, BORDER_WIDTH), + (float)verticalScrollBarWidth, + (float)bounds.height - horizontalScrollBarWidth - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) + }; + + // Make sure scroll bars have a minimum width/height + if (horizontalScrollBar.width < RAYGUI_MIN_SCROLLBAR_WIDTH) horizontalScrollBar.width = RAYGUI_MIN_SCROLLBAR_WIDTH; + if (verticalScrollBar.height < RAYGUI_MIN_SCROLLBAR_HEIGHT) verticalScrollBar.height = RAYGUI_MIN_SCROLLBAR_HEIGHT; + + // Calculate view area (area without the scrollbars) + *view = (GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? + RAYGUI_CLITERAL(Rectangle){ bounds.x + verticalScrollBarWidth + GuiGetStyle(DEFAULT, BORDER_WIDTH), bounds.y + GuiGetStyle(DEFAULT, BORDER_WIDTH), bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - verticalScrollBarWidth, bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - horizontalScrollBarWidth } : + RAYGUI_CLITERAL(Rectangle){ bounds.x + GuiGetStyle(DEFAULT, BORDER_WIDTH), bounds.y + GuiGetStyle(DEFAULT, BORDER_WIDTH), bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - verticalScrollBarWidth, bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - horizontalScrollBarWidth }; + + // Clip view area to the actual content size + if (view->width > content.width) view->width = content.width; + if (view->height > content.height) view->height = content.height; + + float horizontalMin = hasHorizontalScrollBar? ((GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)-verticalScrollBarWidth : 0) - (float)GuiGetStyle(DEFAULT, BORDER_WIDTH) : (((float)GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)-verticalScrollBarWidth : 0) - (float)GuiGetStyle(DEFAULT, BORDER_WIDTH); + float horizontalMax = hasHorizontalScrollBar? content.width - bounds.width + (float)verticalScrollBarWidth + GuiGetStyle(DEFAULT, BORDER_WIDTH) - (((float)GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)verticalScrollBarWidth : 0) : (float)-GuiGetStyle(DEFAULT, BORDER_WIDTH); + float verticalMin = hasVerticalScrollBar? 0.0f : -1.0f; + float verticalMax = hasVerticalScrollBar? content.height - bounds.height + (float)horizontalScrollBarWidth + (float)GuiGetStyle(DEFAULT, BORDER_WIDTH) : (float)-GuiGetStyle(DEFAULT, BORDER_WIDTH); + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked) + { + Vector2 mousePoint = GUI_POINTER_POSITION; + + // Check button state + if (CheckCollisionPointRec(mousePoint, bounds)) + { + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; + else state = STATE_FOCUSED; + +#if defined(SUPPORT_SCROLLBAR_KEY_INPUT) + if (hasHorizontalScrollBar) + { + if (GUI_KEY_DOWN(KEY_RIGHT)) scrollPos.x -= GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + if (GUI_KEY_DOWN(KEY_LEFT)) scrollPos.x += GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + } + + if (hasVerticalScrollBar) + { + if (GUI_KEY_DOWN(KEY_DOWN)) scrollPos.y -= GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + if (GUI_KEY_DOWN(KEY_UP)) scrollPos.y += GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + } +#endif + float scrollDelta = GUI_SCROLL_DELTA; + + // Set scrolling speed with mouse wheel based on ratio between bounds and content + Vector2 scrollSpeed = { content.width/bounds.width, content.height/bounds.height }; + if (scrollSpeed.x < RAYGUI_MIN_MOUSE_WHEEL_SPEED) scrollSpeed.x = RAYGUI_MIN_MOUSE_WHEEL_SPEED; + if (scrollSpeed.y < RAYGUI_MIN_MOUSE_WHEEL_SPEED) scrollSpeed.y = RAYGUI_MIN_MOUSE_WHEEL_SPEED; + + // Horizontal and vertical scrolling with mouse wheel + if (hasHorizontalScrollBar && (GUI_KEY_DOWN(KEY_LEFT_CONTROL) || GUI_KEY_DOWN(KEY_LEFT_SHIFT))) scrollPos.x += scrollDelta*scrollSpeed.x; + else scrollPos.y += scrollDelta*scrollSpeed.y; // Vertical scroll + } + } + + // Normalize scroll values + if (scrollPos.x > -horizontalMin) scrollPos.x = -horizontalMin; + if (scrollPos.x < -horizontalMax) scrollPos.x = -horizontalMax; + if (scrollPos.y > -verticalMin) scrollPos.y = -verticalMin; + if (scrollPos.y < -verticalMax) scrollPos.y = -verticalMax; + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + if (text != NULL) GuiStatusBar(statusBar, text); // Draw panel header as status bar + + GuiDrawRectangle(bounds, 0, BLANK, GetColor(GuiGetStyle(DEFAULT, BACKGROUND_COLOR))); // Draw background + + // Save size of the scrollbar slider + const int slider = GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE); + + // Draw horizontal scrollbar if visible + if (hasHorizontalScrollBar) + { + // Change scrollbar slider size to show the diff in size between the content width and the widget width + GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, (int)(((bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - verticalScrollBarWidth)/(int)content.width)*((int)bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - verticalScrollBarWidth))); + scrollPos.x = (float)-GuiScrollBar(horizontalScrollBar, (int)-scrollPos.x, (int)horizontalMin, (int)horizontalMax); + } + else scrollPos.x = 0.0f; + + // Draw vertical scrollbar if visible + if (hasVerticalScrollBar) + { + // Change scrollbar slider size to show the diff in size between the content height and the widget height + GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, (int)(((bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - horizontalScrollBarWidth)/(int)content.height)*((int)bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - horizontalScrollBarWidth))); + scrollPos.y = (float)-GuiScrollBar(verticalScrollBar, (int)-scrollPos.y, (int)verticalMin, (int)verticalMax); + } + else scrollPos.y = 0.0f; + + // Draw detail corner rectangle if both scroll bars are visible + if (hasHorizontalScrollBar && hasVerticalScrollBar) + { + Rectangle corner = { (GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (bounds.x + GuiGetStyle(DEFAULT, BORDER_WIDTH) + 2) : (horizontalScrollBar.x + horizontalScrollBar.width + 2), verticalScrollBar.y + verticalScrollBar.height + 2, (float)horizontalScrollBarWidth - 4, (float)verticalScrollBarWidth - 4 }; + GuiDrawRectangle(corner, 0, BLANK, GetColor(GuiGetStyle(LISTVIEW, TEXT + (state*3)))); + } + + // Draw scrollbar lines depending on current state + GuiDrawRectangle(bounds, GuiGetStyle(LISTVIEW, BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER + (state*3))), BLANK); + + // Set scrollbar slider size back to the way it was before + GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, slider); + //-------------------------------------------------------------------- + + if (scroll != NULL) *scroll = scrollPos; + + return result; +} + +// Label control +int GuiLabel(Rectangle bounds, const char *text) +{ + int result = 0; + GuiState state = guiState; + + // Update control + //-------------------------------------------------------------------- + //... + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + GuiDrawText(text, GetTextBounds(LABEL, bounds), GuiGetStyle(LABEL, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); + //-------------------------------------------------------------------- + + return result; +} + +// Button control, returns true when clicked +int GuiButton(Rectangle bounds, const char *text) +{ + int result = 0; + GuiState state = guiState; + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + { + Vector2 mousePoint = GUI_POINTER_POSITION; + + // Check button state + if (CheckCollisionPointRec(mousePoint, bounds)) + { + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; + else state = STATE_FOCUSED; + + if (GUI_BUTTON_RELEASED) result = 1; + } + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + GuiDrawRectangle(bounds, GuiGetStyle(BUTTON, BORDER_WIDTH), GetColor(GuiGetStyle(BUTTON, BORDER + (state*3))), GetColor(GuiGetStyle(BUTTON, BASE + (state*3)))); + GuiDrawText(text, GetTextBounds(BUTTON, bounds), GuiGetStyle(BUTTON, TEXT_ALIGNMENT), GetColor(GuiGetStyle(BUTTON, TEXT + (state*3)))); + + if (state == STATE_FOCUSED) GuiTooltip(bounds); + //------------------------------------------------------------------ + + return result; // Button pressed: result = 1 +} + +// Label button control +int GuiLabelButton(Rectangle bounds, const char *text) +{ + GuiState state = guiState; + bool pressed = false; + + // NOTE: Force bounds.width to be all text + float textWidth = (float)GuiGetTextWidth(text); + if ((bounds.width - 2*GuiGetStyle(LABEL, BORDER_WIDTH) - 2*GuiGetStyle(LABEL, TEXT_PADDING)) < textWidth) bounds.width = textWidth + 2*GuiGetStyle(LABEL, BORDER_WIDTH) + 2*GuiGetStyle(LABEL, TEXT_PADDING) + 2; + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + { + Vector2 mousePoint = GUI_POINTER_POSITION; + + // Check checkbox state + if (CheckCollisionPointRec(mousePoint, bounds)) + { + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; + else state = STATE_FOCUSED; + + if (GUI_BUTTON_RELEASED) pressed = true; + } + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + GuiDrawText(text, GetTextBounds(LABEL, bounds), GuiGetStyle(LABEL, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); + //-------------------------------------------------------------------- + + return pressed; +} + +// Toggle Button control +int GuiToggle(Rectangle bounds, const char *text, bool *active) +{ + int result = 0; + GuiState state = guiState; + + bool temp = false; + if (active == NULL) active = &temp; + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + { + Vector2 mousePoint = GUI_POINTER_POSITION; + + // Check toggle button state + if (CheckCollisionPointRec(mousePoint, bounds)) + { + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; + else if (GUI_BUTTON_RELEASED) + { + state = STATE_NORMAL; + *active = !(*active); + } + else state = STATE_FOCUSED; + } + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + if (state == STATE_NORMAL) + { + GuiDrawRectangle(bounds, GuiGetStyle(TOGGLE, BORDER_WIDTH), GetColor(GuiGetStyle(TOGGLE, ((*active)? BORDER_COLOR_PRESSED : (BORDER + state*3)))), GetColor(GuiGetStyle(TOGGLE, ((*active)? BASE_COLOR_PRESSED : (BASE + state*3))))); + GuiDrawText(text, GetTextBounds(TOGGLE, bounds), GuiGetStyle(TOGGLE, TEXT_ALIGNMENT), GetColor(GuiGetStyle(TOGGLE, ((*active)? TEXT_COLOR_PRESSED : (TEXT + state*3))))); + } + else + { + GuiDrawRectangle(bounds, GuiGetStyle(TOGGLE, BORDER_WIDTH), GetColor(GuiGetStyle(TOGGLE, BORDER + state*3)), GetColor(GuiGetStyle(TOGGLE, BASE + state*3))); + GuiDrawText(text, GetTextBounds(TOGGLE, bounds), GuiGetStyle(TOGGLE, TEXT_ALIGNMENT), GetColor(GuiGetStyle(TOGGLE, TEXT + state*3))); + } + + if (state == STATE_FOCUSED) GuiTooltip(bounds); + //-------------------------------------------------------------------- + + return result; +} + +// Toggle Group control +int GuiToggleGroup(Rectangle bounds, const char *text, int *active) +{ + #if !defined(RAYGUI_TOGGLEGROUP_MAX_ITEMS) + #define RAYGUI_TOGGLEGROUP_MAX_ITEMS 32 + #endif + + int result = 0; + float initBoundsX = bounds.x; + + int temp = 0; + if (active == NULL) active = &temp; + + bool toggle = false; // Required for individual toggles + + // Get substrings items from text (items pointers) + int rows[RAYGUI_TOGGLEGROUP_MAX_ITEMS] = { 0 }; + int itemCount = 0; + const char **items = GuiTextSplit(text, ';', &itemCount, rows); + + int prevRow = rows[0]; + + for (int i = 0; i < itemCount; i++) + { + if (prevRow != rows[i]) + { + bounds.x = initBoundsX; + bounds.y += (bounds.height + GuiGetStyle(TOGGLE, GROUP_PADDING)); + prevRow = rows[i]; + } + + if (i == (*active)) + { + toggle = true; + GuiToggle(bounds, items[i], &toggle); + } + else + { + toggle = false; + GuiToggle(bounds, items[i], &toggle); + if (toggle) *active = i; + } + + bounds.x += (bounds.width + GuiGetStyle(TOGGLE, GROUP_PADDING)); + } + + return result; +} + +// Toggle Slider control extended +int GuiToggleSlider(Rectangle bounds, const char *text, int *active) +{ + int result = 0; + GuiState state = guiState; + + int temp = 0; + if (active == NULL) active = &temp; + + //bool toggle = false; // Required for individual toggles + + // Get substrings items from text (items pointers) + int itemCount = 0; + const char **items = NULL; + + if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL); + + Rectangle slider = { + 0, // Calculated later depending on the active toggle + bounds.y + GuiGetStyle(SLIDER, BORDER_WIDTH) + GuiGetStyle(SLIDER, SLIDER_PADDING), + (bounds.width - 2*GuiGetStyle(SLIDER, BORDER_WIDTH) - (itemCount + 1)*GuiGetStyle(SLIDER, SLIDER_PADDING))/itemCount, + bounds.height - 2*GuiGetStyle(SLIDER, BORDER_WIDTH) - 2*GuiGetStyle(SLIDER, SLIDER_PADDING) }; + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked) + { + Vector2 mousePoint = GUI_POINTER_POSITION; + + if (CheckCollisionPointRec(mousePoint, bounds)) + { + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; + else if (GUI_BUTTON_RELEASED) + { + state = STATE_PRESSED; + (*active)++; + result = 1; + } + else state = STATE_FOCUSED; + } + + if ((*active) && (state != STATE_FOCUSED)) state = STATE_PRESSED; + } + + if (*active >= itemCount) *active = 0; + slider.x = bounds.x + GuiGetStyle(SLIDER, BORDER_WIDTH) + (*active + 1)*GuiGetStyle(SLIDER, SLIDER_PADDING) + (*active)*slider.width; + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + GuiDrawRectangle(bounds, GuiGetStyle(SLIDER, BORDER_WIDTH), GetColor(GuiGetStyle(TOGGLE, BORDER + (state*3))), + GetColor(GuiGetStyle(TOGGLE, BASE_COLOR_NORMAL))); + + // Draw internal slider + if (state == STATE_NORMAL) GuiDrawRectangle(slider, 0, BLANK, GetColor(GuiGetStyle(SLIDER, BASE_COLOR_PRESSED))); + else if (state == STATE_FOCUSED) GuiDrawRectangle(slider, 0, BLANK, GetColor(GuiGetStyle(SLIDER, BASE_COLOR_FOCUSED))); + else if (state == STATE_PRESSED) GuiDrawRectangle(slider, 0, BLANK, GetColor(GuiGetStyle(SLIDER, BASE_COLOR_PRESSED))); + + // Draw text in slider + if (text != NULL) + { + Rectangle textBounds = { 0 }; + textBounds.width = (float)GuiGetTextWidth(text); + textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE); + textBounds.x = slider.x + slider.width/2 - textBounds.width/2; + textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2; + + GuiDrawText(items[*active], textBounds, GuiGetStyle(TOGGLE, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(TOGGLE, TEXT + (state*3))), guiAlpha)); + } + //-------------------------------------------------------------------- + + return result; +} + +// Check Box control, returns 1 when state changed +int GuiCheckBox(Rectangle bounds, const char *text, bool *checked) +{ + int result = 0; + GuiState state = guiState; + + bool temp = false; + if (checked == NULL) checked = &temp; + + Rectangle textBounds = { 0 }; + + if (text != NULL) + { + textBounds.width = (float)GuiGetTextWidth(text) + 2; + textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE); + textBounds.x = bounds.x + bounds.width + GuiGetStyle(CHECKBOX, TEXT_PADDING); + textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2; + if (GuiGetStyle(CHECKBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT) textBounds.x = bounds.x - textBounds.width - GuiGetStyle(CHECKBOX, TEXT_PADDING); + } + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + { + Vector2 mousePoint = GUI_POINTER_POSITION; + + Rectangle totalBounds = { + (GuiGetStyle(CHECKBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT)? textBounds.x : bounds.x, + bounds.y, + bounds.width + textBounds.width + GuiGetStyle(CHECKBOX, TEXT_PADDING), + bounds.height, + }; + + // Check checkbox state + if (CheckCollisionPointRec(mousePoint, totalBounds)) + { + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; + else state = STATE_FOCUSED; + + if (GUI_BUTTON_RELEASED) + { + *checked = !(*checked); + result = 1; + } + } + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + GuiDrawRectangle(bounds, GuiGetStyle(CHECKBOX, BORDER_WIDTH), GetColor(GuiGetStyle(CHECKBOX, BORDER + (state*3))), BLANK); + + if (*checked) + { + Rectangle check = { bounds.x + GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, CHECK_PADDING), + bounds.y + GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, CHECK_PADDING), + bounds.width - 2*(GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, CHECK_PADDING)), + bounds.height - 2*(GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, CHECK_PADDING)) }; + GuiDrawRectangle(check, 0, BLANK, GetColor(GuiGetStyle(CHECKBOX, TEXT + state*3))); + } + + GuiDrawText(text, textBounds, (GuiGetStyle(CHECKBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT)? TEXT_ALIGN_LEFT : TEXT_ALIGN_RIGHT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); + //-------------------------------------------------------------------- + + return result; +} + +// Combo Box control +int GuiComboBox(Rectangle bounds, const char *text, int *active) +{ + int result = 0; + GuiState state = guiState; + + int temp = 0; + if (active == NULL) active = &temp; + + bounds.width -= (GuiGetStyle(COMBOBOX, COMBO_BUTTON_WIDTH) + GuiGetStyle(COMBOBOX, COMBO_BUTTON_SPACING)); + + Rectangle selector = { (float)bounds.x + bounds.width + GuiGetStyle(COMBOBOX, COMBO_BUTTON_SPACING), + (float)bounds.y, (float)GuiGetStyle(COMBOBOX, COMBO_BUTTON_WIDTH), (float)bounds.height }; + + // Get substrings items from text (items pointers, lengths and count) + int itemCount = 0; + const char **items = GuiTextSplit(text, ';', &itemCount, NULL); + + if (*active < 0) *active = 0; + else if (*active > (itemCount - 1)) *active = itemCount - 1; + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked && (itemCount > 1) && !guiControlExclusiveMode) + { + Vector2 mousePoint = GUI_POINTER_POSITION; + + if (CheckCollisionPointRec(mousePoint, bounds) || + CheckCollisionPointRec(mousePoint, selector)) + { + if (GUI_BUTTON_PRESSED) + { + *active += 1; + if (*active >= itemCount) *active = 0; // Cyclic combobox + } + + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; + else state = STATE_FOCUSED; + } + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + // Draw combo box main + GuiDrawRectangle(bounds, GuiGetStyle(COMBOBOX, BORDER_WIDTH), GetColor(GuiGetStyle(COMBOBOX, BORDER + (state*3))), GetColor(GuiGetStyle(COMBOBOX, BASE + (state*3)))); + GuiDrawText(items[*active], GetTextBounds(COMBOBOX, bounds), GuiGetStyle(COMBOBOX, TEXT_ALIGNMENT), GetColor(GuiGetStyle(COMBOBOX, TEXT + (state*3)))); + + // Draw selector using a custom button + // NOTE: BORDER_WIDTH and TEXT_ALIGNMENT forced values + int tempBorderWidth = GuiGetStyle(BUTTON, BORDER_WIDTH); + int tempTextAlign = GuiGetStyle(BUTTON, TEXT_ALIGNMENT); + GuiSetStyle(BUTTON, BORDER_WIDTH, 1); + GuiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); + + GuiButton(selector, TextFormat("%i/%i", *active + 1, itemCount)); + + GuiSetStyle(BUTTON, TEXT_ALIGNMENT, tempTextAlign); + GuiSetStyle(BUTTON, BORDER_WIDTH, tempBorderWidth); + //-------------------------------------------------------------------- + + return result; +} + +// Dropdown Box control +// NOTE: Returns mouse click +int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMode) +{ + int result = 0; + GuiState state = guiState; + + int temp = 0; + if (active == NULL) active = &temp; + + int itemSelected = *active; + int itemFocused = -1; + + int direction = 0; // Dropdown box open direction: down (default) + if (GuiGetStyle(DROPDOWNBOX, DROPDOWN_ROLL_UP) == 1) direction = 1; // Up + + // Get substrings items from text (items pointers, lengths and count) + int itemCount = 0; + const char **items = GuiTextSplit(text, ';', &itemCount, NULL); + + Rectangle boundsOpen = bounds; + boundsOpen.height = (itemCount + 1)*(bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING)); + if (direction == 1) boundsOpen.y -= itemCount*(bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING)) + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING); + + Rectangle itemBounds = bounds; + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && (editMode || !guiLocked) && (itemCount > 1) && !guiControlExclusiveMode) + { + Vector2 mousePoint = GUI_POINTER_POSITION; + + if (editMode) + { + state = STATE_PRESSED; + + // Check if mouse has been pressed or released outside limits + if (!CheckCollisionPointRec(mousePoint, boundsOpen)) + { + if (GUI_BUTTON_PRESSED || GUI_BUTTON_RELEASED) result = 1; + } + + // Check if already selected item has been pressed again + if (CheckCollisionPointRec(mousePoint, bounds) && GUI_BUTTON_PRESSED) result = 1; + + // Check focused and selected item + for (int i = 0; i < itemCount; i++) + { + // Update item rectangle y position for next item + if (direction == 0) itemBounds.y += (bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING)); + else itemBounds.y -= (bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING)); + + if (CheckCollisionPointRec(mousePoint, itemBounds)) + { + itemFocused = i; + if (GUI_BUTTON_RELEASED) + { + itemSelected = i; + result = 1; // Item selected + } + break; + } + } + + itemBounds = bounds; + } + else + { + if (CheckCollisionPointRec(mousePoint, bounds)) + { + if (GUI_BUTTON_PRESSED) + { + result = 1; + state = STATE_PRESSED; + } + else state = STATE_FOCUSED; + } + } + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + if (editMode) GuiPanel(boundsOpen, NULL); + + GuiDrawRectangle(bounds, GuiGetStyle(DROPDOWNBOX, BORDER_WIDTH), GetColor(GuiGetStyle(DROPDOWNBOX, BORDER + state*3)), GetColor(GuiGetStyle(DROPDOWNBOX, BASE + state*3))); + GuiDrawText(items[itemSelected], GetTextBounds(DROPDOWNBOX, bounds), GuiGetStyle(DROPDOWNBOX, TEXT_ALIGNMENT), GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + state*3))); + + if (editMode) + { + // Draw visible items + for (int i = 0; i < itemCount; i++) + { + // Update item rectangle y position for next item + if (direction == 0) itemBounds.y += (bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING)); + else itemBounds.y -= (bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING)); + + if (i == itemSelected) + { + GuiDrawRectangle(itemBounds, GuiGetStyle(DROPDOWNBOX, BORDER_WIDTH), GetColor(GuiGetStyle(DROPDOWNBOX, BORDER_COLOR_PRESSED)), GetColor(GuiGetStyle(DROPDOWNBOX, BASE_COLOR_PRESSED))); + GuiDrawText(items[i], GetTextBounds(DROPDOWNBOX, itemBounds), GuiGetStyle(DROPDOWNBOX, TEXT_ALIGNMENT), GetColor(GuiGetStyle(DROPDOWNBOX, TEXT_COLOR_PRESSED))); + } + else if (i == itemFocused) + { + GuiDrawRectangle(itemBounds, GuiGetStyle(DROPDOWNBOX, BORDER_WIDTH), GetColor(GuiGetStyle(DROPDOWNBOX, BORDER_COLOR_FOCUSED)), GetColor(GuiGetStyle(DROPDOWNBOX, BASE_COLOR_FOCUSED))); + GuiDrawText(items[i], GetTextBounds(DROPDOWNBOX, itemBounds), GuiGetStyle(DROPDOWNBOX, TEXT_ALIGNMENT), GetColor(GuiGetStyle(DROPDOWNBOX, TEXT_COLOR_FOCUSED))); + } + else GuiDrawText(items[i], GetTextBounds(DROPDOWNBOX, itemBounds), GuiGetStyle(DROPDOWNBOX, TEXT_ALIGNMENT), GetColor(GuiGetStyle(DROPDOWNBOX, TEXT_COLOR_NORMAL))); + } + } + + if (!GuiGetStyle(DROPDOWNBOX, DROPDOWN_ARROW_HIDDEN)) + { + // Draw arrows (using icon if available) +#if defined(RAYGUI_NO_ICONS) + GuiDrawText("v", RAYGUI_CLITERAL(Rectangle){ bounds.x + bounds.width - GuiGetStyle(DROPDOWNBOX, ARROW_PADDING), bounds.y + bounds.height/2 - 2, 10, 10 }, + TEXT_ALIGN_CENTER, GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + (state*3)))); +#else + GuiDrawText(direction? "#121#" : "#120#", RAYGUI_CLITERAL(Rectangle){ bounds.x + bounds.width - GuiGetStyle(DROPDOWNBOX, ARROW_PADDING), bounds.y + bounds.height/2 - 6, 10, 10 }, + TEXT_ALIGN_CENTER, GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + (state*3)))); // ICON_ARROW_DOWN_FILL +#endif + } + //-------------------------------------------------------------------- + + *active = itemSelected; + + // TODO: Use result to return more internal states: mouse-press out-of-bounds, mouse-press over selected-item... + return result; // Mouse click: result = 1 +} + +// Text Box control +// NOTE: Returns true on ENTER pressed (useful for data validation) +int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) +{ + #if !defined(RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN) + #define RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN 20 // Frames to wait for autocursor movement + #endif + #if !defined(RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY) + #define RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY 1 // Frames delay for autocursor movement + #endif + + int result = 0; + GuiState state = guiState; + + bool multiline = false; // TODO: Consider multiline text input + int wrapMode = GuiGetStyle(DEFAULT, TEXT_WRAP_MODE); + + Rectangle textBounds = GetTextBounds(TEXTBOX, bounds); + int textLength = (text != NULL)? (int)strlen(text) : 0; // Get current text length + int thisCursorIndex = textBoxCursorIndex; + if (thisCursorIndex > textLength) thisCursorIndex = textLength; + int textWidth = GuiGetTextWidth(text) - GuiGetTextWidth(text + thisCursorIndex); + int textIndexOffset = 0; // Text index offset to start drawing in the box + + // Cursor rectangle + // NOTE: Position X value should be updated + Rectangle cursor = { + textBounds.x + textWidth + GuiGetStyle(DEFAULT, TEXT_SPACING), + textBounds.y + textBounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE), + 2, + (float)GuiGetStyle(DEFAULT, TEXT_SIZE)*2 + }; + + if (cursor.height >= bounds.height) cursor.height = bounds.height - GuiGetStyle(TEXTBOX, BORDER_WIDTH)*2; + if (cursor.y < (bounds.y + GuiGetStyle(TEXTBOX, BORDER_WIDTH))) cursor.y = bounds.y + GuiGetStyle(TEXTBOX, BORDER_WIDTH); + + // Mouse cursor rectangle + // NOTE: Initialized outside of screen + Rectangle mouseCursor = cursor; + mouseCursor.x = -1; + mouseCursor.width = 1; + + // Blink-cursor frame counter + //if (!autoCursorMode) blinkCursorFrameCounter++; + //else blinkCursorFrameCounter = 0; + + // Update control + //-------------------------------------------------------------------- + // WARNING: Text editing is only supported under certain conditions: + if ((state != STATE_DISABLED) && // Control not disabled + !GuiGetStyle(TEXTBOX, TEXT_READONLY) && // TextBox not on read-only mode + !guiLocked && // Gui not locked + !guiControlExclusiveMode && // No gui slider on dragging + (wrapMode == TEXT_WRAP_NONE)) // No wrap mode + { + Vector2 mousePosition = GUI_POINTER_POSITION; + + if (editMode) + { + // GLOBAL: Auto-cursor movement logic + // NOTE: Keystrokes are handled repeatedly when button is held down for some time + if (GUI_KEY_DOWN(KEY_LEFT) || GUI_KEY_DOWN(KEY_RIGHT) || GUI_KEY_DOWN(KEY_UP) || GUI_KEY_DOWN(KEY_DOWN) || GUI_KEY_DOWN(KEY_BACKSPACE) || GUI_KEY_DOWN(KEY_DELETE)) autoCursorCounter++; + else autoCursorCounter = 0; + + bool autoCursorShouldTrigger = (autoCursorCounter > RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN) && ((autoCursorCounter % RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY) == 0); + + state = STATE_PRESSED; + + if (textBoxCursorIndex > textLength) textBoxCursorIndex = textLength; + + // If text does not fit in the textbox and current cursor position is out of bounds, + // adding an index offset to text for drawing only what requires depending on cursor + while (textWidth >= textBounds.width) + { + int nextCodepointSize = 0; + GetCodepointNext(text + textIndexOffset, &nextCodepointSize); + + textIndexOffset += nextCodepointSize; + + textWidth = GuiGetTextWidth(text + textIndexOffset) - GuiGetTextWidth(text + textBoxCursorIndex); + } + + int codepoint = GUI_INPUT_KEY; // Get Unicode codepoint + if (multiline && GUI_KEY_PRESSED(KEY_ENTER)) codepoint = (int)'\n'; + + // Encode codepoint as UTF-8 + int codepointSize = 0; + const char *charEncoded = CodepointToUTF8(codepoint, &codepointSize); + + // Handle text paste action + if (GUI_KEY_PRESSED(KEY_V) && (GUI_KEY_DOWN(KEY_LEFT_CONTROL) || GUI_KEY_DOWN(KEY_RIGHT_CONTROL))) + { + const char *pasteText = GetClipboardText(); + if (pasteText != NULL) + { + int pasteLength = 0; + int pasteCodepoint; + int pasteCodepointSize; + + // Count how many codepoints to copy, stopping at the first unwanted control character + while (true) + { + pasteCodepoint = GetCodepointNext(pasteText + pasteLength, &pasteCodepointSize); + if (textLength + pasteLength + pasteCodepointSize >= textSize) break; + if (!(multiline && (pasteCodepoint == (int)'\n')) && !(pasteCodepoint >= 32)) break; + pasteLength += pasteCodepointSize; + } + + if (pasteLength > 0) + { + // Move forward data from cursor position + for (int i = textLength + pasteLength; i > textBoxCursorIndex; i--) text[i] = text[i - pasteLength]; + + // Paste data in at cursor + for (int i = 0; i < pasteLength; i++) text[textBoxCursorIndex + i] = pasteText[i]; + + textBoxCursorIndex += pasteLength; + textLength += pasteLength; + text[textLength] = '\0'; + } + } + } + else if (((multiline && (codepoint == (int)'\n')) || (codepoint >= 32)) && ((textLength + codepointSize) < textSize)) + { + // Adding codepoint to text, at current cursor position + + // Move forward data from cursor position + for (int i = (textLength + codepointSize); i > textBoxCursorIndex; i--) text[i] = text[i - codepointSize]; + + // Add new codepoint in current cursor position + for (int i = 0; i < codepointSize; i++) text[textBoxCursorIndex + i] = charEncoded[i]; + + textBoxCursorIndex += codepointSize; + textLength += codepointSize; + + // Make sure text last character is EOL + text[textLength] = '\0'; + } + + // Move cursor to start + if ((textLength > 0) && GUI_KEY_PRESSED(KEY_HOME)) textBoxCursorIndex = 0; + + // Move cursor to end + if ((textLength > textBoxCursorIndex) && GUI_KEY_PRESSED(KEY_END)) textBoxCursorIndex = textLength; + + // Delete related codepoints from text, after current cursor position + if ((textLength > textBoxCursorIndex) && GUI_KEY_PRESSED(KEY_DELETE) && (GUI_KEY_DOWN(KEY_LEFT_CONTROL) || GUI_KEY_DOWN(KEY_RIGHT_CONTROL))) + { + int offset = textBoxCursorIndex; + int accCodepointSize = 0; + int nextCodepointSize; + int nextCodepoint; + + // Check characters of the same type to delete (either ASCII punctuation or anything non-whitespace) + // Not using isalnum() since it only works on ASCII characters + nextCodepoint = GetCodepointNext(text + offset, &nextCodepointSize); + bool puctuation = ispunct(nextCodepoint & 0xff); + while (offset < textLength) + { + if ((puctuation && !ispunct(nextCodepoint & 0xff)) || (!puctuation && (isspace(nextCodepoint & 0xff) || ispunct(nextCodepoint & 0xff)))) + break; + offset += nextCodepointSize; + accCodepointSize += nextCodepointSize; + nextCodepoint = GetCodepointNext(text + offset, &nextCodepointSize); + } + + // Check whitespace to delete (ASCII only) + while (offset < textLength) + { + if (!isspace(nextCodepoint & 0xff)) break; + + offset += nextCodepointSize; + accCodepointSize += nextCodepointSize; + nextCodepoint = GetCodepointNext(text + offset, &nextCodepointSize); + } + + // Move text after cursor forward (including final null terminator) + for (int i = offset; i <= textLength; i++) text[i - accCodepointSize] = text[i]; + + textLength -= accCodepointSize; + } + + else if ((textLength > textBoxCursorIndex) && (GUI_KEY_PRESSED(KEY_DELETE) || (GUI_KEY_DOWN(KEY_DELETE) && autoCursorShouldTrigger))) + { + // Delete single codepoint from text, after current cursor position + + int nextCodepointSize = 0; + GetCodepointNext(text + textBoxCursorIndex, &nextCodepointSize); + + // Move text after cursor forward (including final null terminator) + for (int i = textBoxCursorIndex + nextCodepointSize; i <= textLength; i++) text[i - nextCodepointSize] = text[i]; + + textLength -= nextCodepointSize; + } + + // Delete related codepoints from text, before current cursor position + if ((textBoxCursorIndex > 0) && GUI_KEY_PRESSED(KEY_BACKSPACE) && (GUI_KEY_DOWN(KEY_LEFT_CONTROL) || GUI_KEY_DOWN(KEY_RIGHT_CONTROL))) + { + int offset = textBoxCursorIndex; + int accCodepointSize = 0; + int prevCodepointSize = 0; + int prevCodepoint = 0; + + // Check whitespace to delete (ASCII only) + while (offset > 0) + { + prevCodepoint = GetCodepointPrevious(text + offset, &prevCodepointSize); + if (!isspace(prevCodepoint & 0xff)) break; + + offset -= prevCodepointSize; + accCodepointSize += prevCodepointSize; + } + + // Check characters of the same type to delete (either ASCII punctuation or anything non-whitespace) + // Not using isalnum() since it only works on ASCII characters + bool puctuation = ispunct(prevCodepoint & 0xff); + while (offset > 0) + { + prevCodepoint = GetCodepointPrevious(text + offset, &prevCodepointSize); + if ((puctuation && !ispunct(prevCodepoint & 0xff)) || (!puctuation && (isspace(prevCodepoint & 0xff) || ispunct(prevCodepoint & 0xff)))) break; + + offset -= prevCodepointSize; + accCodepointSize += prevCodepointSize; + } + + // Move text after cursor forward (including final null terminator) + for (int i = textBoxCursorIndex; i <= textLength; i++) text[i - accCodepointSize] = text[i]; + + textLength -= accCodepointSize; + textBoxCursorIndex -= accCodepointSize; + } + + else if ((textBoxCursorIndex > 0) && (GUI_KEY_PRESSED(KEY_BACKSPACE) || (GUI_KEY_DOWN(KEY_BACKSPACE) && autoCursorShouldTrigger))) + { + // Delete single codepoint from text, before current cursor position + + int prevCodepointSize = 0; + + GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize); + + // Move text after cursor forward (including final null terminator) + for (int i = textBoxCursorIndex; i <= textLength; i++) text[i - prevCodepointSize] = text[i]; + + textLength -= prevCodepointSize; + textBoxCursorIndex -= prevCodepointSize; + } + + // Move cursor position with keys + if ((textBoxCursorIndex > 0) && GUI_KEY_PRESSED(KEY_LEFT) && (GUI_KEY_DOWN(KEY_LEFT_CONTROL) || GUI_KEY_DOWN(KEY_RIGHT_CONTROL))) + { + int offset = textBoxCursorIndex; + //int accCodepointSize = 0; + int prevCodepointSize = 0; + int prevCodepoint = 0; + + // Check whitespace to skip (ASCII only) + while (offset > 0) + { + prevCodepoint = GetCodepointPrevious(text + offset, &prevCodepointSize); + if (!isspace(prevCodepoint & 0xff)) break; + + offset -= prevCodepointSize; + //accCodepointSize += prevCodepointSize; + } + + // Check characters of the same type to skip (either ASCII punctuation or anything non-whitespace) + // Not using isalnum() since it only works on ASCII characters + bool puctuation = ispunct(prevCodepoint & 0xff); + while (offset > 0) + { + prevCodepoint = GetCodepointPrevious(text + offset, &prevCodepointSize); + if ((puctuation && !ispunct(prevCodepoint & 0xff)) || (!puctuation && (isspace(prevCodepoint & 0xff) || ispunct(prevCodepoint & 0xff)))) break; + + offset -= prevCodepointSize; + //accCodepointSize += prevCodepointSize; + } + + textBoxCursorIndex = offset; + } + else if ((textBoxCursorIndex > 0) && (GUI_KEY_PRESSED(KEY_LEFT) || (GUI_KEY_DOWN(KEY_LEFT) && autoCursorShouldTrigger))) + { + int prevCodepointSize = 0; + GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize); + + textBoxCursorIndex -= prevCodepointSize; + } + else if ((textLength > textBoxCursorIndex) && GUI_KEY_PRESSED(KEY_RIGHT) && (GUI_KEY_DOWN(KEY_LEFT_CONTROL) || GUI_KEY_DOWN(KEY_RIGHT_CONTROL))) + { + int offset = textBoxCursorIndex; + //int accCodepointSize = 0; + int nextCodepointSize; + int nextCodepoint; + + // Check characters of the same type to skip (either ASCII punctuation or anything non-whitespace) + // Not using isalnum() since it only works on ASCII characters + nextCodepoint = GetCodepointNext(text + offset, &nextCodepointSize); + bool puctuation = ispunct(nextCodepoint & 0xff); + while (offset < textLength) + { + if ((puctuation && !ispunct(nextCodepoint & 0xff)) || (!puctuation && (isspace(nextCodepoint & 0xff) || ispunct(nextCodepoint & 0xff)))) break; + + offset += nextCodepointSize; + //accCodepointSize += nextCodepointSize; + nextCodepoint = GetCodepointNext(text + offset, &nextCodepointSize); + } + + // Check whitespace to skip (ASCII only) + while (offset < textLength) + { + if (!isspace(nextCodepoint & 0xff)) break; + + offset += nextCodepointSize; + //accCodepointSize += nextCodepointSize; + nextCodepoint = GetCodepointNext(text + offset, &nextCodepointSize); + } + + textBoxCursorIndex = offset; + } + else if ((textLength > textBoxCursorIndex) && (GUI_KEY_PRESSED(KEY_RIGHT) || (GUI_KEY_DOWN(KEY_RIGHT) && autoCursorShouldTrigger))) + { + int nextCodepointSize = 0; + GetCodepointNext(text + textBoxCursorIndex, &nextCodepointSize); + + textBoxCursorIndex += nextCodepointSize; + } + + // Move cursor position with mouse + if (CheckCollisionPointRec(mousePosition, textBounds)) // Mouse hover text + { + float scaleFactor = (float)GuiGetStyle(DEFAULT, TEXT_SIZE)/(float)guiFont.baseSize; + int codepointIndex = 0; + float glyphWidth = 0.0f; + float widthToMouseX = 0; + int mouseCursorIndex = 0; + + for (int i = textIndexOffset; i < textLength; i += codepointSize) + { + codepoint = GetCodepointNext(&text[i], &codepointSize); + codepointIndex = GetGlyphIndex(guiFont, codepoint); + + if (guiFont.glyphs[codepointIndex].advanceX == 0) glyphWidth = ((float)guiFont.recs[codepointIndex].width*scaleFactor); + else glyphWidth = ((float)guiFont.glyphs[codepointIndex].advanceX*scaleFactor); + + if (mousePosition.x <= (textBounds.x + (widthToMouseX + glyphWidth/2))) + { + mouseCursor.x = textBounds.x + widthToMouseX; + mouseCursorIndex = i; + break; + } + + widthToMouseX += (glyphWidth + (float)GuiGetStyle(DEFAULT, TEXT_SPACING)); + } + + // Check if mouse cursor is at the last position + int textEndWidth = GuiGetTextWidth(text + textIndexOffset); + if (GUI_POINTER_POSITION.x >= (textBounds.x + textEndWidth - glyphWidth/2)) + { + mouseCursor.x = textBounds.x + textEndWidth; + mouseCursorIndex = textLength; + } + + // Place cursor at required index on mouse click + if ((mouseCursor.x >= 0) && GUI_BUTTON_PRESSED) + { + cursor.x = mouseCursor.x; + textBoxCursorIndex = mouseCursorIndex; + } + } + else mouseCursor.x = -1; + + // Recalculate cursor position.y depending on textBoxCursorIndex + cursor.x = bounds.x + GuiGetStyle(TEXTBOX, TEXT_PADDING) + GuiGetTextWidth(text + textIndexOffset) - GuiGetTextWidth(text + textBoxCursorIndex) + GuiGetStyle(DEFAULT, TEXT_SPACING); + //if (multiline) cursor.y = GetTextLines() + + // Finish text editing on ENTER or mouse click outside bounds + if ((!multiline && GUI_KEY_PRESSED(KEY_ENTER)) || + (!CheckCollisionPointRec(mousePosition, bounds) && GUI_BUTTON_PRESSED)) + { + textBoxCursorIndex = 0; // GLOBAL: Reset the shared cursor index + autoCursorCounter = 0; // GLOBAL: Reset counter for repeated keystrokes + result = 1; + } + } + else + { + if (CheckCollisionPointRec(mousePosition, bounds)) + { + state = STATE_FOCUSED; + + if (GUI_BUTTON_PRESSED) + { + textBoxCursorIndex = textLength; // GLOBAL: Place cursor index to the end of current text + autoCursorCounter = 0; // GLOBAL: Reset counter for repeated keystrokes + result = 1; + } + } + } + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + if (state == STATE_PRESSED) + { + GuiDrawRectangle(bounds, GuiGetStyle(TEXTBOX, BORDER_WIDTH), GetColor(GuiGetStyle(TEXTBOX, BORDER + (state*3))), GetColor(GuiGetStyle(TEXTBOX, BASE_COLOR_PRESSED))); + } + else if (state == STATE_DISABLED) + { + GuiDrawRectangle(bounds, GuiGetStyle(TEXTBOX, BORDER_WIDTH), GetColor(GuiGetStyle(TEXTBOX, BORDER + (state*3))), GetColor(GuiGetStyle(TEXTBOX, BASE_COLOR_DISABLED))); + } + else GuiDrawRectangle(bounds, GuiGetStyle(TEXTBOX, BORDER_WIDTH), GetColor(GuiGetStyle(TEXTBOX, BORDER + (state*3))), BLANK); + + // Draw text considering index offset if required + // NOTE: Text index offset depends on cursor position + GuiDrawText(text + textIndexOffset, textBounds, GuiGetStyle(TEXTBOX, TEXT_ALIGNMENT), GetColor(GuiGetStyle(TEXTBOX, TEXT + (state*3)))); + + // Draw cursor + if (editMode && !GuiGetStyle(TEXTBOX, TEXT_READONLY)) + { + //if (autoCursorMode || ((blinkCursorFrameCounter/40)%2 == 0)) + GuiDrawRectangle(cursor, 0, BLANK, GetColor(GuiGetStyle(TEXTBOX, BORDER_COLOR_PRESSED))); + + // Draw mouse position cursor (if required) + if (mouseCursor.x >= 0) GuiDrawRectangle(mouseCursor, 0, BLANK, GetColor(GuiGetStyle(TEXTBOX, BORDER_COLOR_PRESSED))); + } + else if (state == STATE_FOCUSED) GuiTooltip(bounds); + //-------------------------------------------------------------------- + + return result; // Mouse button pressed: result = 1 +} + +/* +// Text Box control with multiple lines and word-wrap +// NOTE: This text-box is readonly, no editing supported by default +bool GuiTextBoxMulti(Rectangle bounds, char *text, int textSize, bool editMode) +{ + bool pressed = false; + + GuiSetStyle(TEXTBOX, TEXT_READONLY, 1); + GuiSetStyle(DEFAULT, TEXT_WRAP_MODE, TEXT_WRAP_WORD); // WARNING: If wrap mode enabled, text editing is not supported + GuiSetStyle(DEFAULT, TEXT_ALIGNMENT_VERTICAL, TEXT_ALIGN_TOP); + + // TODO: Implement methods to calculate cursor position properly + pressed = GuiTextBox(bounds, text, textSize, editMode); + + GuiSetStyle(DEFAULT, TEXT_ALIGNMENT_VERTICAL, TEXT_ALIGN_MIDDLE); + GuiSetStyle(DEFAULT, TEXT_WRAP_MODE, TEXT_WRAP_NONE); + GuiSetStyle(TEXTBOX, TEXT_READONLY, 0); + + return pressed; +} +*/ + +// Spinner control, returns selected value +int GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode) +{ + int result = 1; + GuiState state = guiState; + + int tempValue = *value; + + Rectangle valueBoxBounds = { + bounds.x + GuiGetStyle(VALUEBOX, SPINNER_BUTTON_WIDTH) + GuiGetStyle(VALUEBOX, SPINNER_BUTTON_SPACING), + bounds.y, + bounds.width - 2*(GuiGetStyle(VALUEBOX, SPINNER_BUTTON_WIDTH) + GuiGetStyle(VALUEBOX, SPINNER_BUTTON_SPACING)), bounds.height }; + Rectangle leftButtonBound = { (float)bounds.x, (float)bounds.y, (float)GuiGetStyle(VALUEBOX, SPINNER_BUTTON_WIDTH), (float)bounds.height }; + Rectangle rightButtonBound = { (float)bounds.x + bounds.width - GuiGetStyle(VALUEBOX, SPINNER_BUTTON_WIDTH), (float)bounds.y, + (float)GuiGetStyle(VALUEBOX, SPINNER_BUTTON_WIDTH), (float)bounds.height }; + + Rectangle textBounds = { 0 }; + if (text != NULL) + { + textBounds.width = (float)GuiGetTextWidth(text) + 2; + textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE); + textBounds.x = bounds.x + bounds.width + GuiGetStyle(VALUEBOX, TEXT_PADDING); + textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2; + if (GuiGetStyle(VALUEBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT) textBounds.x = bounds.x - textBounds.width - GuiGetStyle(VALUEBOX, TEXT_PADDING); + } + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + { + Vector2 mousePoint = GUI_POINTER_POSITION; + + // Check spinner state + if (CheckCollisionPointRec(mousePoint, bounds)) + { + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; + else state = STATE_FOCUSED; + } + } + +#if defined(RAYGUI_NO_ICONS) + if (GuiButton(leftButtonBound, "<")) tempValue--; + if (GuiButton(rightButtonBound, ">")) tempValue++; +#else + if (GuiButton(leftButtonBound, GuiIconText(ICON_ARROW_LEFT_FILL, NULL))) tempValue--; + if (GuiButton(rightButtonBound, GuiIconText(ICON_ARROW_RIGHT_FILL, NULL))) tempValue++; +#endif + + if (!editMode) + { + if (tempValue < minValue) tempValue = minValue; + if (tempValue > maxValue) tempValue = maxValue; + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + result = GuiValueBox(valueBoxBounds, NULL, &tempValue, minValue, maxValue, editMode); + + // Draw value selector custom buttons + // NOTE: BORDER_WIDTH and TEXT_ALIGNMENT forced values + int tempBorderWidth = GuiGetStyle(BUTTON, BORDER_WIDTH); + int tempTextAlign = GuiGetStyle(BUTTON, TEXT_ALIGNMENT); + GuiSetStyle(BUTTON, BORDER_WIDTH, GuiGetStyle(VALUEBOX, BORDER_WIDTH)); + GuiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); + + GuiSetStyle(BUTTON, TEXT_ALIGNMENT, tempTextAlign); + GuiSetStyle(BUTTON, BORDER_WIDTH, tempBorderWidth); + + // Draw text label if provided + GuiDrawText(text, textBounds, (GuiGetStyle(VALUEBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT)? TEXT_ALIGN_LEFT : TEXT_ALIGN_RIGHT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); + //-------------------------------------------------------------------- + + *value = tempValue; + return result; +} + +// Value Box control, updates input text with numbers +// NOTE: Requires static variables: frameCounter +int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode) +{ + #if !defined(RAYGUI_VALUEBOX_MAX_CHARS) + #define RAYGUI_VALUEBOX_MAX_CHARS 32 + #endif + + int result = 0; + GuiState state = guiState; + + char textValue[RAYGUI_VALUEBOX_MAX_CHARS + 1] = { 0 }; + snprintf(textValue, RAYGUI_VALUEBOX_MAX_CHARS + 1, "%i", *value); + + Rectangle textBounds = { 0 }; + if (text != NULL) + { + textBounds.width = (float)GuiGetTextWidth(text) + 2; + textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE); + textBounds.x = bounds.x + bounds.width + GuiGetStyle(VALUEBOX, TEXT_PADDING); + textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2; + if (GuiGetStyle(VALUEBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT) textBounds.x = bounds.x - textBounds.width - GuiGetStyle(VALUEBOX, TEXT_PADDING); + } + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + { + Vector2 mousePoint = GUI_POINTER_POSITION; + bool valueHasChanged = false; + + if (editMode) + { + state = STATE_PRESSED; + + int keyCount = (int)strlen(textValue); + + // Add or remove minus symbol + if (GUI_KEY_PRESSED(KEY_MINUS)) + { + if (textValue[0] == '-') + { + for (int i = 0 ; i < keyCount; i++) textValue[i] = textValue[i + 1]; + + keyCount--; + valueHasChanged = true; + } + else if (keyCount < RAYGUI_VALUEBOX_MAX_CHARS) + { + if (keyCount == 0) + { + textValue[0] = '0'; + textValue[1] = '\0'; + keyCount++; + } + + for (int i = keyCount ; i > -1; i--) textValue[i + 1] = textValue[i]; + + textValue[0] = '-'; + keyCount++; + valueHasChanged = true; + } + } + + // Add new digit to text value + if ((keyCount >= 0) && (keyCount < RAYGUI_VALUEBOX_MAX_CHARS) && (GuiGetTextWidth(textValue) < bounds.width)) + { + int key = GUI_INPUT_KEY; + + // Only allow keys in range [48..57] + if ((key >= 48) && (key <= 57)) + { + textValue[keyCount] = (char)key; + keyCount++; + valueHasChanged = true; + } + } + + // Delete text + if ((keyCount > 0) && GUI_KEY_PRESSED(KEY_BACKSPACE)) + { + keyCount--; + textValue[keyCount] = '\0'; + valueHasChanged = true; + } + + if (valueHasChanged) *value = TextToInteger(textValue); + + // NOTE: Values are not clamped until user input finishes + //if (*value > maxValue) *value = maxValue; + //else if (*value < minValue) *value = minValue; + + if ((GUI_KEY_PRESSED(KEY_ENTER) || GUI_KEY_PRESSED(KEY_KP_ENTER)) || (!CheckCollisionPointRec(mousePoint, bounds) && GUI_BUTTON_PRESSED)) + { + if (*value > maxValue) *value = maxValue; + else if (*value < minValue) *value = minValue; + + result = 1; + } + } + else + { + if (*value > maxValue) *value = maxValue; + else if (*value < minValue) *value = minValue; + + if (CheckCollisionPointRec(mousePoint, bounds)) + { + state = STATE_FOCUSED; + if (GUI_BUTTON_PRESSED) result = 1; + } + } + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + Color baseColor = BLANK; + if (state == STATE_PRESSED) baseColor = GetColor(GuiGetStyle(VALUEBOX, BASE_COLOR_PRESSED)); + else if (state == STATE_DISABLED) baseColor = GetColor(GuiGetStyle(VALUEBOX, BASE_COLOR_DISABLED)); + + GuiDrawRectangle(bounds, GuiGetStyle(VALUEBOX, BORDER_WIDTH), GetColor(GuiGetStyle(VALUEBOX, BORDER + (state*3))), baseColor); + GuiDrawText(textValue, GetTextBounds(VALUEBOX, bounds), TEXT_ALIGN_CENTER, GetColor(GuiGetStyle(VALUEBOX, TEXT + (state*3)))); + + // Draw cursor rectangle + if (editMode) + { + // NOTE: ValueBox internal text is always centered + Rectangle cursor = { bounds.x + GuiGetTextWidth(textValue)/2 + bounds.width/2 + 1, + bounds.y + GuiGetStyle(TEXTBOX, BORDER_WIDTH) + 2, + 2, bounds.height - GuiGetStyle(TEXTBOX, BORDER_WIDTH)*2 - 4 }; + if (cursor.height > bounds.height) cursor.height = bounds.height - GuiGetStyle(TEXTBOX, BORDER_WIDTH)*2; + GuiDrawRectangle(cursor, 0, BLANK, GetColor(GuiGetStyle(VALUEBOX, BORDER_COLOR_PRESSED))); + } + + // Draw text label if provided + GuiDrawText(text, textBounds, (GuiGetStyle(VALUEBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT)? TEXT_ALIGN_LEFT : TEXT_ALIGN_RIGHT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); + //-------------------------------------------------------------------- + + return result; +} + +// Floating point Value Box control, updates input val_str with numbers +// NOTE: Requires static variables: frameCounter +int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float *value, bool editMode) +{ + #if !defined(RAYGUI_VALUEBOX_MAX_CHARS) + #define RAYGUI_VALUEBOX_MAX_CHARS 32 + #endif + + int result = 0; + GuiState state = guiState; + + //char textValue[RAYGUI_VALUEBOX_MAX_CHARS + 1] = "\0"; + //snprintf(textValue, sizeof(textValue), "%2.2f", *value); + + Rectangle textBounds = { 0 }; + if (text != NULL) + { + textBounds.width = (float)GuiGetTextWidth(text) + 2; + textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE); + textBounds.x = bounds.x + bounds.width + GuiGetStyle(VALUEBOX, TEXT_PADDING); + textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2; + if (GuiGetStyle(VALUEBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT) textBounds.x = bounds.x - textBounds.width - GuiGetStyle(VALUEBOX, TEXT_PADDING); + } + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + { + Vector2 mousePoint = GUI_POINTER_POSITION; + + bool valueHasChanged = false; + + if (editMode) + { + state = STATE_PRESSED; + + int keyCount = (int)strlen(textValue); + + // Add or remove minus symbol + if (GUI_KEY_PRESSED(KEY_MINUS)) + { + if (textValue[0] == '-') + { + for (int i = 0; i < keyCount; i++) textValue[i] = textValue[i + 1]; + + keyCount--; + valueHasChanged = true; + } + else if (keyCount < (RAYGUI_VALUEBOX_MAX_CHARS - 1)) + { + if (keyCount == 0) + { + textValue[0] = '0'; + textValue[1] = '\0'; + keyCount++; + } + + for (int i = keyCount; i > -1; i--) textValue[i + 1] = textValue[i]; + + textValue[0] = '-'; + keyCount++; + valueHasChanged = true; + } + } + + // Only allow keys in range [48..57] + if (keyCount < RAYGUI_VALUEBOX_MAX_CHARS) + { + if (GuiGetTextWidth(textValue) < bounds.width) + { + int key = GUI_INPUT_KEY; + if (((key >= 48) && (key <= 57)) || + (key == '.') || + ((keyCount == 0) && (key == '+')) || // NOTE: Sign can only be in first position + ((keyCount == 0) && (key == '-'))) + { + textValue[keyCount] = (char)key; + keyCount++; + + valueHasChanged = true; + } + } + } + + // Pressed backspace + if (GUI_KEY_PRESSED(KEY_BACKSPACE)) + { + if (keyCount > 0) + { + keyCount--; + textValue[keyCount] = '\0'; + valueHasChanged = true; + } + } + + if (valueHasChanged) *value = TextToFloat(textValue); + + if ((GUI_KEY_PRESSED(KEY_ENTER) || GUI_KEY_PRESSED(KEY_KP_ENTER)) || (!CheckCollisionPointRec(mousePoint, bounds) && GUI_BUTTON_PRESSED)) result = 1; + } + else + { + if (CheckCollisionPointRec(mousePoint, bounds)) + { + state = STATE_FOCUSED; + if (GUI_BUTTON_PRESSED) result = 1; + } + } + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + Color baseColor = BLANK; + if (state == STATE_PRESSED) baseColor = GetColor(GuiGetStyle(VALUEBOX, BASE_COLOR_PRESSED)); + else if (state == STATE_DISABLED) baseColor = GetColor(GuiGetStyle(VALUEBOX, BASE_COLOR_DISABLED)); + + GuiDrawRectangle(bounds, GuiGetStyle(VALUEBOX, BORDER_WIDTH), GetColor(GuiGetStyle(VALUEBOX, BORDER + (state*3))), baseColor); + GuiDrawText(textValue, GetTextBounds(VALUEBOX, bounds), TEXT_ALIGN_CENTER, GetColor(GuiGetStyle(VALUEBOX, TEXT + (state*3)))); + + // Draw cursor + if (editMode) + { + // NOTE: ValueBox internal text is always centered + Rectangle cursor = {bounds.x + GuiGetTextWidth(textValue)/2 + bounds.width/2 + 1, + bounds.y + 2*GuiGetStyle(VALUEBOX, BORDER_WIDTH), 4, + bounds.height - 4*GuiGetStyle(VALUEBOX, BORDER_WIDTH)}; + GuiDrawRectangle(cursor, 0, BLANK, GetColor(GuiGetStyle(VALUEBOX, BORDER_COLOR_PRESSED))); + } + + // Draw text label if provided + GuiDrawText(text, textBounds, + (GuiGetStyle(VALUEBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT)? TEXT_ALIGN_LEFT : TEXT_ALIGN_RIGHT, + GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); + //-------------------------------------------------------------------- + + return result; +} + +// Slider control with pro parameters +// NOTE: Other GuiSlider*() controls use this one +int GuiSlider(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue) +{ + int result = 0; + GuiState state = guiState; + + float temp = (maxValue - minValue)/2.0f; + if (value == NULL) value = &temp; + float oldValue = *value; + + int sliderWidth = GuiGetStyle(SLIDER, SLIDER_WIDTH); + + Rectangle slider = { bounds.x, bounds.y + GuiGetStyle(SLIDER, BORDER_WIDTH) + GuiGetStyle(SLIDER, SLIDER_PADDING), + 0, bounds.height - 2*GuiGetStyle(SLIDER, BORDER_WIDTH) - 2*GuiGetStyle(SLIDER, SLIDER_PADDING) }; + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked) + { + Vector2 mousePoint = GUI_POINTER_POSITION; + + if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds + { + if (GUI_BUTTON_DOWN) + { + if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) + { + state = STATE_PRESSED; + // Get equivalent value and slider position from mousePosition.x + *value = (maxValue - minValue)*((mousePoint.x - bounds.x - sliderWidth/2)/(bounds.width - sliderWidth)) + minValue; + } + } + else + { + guiControlExclusiveMode = false; + guiControlExclusiveRec = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 }; + } + } + else if (CheckCollisionPointRec(mousePoint, bounds)) + { + if (GUI_BUTTON_DOWN) + { + state = STATE_PRESSED; + guiControlExclusiveMode = true; + guiControlExclusiveRec = bounds; // Store bounds as an identifier when dragging starts + + if (!CheckCollisionPointRec(mousePoint, slider)) + { + // Get equivalent value and slider position from mousePosition.x + *value = (maxValue - minValue)*((mousePoint.x - bounds.x - sliderWidth/2)/(bounds.width - sliderWidth)) + minValue; + } + } + else state = STATE_FOCUSED; + } + + if (*value > maxValue) *value = maxValue; + else if (*value < minValue) *value = minValue; + } + + // Control value change check + if (oldValue == *value) result = 0; + else result = 1; + + // Slider bar limits check + float sliderValue = (((*value - minValue)/(maxValue - minValue))*(bounds.width - sliderWidth - 2*GuiGetStyle(SLIDER, BORDER_WIDTH))); + if (sliderWidth > 0) // Slider + { + slider.x += sliderValue; + slider.width = (float)sliderWidth; + if (slider.x <= (bounds.x + GuiGetStyle(SLIDER, BORDER_WIDTH))) slider.x = bounds.x + GuiGetStyle(SLIDER, BORDER_WIDTH); + else if ((slider.x + slider.width) >= (bounds.x + bounds.width)) slider.x = bounds.x + bounds.width - slider.width - GuiGetStyle(SLIDER, BORDER_WIDTH); + } + else if (sliderWidth == 0) // SliderBar + { + slider.x += GuiGetStyle(SLIDER, BORDER_WIDTH); + slider.width = sliderValue; + if (slider.width > bounds.width) slider.width = bounds.width - 2*GuiGetStyle(SLIDER, BORDER_WIDTH); + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + GuiDrawRectangle(bounds, GuiGetStyle(SLIDER, BORDER_WIDTH), GetColor(GuiGetStyle(SLIDER, BORDER + (state*3))), GetColor(GuiGetStyle(SLIDER, (state != STATE_DISABLED)? BASE_COLOR_NORMAL : BASE_COLOR_DISABLED))); + + // Draw slider internal bar (depends on state) + if (state == STATE_NORMAL) GuiDrawRectangle(slider, 0, BLANK, GetColor(GuiGetStyle(SLIDER, BASE_COLOR_PRESSED))); + else if (state == STATE_FOCUSED) GuiDrawRectangle(slider, 0, BLANK, GetColor(GuiGetStyle(SLIDER, TEXT_COLOR_FOCUSED))); + else if (state == STATE_PRESSED) GuiDrawRectangle(slider, 0, BLANK, GetColor(GuiGetStyle(SLIDER, TEXT_COLOR_PRESSED))); + else if (state == STATE_DISABLED) GuiDrawRectangle(slider, 0, BLANK, GetColor(GuiGetStyle(SLIDER, TEXT_COLOR_DISABLED))); + + // Draw left/right text if provided + if (textLeft != NULL) + { + Rectangle textBounds = { 0 }; + textBounds.width = (float)GuiGetTextWidth(textLeft); + textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE); + textBounds.x = bounds.x - textBounds.width - GuiGetStyle(SLIDER, TEXT_PADDING); + textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2; + + GuiDrawText(textLeft, textBounds, TEXT_ALIGN_RIGHT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); + } + + if (textRight != NULL) + { + Rectangle textBounds = { 0 }; + textBounds.width = (float)GuiGetTextWidth(textRight); + textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE); + textBounds.x = bounds.x + bounds.width + GuiGetStyle(SLIDER, TEXT_PADDING); + textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2; + + GuiDrawText(textRight, textBounds, TEXT_ALIGN_LEFT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); + } + //-------------------------------------------------------------------- + + return result; +} + +// Slider Bar control extended, returns selected value +int GuiSliderBar(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue) +{ + int result = 0; + int preSliderWidth = GuiGetStyle(SLIDER, SLIDER_WIDTH); + GuiSetStyle(SLIDER, SLIDER_WIDTH, 0); + result = GuiSlider(bounds, textLeft, textRight, value, minValue, maxValue); + GuiSetStyle(SLIDER, SLIDER_WIDTH, preSliderWidth); + + return result; +} + +// Progress Bar control extended, shows current progress value +int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue) +{ + int result = 0; + GuiState state = guiState; + + float temp = (maxValue - minValue)/2.0f; + if (value == NULL) value = &temp; + + // Progress bar + Rectangle progress = { bounds.x + GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), + bounds.y + GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) + GuiGetStyle(PROGRESSBAR, PROGRESS_PADDING), 0, + bounds.height - GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) - 2*GuiGetStyle(PROGRESSBAR, PROGRESS_PADDING) -1 }; + + // Update control + //-------------------------------------------------------------------- + if (*value > maxValue) *value = maxValue; + + // WARNING: Working with floats could lead to rounding issues + if ((state != STATE_DISABLED)) progress.width = ((float)*value/(maxValue - minValue))*(bounds.width - 2*GuiGetStyle(PROGRESSBAR, BORDER_WIDTH)); + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + if (state == STATE_DISABLED) + { + GuiDrawRectangle(bounds, GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), GetColor(GuiGetStyle(PROGRESSBAR, BORDER + (state*3))), BLANK); + } + else + { + if (*value > minValue) + { + // Draw progress bar with colored border, more visual + GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y, (int)progress.width + (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_FOCUSED))); + GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + 1, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.height - 2 }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_FOCUSED))); + GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + bounds.height - 1, (int)progress.width + (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_FOCUSED))); + } + else GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.height+GuiGetStyle(PROGRESSBAR, BORDER_WIDTH)-1 }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_NORMAL))); + + if (*value >= maxValue) GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x + progress.width + (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.y, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.height+GuiGetStyle(PROGRESSBAR, BORDER_WIDTH)-1}, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_FOCUSED))); + else + { + // Draw borders not yet reached by value + GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x + (int)progress.width + (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.y, bounds.width - (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) - (int)progress.width - 1, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_NORMAL))); + GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x + (int)progress.width + (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.y + bounds.height - 1, bounds.width - (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) - (int)progress.width - 1, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_NORMAL))); + GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x + bounds.width - (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.y, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.height+GuiGetStyle(PROGRESSBAR, BORDER_WIDTH)-1 }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_NORMAL))); + } + + // Draw slider internal progress bar (depends on state) + GuiDrawRectangle(progress, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BASE_COLOR_PRESSED))); + } + + // Draw left/right text if provided + if (textLeft != NULL) + { + Rectangle textBounds = { 0 }; + textBounds.width = (float)GuiGetTextWidth(textLeft); + textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE); + textBounds.x = bounds.x - textBounds.width - GuiGetStyle(PROGRESSBAR, TEXT_PADDING); + textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2; + + GuiDrawText(textLeft, textBounds, TEXT_ALIGN_RIGHT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); + } + + if (textRight != NULL) + { + Rectangle textBounds = { 0 }; + textBounds.width = (float)GuiGetTextWidth(textRight); + textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE); + textBounds.x = bounds.x + bounds.width + GuiGetStyle(PROGRESSBAR, TEXT_PADDING); + textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2; + + GuiDrawText(textRight, textBounds, TEXT_ALIGN_LEFT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); + } + //-------------------------------------------------------------------- + + return result; +} + +// Status Bar control +int GuiStatusBar(Rectangle bounds, const char *text) +{ + int result = 0; + GuiState state = guiState; + + // Draw control + //-------------------------------------------------------------------- + GuiDrawRectangle(bounds, GuiGetStyle(STATUSBAR, BORDER_WIDTH), GetColor(GuiGetStyle(STATUSBAR, BORDER + (state*3))), GetColor(GuiGetStyle(STATUSBAR, BASE + (state*3)))); + GuiDrawText(text, GetTextBounds(STATUSBAR, bounds), GuiGetStyle(STATUSBAR, TEXT_ALIGNMENT), GetColor(GuiGetStyle(STATUSBAR, TEXT + (state*3)))); + //-------------------------------------------------------------------- + + return result; +} + +// Dummy rectangle control, intended for placeholding +int GuiDummyRec(Rectangle bounds, const char *text) +{ + int result = 0; + GuiState state = guiState; + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + { + Vector2 mousePoint = GUI_POINTER_POSITION; + + // Check button state + if (CheckCollisionPointRec(mousePoint, bounds)) + { + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; + else state = STATE_FOCUSED; + } + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + GuiDrawRectangle(bounds, 0, BLANK, GetColor(GuiGetStyle(DEFAULT, (state != STATE_DISABLED)? BASE_COLOR_NORMAL : BASE_COLOR_DISABLED))); + GuiDrawText(text, GetTextBounds(DEFAULT, bounds), TEXT_ALIGN_CENTER, GetColor(GuiGetStyle(BUTTON, (state != STATE_DISABLED)? TEXT_COLOR_NORMAL : TEXT_COLOR_DISABLED))); + //------------------------------------------------------------------ + + return result; +} + +// List View control +int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *active) +{ + int result = 0; + int itemCount = 0; + const char **items = NULL; + + if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL); + + result = GuiListViewEx(bounds, items, itemCount, scrollIndex, active, NULL); + + return result; +} + +// List View control with extended parameters +int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus) +{ + int result = 0; + GuiState state = guiState; + + int itemFocused = (focus == NULL)? -1 : *focus; + int itemSelected = (active == NULL)? -1 : *active; + + // Check if scroll bar is needed + bool useScrollBar = false; + if ((GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT) + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING))*count > bounds.height) useScrollBar = true; + + // Define base item rectangle [0] + Rectangle itemBounds = { 0 }; + itemBounds.x = bounds.x + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING); + itemBounds.y = bounds.y + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING) + GuiGetStyle(DEFAULT, BORDER_WIDTH); + itemBounds.width = bounds.width - 2*GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING) - GuiGetStyle(DEFAULT, BORDER_WIDTH); + itemBounds.height = (float)GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT); + if (useScrollBar) itemBounds.width -= GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH); + + // Get items on the list + int visibleItems = (int)bounds.height/(GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT) + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING)); + if (visibleItems > count) visibleItems = count; + + int startIndex = (scrollIndex == NULL)? 0 : *scrollIndex; + if ((startIndex < 0) || (startIndex > (count - visibleItems))) startIndex = 0; + int endIndex = startIndex + visibleItems; + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + { + Vector2 mousePoint = GUI_POINTER_POSITION; + + // Check mouse inside list view + if (CheckCollisionPointRec(mousePoint, bounds)) + { + state = STATE_FOCUSED; + + // Check focused and selected item + for (int i = 0; i < visibleItems; i++) + { + if (CheckCollisionPointRec(mousePoint, itemBounds)) + { + itemFocused = startIndex + i; + if (GUI_BUTTON_PRESSED) + { + if (itemSelected == (startIndex + i)) itemSelected = -1; + else itemSelected = startIndex + i; + } + break; + } + + // Update item rectangle y position for next item + itemBounds.y += (GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT) + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING)); + } + + if (useScrollBar) + { + float scrollDelta = GUI_SCROLL_DELTA; + startIndex -= (int)scrollDelta; + + if (startIndex < 0) startIndex = 0; + else if (startIndex > (count - visibleItems)) startIndex = count - visibleItems; + + endIndex = startIndex + visibleItems; + if (endIndex > count) endIndex = count; + } + } + else itemFocused = -1; + + // Reset item rectangle y to [0] + itemBounds.y = bounds.y + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING) + GuiGetStyle(DEFAULT, BORDER_WIDTH); + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + GuiDrawRectangle(bounds, GuiGetStyle(LISTVIEW, BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER + state*3)), GetColor(GuiGetStyle(DEFAULT, BACKGROUND_COLOR))); // Draw background + + // Draw visible items + for (int i = 0; ((i < visibleItems) && (text != NULL)); i++) + { + if (GuiGetStyle(LISTVIEW, LIST_ITEMS_BORDER_NORMAL)) GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, LIST_ITEMS_BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_NORMAL)), BLANK); + + if (state == STATE_DISABLED) + { + if ((startIndex + i) == itemSelected) GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, LIST_ITEMS_BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_DISABLED)), GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_DISABLED))); + + GuiDrawText(text[startIndex + i], GetTextBounds(LISTVIEW, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_DISABLED))); + } + else + { + if (((startIndex + i) == itemSelected) && (active != NULL)) + { + // Draw item selected + GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, LIST_ITEMS_BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_PRESSED)), GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_PRESSED))); + GuiDrawText(text[startIndex + i], GetTextBounds(LISTVIEW, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_PRESSED))); + } + else if (((startIndex + i) == itemFocused)) // && (focus != NULL)) // NOTE: Items focused, despite not returned + { + // Draw item focused + GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, LIST_ITEMS_BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_FOCUSED)), GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_FOCUSED))); + GuiDrawText(text[startIndex + i], GetTextBounds(LISTVIEW, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_FOCUSED))); + } + else + { + // Draw item normal (no rectangle) + GuiDrawText(text[startIndex + i], GetTextBounds(LISTVIEW, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_NORMAL))); + } + } + + // Update item rectangle y position for next item + itemBounds.y += (GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT) + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING)); + } + + if (useScrollBar) + { + Rectangle scrollBarBounds = { + bounds.x + bounds.width - GuiGetStyle(LISTVIEW, BORDER_WIDTH) - GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH), + bounds.y + GuiGetStyle(LISTVIEW, BORDER_WIDTH), (float)GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH), + bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) + }; + + // Calculate percentage of visible items and apply same percentage to scrollbar + float percentVisible = (float)(endIndex - startIndex)/count; + float sliderSize = bounds.height*percentVisible; + + int prevSliderSize = GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE); // Save default slider size + int prevScrollSpeed = GuiGetStyle(SCROLLBAR, SCROLL_SPEED); // Save default scroll speed + GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, (int)sliderSize); // Change slider size + GuiSetStyle(SCROLLBAR, SCROLL_SPEED, count - visibleItems); // Change scroll speed + + startIndex = GuiScrollBar(scrollBarBounds, startIndex, 0, count - visibleItems); + + GuiSetStyle(SCROLLBAR, SCROLL_SPEED, prevScrollSpeed); // Reset scroll speed to default + GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, prevSliderSize); // Reset slider size to default + } + //-------------------------------------------------------------------- + + if (active != NULL) *active = itemSelected; + if (focus != NULL) *focus = itemFocused; + if (scrollIndex != NULL) *scrollIndex = startIndex; + + return result; +} + +// Color Panel control - Color (RGBA) variant +int GuiColorPanel(Rectangle bounds, const char *text, Color *color) +{ + int result = 0; + + Vector3 vcolor = { (float)color->r/255.0f, (float)color->g/255.0f, (float)color->b/255.0f }; + Vector3 hsv = ConvertRGBtoHSV(vcolor); + Vector3 prevHsv = hsv; // workaround to see if GuiColorPanelHSV modifies the hsv + + GuiColorPanelHSV(bounds, text, &hsv); + + // Check if the hsv was changed, only then change the color + // This is required, because the Color->HSV->Color conversion has precision errors + // Thus the assignment from HSV to Color should only be made, if the HSV has a new user-entered value + // Otherwise GuiColorPanel would often modify it's color without user input + // TODO: GuiColorPanelHSV could return 1 if the slider was dragged, to simplify this check + if (hsv.x != prevHsv.x || hsv.y != prevHsv.y || hsv.z != prevHsv.z) + { + Vector3 rgb = ConvertHSVtoRGB(hsv); + + // NOTE: Vector3ToColor() only available on raylib 1.8.1 + *color = RAYGUI_CLITERAL(Color){ (unsigned char)(255.0f*rgb.x), + (unsigned char)(255.0f*rgb.y), + (unsigned char)(255.0f*rgb.z), + color->a }; + } + return result; +} + +// Color Bar Alpha control +// NOTE: Returns alpha value normalized [0..1] +int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha) +{ + #if !defined(RAYGUI_COLORBARALPHA_CHECKED_SIZE) + #define RAYGUI_COLORBARALPHA_CHECKED_SIZE 10 + #endif + + int result = 0; + GuiState state = guiState; + Rectangle selector = { (float)bounds.x + (*alpha)*bounds.width - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT)/2, + (float)bounds.y - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW), + (float)GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT), + (float)bounds.height + GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW)*2 }; + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked) + { + Vector2 mousePoint = GUI_POINTER_POSITION; + + if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds + { + if (GUI_BUTTON_DOWN) + { + if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) + { + state = STATE_PRESSED; + + *alpha = (mousePoint.x - bounds.x)/bounds.width; + if (*alpha <= 0.0f) *alpha = 0.0f; + if (*alpha >= 1.0f) *alpha = 1.0f; + } + } + else + { + guiControlExclusiveMode = false; + guiControlExclusiveRec = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 }; + } + } + else if (CheckCollisionPointRec(mousePoint, bounds) || CheckCollisionPointRec(mousePoint, selector)) + { + if (GUI_BUTTON_DOWN) + { + state = STATE_PRESSED; + guiControlExclusiveMode = true; + guiControlExclusiveRec = bounds; // Store bounds as an identifier when dragging starts + + *alpha = (mousePoint.x - bounds.x)/bounds.width; + if (*alpha <= 0.0f) *alpha = 0.0f; + if (*alpha >= 1.0f) *alpha = 1.0f; + //selector.x = bounds.x + (int)(((alpha - 0)/(100 - 0))*(bounds.width - 2*GuiGetStyle(SLIDER, BORDER_WIDTH))) - selector.width/2; + } + else state = STATE_FOCUSED; + } + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + // Draw alpha bar: checked background + if (state != STATE_DISABLED) + { + int checksX = (int)bounds.width/RAYGUI_COLORBARALPHA_CHECKED_SIZE; + int checksY = (int)bounds.height/RAYGUI_COLORBARALPHA_CHECKED_SIZE; + + for (int x = 0; x < checksX; x++) + { + for (int y = 0; y < checksY; y++) + { + Rectangle check = { bounds.x + x*RAYGUI_COLORBARALPHA_CHECKED_SIZE, bounds.y + y*RAYGUI_COLORBARALPHA_CHECKED_SIZE, RAYGUI_COLORBARALPHA_CHECKED_SIZE, RAYGUI_COLORBARALPHA_CHECKED_SIZE }; + GuiDrawRectangle(check, 0, BLANK, ((x + y)%2)? Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), 0.4f) : Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.4f)); + } + } + + DrawRectangleGradientEx(bounds, RAYGUI_CLITERAL(Color){ 255, 255, 255, 0 }, RAYGUI_CLITERAL(Color){ 255, 255, 255, 0 }, Fade(RAYGUI_CLITERAL(Color){ 0, 0, 0, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 0, 0, 0, 255 }, guiAlpha)); + } + else DrawRectangleGradientEx(bounds, Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.1f), Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.1f), Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), guiAlpha), Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), guiAlpha)); + + GuiDrawRectangle(bounds, GuiGetStyle(COLORPICKER, BORDER_WIDTH), GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)), BLANK); + + // Draw alpha bar: selector + GuiDrawRectangle(selector, 0, BLANK, GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3))); + //-------------------------------------------------------------------- + + return result; +} + +// Color Bar Hue control +// Returns hue value normalized [0..1] +// NOTE: Other similar bars (for reference): +// Color GuiColorBarSat() [WHITE->color] +// Color GuiColorBarValue() [BLACK->color], HSV/HSL +// float GuiColorBarLuminance() [BLACK->WHITE] +int GuiColorBarHue(Rectangle bounds, const char *text, float *hue) +{ + int result = 0; + GuiState state = guiState; + Rectangle selector = { (float)bounds.x - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW), (float)bounds.y + (*hue)/360.0f*bounds.height - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT)/2, (float)bounds.width + GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW)*2, (float)GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT) }; + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked) + { + Vector2 mousePoint = GUI_POINTER_POSITION; + + if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds + { + if (GUI_BUTTON_DOWN) + { + if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) + { + state = STATE_PRESSED; + + *hue = (mousePoint.y - bounds.y)*360/bounds.height; + if (*hue <= 0.0f) *hue = 0.0f; + if (*hue >= 359.0f) *hue = 359.0f; + } + } + else + { + guiControlExclusiveMode = false; + guiControlExclusiveRec = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 }; + } + } + else if (CheckCollisionPointRec(mousePoint, bounds) || CheckCollisionPointRec(mousePoint, selector)) + { + if (GUI_BUTTON_DOWN) + { + state = STATE_PRESSED; + guiControlExclusiveMode = true; + guiControlExclusiveRec = bounds; // Store bounds as an identifier when dragging starts + + *hue = (mousePoint.y - bounds.y)*360/bounds.height; + if (*hue <= 0.0f) *hue = 0.0f; + if (*hue >= 359.0f) *hue = 359.0f; + + } + else state = STATE_FOCUSED; + + /*if (GUI_KEY_DOWN(KEY_UP)) + { + hue -= 2.0f; + if (hue <= 0.0f) hue = 0.0f; + } + else if (GUI_KEY_DOWN(KEY_DOWN)) + { + hue += 2.0f; + if (hue >= 360.0f) hue = 360.0f; + }*/ + } + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + if (state != STATE_DISABLED) + { + // Draw hue bar:color bars + // TODO: Use directly DrawRectangleGradientEx(bounds, color1, color2, color2, color1); + DrawRectangleGradientV((int)bounds.x, (int)(bounds.y), (int)bounds.width, (int)ceilf(bounds.height/6), Fade(RAYGUI_CLITERAL(Color){ 255, 0, 0, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 255, 255, 0, 255 }, guiAlpha)); + DrawRectangleGradientV((int)bounds.x, (int)(bounds.y + bounds.height/6), (int)bounds.width, (int)ceilf(bounds.height/6), Fade(RAYGUI_CLITERAL(Color){ 255, 255, 0, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 0, 255, 0, 255 }, guiAlpha)); + DrawRectangleGradientV((int)bounds.x, (int)(bounds.y + 2*(bounds.height/6)), (int)bounds.width, (int)ceilf(bounds.height/6), Fade(RAYGUI_CLITERAL(Color){ 0, 255, 0, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 0, 255, 255, 255 }, guiAlpha)); + DrawRectangleGradientV((int)bounds.x, (int)(bounds.y + 3*(bounds.height/6)), (int)bounds.width, (int)ceilf(bounds.height/6), Fade(RAYGUI_CLITERAL(Color){ 0, 255, 255, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 0, 0, 255, 255 }, guiAlpha)); + DrawRectangleGradientV((int)bounds.x, (int)(bounds.y + 4*(bounds.height/6)), (int)bounds.width, (int)ceilf(bounds.height/6), Fade(RAYGUI_CLITERAL(Color){ 0, 0, 255, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 255, 0, 255, 255 }, guiAlpha)); + DrawRectangleGradientV((int)bounds.x, (int)(bounds.y + 5*(bounds.height/6)), (int)bounds.width, (int)(bounds.height/6), Fade(RAYGUI_CLITERAL(Color){ 255, 0, 255, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 255, 0, 0, 255 }, guiAlpha)); + } + else DrawRectangleGradientV((int)bounds.x, (int)bounds.y, (int)bounds.width, (int)bounds.height, Fade(Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.1f), guiAlpha), Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), guiAlpha)); + + GuiDrawRectangle(bounds, GuiGetStyle(COLORPICKER, BORDER_WIDTH), GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)), BLANK); + + // Draw hue bar: selector + GuiDrawRectangle(selector, 0, BLANK, GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3))); + //-------------------------------------------------------------------- + + return result; +} + +// Color Picker control +// NOTE: It's divided in multiple controls: +// Color GuiColorPanel(Rectangle bounds, Color color) +// float GuiColorBarAlpha(Rectangle bounds, float alpha) +// float GuiColorBarHue(Rectangle bounds, float value) +// NOTE: bounds define GuiColorPanel() size +// NOTE: this picker converts RGB to HSV, which can cause the Hue control to jump. If you have this problem, consider using the HSV variant instead +int GuiColorPicker(Rectangle bounds, const char *text, Color *color) +{ + int result = 0; + + Color temp = { 200, 0, 0, 255 }; + if (color == NULL) color = &temp; + + GuiColorPanel(bounds, NULL, color); + + Rectangle boundsHue = { (float)bounds.x + bounds.width + GuiGetStyle(COLORPICKER, HUEBAR_PADDING), (float)bounds.y, (float)GuiGetStyle(COLORPICKER, HUEBAR_WIDTH), (float)bounds.height }; + //Rectangle boundsAlpha = { bounds.x, bounds.y + bounds.height + GuiGetStyle(COLORPICKER, BARS_PADDING), bounds.width, GuiGetStyle(COLORPICKER, BARS_THICK) }; + + // NOTE: this conversion can cause low hue-resolution, if the r, g and b value are very similar, which causes the hue bar to shift around when only the GuiColorPanel is used + Vector3 hsv = ConvertRGBtoHSV(RAYGUI_CLITERAL(Vector3){ (*color).r/255.0f, (*color).g/255.0f, (*color).b/255.0f }); + + GuiColorBarHue(boundsHue, NULL, &hsv.x); + + //color.a = (unsigned char)(GuiColorBarAlpha(boundsAlpha, (float)color.a/255.0f)*255.0f); + Vector3 rgb = ConvertHSVtoRGB(hsv); + + *color = RAYGUI_CLITERAL(Color){ (unsigned char)roundf(rgb.x*255.0f), (unsigned char)roundf(rgb.y*255.0f), (unsigned char)roundf(rgb.z*255.0f), (*color).a }; + + return result; +} + +// Color Picker control that avoids conversion to RGB and back to HSV on each call, thus avoiding jittering +// The user can call ConvertHSVtoRGB() to convert *colorHsv value to RGB +// NOTE: It's divided in multiple controls: +// int GuiColorPanelHSV(Rectangle bounds, const char *text, Vector3 *colorHsv) +// int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha) +// float GuiColorBarHue(Rectangle bounds, float value) +// NOTE: bounds define GuiColorPanelHSV() size +int GuiColorPickerHSV(Rectangle bounds, const char *text, Vector3 *colorHsv) +{ + int result = 0; + + Vector3 tempHsv = { 0 }; + + if (colorHsv == NULL) + { + const Vector3 tempColor = { 200.0f/255.0f, 0.0f, 0.0f }; + tempHsv = ConvertRGBtoHSV(tempColor); + colorHsv = &tempHsv; + } + + GuiColorPanelHSV(bounds, NULL, colorHsv); + + const Rectangle boundsHue = { (float)bounds.x + bounds.width + GuiGetStyle(COLORPICKER, HUEBAR_PADDING), (float)bounds.y, (float)GuiGetStyle(COLORPICKER, HUEBAR_WIDTH), (float)bounds.height }; + + GuiColorBarHue(boundsHue, NULL, &colorHsv->x); + + return result; +} + +// Color Panel control - HSV variant +int GuiColorPanelHSV(Rectangle bounds, const char *text, Vector3 *colorHsv) +{ + int result = 0; + GuiState state = guiState; + Vector2 pickerSelector = { 0 }; + + const Color colWhite = { 255, 255, 255, 255 }; + const Color colBlack = { 0, 0, 0, 255 }; + + pickerSelector.x = bounds.x + (float)colorHsv->y*bounds.width; // HSV: Saturation + pickerSelector.y = bounds.y + (1.0f - (float)colorHsv->z)*bounds.height; // HSV: Value + + Vector3 maxHue = { colorHsv->x, 1.0f, 1.0f }; + Vector3 rgbHue = ConvertHSVtoRGB(maxHue); + Color maxHueCol = { (unsigned char)(255.0f*rgbHue.x), + (unsigned char)(255.0f*rgbHue.y), + (unsigned char)(255.0f*rgbHue.z), 255 }; + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked) + { + Vector2 mousePoint = GUI_POINTER_POSITION; + + if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds + { + if (GUI_BUTTON_DOWN) + { + if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) + { + pickerSelector = mousePoint; + + if (pickerSelector.x < bounds.x) pickerSelector.x = bounds.x; + if (pickerSelector.x > bounds.x + bounds.width) pickerSelector.x = bounds.x + bounds.width; + if (pickerSelector.y < bounds.y) pickerSelector.y = bounds.y; + if (pickerSelector.y > bounds.y + bounds.height) pickerSelector.y = bounds.y + bounds.height; + + // Calculate color from picker + Vector2 colorPick = { pickerSelector.x - bounds.x, pickerSelector.y - bounds.y }; + + colorPick.x /= (float)bounds.width; // Get normalized value on x + colorPick.y /= (float)bounds.height; // Get normalized value on y + + colorHsv->y = colorPick.x; + colorHsv->z = 1.0f - colorPick.y; + + } + } + else + { + guiControlExclusiveMode = false; + guiControlExclusiveRec = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 }; + } + } + else if (CheckCollisionPointRec(mousePoint, bounds)) + { + if (GUI_BUTTON_DOWN) + { + state = STATE_PRESSED; + guiControlExclusiveMode = true; + guiControlExclusiveRec = bounds; + pickerSelector = mousePoint; + + // Calculate color from picker + Vector2 colorPick = { pickerSelector.x - bounds.x, pickerSelector.y - bounds.y }; + + colorPick.x /= (float)bounds.width; // Get normalized value on x + colorPick.y /= (float)bounds.height; // Get normalized value on y + + colorHsv->y = colorPick.x; + colorHsv->z = 1.0f - colorPick.y; + } + else state = STATE_FOCUSED; + } + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + if (state != STATE_DISABLED) + { + DrawRectangleGradientEx(bounds, Fade(colWhite, guiAlpha), Fade(colWhite, guiAlpha), Fade(maxHueCol, guiAlpha), Fade(maxHueCol, guiAlpha)); + DrawRectangleGradientEx(bounds, Fade(colBlack, 0), Fade(colBlack, guiAlpha), Fade(colBlack, guiAlpha), Fade(colBlack, 0)); + + // Draw color picker: selector + Rectangle selector = { pickerSelector.x - GuiGetStyle(COLORPICKER, COLOR_SELECTOR_SIZE)/2, pickerSelector.y - GuiGetStyle(COLORPICKER, COLOR_SELECTOR_SIZE)/2, (float)GuiGetStyle(COLORPICKER, COLOR_SELECTOR_SIZE), (float)GuiGetStyle(COLORPICKER, COLOR_SELECTOR_SIZE) }; + GuiDrawRectangle(selector, 0, BLANK, colWhite); + } + else + { + DrawRectangleGradientEx(bounds, Fade(Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.1f), guiAlpha), Fade(Fade(colBlack, 0.6f), guiAlpha), Fade(Fade(colBlack, 0.6f), guiAlpha), Fade(Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), 0.6f), guiAlpha)); + } + + GuiDrawRectangle(bounds, GuiGetStyle(COLORPICKER, BORDER_WIDTH), GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)), BLANK); + //-------------------------------------------------------------------- + + return result; +} + +// Message Box control +int GuiMessageBox(Rectangle bounds, const char *title, const char *message, const char *buttons) +{ + #if !defined(RAYGUI_MESSAGEBOX_BUTTON_HEIGHT) + #define RAYGUI_MESSAGEBOX_BUTTON_HEIGHT 24 + #endif + #if !defined(RAYGUI_MESSAGEBOX_BUTTON_PADDING) + #define RAYGUI_MESSAGEBOX_BUTTON_PADDING 12 + #endif + + int result = -1; // Returns clicked button from buttons list, 0 refers to closed window button + + int buttonCount = 0; + const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL); + Rectangle buttonBounds = { 0 }; + buttonBounds.x = bounds.x + RAYGUI_MESSAGEBOX_BUTTON_PADDING; + buttonBounds.y = bounds.y + bounds.height - RAYGUI_MESSAGEBOX_BUTTON_HEIGHT - RAYGUI_MESSAGEBOX_BUTTON_PADDING; + buttonBounds.width = (bounds.width - RAYGUI_MESSAGEBOX_BUTTON_PADDING*(buttonCount + 1))/buttonCount; + buttonBounds.height = RAYGUI_MESSAGEBOX_BUTTON_HEIGHT; + + //int textWidth = GuiGetTextWidth(message) + 2; + + Rectangle textBounds = { 0 }; + textBounds.x = bounds.x + RAYGUI_MESSAGEBOX_BUTTON_PADDING; + textBounds.y = bounds.y + RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT + RAYGUI_MESSAGEBOX_BUTTON_PADDING; + textBounds.width = bounds.width - RAYGUI_MESSAGEBOX_BUTTON_PADDING*2; + textBounds.height = bounds.height - RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - 3*RAYGUI_MESSAGEBOX_BUTTON_PADDING - RAYGUI_MESSAGEBOX_BUTTON_HEIGHT; + + // Draw control + //-------------------------------------------------------------------- + if (GuiWindowBox(bounds, title)) result = 0; + + int prevTextAlignment = GuiGetStyle(LABEL, TEXT_ALIGNMENT); + GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); + GuiLabel(textBounds, message); + GuiSetStyle(LABEL, TEXT_ALIGNMENT, prevTextAlignment); + + prevTextAlignment = GuiGetStyle(BUTTON, TEXT_ALIGNMENT); + GuiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); + + for (int i = 0; i < buttonCount; i++) + { + if (GuiButton(buttonBounds, buttonsText[i])) result = i + 1; + buttonBounds.x += (buttonBounds.width + RAYGUI_MESSAGEBOX_BUTTON_PADDING); + } + + GuiSetStyle(BUTTON, TEXT_ALIGNMENT, prevTextAlignment); + //-------------------------------------------------------------------- + + return result; +} + +// Text Input Box control, ask for text +int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, const char *buttons, char *text, int textMaxSize, bool *secretViewActive) +{ + #if !defined(RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT) + #define RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT 24 + #endif + #if !defined(RAYGUI_TEXTINPUTBOX_BUTTON_PADDING) + #define RAYGUI_TEXTINPUTBOX_BUTTON_PADDING 12 + #endif + #if !defined(RAYGUI_TEXTINPUTBOX_HEIGHT) + #define RAYGUI_TEXTINPUTBOX_HEIGHT 26 + #endif + + // Used to enable text edit mode + // WARNING: No more than one GuiTextInputBox() should be open at the same time + static bool textEditMode = false; + + int result = -1; + + int buttonCount = 0; + const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL); + Rectangle buttonBounds = { 0 }; + buttonBounds.x = bounds.x + RAYGUI_TEXTINPUTBOX_BUTTON_PADDING; + buttonBounds.y = bounds.y + bounds.height - RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT - RAYGUI_TEXTINPUTBOX_BUTTON_PADDING; + buttonBounds.width = (bounds.width - RAYGUI_TEXTINPUTBOX_BUTTON_PADDING*(buttonCount + 1))/buttonCount; + buttonBounds.height = RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT; + + int messageInputHeight = (int)bounds.height - RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - GuiGetStyle(STATUSBAR, BORDER_WIDTH) - RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT - 2*RAYGUI_TEXTINPUTBOX_BUTTON_PADDING; + + Rectangle textBounds = { 0 }; + if (message != NULL) + { + int textSize = GuiGetTextWidth(message) + 2; + + textBounds.x = bounds.x + bounds.width/2 - textSize/2; + textBounds.y = bounds.y + RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT + messageInputHeight/4 - (float)GuiGetStyle(DEFAULT, TEXT_SIZE)/2; + textBounds.width = (float)textSize; + textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE); + } + + Rectangle textBoxBounds = { 0 }; + textBoxBounds.x = bounds.x + RAYGUI_TEXTINPUTBOX_BUTTON_PADDING; + textBoxBounds.y = bounds.y + RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - RAYGUI_TEXTINPUTBOX_HEIGHT/2; + if (message == NULL) textBoxBounds.y = bounds.y + 24 + RAYGUI_TEXTINPUTBOX_BUTTON_PADDING; + else textBoxBounds.y += (messageInputHeight/2 + messageInputHeight/4); + textBoxBounds.width = bounds.width - RAYGUI_TEXTINPUTBOX_BUTTON_PADDING*2; + textBoxBounds.height = RAYGUI_TEXTINPUTBOX_HEIGHT; + + // Draw control + //-------------------------------------------------------------------- + if (GuiWindowBox(bounds, title)) result = 0; + + // Draw message if available + if (message != NULL) + { + int prevTextAlignment = GuiGetStyle(LABEL, TEXT_ALIGNMENT); + GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); + GuiLabel(textBounds, message); + GuiSetStyle(LABEL, TEXT_ALIGNMENT, prevTextAlignment); + } + + int prevTextBoxAlignment = GuiGetStyle(TEXTBOX, TEXT_ALIGNMENT); + GuiSetStyle(TEXTBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); + + if (secretViewActive != NULL) + { + static char stars[] = "****************"; + if (GuiTextBox(RAYGUI_CLITERAL(Rectangle){ textBoxBounds.x, textBoxBounds.y, textBoxBounds.width - 4 - RAYGUI_TEXTINPUTBOX_HEIGHT, textBoxBounds.height }, + ((*secretViewActive == 1) || textEditMode)? text : stars, textMaxSize, textEditMode)) textEditMode = !textEditMode; + + GuiToggle(RAYGUI_CLITERAL(Rectangle){ textBoxBounds.x + textBoxBounds.width - RAYGUI_TEXTINPUTBOX_HEIGHT, textBoxBounds.y, RAYGUI_TEXTINPUTBOX_HEIGHT, RAYGUI_TEXTINPUTBOX_HEIGHT }, (*secretViewActive == 1)? "#44#" : "#45#", secretViewActive); + } + else + { + if (GuiTextBox(textBoxBounds, text, textMaxSize, textEditMode)) textEditMode = !textEditMode; + } + + GuiSetStyle(TEXTBOX, TEXT_ALIGNMENT, prevTextBoxAlignment); + + int prevBtnTextAlignment = GuiGetStyle(BUTTON, TEXT_ALIGNMENT); + GuiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); + + for (int i = 0; i < buttonCount; i++) + { + if (GuiButton(buttonBounds, buttonsText[i])) result = i + 1; + buttonBounds.x += (buttonBounds.width + RAYGUI_MESSAGEBOX_BUTTON_PADDING); + } + + if (result >= 0) textEditMode = false; + + GuiSetStyle(BUTTON, TEXT_ALIGNMENT, prevBtnTextAlignment); + //-------------------------------------------------------------------- + + return result; // Result is the pressed button index +} + +// Grid control +// NOTE: Returns grid mouse-hover selected cell +// About drawing lines at subpixel spacing, simple put, not easy solution: +// REF: https://stackoverflow.com/questions/4435450/2d-opengl-drawing-lines-that-dont-exactly-fit-pixel-raster +int GuiGrid(Rectangle bounds, const char *text, float spacing, int subdivs, Vector2 *mouseCell) +{ + // Grid lines alpha amount + #if !defined(RAYGUI_GRID_ALPHA) + #define RAYGUI_GRID_ALPHA 0.15f + #endif + + int result = 0; + GuiState state = guiState; + + Vector2 mousePoint = GUI_POINTER_POSITION; + Vector2 currentMouseCell = { -1, -1 }; + + float spaceWidth = spacing/(float)subdivs; + int linesV = (int)(bounds.width/spaceWidth) + 1; + int linesH = (int)(bounds.height/spaceWidth) + 1; + + int color = GuiGetStyle(DEFAULT, LINE_COLOR); + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + { + if (CheckCollisionPointRec(mousePoint, bounds)) + { + // NOTE: Cell values must be the upper left of the cell the mouse is in + currentMouseCell.x = floorf((mousePoint.x - bounds.x)/spacing); + currentMouseCell.y = floorf((mousePoint.y - bounds.y)/spacing); + } + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + if (state == STATE_DISABLED) color = GuiGetStyle(DEFAULT, BORDER_COLOR_DISABLED); + + if (subdivs > 0) + { + // Draw vertical grid lines + for (int i = 0; i < linesV; i++) + { + Rectangle lineV = { bounds.x + spacing*i/subdivs, bounds.y, 1, bounds.height + 1 }; + GuiDrawRectangle(lineV, 0, BLANK, ((i%subdivs) == 0)? GuiFade(GetColor(color), RAYGUI_GRID_ALPHA*4) : GuiFade(GetColor(color), RAYGUI_GRID_ALPHA)); + } + + // Draw horizontal grid lines + for (int i = 0; i < linesH; i++) + { + Rectangle lineH = { bounds.x, bounds.y + spacing*i/subdivs, bounds.width + 1, 1 }; + GuiDrawRectangle(lineH, 0, BLANK, ((i%subdivs) == 0)? GuiFade(GetColor(color), RAYGUI_GRID_ALPHA*4) : GuiFade(GetColor(color), RAYGUI_GRID_ALPHA)); + } + } + + if (mouseCell != NULL) *mouseCell = currentMouseCell; + return result; +} + +//---------------------------------------------------------------------------------- +// Tooltip management functions +// NOTE: Tooltips requires some global variables: tooltipPtr +//---------------------------------------------------------------------------------- +// Enable gui tooltips (global state) +void GuiEnableTooltip(void) { guiTooltip = true; } + +// Disable gui tooltips (global state) +void GuiDisableTooltip(void) { guiTooltip = false; } + +// Set tooltip string +void GuiSetTooltip(const char *tooltip) { guiTooltipPtr = tooltip; } + +//---------------------------------------------------------------------------------- +// Styles loading functions +//---------------------------------------------------------------------------------- + +// Load raygui style file (.rgs) +// NOTE: By default a binary file is expected, that file could contain a custom font, +// in that case, custom font image atlas is GRAY+ALPHA and pixel data can be compressed (DEFLATE) +void GuiLoadStyle(const char *fileName) +{ + #define MAX_LINE_BUFFER_SIZE 256 + + bool tryBinary = false; + if (!guiStyleLoaded) GuiLoadStyleDefault(); + + // Try reading the files as text file first + FILE *rgsFile = fopen(fileName, "rt"); + + if (rgsFile != NULL) + { + char buffer[MAX_LINE_BUFFER_SIZE] = { 0 }; + fgets(buffer, MAX_LINE_BUFFER_SIZE, rgsFile); + + if (buffer[0] == '#') + { + int controlId = 0; + int propertyId = 0; + unsigned int propertyValue = 0; + + while (!feof(rgsFile)) + { + switch (buffer[0]) + { + case 'p': + { + // Style property: p + + sscanf(buffer, "p %d %d 0x%x", &controlId, &propertyId, &propertyValue); + GuiSetStyle(controlId, propertyId, (int)propertyValue); + + } break; + case 'f': + { + // Style font: f + + int fontSize = 0; + char charmapFileName[256] = { 0 }; + char fontFileName[256] = { 0 }; + sscanf(buffer, "f %d %s %[^\r\n]s", &fontSize, charmapFileName, fontFileName); + + Font font = { 0 }; + int *codepoints = NULL; + int codepointCount = 0; + + if (charmapFileName[0] != '0') + { + // Load text data from file + // NOTE: Expected an UTF-8 array of codepoints, no separation + char *textData = LoadFileText(TextFormat("%s/%s", GetDirectoryPath(fileName), charmapFileName)); + codepoints = LoadCodepoints(textData, &codepointCount); + UnloadFileText(textData); + } + + if (fontFileName[0] != '\0') + { + // In case a font is already loaded and it is not default internal font, unload it + if (font.texture.id != GetFontDefault().texture.id) UnloadTexture(font.texture); + + if (codepointCount > 0) font = LoadFontEx(TextFormat("%s/%s", GetDirectoryPath(fileName), fontFileName), fontSize, codepoints, codepointCount); + else font = LoadFontEx(TextFormat("%s/%s", GetDirectoryPath(fileName), fontFileName), fontSize, NULL, 0); // Default to 95 standard codepoints + } + + // If font texture not properly loaded, revert to default font and size/spacing + if (font.texture.id == 0) + { + font = GetFontDefault(); + GuiSetStyle(DEFAULT, TEXT_SIZE, 10); + GuiSetStyle(DEFAULT, TEXT_SPACING, 1); + } + + UnloadCodepoints(codepoints); + + if ((font.texture.id > 0) && (font.glyphCount > 0)) GuiSetFont(font); + + } break; + default: break; + } + + fgets(buffer, MAX_LINE_BUFFER_SIZE, rgsFile); + } + } + else tryBinary = true; + + fclose(rgsFile); + } + + if (tryBinary) + { + rgsFile = fopen(fileName, "rb"); + + if (rgsFile != NULL) + { + fseek(rgsFile, 0, SEEK_END); + int fileDataSize = ftell(rgsFile); + fseek(rgsFile, 0, SEEK_SET); + + if (fileDataSize > 0) + { + unsigned char *fileData = (unsigned char *)RAYGUI_CALLOC(fileDataSize, sizeof(unsigned char)); + if (fileData != NULL) + { + fread(fileData, sizeof(unsigned char), fileDataSize, rgsFile); + + GuiLoadStyleFromMemory(fileData, fileDataSize); + + RAYGUI_FREE(fileData); + } + } + + fclose(rgsFile); + } + } +} + +// Load style default over global style +void GuiLoadStyleDefault(void) +{ + // Setting this flag first to avoid cyclic function calls + // when calling GuiSetStyle() and GuiGetStyle() + guiStyleLoaded = true; + + // Initialize default LIGHT style property values + // WARNING: Default value are applied to all controls on set but + // they can be overwritten later on for every custom control + GuiSetStyle(DEFAULT, BORDER_COLOR_NORMAL, 0x838383ff); + GuiSetStyle(DEFAULT, BASE_COLOR_NORMAL, 0xc9c9c9ff); + GuiSetStyle(DEFAULT, TEXT_COLOR_NORMAL, 0x686868ff); + GuiSetStyle(DEFAULT, BORDER_COLOR_FOCUSED, 0x5bb2d9ff); + GuiSetStyle(DEFAULT, BASE_COLOR_FOCUSED, 0xc9effeff); + GuiSetStyle(DEFAULT, TEXT_COLOR_FOCUSED, 0x6c9bbcff); + GuiSetStyle(DEFAULT, BORDER_COLOR_PRESSED, 0x0492c7ff); + GuiSetStyle(DEFAULT, BASE_COLOR_PRESSED, 0x97e8ffff); + GuiSetStyle(DEFAULT, TEXT_COLOR_PRESSED, 0x368bafff); + GuiSetStyle(DEFAULT, BORDER_COLOR_DISABLED, 0xb5c1c2ff); + GuiSetStyle(DEFAULT, BASE_COLOR_DISABLED, 0xe6e9e9ff); + GuiSetStyle(DEFAULT, TEXT_COLOR_DISABLED, 0xaeb7b8ff); + GuiSetStyle(DEFAULT, BORDER_WIDTH, 1); + GuiSetStyle(DEFAULT, TEXT_PADDING, 0); + GuiSetStyle(DEFAULT, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); + + // Initialize default extended property values + // NOTE: By default, extended property values are initialized to 0 + GuiSetStyle(DEFAULT, TEXT_SIZE, 10); // DEFAULT, shared by all controls + GuiSetStyle(DEFAULT, TEXT_SPACING, 1); // DEFAULT, shared by all controls + GuiSetStyle(DEFAULT, LINE_COLOR, 0x90abb5ff); // DEFAULT specific property + GuiSetStyle(DEFAULT, BACKGROUND_COLOR, 0xf5f5f5ff); // DEFAULT specific property + GuiSetStyle(DEFAULT, TEXT_LINE_SPACING, 5); // DEFAULT, pixels between lines, from bottom of first line to top of second + GuiSetStyle(DEFAULT, TEXT_ALIGNMENT_VERTICAL, TEXT_ALIGN_MIDDLE); // DEFAULT, text aligned vertically to middle of text-bounds + + // Initialize control-specific property values + // NOTE: Those properties are in default list but require specific values by control type + GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); + GuiSetStyle(BUTTON, BORDER_WIDTH, 2); + GuiSetStyle(SLIDER, TEXT_PADDING, 4); + GuiSetStyle(PROGRESSBAR, TEXT_PADDING, 4); + GuiSetStyle(CHECKBOX, TEXT_PADDING, 4); + GuiSetStyle(CHECKBOX, TEXT_ALIGNMENT, TEXT_ALIGN_RIGHT); + GuiSetStyle(DROPDOWNBOX, TEXT_PADDING, 0); + GuiSetStyle(DROPDOWNBOX, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); + GuiSetStyle(TEXTBOX, TEXT_PADDING, 4); + GuiSetStyle(TEXTBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); + GuiSetStyle(VALUEBOX, TEXT_PADDING, 0); + GuiSetStyle(VALUEBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); + GuiSetStyle(STATUSBAR, TEXT_PADDING, 8); + GuiSetStyle(STATUSBAR, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); + + // Initialize extended property values + // NOTE: By default, extended property values are initialized to 0 + GuiSetStyle(TOGGLE, GROUP_PADDING, 2); + GuiSetStyle(SLIDER, SLIDER_WIDTH, 16); + GuiSetStyle(SLIDER, SLIDER_PADDING, 1); + GuiSetStyle(PROGRESSBAR, PROGRESS_PADDING, 1); + GuiSetStyle(CHECKBOX, CHECK_PADDING, 1); + GuiSetStyle(COMBOBOX, COMBO_BUTTON_WIDTH, 32); + GuiSetStyle(COMBOBOX, COMBO_BUTTON_SPACING, 2); + GuiSetStyle(DROPDOWNBOX, ARROW_PADDING, 16); + GuiSetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING, 2); + GuiSetStyle(VALUEBOX, SPINNER_BUTTON_WIDTH, 24); + GuiSetStyle(VALUEBOX, SPINNER_BUTTON_SPACING, 2); + GuiSetStyle(SCROLLBAR, BORDER_WIDTH, 0); + GuiSetStyle(SCROLLBAR, ARROWS_VISIBLE, 0); + GuiSetStyle(SCROLLBAR, ARROWS_SIZE, 6); + GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING, 0); + GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, 16); + GuiSetStyle(SCROLLBAR, SCROLL_PADDING, 0); + GuiSetStyle(SCROLLBAR, SCROLL_SPEED, 12); + GuiSetStyle(LISTVIEW, LIST_ITEMS_HEIGHT, 28); + GuiSetStyle(LISTVIEW, LIST_ITEMS_SPACING, 2); + GuiSetStyle(LISTVIEW, LIST_ITEMS_BORDER_WIDTH, 1); + GuiSetStyle(LISTVIEW, SCROLLBAR_WIDTH, 12); + GuiSetStyle(LISTVIEW, SCROLLBAR_SIDE, SCROLLBAR_RIGHT_SIDE); + GuiSetStyle(COLORPICKER, COLOR_SELECTOR_SIZE, 8); + GuiSetStyle(COLORPICKER, HUEBAR_WIDTH, 16); + GuiSetStyle(COLORPICKER, HUEBAR_PADDING, 8); + GuiSetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT, 8); + GuiSetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW, 2); + + if (guiFont.texture.id != GetFontDefault().texture.id) + { + // Unload previous font texture + UnloadTexture(guiFont.texture); + RAYGUI_FREE(guiFont.recs); + RAYGUI_FREE(guiFont.glyphs); + guiFont.recs = NULL; + guiFont.glyphs = NULL; + + // Setup default raylib font + guiFont = GetFontDefault(); + + // NOTE: Default raylib font character 95 is a white square + Rectangle whiteChar = guiFont.recs[95]; + + // NOTE: Setting up a 1px padding on char rectangle to avoid pixel bleeding on MSAA filtering + SetShapesTexture(guiFont.texture, RAYGUI_CLITERAL(Rectangle){ whiteChar.x + 1, whiteChar.y + 1, whiteChar.width - 2, whiteChar.height - 2 }); + } +} + +// Get text with icon id prepended +// NOTE: Useful to add icons by name id (enum) instead of +// a number that can change between ricon versions +const char *GuiIconText(int iconId, const char *text) +{ +#if defined(RAYGUI_NO_ICONS) + return NULL; +#else + static char buffer[1024] = { 0 }; + static char iconBuffer[16] = { 0 }; + + if (text != NULL) + { + memset(buffer, 0, 1024); + snprintf(buffer, 1024, "#%03i#", iconId); + + for (int i = 5; i < 1024; i++) + { + buffer[i] = text[i - 5]; + if (text[i - 5] == '\0') break; + } + + return buffer; + } + else + { + snprintf(iconBuffer, 16, "#%03i#", iconId); + + return iconBuffer; + } +#endif +} + +#if !defined(RAYGUI_NO_ICONS) +// Get full icons data pointer +unsigned int *GuiGetIcons(void) { return guiIconsPtr; } + +// Load raygui icons file (.rgi) +// NOTE: In case nameIds are required, they can be requested with loadIconsName, +// they are returned as a guiIconsName[iconCount][RAYGUI_ICON_MAX_NAME_LENGTH], +// WARNING: guiIconsName[]][] memory should be manually freed! +char **GuiLoadIcons(const char *fileName, bool loadIconsName) +{ + // Style File Structure (.rgi) + // ------------------------------------------------------ + // Offset | Size | Type | Description + // ------------------------------------------------------ + // 0 | 4 | char | Signature: "rGI " + // 4 | 2 | short | Version: 100 + // 6 | 2 | short | reserved + + // 8 | 2 | short | Num icons (N) + // 10 | 2 | short | Icons size (Options: 16, 32, 64) (S) + + // Icons name id (32 bytes per name id) + // foreach (icon) + // { + // 12+32*i | 32 | char | Icon NameId + // } + + // Icons data: One bit per pixel, stored as unsigned int array (depends on icon size) + // S*S pixels/32bit per unsigned int = K unsigned int per icon + // foreach (icon) + // { + // ... | K | unsigned int | Icon Data + // } + + FILE *rgiFile = fopen(fileName, "rb"); + + char **guiIconsName = NULL; + + if (rgiFile != NULL) + { + char signature[5] = { 0 }; + short version = 0; + short reserved = 0; + short iconCount = 0; + short iconSize = 0; + + fread(signature, 1, 4, rgiFile); + fread(&version, sizeof(short), 1, rgiFile); + fread(&reserved, sizeof(short), 1, rgiFile); + fread(&iconCount, sizeof(short), 1, rgiFile); + fread(&iconSize, sizeof(short), 1, rgiFile); + + if ((signature[0] == 'r') && + (signature[1] == 'G') && + (signature[2] == 'I') && + (signature[3] == ' ')) + { + if (loadIconsName) + { + guiIconsName = (char **)RAYGUI_CALLOC(iconCount, sizeof(char *)); + for (int i = 0; i < iconCount; i++) + { + guiIconsName[i] = (char *)RAYGUI_CALLOC(RAYGUI_ICON_MAX_NAME_LENGTH, sizeof(char)); + fread(guiIconsName[i], 1, RAYGUI_ICON_MAX_NAME_LENGTH, rgiFile); + } + } + else fseek(rgiFile, iconCount*RAYGUI_ICON_MAX_NAME_LENGTH, SEEK_CUR); + + // Read icons data directly over internal icons array + fread(guiIconsPtr, sizeof(unsigned int), (int)iconCount*((int)iconSize*(int)iconSize/32), rgiFile); + } + + fclose(rgiFile); + } + + return guiIconsName; +} + +// Load icons from memory +// WARNING: Binary files only +char **GuiLoadIconsFromMemory(const unsigned char *fileData, int dataSize, bool loadIconsName) +{ + unsigned char *fileDataPtr = (unsigned char *)fileData; + char **guiIconsName = NULL; + + char signature[5] = { 0 }; + short version = 0; + short reserved = 0; + short iconCount = 0; + short iconSize = 0; + + memcpy(signature, fileDataPtr, 4); + memcpy(&version, fileDataPtr + 4, sizeof(short)); + memcpy(&reserved, fileDataPtr + 4 + 2, sizeof(short)); + memcpy(&iconCount, fileDataPtr + 4 + 2 + 2, sizeof(short)); + memcpy(&iconSize, fileDataPtr + 4 + 2 + 2 + 2, sizeof(short)); + fileDataPtr += 12; + + if ((signature[0] == 'r') && + (signature[1] == 'G') && + (signature[2] == 'I') && + (signature[3] == ' ')) + { + if (loadIconsName) + { + guiIconsName = (char **)RAYGUI_CALLOC(iconCount, sizeof(char *)); + for (int i = 0; i < iconCount; i++) + { + guiIconsName[i] = (char *)RAYGUI_CALLOC(RAYGUI_ICON_MAX_NAME_LENGTH, sizeof(char)); + memcpy(guiIconsName[i], fileDataPtr, RAYGUI_ICON_MAX_NAME_LENGTH); + fileDataPtr += RAYGUI_ICON_MAX_NAME_LENGTH; + } + } + else + { + // Skip icon name data if not required + fileDataPtr += iconCount*RAYGUI_ICON_MAX_NAME_LENGTH; + } + + int iconDataSize = iconCount*((int)iconSize*(int)iconSize/32)*(int)sizeof(unsigned int); + guiIconsPtr = (unsigned int *)RAYGUI_CALLOC(iconDataSize, 1); + + memcpy(guiIconsPtr, fileDataPtr, iconDataSize); + } + + return guiIconsName; +} + +// Draw selected icon using rectangles pixel-by-pixel +void GuiDrawIcon(int iconId, int posX, int posY, int pixelSize, Color color) +{ + #define BIT_CHECK(a,b) ((a) & (1u<<(b))) + + for (int i = 0, y = 0; i < RAYGUI_ICON_SIZE*RAYGUI_ICON_SIZE/32; i++) + { + for (int k = 0; k < 32; k++) + { + if (BIT_CHECK(guiIconsPtr[iconId*RAYGUI_ICON_DATA_ELEMENTS + i], k)) + { + #if !defined(RAYGUI_STANDALONE) + GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ (float)posX + (k%RAYGUI_ICON_SIZE)*pixelSize, (float)posY + y*pixelSize, (float)pixelSize, (float)pixelSize }, 0, BLANK, color); + #endif + } + + if ((k == 15) || (k == 31)) y++; + } + } +} + +// Set icon drawing size +void GuiSetIconScale(int scale) +{ + if (scale >= 1) guiIconScale = scale; +} + +// Get text width considering gui style and icon size (if required) +int GuiGetTextWidth(const char *text) +{ + #if !defined(ICON_TEXT_PADDING) + #define ICON_TEXT_PADDING 4 + #endif + + Vector2 textSize = { 0 }; + int textIconOffset = 0; + + if ((text != NULL) && (text[0] != '\0')) + { + if (text[0] == '#') + { + for (int i = 1; (i < 5) && (text[i] != '\0'); i++) + { + if (text[i] == '#') + { + textIconOffset = i; + break; + } + } + } + + text += textIconOffset; + + // Make sure guiFont is set, GuiGetStyle() initializes it lazynessly + float fontSize = (float)GuiGetStyle(DEFAULT, TEXT_SIZE); + + // Custom MeasureText() implementation + if ((guiFont.texture.id > 0) && (text != NULL)) + { + // Get size in bytes of text, considering end of line and line break + int size = 0; + for (int i = 0; i < MAX_LINE_BUFFER_SIZE; i++) + { + if ((text[i] != '\0') && (text[i] != '\n')) size++; + else break; + } + + float scaleFactor = fontSize/(float)guiFont.baseSize; + textSize.y = (float)guiFont.baseSize*scaleFactor; + float glyphWidth = 0.0f; + + for (int i = 0, codepointSize = 0; i < size; i += codepointSize) + { + int codepoint = GetCodepointNext(&text[i], &codepointSize); + int codepointIndex = GetGlyphIndex(guiFont, codepoint); + + if (guiFont.glyphs[codepointIndex].advanceX == 0) glyphWidth = ((float)guiFont.recs[codepointIndex].width*scaleFactor); + else glyphWidth = ((float)guiFont.glyphs[codepointIndex].advanceX*scaleFactor); + + textSize.x += (glyphWidth + (float)GuiGetStyle(DEFAULT, TEXT_SPACING)); + } + } + + if (textIconOffset > 0) textSize.x += (RAYGUI_ICON_SIZE + ICON_TEXT_PADDING); + } + + return (int)textSize.x; +} + +#endif // !RAYGUI_NO_ICONS + +//---------------------------------------------------------------------------------- +// Module Internal Functions Definition +//---------------------------------------------------------------------------------- +// Load style from memory +// WARNING: Binary files only +static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize) +{ + unsigned char *fileDataPtr = (unsigned char *)fileData; + + char signature[5] = { 0 }; + short version = 0; + short reserved = 0; + int propertyCount = 0; + + memcpy(signature, fileDataPtr, 4); + memcpy(&version, fileDataPtr + 4, sizeof(short)); + memcpy(&reserved, fileDataPtr + 4 + 2, sizeof(short)); + memcpy(&propertyCount, fileDataPtr + 4 + 2 + 2, sizeof(int)); + fileDataPtr += 12; + + if ((signature[0] == 'r') && + (signature[1] == 'G') && + (signature[2] == 'S') && + (signature[3] == ' ')) + { + short controlId = 0; + short propertyId = 0; + unsigned int propertyValue = 0; + + for (int i = 0; i < propertyCount; i++) + { + memcpy(&controlId, fileDataPtr, sizeof(short)); + memcpy(&propertyId, fileDataPtr + 2, sizeof(short)); + memcpy(&propertyValue, fileDataPtr + 2 + 2, sizeof(unsigned int)); + fileDataPtr += 8; + + if (controlId == 0) // DEFAULT control + { + // If a DEFAULT property is loaded, it is propagated to all controls + // NOTE: All DEFAULT properties should be defined first in the file + GuiSetStyle(0, (int)propertyId, propertyValue); + + if (propertyId < RAYGUI_MAX_PROPS_BASE) for (int j = 1; j < RAYGUI_MAX_CONTROLS; j++) GuiSetStyle(j, (int)propertyId, propertyValue); + } + else GuiSetStyle((int)controlId, (int)propertyId, propertyValue); + } + + // Font loading is highly dependant on raylib API to load font data and image + +#if !defined(RAYGUI_STANDALONE) + // Load custom font if available + int fontDataSize = 0; + memcpy(&fontDataSize, fileDataPtr, sizeof(int)); + fileDataPtr += 4; + + if (fontDataSize > 0) + { + Font font = { 0 }; + int fontType = 0; // 0-Normal, 1-SDF + + memcpy(&font.baseSize, fileDataPtr, sizeof(int)); + memcpy(&font.glyphCount, fileDataPtr + 4, sizeof(int)); + memcpy(&fontType, fileDataPtr + 4 + 4, sizeof(int)); + fileDataPtr += 12; + + // Load font white rectangle + Rectangle fontWhiteRec = { 0 }; + memcpy(&fontWhiteRec, fileDataPtr, sizeof(Rectangle)); + fileDataPtr += 16; + + // Load font image parameters + int fontImageUncompSize = 0; + int fontImageCompSize = 0; + memcpy(&fontImageUncompSize, fileDataPtr, sizeof(int)); + memcpy(&fontImageCompSize, fileDataPtr + 4, sizeof(int)); + fileDataPtr += 8; + + Image imFont = { 0 }; + imFont.mipmaps = 1; + memcpy(&imFont.width, fileDataPtr, sizeof(int)); + memcpy(&imFont.height, fileDataPtr + 4, sizeof(int)); + memcpy(&imFont.format, fileDataPtr + 4 + 4, sizeof(int)); + fileDataPtr += 12; + + if ((fontImageCompSize > 0) && (fontImageCompSize != fontImageUncompSize)) + { + // Compressed font atlas image data (DEFLATE), it requires DecompressData() + int dataUncompSize = 0; + unsigned char *compData = (unsigned char *)RAYGUI_CALLOC(fontImageCompSize, sizeof(unsigned char)); + memcpy(compData, fileDataPtr, fontImageCompSize); + fileDataPtr += fontImageCompSize; + + imFont.data = DecompressData(compData, fontImageCompSize, &dataUncompSize); + + // Security check, dataUncompSize must match the provided fontImageUncompSize + if (dataUncompSize != fontImageUncompSize) RAYGUI_LOG("WARNING: Uncompressed font atlas image data could be corrupted"); + + RAYGUI_FREE(compData); + } + else + { + // Font atlas image data is not compressed + imFont.data = (unsigned char *)RAYGUI_CALLOC(fontImageUncompSize, sizeof(unsigned char)); + memcpy(imFont.data, fileDataPtr, fontImageUncompSize); + fileDataPtr += fontImageUncompSize; + } + + if (font.texture.id != GetFontDefault().texture.id) UnloadTexture(font.texture); + font.texture = LoadTextureFromImage(imFont); + + RAYGUI_FREE(imFont.data); + + // Validate font atlas texture was loaded correctly + if (font.texture.id != 0) + { + // Load font recs data + int recsDataSize = font.glyphCount*sizeof(Rectangle); + int recsDataCompressedSize = 0; + + // WARNING: Version 400 adds the compression size parameter + if (version >= 400) + { + // RGS files version 400 support compressed recs data + memcpy(&recsDataCompressedSize, fileDataPtr, sizeof(int)); + fileDataPtr += sizeof(int); + } + + if ((recsDataCompressedSize > 0) && (recsDataCompressedSize != recsDataSize)) + { + // Recs data is compressed, uncompress it + unsigned char *recsDataCompressed = (unsigned char *)RAYGUI_CALLOC(recsDataCompressedSize, sizeof(unsigned char)); + + memcpy(recsDataCompressed, fileDataPtr, recsDataCompressedSize); + fileDataPtr += recsDataCompressedSize; + + int recsDataUncompSize = 0; + font.recs = (Rectangle *)DecompressData(recsDataCompressed, recsDataCompressedSize, &recsDataUncompSize); + + // Security check, data uncompressed size must match the expected original data size + if (recsDataUncompSize != recsDataSize) RAYGUI_LOG("WARNING: Uncompressed font recs data could be corrupted"); + + RAYGUI_FREE(recsDataCompressed); + } + else + { + // Recs data is uncompressed + font.recs = (Rectangle *)RAYGUI_CALLOC(font.glyphCount, sizeof(Rectangle)); + for (int i = 0; i < font.glyphCount; i++) + { + memcpy(&font.recs[i], fileDataPtr, sizeof(Rectangle)); + fileDataPtr += sizeof(Rectangle); + } + } + + // Load font glyphs info data + int glyphsDataSize = font.glyphCount*16; // 16 bytes data per glyph + int glyphsDataCompressedSize = 0; + + // WARNING: Version 400 adds the compression size parameter + if (version >= 400) + { + // RGS files version 400 support compressed glyphs data + memcpy(&glyphsDataCompressedSize, fileDataPtr, sizeof(int)); + fileDataPtr += sizeof(int); + } + + // Allocate required glyphs space to fill with data + font.glyphs = (GlyphInfo *)RAYGUI_CALLOC(font.glyphCount, sizeof(GlyphInfo)); + + if ((glyphsDataCompressedSize > 0) && (glyphsDataCompressedSize != glyphsDataSize)) + { + // Glyphs data is compressed, uncompress it + unsigned char *glypsDataCompressed = (unsigned char *)RAYGUI_CALLOC(glyphsDataCompressedSize, sizeof(unsigned char)); + + memcpy(glypsDataCompressed, fileDataPtr, glyphsDataCompressedSize); + fileDataPtr += glyphsDataCompressedSize; + + int glyphsDataUncompSize = 0; + unsigned char *glyphsDataUncomp = DecompressData(glypsDataCompressed, glyphsDataCompressedSize, &glyphsDataUncompSize); + + // Security check, data uncompressed size must match the expected original data size + if (glyphsDataUncompSize != glyphsDataSize) RAYGUI_LOG("WARNING: Uncompressed font glyphs data could be corrupted"); + + unsigned char *glyphsDataUncompPtr = glyphsDataUncomp; + + for (int i = 0; i < font.glyphCount; i++) + { + memcpy(&font.glyphs[i].value, glyphsDataUncompPtr, sizeof(int)); + memcpy(&font.glyphs[i].offsetX, glyphsDataUncompPtr + 4, sizeof(int)); + memcpy(&font.glyphs[i].offsetY, glyphsDataUncompPtr + 8, sizeof(int)); + memcpy(&font.glyphs[i].advanceX, glyphsDataUncompPtr + 12, sizeof(int)); + glyphsDataUncompPtr += 16; + } + + RAYGUI_FREE(glypsDataCompressed); + RAYGUI_FREE(glyphsDataUncomp); + } + else + { + // Glyphs data is uncompressed + for (int i = 0; i < font.glyphCount; i++) + { + memcpy(&font.glyphs[i].value, fileDataPtr, sizeof(int)); + memcpy(&font.glyphs[i].offsetX, fileDataPtr + 4, sizeof(int)); + memcpy(&font.glyphs[i].offsetY, fileDataPtr + 8, sizeof(int)); + memcpy(&font.glyphs[i].advanceX, fileDataPtr + 12, sizeof(int)); + fileDataPtr += 16; + } + } + } + else font = GetFontDefault(); // Fallback in case of errors loading font atlas texture + + GuiSetFont(font); + + // Set font texture source rectangle to be used as white texture to draw shapes + // NOTE: It makes possible to draw shapes and text (full UI) in a single draw call + if ((fontWhiteRec.x > 0) && + (fontWhiteRec.y > 0) && + (fontWhiteRec.width > 0) && + (fontWhiteRec.height > 0)) SetShapesTexture(font.texture, fontWhiteRec); + } +#endif + } +} + +// Get text bounds considering control bounds +static Rectangle GetTextBounds(int control, Rectangle bounds) +{ + Rectangle textBounds = bounds; + + textBounds.x = bounds.x + GuiGetStyle(control, BORDER_WIDTH); + textBounds.y = bounds.y + GuiGetStyle(control, BORDER_WIDTH) + GuiGetStyle(control, TEXT_PADDING); + textBounds.width = bounds.width - 2*GuiGetStyle(control, BORDER_WIDTH) - 2*GuiGetStyle(control, TEXT_PADDING); + textBounds.height = bounds.height - 2*GuiGetStyle(control, BORDER_WIDTH) - 2*GuiGetStyle(control, TEXT_PADDING); // NOTE: Text is processed line per line! + + // Depending on control, TEXT_PADDING and TEXT_ALIGNMENT properties could affect the text-bounds + switch (control) + { + case COMBOBOX: + case DROPDOWNBOX: + case LISTVIEW: + // TODO: Special cases (no label): COMBOBOX, DROPDOWNBOX, LISTVIEW + case SLIDER: + case CHECKBOX: + case VALUEBOX: + case CONTROL11: + // TODO: More special cases (label on side): SLIDER, CHECKBOX, VALUEBOX, SPINNER + default: + { + // TODO: WARNING: TEXT_ALIGNMENT is already considered in GuiDrawText() + if (GuiGetStyle(control, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT) textBounds.x -= GuiGetStyle(control, TEXT_PADDING); + else textBounds.x += GuiGetStyle(control, TEXT_PADDING); + } + break; + } + + return textBounds; +} + +// Get text icon if provided and move text cursor +// NOTE: Up to #999# values supported for iconId +static const char *GetTextIcon(const char *text, int *iconId) +{ +#if !defined(RAYGUI_NO_ICONS) + *iconId = -1; + if (text[0] == '#') // Maybe it is stars with an icon, ending # must be found + { + char iconValue[4] = { 0 }; // Maximum length for icon value: 3 digits + '\0' + + int pos = 1; + while ((pos < 4) && (text[pos] >= '0') && (text[pos] <= '9')) + { + iconValue[pos - 1] = text[pos]; + pos++; + } + + if (text[pos] == '#') + { + *iconId = TextToInteger(iconValue); + + // Move text pointer after icon + // WARNING: If only icon provided, it could point to EOL character: '\0' + if (*iconId >= 0) text += (pos + 1); + } + } +#endif + + return text; +} + +// Get text divided into lines (by line-breaks '\n') +// WARNING: It returns pointers to new lines but it does not add NULL ('\0') terminator! +static const char **GetTextLines(const char *text, int *count) +{ + #define RAYGUI_MAX_TEXT_LINES 128 + + static const char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 }; + for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings + + int textLength = (int)strlen(text); + + lines[0] = text; + *count = 1; + + for (int i = 0, k = 0; (i < textLength) && (*count < RAYGUI_MAX_TEXT_LINES); i++) + { + if (text[i] == '\n') + { + k++; + lines[k] = &text[i + 1]; // WARNING: next value is valid? + *count += 1; + } + } + + return lines; +} + +// Get text width to next space for provided string +static float GetNextSpaceWidth(const char *text, int *nextSpaceIndex) +{ + float width = 0; + int codepointByteCount = 0; + int codepoint = 0; + int index = 0; + float glyphWidth = 0; + float scaleFactor = (float)GuiGetStyle(DEFAULT, TEXT_SIZE)/guiFont.baseSize; + + for (int i = 0; text[i] != '\0'; i++) + { + if (text[i] != ' ') + { + codepoint = GetCodepoint(&text[i], &codepointByteCount); + index = GetGlyphIndex(guiFont, codepoint); + glyphWidth = (guiFont.glyphs[index].advanceX == 0)? guiFont.recs[index].width*scaleFactor : guiFont.glyphs[index].advanceX*scaleFactor; + width += (glyphWidth + (float)GuiGetStyle(DEFAULT, TEXT_SPACING)); + } + else + { + *nextSpaceIndex = i; + break; + } + } + + return width; +} + +// Gui draw text using default font +static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, Color tint) +{ + #define TEXT_VALIGN_PIXEL_OFFSET(h) ((int)h%2) // Vertical alignment for pixel perfect + + #if !defined(ICON_TEXT_PADDING) + #define ICON_TEXT_PADDING 4 + #endif + + if ((text == NULL) || (text[0] == '\0')) return; // Security check + + // PROCEDURE: + // - Text is processed line per line + // - For every line, horizontal alignment is defined + // - For all text, vertical alignment is defined (multiline text only) + // - For every line, wordwrap mode is checked (useful for GuitextBox(), read-only) + + // Get text lines (using '\n' as delimiter) to be processed individually + // WARNING: GuiTextSplit() function can't be used now because it can have already been used + // before the GuiDrawText() call and its buffer is static, it would be overriden :( + int lineCount = 0; + const char **lines = GetTextLines(text, &lineCount); + + // Text style variables + //int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT); + int alignmentVertical = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT_VERTICAL); + int wrapMode = GuiGetStyle(DEFAULT, TEXT_WRAP_MODE); // Wrap-mode only available in read-only mode, no for text editing + + // TODO: WARNING: This totalHeight is not valid for vertical alignment in case of word-wrap + float totalHeight = (float)(lineCount*GuiGetStyle(DEFAULT, TEXT_SIZE) + (lineCount - 1)*GuiGetStyle(DEFAULT, TEXT_LINE_SPACING)); + float posOffsetY = 0.0f; + + for (int i = 0; i < lineCount; i++) + { + int iconId = 0; + lines[i] = GetTextIcon(lines[i], &iconId); // Check text for icon and move cursor + + // Get text position depending on alignment and iconId + //--------------------------------------------------------------------------------- + Vector2 textBoundsPosition = { textBounds.x, textBounds.y }; + float textBoundsWidthOffset = 0.0f; + + // NOTE: Get text size after icon has been processed + // WARNING: GuiGetTextWidth() also processes text icon to get width! -> Really needed? + int textSizeX = GuiGetTextWidth(lines[i]); + + // If text requires an icon, add size to measure + if (iconId >= 0) + { + textSizeX += RAYGUI_ICON_SIZE*guiIconScale; + + // WARNING: If only icon provided, text could be pointing to EOF character: '\0' +#if !defined(RAYGUI_NO_ICONS) + if ((lines[i] != NULL) && (lines[i][0] != '\0')) textSizeX += ICON_TEXT_PADDING; +#endif + } + + // Check guiTextAlign global variables + switch (alignment) + { + case TEXT_ALIGN_LEFT: textBoundsPosition.x = textBounds.x; break; + case TEXT_ALIGN_CENTER: textBoundsPosition.x = textBounds.x + textBounds.width/2 - textSizeX/2; break; + case TEXT_ALIGN_RIGHT: textBoundsPosition.x = textBounds.x + textBounds.width - textSizeX; break; + default: break; + } + + if (textSizeX > textBounds.width && (lines[i] != NULL) && (lines[i][0] != '\0')) textBoundsPosition.x = textBounds.x; + + switch (alignmentVertical) + { + // Only valid in case of wordWrap = 0; + case TEXT_ALIGN_TOP: textBoundsPosition.y = textBounds.y + posOffsetY; break; + case TEXT_ALIGN_MIDDLE: textBoundsPosition.y = textBounds.y + posOffsetY + textBounds.height/2 - totalHeight/2 + TEXT_VALIGN_PIXEL_OFFSET(textBounds.height); break; + case TEXT_ALIGN_BOTTOM: textBoundsPosition.y = textBounds.y + posOffsetY + textBounds.height - totalHeight + TEXT_VALIGN_PIXEL_OFFSET(textBounds.height); break; + default: break; + } + + // NOTE: Make sure getting pixel-perfect coordinates, + // In case of decimals, it could result in text positioning artifacts + textBoundsPosition.x = (float)((int)textBoundsPosition.x); + textBoundsPosition.y = (float)((int)textBoundsPosition.y); + //--------------------------------------------------------------------------------- + + // Draw text (with icon if available) + //--------------------------------------------------------------------------------- +#if !defined(RAYGUI_NO_ICONS) + if (iconId >= 0) + { + // NOTE: Considering icon height, probably different than text size + GuiDrawIcon(iconId, (int)textBoundsPosition.x, (int)(textBounds.y + textBounds.height/2 - RAYGUI_ICON_SIZE*guiIconScale/2 + TEXT_VALIGN_PIXEL_OFFSET(textBounds.height)), guiIconScale, tint); + textBoundsPosition.x += (float)(RAYGUI_ICON_SIZE*guiIconScale + ICON_TEXT_PADDING); + textBoundsWidthOffset = (float)(RAYGUI_ICON_SIZE*guiIconScale + ICON_TEXT_PADDING); + } +#endif + // Get size in bytes of text, + // considering end of line and line break + int lineSize = 0; + for (int c = 0; (lines[i][c] != '\0') && (lines[i][c] != '\n') && (lines[i][c] != '\r'); c++, lineSize++){ } + float scaleFactor = (float)GuiGetStyle(DEFAULT, TEXT_SIZE)/guiFont.baseSize; + + int lastSpaceIndex = 0; + bool tempWrapCharMode = false; + + int textOffsetY = 0; + float textOffsetX = 0.0f; + float glyphWidth = 0; + + int ellipsisWidth = GuiGetTextWidth("..."); + bool textOverflow = false; + for (int c = 0, codepointSize = 0; c < lineSize; c += codepointSize) + { + int codepoint = GetCodepointNext(&lines[i][c], &codepointSize); + int index = GetGlyphIndex(guiFont, codepoint); + + // NOTE: Normally, exiting the decoding sequence as soon as a bad byte is found (and return 0x3f) + // but all of the bad bytes need to be drawn using the '?' symbol, moving one byte + if (codepoint == 0x3f) codepointSize = 1; // TODO: Review not recognized codepoints size + + // Get glyph width to check if it goes out of bounds + if (guiFont.glyphs[index].advanceX == 0) glyphWidth = ((float)guiFont.recs[index].width*scaleFactor); + else glyphWidth = (float)guiFont.glyphs[index].advanceX*scaleFactor; + + // Wrap mode text measuring, to validate if + // it can be drawn or a new line is required + if (wrapMode == TEXT_WRAP_CHAR) + { + // Jump to next line if current character reach end of the box limits + if ((textOffsetX + glyphWidth) > textBounds.width - textBoundsWidthOffset) + { + textOffsetX = 0.0f; + textOffsetY += (GuiGetStyle(DEFAULT, TEXT_SIZE) + GuiGetStyle(DEFAULT, TEXT_LINE_SPACING)); + + if (tempWrapCharMode) // Wrap at char level when too long words + { + wrapMode = TEXT_WRAP_WORD; + tempWrapCharMode = false; + } + } + } + else if (wrapMode == TEXT_WRAP_WORD) + { + if (codepoint == 32) lastSpaceIndex = c; + + // Get width to next space in line + int nextSpaceIndex = 0; + float nextSpaceWidth = GetNextSpaceWidth(lines[i] + c, &nextSpaceIndex); + + int nextSpaceIndex2 = 0; + float nextWordSize = GetNextSpaceWidth(lines[i] + lastSpaceIndex + 1, &nextSpaceIndex2); + + if (nextWordSize > textBounds.width - textBoundsWidthOffset) + { + // Considering the case the next word is longer than bounds + tempWrapCharMode = true; + wrapMode = TEXT_WRAP_CHAR; + } + else if ((textOffsetX + nextSpaceWidth) > textBounds.width - textBoundsWidthOffset) + { + textOffsetX = 0.0f; + textOffsetY += (GuiGetStyle(DEFAULT, TEXT_SIZE) + GuiGetStyle(DEFAULT, TEXT_LINE_SPACING)); + } + } + + if (codepoint == '\n') break; // WARNING: Lines are already processed manually, no need to keep drawing after this codepoint + else + { + // TODO: There are multiple types of spaces in Unicode, + // maybe it's a good idea to add support for more: http://jkorpela.fi/chars/spaces.html + if ((codepoint != ' ') && (codepoint != '\t')) // Do not draw codepoints with no glyph + { + if (wrapMode == TEXT_WRAP_NONE) + { + // Draw only required text glyphs fitting the textBounds.width + if (textSizeX > textBounds.width) + { + if (textOffsetX <= (textBounds.width - glyphWidth - textBoundsWidthOffset - ellipsisWidth)) + { + DrawTextCodepoint(guiFont, codepoint, RAYGUI_CLITERAL(Vector2){ textBoundsPosition.x + textOffsetX, textBoundsPosition.y + textOffsetY }, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), GuiFade(tint, guiAlpha)); + } + else if (!textOverflow) + { + textOverflow = true; + + for (int j = 0; j < ellipsisWidth; j += ellipsisWidth/3) + { + DrawTextCodepoint(guiFont, '.', RAYGUI_CLITERAL(Vector2){ textBoundsPosition.x + textOffsetX + j, textBoundsPosition.y + textOffsetY }, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), GuiFade(tint, guiAlpha)); + } + } + } + else + { + DrawTextCodepoint(guiFont, codepoint, RAYGUI_CLITERAL(Vector2){ textBoundsPosition.x + textOffsetX, textBoundsPosition.y + textOffsetY }, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), GuiFade(tint, guiAlpha)); + } + } + else if ((wrapMode == TEXT_WRAP_CHAR) || (wrapMode == TEXT_WRAP_WORD)) + { + // Draw only glyphs inside the bounds + if ((textBoundsPosition.y + textOffsetY) <= (textBounds.y + textBounds.height - GuiGetStyle(DEFAULT, TEXT_SIZE))) + { + DrawTextCodepoint(guiFont, codepoint, RAYGUI_CLITERAL(Vector2){ textBoundsPosition.x + textOffsetX, textBoundsPosition.y + textOffsetY }, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), GuiFade(tint, guiAlpha)); + } + } + } + + if (guiFont.glyphs[index].advanceX == 0) textOffsetX += ((float)guiFont.recs[index].width*scaleFactor + (float)GuiGetStyle(DEFAULT, TEXT_SPACING)); + else textOffsetX += ((float)guiFont.glyphs[index].advanceX*scaleFactor + (float)GuiGetStyle(DEFAULT, TEXT_SPACING)); + } + } + + if (wrapMode == TEXT_WRAP_NONE) posOffsetY += (float)(GuiGetStyle(DEFAULT, TEXT_SIZE) + GuiGetStyle(DEFAULT, TEXT_LINE_SPACING)); + else if ((wrapMode == TEXT_WRAP_CHAR) || (wrapMode == TEXT_WRAP_WORD)) posOffsetY += (textOffsetY + (float)GuiGetStyle(DEFAULT, TEXT_LINE_SPACING)); + //--------------------------------------------------------------------------------- + } + +#if defined(RAYGUI_DEBUG_TEXT_BOUNDS) + GuiDrawRectangle(textBounds, 0, WHITE, Fade(BLUE, 0.4f)); +#endif +} + +// Gui draw rectangle using default raygui plain style with borders +static void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor, Color color) +{ + if (color.a > 0) + { + // Draw rectangle filled with color + DrawRectangle((int)rec.x, (int)rec.y, (int)rec.width, (int)rec.height, GuiFade(color, guiAlpha)); + } + + if (borderWidth > 0) + { + // Draw rectangle border lines with color + DrawRectangle((int)rec.x, (int)rec.y, (int)rec.width, borderWidth, GuiFade(borderColor, guiAlpha)); + DrawRectangle((int)rec.x, (int)rec.y + borderWidth, borderWidth, (int)rec.height - 2*borderWidth, GuiFade(borderColor, guiAlpha)); + DrawRectangle((int)rec.x + (int)rec.width - borderWidth, (int)rec.y + borderWidth, borderWidth, (int)rec.height - 2*borderWidth, GuiFade(borderColor, guiAlpha)); + DrawRectangle((int)rec.x, (int)rec.y + (int)rec.height - borderWidth, (int)rec.width, borderWidth, GuiFade(borderColor, guiAlpha)); + } + +#if defined(RAYGUI_DEBUG_RECS_BOUNDS) + DrawRectangle((int)rec.x, (int)rec.y, (int)rec.width, (int)rec.height, Fade(RED, 0.4f)); +#endif +} + +// Draw tooltip using control bounds +static void GuiTooltip(Rectangle controlRec) +{ + if (!guiLocked && guiTooltip && (guiTooltipPtr != NULL) && !guiControlExclusiveMode) + { + Vector2 textSize = MeasureTextEx(GuiGetFont(), guiTooltipPtr, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), (float)GuiGetStyle(DEFAULT, TEXT_SPACING)); + + if ((controlRec.x + textSize.x + 16) > GetScreenWidth()) controlRec.x -= (textSize.x + 16 - controlRec.width); + + int lineCount = 0; + GetTextLines(guiTooltipPtr, &lineCount); // Only using the line count + if ((controlRec.y + controlRec.height + textSize.y + 4 + 8*lineCount) > GetScreenHeight()) + controlRec.y -= (controlRec.height + textSize.y + 4 + 8*lineCount); + + // TODO: Probably TEXT_LINE_SPACING should be considered on panel size instead of hardcoding 8.0f + GuiPanel(RAYGUI_CLITERAL(Rectangle){ controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, textSize.y + 8.0f*lineCount }, NULL); + + int textPadding = GuiGetStyle(LABEL, TEXT_PADDING); + int textAlignment = GuiGetStyle(LABEL, TEXT_ALIGNMENT); + GuiSetStyle(LABEL, TEXT_PADDING, 0); + GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); + GuiLabel(RAYGUI_CLITERAL(Rectangle){ controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, textSize.y + 8.0f*lineCount }, guiTooltipPtr); + GuiSetStyle(LABEL, TEXT_ALIGNMENT, textAlignment); + GuiSetStyle(LABEL, TEXT_PADDING, textPadding); + } +} + +// Split controls text into multiple strings +// Also check for multiple columns (required by GuiToggleGroup()) +static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow) +{ + // NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter) + // inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated, + // all used memory is static... it has some limitations: + // 1. Maximum number of possible split strings is set by RAYGUI_TEXTSPLIT_MAX_ITEMS + // 2. Maximum size of text to split is RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE + // NOTE: Those definitions could be externally provided if required + + // TODO: HACK: GuiTextSplit() - Review how textRows are returned to user + // textRow is an externally provided array of integers that stores row number for every splitted string + + #if !defined(RAYGUI_TEXTSPLIT_MAX_ITEMS) + #define RAYGUI_TEXTSPLIT_MAX_ITEMS 128 + #endif + #if !defined(RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE) + #define RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE 1024 + #endif + + static const char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data) + static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; // Buffer data (text input copy with '\0' added) + memset(buffer, 0, RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE); + + result[0] = buffer; + int counter = 1; + + if (textRow != NULL) textRow[0] = 0; + + // Count how many substrings text contains and point to every one of them + for (int i = 0; i < RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE; i++) + { + buffer[i] = text[i]; + if (buffer[i] == '\0') break; + else if ((buffer[i] == delimiter) || (buffer[i] == '\n')) + { + result[counter] = buffer + i + 1; + + if (textRow != NULL) + { + if (buffer[i] == '\n') textRow[counter] = textRow[counter - 1] + 1; + else textRow[counter] = textRow[counter - 1]; + } + + buffer[i] = '\0'; // Set an end of string at this point + + counter++; + if (counter >= RAYGUI_TEXTSPLIT_MAX_ITEMS) break; + } + } + + *count = counter; + + return result; +} + +// Convert color data from RGB to HSV +// NOTE: Color data should be passed normalized +static Vector3 ConvertRGBtoHSV(Vector3 rgb) +{ + Vector3 hsv = { 0 }; + float min = 0.0f; + float max = 0.0f; + float delta = 0.0f; + + min = (rgb.x < rgb.y)? rgb.x : rgb.y; + min = (min < rgb.z)? min : rgb.z; + + max = (rgb.x > rgb.y)? rgb.x : rgb.y; + max = (max > rgb.z)? max : rgb.z; + + hsv.z = max; // Value + delta = max - min; + + if (delta < 0.00001f) + { + hsv.y = 0.0f; + hsv.x = 0.0f; // Undefined, maybe NAN? + return hsv; + } + + if (max > 0.0f) + { + // NOTE: If max is 0, this divide would cause a crash + hsv.y = (delta/max); // Saturation + } + else + { + // NOTE: If max is 0, then r = g = b = 0, s = 0, h is undefined + hsv.y = 0.0f; + hsv.x = 0.0f; // Undefined, maybe NAN? + return hsv; + } + + // NOTE: Comparing float values could not work properly + if (rgb.x >= max) hsv.x = (rgb.y - rgb.z)/delta; // Between yellow & magenta + else + { + if (rgb.y >= max) hsv.x = 2.0f + (rgb.z - rgb.x)/delta; // Between cyan & yellow + else hsv.x = 4.0f + (rgb.x - rgb.y)/delta; // Between magenta & cyan + } + + hsv.x *= 60.0f; // Convert to degrees + + if (hsv.x < 0.0f) hsv.x += 360.0f; + + return hsv; +} + +// Convert color data from HSV to RGB +// NOTE: Color data should be passed normalized +static Vector3 ConvertHSVtoRGB(Vector3 hsv) +{ + Vector3 rgb = { 0 }; + float hh = 0.0f, p = 0.0f, q = 0.0f, t = 0.0f, ff = 0.0f; + long i = 0; + + // NOTE: Comparing float values could not work properly + if (hsv.y <= 0.0f) + { + rgb.x = hsv.z; + rgb.y = hsv.z; + rgb.z = hsv.z; + return rgb; + } + + hh = hsv.x; + if (hh >= 360.0f) hh = 0.0f; + hh /= 60.0f; + + i = (long)hh; + ff = hh - i; + p = hsv.z*(1.0f - hsv.y); + q = hsv.z*(1.0f - (hsv.y*ff)); + t = hsv.z*(1.0f - (hsv.y*(1.0f - ff))); + + switch (i) + { + case 0: + { + rgb.x = hsv.z; + rgb.y = t; + rgb.z = p; + } break; + case 1: + { + rgb.x = q; + rgb.y = hsv.z; + rgb.z = p; + } break; + case 2: + { + rgb.x = p; + rgb.y = hsv.z; + rgb.z = t; + } break; + case 3: + { + rgb.x = p; + rgb.y = q; + rgb.z = hsv.z; + } break; + case 4: + { + rgb.x = t; + rgb.y = p; + rgb.z = hsv.z; + } break; + case 5: + default: + { + rgb.x = hsv.z; + rgb.y = p; + rgb.z = q; + } break; + } + + return rgb; +} + +// Scroll bar control (used by GuiScrollPanel()) +static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue) +{ + GuiState state = guiState; + + // Is the scrollbar horizontal or vertical? + bool isVertical = (bounds.width > bounds.height)? false : true; + + // The size (width or height depending on scrollbar type) of the spinner buttons + const int spinnerSize = GuiGetStyle(SCROLLBAR, ARROWS_VISIBLE)? + (isVertical? (int)bounds.width - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH) : + (int)bounds.height - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH)) : 0; + + // Arrow buttons [<] [>] [∧] [∨] + Rectangle arrowUpLeft = { 0 }; + Rectangle arrowDownRight = { 0 }; + + // Actual area of the scrollbar excluding the arrow buttons + Rectangle scrollbar = { 0 }; + + // Slider bar that moves --[///]----- + Rectangle slider = { 0 }; + + // Normalize value + if (value > maxValue) value = maxValue; + if (value < minValue) value = minValue; + + int valueRange = maxValue - minValue; + if (valueRange <= 0) valueRange = 1; + + int sliderSize = GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE); + if (sliderSize < 1) sliderSize = 1; // TODO: Consider a minimum slider size + + // Calculate rectangles for all of the components + arrowUpLeft = RAYGUI_CLITERAL(Rectangle){ + (float)bounds.x + GuiGetStyle(SCROLLBAR, BORDER_WIDTH), + (float)bounds.y + GuiGetStyle(SCROLLBAR, BORDER_WIDTH), + (float)spinnerSize, (float)spinnerSize }; + + if (isVertical) + { + arrowDownRight = RAYGUI_CLITERAL(Rectangle){ (float)bounds.x + GuiGetStyle(SCROLLBAR, BORDER_WIDTH), (float)bounds.y + bounds.height - spinnerSize - GuiGetStyle(SCROLLBAR, BORDER_WIDTH), (float)spinnerSize, (float)spinnerSize }; + scrollbar = RAYGUI_CLITERAL(Rectangle){ bounds.x + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_PADDING), arrowUpLeft.y + arrowUpLeft.height, bounds.width - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_PADDING)), bounds.height - arrowUpLeft.height - arrowDownRight.height - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH) }; + + // Make sure the slider won't get outside of the scrollbar + sliderSize = (sliderSize >= scrollbar.height)? ((int)scrollbar.height - 2) : sliderSize; + slider = RAYGUI_CLITERAL(Rectangle){ + bounds.x + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING), + scrollbar.y + (int)(((float)(value - minValue)/valueRange)*(scrollbar.height - sliderSize)), + bounds.width - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING)), + (float)sliderSize }; + } + else // horizontal + { + arrowDownRight = RAYGUI_CLITERAL(Rectangle){ (float)bounds.x + bounds.width - spinnerSize - GuiGetStyle(SCROLLBAR, BORDER_WIDTH), (float)bounds.y + GuiGetStyle(SCROLLBAR, BORDER_WIDTH), (float)spinnerSize, (float)spinnerSize }; + scrollbar = RAYGUI_CLITERAL(Rectangle){ arrowUpLeft.x + arrowUpLeft.width, bounds.y + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_PADDING), bounds.width - arrowUpLeft.width - arrowDownRight.width - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH), bounds.height - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_PADDING)) }; + + // Make sure the slider won't get outside of the scrollbar + sliderSize = (sliderSize >= scrollbar.width)? ((int)scrollbar.width - 2) : sliderSize; + slider = RAYGUI_CLITERAL(Rectangle){ + scrollbar.x + (int)(((float)(value - minValue)/valueRange)*(scrollbar.width - sliderSize)), + bounds.y + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING), + (float)sliderSize, + bounds.height - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING)) }; + } + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked) + { + Vector2 mousePoint = GUI_POINTER_POSITION; + + if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds + { + if (GUI_BUTTON_DOWN && + !CheckCollisionPointRec(mousePoint, arrowUpLeft) && + !CheckCollisionPointRec(mousePoint, arrowDownRight)) + { + if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) + { + state = STATE_PRESSED; + + if (isVertical) value = (int)(((float)(mousePoint.y - scrollbar.y - slider.height/2)*valueRange)/(scrollbar.height - slider.height) + minValue); + else value = (int)(((float)(mousePoint.x - scrollbar.x - slider.width/2)*valueRange)/(scrollbar.width - slider.width) + minValue); + } + } + else + { + guiControlExclusiveMode = false; + guiControlExclusiveRec = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 }; + } + } + else if (CheckCollisionPointRec(mousePoint, bounds)) + { + state = STATE_FOCUSED; + + // Handle mouse wheel + float scrollDelta = GUI_SCROLL_DELTA; + if (scrollDelta != 0) value += (int)scrollDelta; + + // Handle mouse button down + if (GUI_BUTTON_PRESSED) + { + guiControlExclusiveMode = true; + guiControlExclusiveRec = bounds; // Store bounds as an identifier when dragging starts + + // Check arrows click + if (CheckCollisionPointRec(mousePoint, arrowUpLeft)) value -= valueRange/GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + else if (CheckCollisionPointRec(mousePoint, arrowDownRight)) value += valueRange/GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + else if (!CheckCollisionPointRec(mousePoint, slider)) + { + // If click on scrollbar position but not on slider, place slider directly on that position + if (isVertical) value = (int)(((float)(mousePoint.y - scrollbar.y - slider.height/2)*valueRange)/(scrollbar.height - slider.height) + minValue); + else value = (int)(((float)(mousePoint.x - scrollbar.x - slider.width/2)*valueRange)/(scrollbar.width - slider.width) + minValue); + } + + state = STATE_PRESSED; + } + + // Keyboard control on mouse hover scrollbar + /* + if (isVertical) + { + if (GUI_KEY_DOWN(KEY_DOWN)) value += 5; + else if (GUI_KEY_DOWN(KEY_UP)) value -= 5; + } + else + { + if (GUI_KEY_DOWN(KEY_RIGHT)) value += 5; + else if (GUI_KEY_DOWN(KEY_LEFT)) value -= 5; + } + */ + } + + // Normalize value + if (value > maxValue) value = maxValue; + if (value < minValue) value = minValue; + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + GuiDrawRectangle(bounds, GuiGetStyle(SCROLLBAR, BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER + state*3)), GetColor(GuiGetStyle(DEFAULT, BORDER_COLOR_DISABLED))); // Draw the background + + GuiDrawRectangle(scrollbar, 0, BLANK, GetColor(GuiGetStyle(BUTTON, BASE_COLOR_NORMAL))); // Draw the scrollbar active area background + GuiDrawRectangle(slider, 0, BLANK, GetColor(GuiGetStyle(SLIDER, BORDER + state*3))); // Draw the slider bar + + // Draw arrows (using icon if available) + if (GuiGetStyle(SCROLLBAR, ARROWS_VISIBLE)) + { +#if defined(RAYGUI_NO_ICONS) + GuiDrawText(isVertical? "^" : "<", + RAYGUI_CLITERAL(Rectangle){ arrowUpLeft.x, arrowUpLeft.y, isVertical? bounds.width : bounds.height, isVertical? bounds.width : bounds.height }, + TEXT_ALIGN_CENTER, GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + (state*3)))); + GuiDrawText(isVertical? "v" : ">", + RAYGUI_CLITERAL(Rectangle){ arrowDownRight.x, arrowDownRight.y, isVertical? bounds.width : bounds.height, isVertical? bounds.width : bounds.height }, + TEXT_ALIGN_CENTER, GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + (state*3)))); +#else + GuiDrawText(isVertical? "#121#" : "#118#", + RAYGUI_CLITERAL(Rectangle){ arrowUpLeft.x, arrowUpLeft.y, isVertical? bounds.width : bounds.height, isVertical? bounds.width : bounds.height }, + TEXT_ALIGN_CENTER, GetColor(GuiGetStyle(SCROLLBAR, TEXT + state*3))); // ICON_ARROW_UP_FILL / ICON_ARROW_LEFT_FILL + GuiDrawText(isVertical? "#120#" : "#119#", + RAYGUI_CLITERAL(Rectangle){ arrowDownRight.x, arrowDownRight.y, isVertical? bounds.width : bounds.height, isVertical? bounds.width : bounds.height }, + TEXT_ALIGN_CENTER, GetColor(GuiGetStyle(SCROLLBAR, TEXT + state*3))); // ICON_ARROW_DOWN_FILL / ICON_ARROW_RIGHT_FILL +#endif + } + //-------------------------------------------------------------------- + + return value; +} + +// Color fade-in or fade-out, alpha goes from 0.0f to 1.0f +// WARNING: It multiplies current alpha by alpha scale factor +static Color GuiFade(Color color, float alpha) +{ + if (alpha < 0.0f) alpha = 0.0f; + else if (alpha > 1.0f) alpha = 1.0f; + + Color result = { color.r, color.g, color.b, (unsigned char)(color.a*alpha) }; + + return result; +} + +#if defined(RAYGUI_STANDALONE) +// Returns a Color struct from hexadecimal value +static Color GetColor(int hexValue) +{ + Color color; + + color.r = (unsigned char)(hexValue >> 24) & 0xff; + color.g = (unsigned char)(hexValue >> 16) & 0xff; + color.b = (unsigned char)(hexValue >> 8) & 0xff; + color.a = (unsigned char)hexValue & 0xff; + + return color; +} + +// Returns hexadecimal value for a Color +static int ColorToInt(Color color) +{ + return (((int)color.r << 24) | ((int)color.g << 16) | ((int)color.b << 8) | (int)color.a); +} + +// Check if point is inside rectangle +static bool CheckCollisionPointRec(Vector2 point, Rectangle rec) +{ + bool collision = false; + + if ((point.x >= rec.x) && (point.x <= (rec.x + rec.width)) && + (point.y >= rec.y) && (point.y <= (rec.y + rec.height))) collision = true; + + return collision; +} + +// Formatting of text with variables to 'embed' +static const char *TextFormat(const char *text, ...) +{ + #if !defined(RAYGUI_TEXTFORMAT_MAX_SIZE) + #define RAYGUI_TEXTFORMAT_MAX_SIZE 256 + #endif + + static char buffer[RAYGUI_TEXTFORMAT_MAX_SIZE]; + + va_list args; + va_start(args, text); + vsnprintf(buffer, RAYGUI_TEXTFORMAT_MAX_SIZE, text, args); + va_end(args); + + return buffer; +} + +// Draw rectangle with vertical gradient fill color +// NOTE: This function is only used by GuiColorPicker() +static void DrawRectangleGradientV(int posX, int posY, int width, int height, Color color1, Color color2) +{ + Rectangle bounds = { (float)posX, (float)posY, (float)width, (float)height }; + DrawRectangleGradientEx(bounds, color1, color2, color2, color1); +} + +// Split string into multiple strings +const char **TextSplit(const char *text, char delimiter, int *count) +{ + // NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter) + // inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated, + // all used memory is static... it has some limitations: + // 1. Maximum number of possible split strings is set by RAYGUI_TEXTSPLIT_MAX_ITEMS + // 2. Maximum size of text to split is RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE + + #if !defined(RAYGUI_TEXTSPLIT_MAX_ITEMS) + #define RAYGUI_TEXTSPLIT_MAX_ITEMS 128 + #endif + #if !defined(RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE) + #define RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE 1024 + #endif + + static const char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; + static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; + memset(buffer, 0, RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE); + + result[0] = buffer; + int counter = 0; + + if (text != NULL) + { + counter = 1; + + // Count how many substrings text contains and point to every one of them + for (int i = 0; i < RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE; i++) + { + buffer[i] = text[i]; + if (buffer[i] == '\0') break; + else if (buffer[i] == delimiter) + { + buffer[i] = '\0'; // Set an end of string at this point + result[counter] = buffer + i + 1; + counter++; + + if (counter == RAYGUI_TEXTSPLIT_MAX_ITEMS) break; + } + } + } + + *count = counter; + return result; +} + +// Get integer value from text +// NOTE: This function replaces atoi() [stdlib.h] +static int TextToInteger(const char *text) +{ + int value = 0; + int sign = 1; + + if ((text[0] == '+') || (text[0] == '-')) + { + if (text[0] == '-') sign = -1; + text++; + } + + for (int i = 0; ((text[i] >= '0') && (text[i] <= '9')); i++) value = value*10 + (int)(text[i] - '0'); + + return value*sign; +} + +// Get float value from text +// NOTE: This function replaces atof() [stdlib.h] +// WARNING: Only '.' character is understood as decimal point +static float TextToFloat(const char *text) +{ + float value = 0.0f; + float sign = 1.0f; + + if ((text[0] == '+') || (text[0] == '-')) + { + if (text[0] == '-') sign = -1.0f; + text++; + } + + int i = 0; + for (; ((text[i] >= '0') && (text[i] <= '9')); i++) value = value*10.0f + (float)(text[i] - '0'); + + if (text[i++] != '.') value *= sign; + else + { + float divisor = 10.0f; + for (; ((text[i] >= '0') && (text[i] <= '9')); i++) + { + value += ((float)(text[i] - '0'))/divisor; + divisor = divisor*10.0f; + } + } + + return value; +} + +// Encode codepoint into UTF-8 text (char array size returned as parameter) +static const char *CodepointToUTF8(int codepoint, int *byteSize) +{ + static char utf8[6] = { 0 }; + int size = 0; + + if (codepoint <= 0x7f) + { + utf8[0] = (char)codepoint; + size = 1; + } + else if (codepoint <= 0x7ff) + { + utf8[0] = (char)(((codepoint >> 6) & 0x1f) | 0xc0); + utf8[1] = (char)((codepoint & 0x3f) | 0x80); + size = 2; + } + else if (codepoint <= 0xffff) + { + utf8[0] = (char)(((codepoint >> 12) & 0x0f) | 0xe0); + utf8[1] = (char)(((codepoint >> 6) & 0x3f) | 0x80); + utf8[2] = (char)((codepoint & 0x3f) | 0x80); + size = 3; + } + else if (codepoint <= 0x10ffff) + { + utf8[0] = (char)(((codepoint >> 18) & 0x07) | 0xf0); + utf8[1] = (char)(((codepoint >> 12) & 0x3f) | 0x80); + utf8[2] = (char)(((codepoint >> 6) & 0x3f) | 0x80); + utf8[3] = (char)((codepoint & 0x3f) | 0x80); + size = 4; + } + + *byteSize = size; + + return utf8; +} + +// Get next codepoint in a UTF-8 encoded text, scanning until '\0' is found +// When a invalid UTF-8 byte is encountered, exiting as soon as possible and returning a '?'(0x3f) codepoint +// Total number of bytes processed are returned as a parameter +// NOTE: The standard says U+FFFD should be returned in case of errors +// but that character is not supported by the default font in raylib +static int GetCodepointNext(const char *text, int *codepointSize) +{ + const char *ptr = text; + int codepoint = 0x3f; // Codepoint (defaults to '?') + *codepointSize = 1; + + // Get current codepoint and bytes processed + if (0xf0 == (0xf8 & ptr[0])) + { + // 4 byte UTF-8 codepoint + if (((ptr[1] & 0xC0) ^ 0x80) || ((ptr[2] & 0xC0) ^ 0x80) || ((ptr[3] & 0xC0) ^ 0x80)) { return codepoint; } //10xxxxxx checks + codepoint = ((0x07 & ptr[0]) << 18) | ((0x3f & ptr[1]) << 12) | ((0x3f & ptr[2]) << 6) | (0x3f & ptr[3]); + *codepointSize = 4; + } + else if (0xe0 == (0xf0 & ptr[0])) + { + // 3 byte UTF-8 codepoint + if (((ptr[1] & 0xC0) ^ 0x80) || ((ptr[2] & 0xC0) ^ 0x80)) { return codepoint; } //10xxxxxx checks + codepoint = ((0x0f & ptr[0]) << 12) | ((0x3f & ptr[1]) << 6) | (0x3f & ptr[2]); + *codepointSize = 3; + } + else if (0xc0 == (0xe0 & ptr[0])) + { + // 2 byte UTF-8 codepoint + if ((ptr[1] & 0xC0) ^ 0x80) { return codepoint; } //10xxxxxx checks + codepoint = ((0x1f & ptr[0]) << 6) | (0x3f & ptr[1]); + *codepointSize = 2; + } + else if (0x00 == (0x80 & ptr[0])) + { + // 1 byte UTF-8 codepoint + codepoint = ptr[0]; + *codepointSize = 1; + } + + return codepoint; +} +#endif // RAYGUI_STANDALONE + +#endif // RAYGUI_IMPLEMENTATION diff --git a/examples/shaders/raygui.h b/examples/shaders/raygui.h index 88fe5cc5b..67c16be45 100644 --- a/examples/shaders/raygui.h +++ b/examples/shaders/raygui.h @@ -1,6 +1,6 @@ /******************************************************************************************* * -* raygui v4.5-dev - A simple and easy-to-use immediate-mode gui library +* raygui v5.0-dev - A simple and easy-to-use immediate-mode gui library * * DESCRIPTION: * raygui is a tools-dev-focused immediate-mode-gui library based on raylib but also @@ -83,8 +83,8 @@ * used for all controls, when any of those base values is set, it is automatically populated to all * controls, so, specific control values overwriting generic style should be set after base values * -* After the first BASE set we have the EXTENDED properties (by default guiStyle[16..23]), those -* properties are actually common to all controls and can not be overwritten individually (like BASE ones) +* After the first BASE properties set, the EXTENDED properties set is defined (by default guiStyle[16..23]), +* those properties are actually common to all controls and can not be overwritten individually (like BASE ones) * Some of those properties are: TEXT_SIZE, TEXT_SPACING, LINE_COLOR, BACKGROUND_COLOR * * Custom control properties can be defined using the EXTENDED properties for each independent control. @@ -141,13 +141,14 @@ * Draw text bounds rectangles for debug * * VERSIONS HISTORY: -* 5.0 (xx-Nov-2025) ADDED: Support up to 32 controls (v500) +* 5.0 (xx-Mar-2026) ADDED: Support up to 32 controls (v500) * ADDED: guiControlExclusiveMode and guiControlExclusiveRec for exclusive modes * ADDED: GuiValueBoxFloat() * ADDED: GuiDropdonwBox() properties: DROPDOWN_ARROW_HIDDEN, DROPDOWN_ROLL_UP * ADDED: GuiListView() property: LIST_ITEMS_BORDER_WIDTH * ADDED: GuiLoadIconsFromMemory() * ADDED: Multiple new icons +* ADDED: Macros for inputs customization, raylib decoupling * REMOVED: GuiSpinner() from controls list, using BUTTON + VALUEBOX properties * REMOVED: GuiSliderPro(), functionality was redundant * REVIEWED: Controls using text labels to use LABEL properties @@ -165,6 +166,7 @@ * REVIEWED: GuiTextBox(), multiple improvements: autocursor and more * REVIEWED: Functions descriptions, removed wrong return value reference * REDESIGNED: GuiColorPanel(), improved HSV <-> RGBA convertion +* REDESIGNED: WARNING: TEXT_LINE_SPACING does not consider text height, only lines spacing * * 4.0 (12-Sep-2023) ADDED: GuiToggleSlider() * ADDED: GuiColorPickerHSV() and GuiColorPanelHSV() @@ -316,7 +318,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2014-2025 Ramon Santamaria (@raysan5) +* Copyright (c) 2014-2026 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -351,10 +353,11 @@ // NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll #if defined(_WIN32) #if defined(BUILD_LIBTYPE_SHARED) - #define RAYGUIAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll) + #define RAYGUIAPI __declspec(dllexport) // Building the library as a Win32 shared library (.dll) #elif defined(USE_LIBTYPE_SHARED) - #define RAYGUIAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll) + #define RAYGUIAPI __declspec(dllimport) // Using the library as a Win32 shared library (.dll) #endif + #define _CRT_SECURE_NO_WARNINGS // Disable unsafe warnings on scanf() functions in MSVC #endif // Function specifiers definition @@ -369,9 +372,48 @@ // NOTE: Avoiding those calls, also avoids const strings memory usage #define RAYGUI_SUPPORT_LOG_INFO #if defined(RAYGUI_SUPPORT_LOG_INFO) - #define RAYGUI_LOG(...) printf(__VA_ARGS__) + #define RAYGUI_LOG(...) printf(__VA_ARGS__) #else - #define RAYGUI_LOG(...) + #define RAYGUI_LOG(...) +#endif + +// Macros to define required UI inputs, including mapping to gamepad controls +// TODO: Define additionally required macros for missing inputs +#if !defined(GUI_BUTTON_DOWN) + #define GUI_BUTTON_DOWN (IsMouseButtonDown(MOUSE_LEFT_BUTTON) || IsGamepadButtonDown(0, GAMEPAD_BUTTON_RIGHT_FACE_DOWN)) +#endif +#if !defined(GUI_BUTTON_DOWN_ALT) + // Mapping to alternative button down pressed + #define GUI_BUTTON_DOWN_ALT (IsMouseButtonDown(MOUSE_RIGHT_BUTTON) || IsGamepadButtonDown(0, GAMEPAD_BUTTON_RIGHT_FACE_RIGHT)) +#endif +#if !defined(GUI_BUTTON_PRESSED) + #define GUI_BUTTON_PRESSED (IsMouseButtonPressed(MOUSE_LEFT_BUTTON) || IsGamepadButtonPressed(0, GAMEPAD_BUTTON_RIGHT_FACE_DOWN)) +#endif +// TODO: WARNING: GuiTabBar() still requires IsMouseButtonPressed(MOUSE_MIDDLE_BUTTON) +#if !defined(GUI_BUTTON_RELEASED) + #define GUI_BUTTON_RELEASED (IsMouseButtonReleased(MOUSE_LEFT_BUTTON) || IsGamepadButtonReleased(0, GAMEPAD_BUTTON_RIGHT_FACE_DOWN)) +#endif +#if !defined(GUI_SCROLL_DELTA) + // Mapping to scroll delta changes + // TODO: Review inconsistencies between platforms + #if defined(PLATFORM_WEB) + // NOTE: Gamepad axis triggers not detected on web platform + #define GUI_SCROLL_DELTA ((float)IsGamepadButtonDown(0, GAMEPAD_BUTTON_RIGHT_TRIGGER_2) - (float)IsGamepadButtonDown(0, GAMEPAD_BUTTON_LEFT_TRIGGER_2)) + #else + #define GUI_SCROLL_DELTA (GetMouseWheelMove() + (GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_TRIGGER) + 1) - (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_TRIGGER) + 1)) + #endif +#endif +#if !defined(GUI_POINTER_POSITION) + #define GUI_POINTER_POSITION GetMousePosition() +#endif +#if !defined(GUI_KEY_DOWN) + #define GUI_KEY_DOWN(key) IsKeyDown(key) +#endif +#if !defined(GUI_KEY_PRESSED) + #define GUI_KEY_PRESSED(key) IsKeyPressed(key) +#endif +#if !defined(GUI_INPUT_KEY) + #define GUI_INPUT_KEY GetCharPressed() #endif //---------------------------------------------------------------------------------- @@ -567,7 +609,7 @@ typedef enum { //---------------------------------------------------------------------------------- // DEFAULT extended properties // NOTE: Those properties are common to all controls or global -// WARNING: We only have 8 slots for those properties by default!!! -> New global control: TEXT? +// WARNING: Only 8 slots vailable for those properties by default typedef enum { TEXT_SIZE = 16, // Text size (glyphs max height) TEXT_SPACING, // Text spacing between glyphs @@ -1091,7 +1133,7 @@ typedef enum { // Icons data is defined by bit array (every bit represents one pixel) // Those arrays are stored as unsigned int data arrays, so, // every array element defines 32 pixels (bits) of information -// One icon is defined by 8 int, (8 int * 32 bit = 256 bit = 16*16 pixels) +// One icon is defined by 8 int, (8 int*32 bit = 256 bit = 16*16 pixels) // NOTE: Number of elemens depend on RAYGUI_ICON_SIZE (by default 16x16 pixels) #define RAYGUI_ICON_DATA_ELEMENTS (RAYGUI_ICON_SIZE*RAYGUI_ICON_SIZE/32) @@ -1450,12 +1492,12 @@ static bool IsMouseButtonReleased(int button); static bool IsKeyDown(int key); static bool IsKeyPressed(int key); -static int GetCharPressed(void); // -- GuiTextBox(), GuiValueBox() +static int GetCharPressed(void); // -- GuiTextBox(), GuiValueBox() //------------------------------------------------------------------------------- // Drawing required functions //------------------------------------------------------------------------------- -static void DrawRectangle(int x, int y, int width, int height, Color color); // -- GuiDrawRectangle() +static void DrawRectangle(int x, int y, int width, int height, Color color); // -- GuiDrawRectangle() static void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4); // -- GuiColorPicker() //------------------------------------------------------------------------------- @@ -1520,11 +1562,11 @@ static Color GuiFade(Color color, float alpha); // Fade color by an alph // Gui Setup Functions Definition //---------------------------------------------------------------------------------- // Enable gui global state -// NOTE: We check for STATE_DISABLED to avoid messing custom global state setups +// NOTE: Checking for STATE_DISABLED to avoid messing custom global state setups void GuiEnable(void) { if (guiState == STATE_DISABLED) guiState = STATE_NORMAL; } // Disable gui global state -// NOTE: We check for STATE_NORMAL to avoid messing custom global state setups +// NOTE: Checking for STATE_NORMAL to avoid messing custom global state setups void GuiDisable(void) { if (guiState == STATE_NORMAL) guiState = STATE_DISABLED; } // Lock gui global state @@ -1557,9 +1599,8 @@ void GuiSetFont(Font font) { if (font.texture.id > 0) { - // NOTE: If we try to setup a font but default style has not been - // lazily loaded before, it will be overwritten, so we need to force - // default style loading first + // NOTE: If a font is tried to be set but default style has not been lazily loaded first, + // it will be overwritten, so default style loading needs to be forced first if (!guiStyleLoaded) GuiLoadStyleDefault(); guiFont = font; @@ -1613,13 +1654,14 @@ int GuiWindowBox(Rectangle bounds, const char *title) //GuiState state = guiState; int statusBarHeight = RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT; + int statusBorderWidth = GuiGetStyle(STATUSBAR, BORDER_WIDTH); Rectangle statusBar = { bounds.x, bounds.y, bounds.width, (float)statusBarHeight }; if (bounds.height < statusBarHeight*2.0f) bounds.height = statusBarHeight*2.0f; const float vPadding = statusBarHeight/2.0f - RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT/2.0f; - Rectangle windowPanel = { bounds.x, bounds.y + (float)statusBarHeight - 1, bounds.width, bounds.height - (float)statusBarHeight + 1 }; - Rectangle closeButtonRec = { statusBar.x + statusBar.width - GuiGetStyle(STATUSBAR, BORDER_WIDTH) - RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT - vPadding, + Rectangle windowPanel = { bounds.x, bounds.y + (float)statusBarHeight - (float)statusBorderWidth, bounds.width, bounds.height - (float)statusBarHeight + (float)statusBorderWidth }; + Rectangle closeButtonRec = { statusBar.x + statusBar.width - (float)statusBorderWidth - RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT - vPadding, statusBar.y + vPadding, RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT, RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT }; // Update control @@ -1629,8 +1671,8 @@ int GuiWindowBox(Rectangle bounds, const char *title) // Draw control //-------------------------------------------------------------------- - GuiStatusBar(statusBar, title); // Draw window header as status bar GuiPanel(windowPanel, NULL); // Draw window base + GuiStatusBar(statusBar, title); // Draw window header as status bar // Draw window close button int tempBorderWidth = GuiGetStyle(BUTTON, BORDER_WIDTH); @@ -1786,7 +1828,7 @@ int GuiTabBar(Rectangle bounds, const char **text, int count, int *active) } // Close tab with middle mouse button pressed - if (CheckCollisionPointRec(GetMousePosition(), tabBounds) && IsMouseButtonPressed(MOUSE_MIDDLE_BUTTON)) result = i; + if (CheckCollisionPointRec(GUI_POINTER_POSITION, tabBounds) && IsMouseButtonPressed(MOUSE_MIDDLE_BUTTON)) result = i; GuiSetStyle(TOGGLE, TEXT_PADDING, textPadding); GuiSetStyle(TOGGLE, TEXT_ALIGNMENT, textAlignment); @@ -1885,37 +1927,37 @@ int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; // Check button state if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; else state = STATE_FOCUSED; #if defined(SUPPORT_SCROLLBAR_KEY_INPUT) if (hasHorizontalScrollBar) { - if (IsKeyDown(KEY_RIGHT)) scrollPos.x -= GuiGetStyle(SCROLLBAR, SCROLL_SPEED); - if (IsKeyDown(KEY_LEFT)) scrollPos.x += GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + if (GUI_KEY_DOWN(KEY_RIGHT)) scrollPos.x -= GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + if (GUI_KEY_DOWN(KEY_LEFT)) scrollPos.x += GuiGetStyle(SCROLLBAR, SCROLL_SPEED); } if (hasVerticalScrollBar) { - if (IsKeyDown(KEY_DOWN)) scrollPos.y -= GuiGetStyle(SCROLLBAR, SCROLL_SPEED); - if (IsKeyDown(KEY_UP)) scrollPos.y += GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + if (GUI_KEY_DOWN(KEY_DOWN)) scrollPos.y -= GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + if (GUI_KEY_DOWN(KEY_UP)) scrollPos.y += GuiGetStyle(SCROLLBAR, SCROLL_SPEED); } #endif - float wheelMove = GetMouseWheelMove(); + float scrollDelta = GUI_SCROLL_DELTA; // Set scrolling speed with mouse wheel based on ratio between bounds and content - Vector2 mouseWheelSpeed = { content.width/bounds.width, content.height/bounds.height }; - if (mouseWheelSpeed.x < RAYGUI_MIN_MOUSE_WHEEL_SPEED) mouseWheelSpeed.x = RAYGUI_MIN_MOUSE_WHEEL_SPEED; - if (mouseWheelSpeed.y < RAYGUI_MIN_MOUSE_WHEEL_SPEED) mouseWheelSpeed.y = RAYGUI_MIN_MOUSE_WHEEL_SPEED; + Vector2 scrollSpeed = { content.width/bounds.width, content.height/bounds.height }; + if (scrollSpeed.x < RAYGUI_MIN_MOUSE_WHEEL_SPEED) scrollSpeed.x = RAYGUI_MIN_MOUSE_WHEEL_SPEED; + if (scrollSpeed.y < RAYGUI_MIN_MOUSE_WHEEL_SPEED) scrollSpeed.y = RAYGUI_MIN_MOUSE_WHEEL_SPEED; // Horizontal and vertical scrolling with mouse wheel - if (hasHorizontalScrollBar && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_LEFT_SHIFT))) scrollPos.x += wheelMove*mouseWheelSpeed.x; - else scrollPos.y += wheelMove*mouseWheelSpeed.y; // Vertical scroll + if (hasHorizontalScrollBar && (GUI_KEY_DOWN(KEY_LEFT_CONTROL) || GUI_KEY_DOWN(KEY_LEFT_SHIFT))) scrollPos.x += scrollDelta*scrollSpeed.x; + else scrollPos.y += scrollDelta*scrollSpeed.y; // Vertical scroll } } @@ -2001,15 +2043,15 @@ int GuiButton(Rectangle bounds, const char *text) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; // Check button state if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; else state = STATE_FOCUSED; - if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) result = 1; + if (GUI_BUTTON_RELEASED) result = 1; } } //-------------------------------------------------------------------- @@ -2031,7 +2073,7 @@ int GuiLabelButton(Rectangle bounds, const char *text) GuiState state = guiState; bool pressed = false; - // NOTE: We force bounds.width to be all text + // NOTE: Force bounds.width to be all text float textWidth = (float)GuiGetTextWidth(text); if ((bounds.width - 2*GuiGetStyle(LABEL, BORDER_WIDTH) - 2*GuiGetStyle(LABEL, TEXT_PADDING)) < textWidth) bounds.width = textWidth + 2*GuiGetStyle(LABEL, BORDER_WIDTH) + 2*GuiGetStyle(LABEL, TEXT_PADDING) + 2; @@ -2039,15 +2081,15 @@ int GuiLabelButton(Rectangle bounds, const char *text) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; // Check checkbox state if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; else state = STATE_FOCUSED; - if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) pressed = true; + if (GUI_BUTTON_RELEASED) pressed = true; } } //-------------------------------------------------------------------- @@ -2073,13 +2115,13 @@ int GuiToggle(Rectangle bounds, const char *text, bool *active) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; // Check toggle button state if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; - else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; + else if (GUI_BUTTON_RELEASED) { state = STATE_NORMAL; *active = !(*active); @@ -2184,12 +2226,12 @@ int GuiToggleSlider(Rectangle bounds, const char *text, int *active) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; - else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; + else if (GUI_BUTTON_RELEASED) { state = STATE_PRESSED; (*active)++; @@ -2255,7 +2297,7 @@ int GuiCheckBox(Rectangle bounds, const char *text, bool *checked) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; Rectangle totalBounds = { (GuiGetStyle(CHECKBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT)? textBounds.x : bounds.x, @@ -2267,10 +2309,10 @@ int GuiCheckBox(Rectangle bounds, const char *text, bool *checked) // Check checkbox state if (CheckCollisionPointRec(mousePoint, totalBounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; else state = STATE_FOCUSED; - if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_RELEASED) { *checked = !(*checked); result = 1; @@ -2323,18 +2365,18 @@ int GuiComboBox(Rectangle bounds, const char *text, int *active) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && (itemCount > 1) && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; if (CheckCollisionPointRec(mousePoint, bounds) || CheckCollisionPointRec(mousePoint, selector)) { - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_PRESSED) { *active += 1; if (*active >= itemCount) *active = 0; // Cyclic combobox } - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; else state = STATE_FOCUSED; } } @@ -2392,7 +2434,7 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && (editMode || !guiLocked) && (itemCount > 1) && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; if (editMode) { @@ -2401,11 +2443,11 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod // Check if mouse has been pressed or released outside limits if (!CheckCollisionPointRec(mousePoint, boundsOpen)) { - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON) || IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) result = 1; + if (GUI_BUTTON_PRESSED || GUI_BUTTON_RELEASED) result = 1; } // Check if already selected item has been pressed again - if (CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) result = 1; + if (CheckCollisionPointRec(mousePoint, bounds) && GUI_BUTTON_PRESSED) result = 1; // Check focused and selected item for (int i = 0; i < itemCount; i++) @@ -2417,7 +2459,7 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod if (CheckCollisionPointRec(mousePoint, itemBounds)) { itemFocused = i; - if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_RELEASED) { itemSelected = i; result = 1; // Item selected @@ -2432,7 +2474,7 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod { if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_PRESSED) { result = 1; state = STATE_PRESSED; @@ -2506,7 +2548,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) int result = 0; GuiState state = guiState; - bool multiline = false; // TODO: Consider multiline text input + bool multiline = false; // TODO: Consider multiline text input int wrapMode = GuiGetStyle(DEFAULT, TEXT_WRAP_MODE); Rectangle textBounds = GetTextBounds(TEXTBOX, bounds); @@ -2514,7 +2556,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) int thisCursorIndex = textBoxCursorIndex; if (thisCursorIndex > textLength) thisCursorIndex = textLength; int textWidth = GuiGetTextWidth(text) - GuiGetTextWidth(text + thisCursorIndex); - int textIndexOffset = 0; // Text index offset to start drawing in the box + int textIndexOffset = 0; // Text index offset to start drawing in the box // Cursor rectangle // NOTE: Position X value should be updated @@ -2547,13 +2589,13 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) !guiControlExclusiveMode && // No gui slider on dragging (wrapMode == TEXT_WRAP_NONE)) // No wrap mode { - Vector2 mousePosition = GetMousePosition(); + Vector2 mousePosition = GUI_POINTER_POSITION; if (editMode) { // GLOBAL: Auto-cursor movement logic // NOTE: Keystrokes are handled repeatedly when button is held down for some time - if (IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_UP) || IsKeyDown(KEY_DOWN) || IsKeyDown(KEY_BACKSPACE) || IsKeyDown(KEY_DELETE)) autoCursorCounter++; + if (GUI_KEY_DOWN(KEY_LEFT) || GUI_KEY_DOWN(KEY_RIGHT) || GUI_KEY_DOWN(KEY_UP) || GUI_KEY_DOWN(KEY_DOWN) || GUI_KEY_DOWN(KEY_BACKSPACE) || GUI_KEY_DOWN(KEY_DELETE)) autoCursorCounter++; else autoCursorCounter = 0; bool autoCursorShouldTrigger = (autoCursorCounter > RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN) && ((autoCursorCounter % RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY) == 0); @@ -2563,7 +2605,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) if (textBoxCursorIndex > textLength) textBoxCursorIndex = textLength; // If text does not fit in the textbox and current cursor position is out of bounds, - // we add an index offset to text for drawing only what requires depending on cursor + // adding an index offset to text for drawing only what requires depending on cursor while (textWidth >= textBounds.width) { int nextCodepointSize = 0; @@ -2574,15 +2616,15 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) textWidth = GuiGetTextWidth(text + textIndexOffset) - GuiGetTextWidth(text + textBoxCursorIndex); } - int codepoint = GetCharPressed(); // Get Unicode codepoint - if (multiline && IsKeyPressed(KEY_ENTER)) codepoint = (int)'\n'; + int codepoint = GUI_INPUT_KEY; // Get Unicode codepoint + if (multiline && GUI_KEY_PRESSED(KEY_ENTER)) codepoint = (int)'\n'; // Encode codepoint as UTF-8 int codepointSize = 0; const char *charEncoded = CodepointToUTF8(codepoint, &codepointSize); // Handle text paste action - if (IsKeyPressed(KEY_V) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))) + if (GUI_KEY_PRESSED(KEY_V) && (GUI_KEY_DOWN(KEY_LEFT_CONTROL) || GUI_KEY_DOWN(KEY_RIGHT_CONTROL))) { const char *pasteText = GetClipboardText(); if (pasteText != NULL) @@ -2632,13 +2674,13 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) } // Move cursor to start - if ((textLength > 0) && IsKeyPressed(KEY_HOME)) textBoxCursorIndex = 0; + if ((textLength > 0) && GUI_KEY_PRESSED(KEY_HOME)) textBoxCursorIndex = 0; // Move cursor to end - if ((textLength > textBoxCursorIndex) && IsKeyPressed(KEY_END)) textBoxCursorIndex = textLength; + if ((textLength > textBoxCursorIndex) && GUI_KEY_PRESSED(KEY_END)) textBoxCursorIndex = textLength; // Delete related codepoints from text, after current cursor position - if ((textLength > textBoxCursorIndex) && IsKeyPressed(KEY_DELETE) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))) + if ((textLength > textBoxCursorIndex) && GUI_KEY_PRESSED(KEY_DELETE) && (GUI_KEY_DOWN(KEY_LEFT_CONTROL) || GUI_KEY_DOWN(KEY_RIGHT_CONTROL))) { int offset = textBoxCursorIndex; int accCodepointSize = 0; @@ -2674,7 +2716,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) textLength -= accCodepointSize; } - else if ((textLength > textBoxCursorIndex) && (IsKeyPressed(KEY_DELETE) || (IsKeyDown(KEY_DELETE) && autoCursorShouldTrigger))) + else if ((textLength > textBoxCursorIndex) && (GUI_KEY_PRESSED(KEY_DELETE) || (GUI_KEY_DOWN(KEY_DELETE) && autoCursorShouldTrigger))) { // Delete single codepoint from text, after current cursor position @@ -2688,12 +2730,12 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) } // Delete related codepoints from text, before current cursor position - if ((textBoxCursorIndex > 0) && IsKeyPressed(KEY_BACKSPACE) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))) + if ((textBoxCursorIndex > 0) && GUI_KEY_PRESSED(KEY_BACKSPACE) && (GUI_KEY_DOWN(KEY_LEFT_CONTROL) || GUI_KEY_DOWN(KEY_RIGHT_CONTROL))) { int offset = textBoxCursorIndex; int accCodepointSize = 0; - int prevCodepointSize; - int prevCodepoint; + int prevCodepointSize = 0; + int prevCodepoint = 0; // Check whitespace to delete (ASCII only) while (offset > 0) @@ -2724,7 +2766,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) textBoxCursorIndex -= accCodepointSize; } - else if ((textBoxCursorIndex > 0) && (IsKeyPressed(KEY_BACKSPACE) || (IsKeyDown(KEY_BACKSPACE) && autoCursorShouldTrigger))) + else if ((textBoxCursorIndex > 0) && (GUI_KEY_PRESSED(KEY_BACKSPACE) || (GUI_KEY_DOWN(KEY_BACKSPACE) && autoCursorShouldTrigger))) { // Delete single codepoint from text, before current cursor position @@ -2740,12 +2782,12 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) } // Move cursor position with keys - if ((textBoxCursorIndex > 0) && IsKeyPressed(KEY_LEFT) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))) + if ((textBoxCursorIndex > 0) && GUI_KEY_PRESSED(KEY_LEFT) && (GUI_KEY_DOWN(KEY_LEFT_CONTROL) || GUI_KEY_DOWN(KEY_RIGHT_CONTROL))) { int offset = textBoxCursorIndex; //int accCodepointSize = 0; - int prevCodepointSize; - int prevCodepoint; + int prevCodepointSize = 0; + int prevCodepoint = 0; // Check whitespace to skip (ASCII only) while (offset > 0) @@ -2771,14 +2813,14 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) textBoxCursorIndex = offset; } - else if ((textBoxCursorIndex > 0) && (IsKeyPressed(KEY_LEFT) || (IsKeyDown(KEY_LEFT) && autoCursorShouldTrigger))) + else if ((textBoxCursorIndex > 0) && (GUI_KEY_PRESSED(KEY_LEFT) || (GUI_KEY_DOWN(KEY_LEFT) && autoCursorShouldTrigger))) { int prevCodepointSize = 0; GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize); textBoxCursorIndex -= prevCodepointSize; } - else if ((textLength > textBoxCursorIndex) && IsKeyPressed(KEY_RIGHT) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))) + else if ((textLength > textBoxCursorIndex) && GUI_KEY_PRESSED(KEY_RIGHT) && (GUI_KEY_DOWN(KEY_LEFT_CONTROL) || GUI_KEY_DOWN(KEY_RIGHT_CONTROL))) { int offset = textBoxCursorIndex; //int accCodepointSize = 0; @@ -2810,7 +2852,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) textBoxCursorIndex = offset; } - else if ((textLength > textBoxCursorIndex) && (IsKeyPressed(KEY_RIGHT) || (IsKeyDown(KEY_RIGHT) && autoCursorShouldTrigger))) + else if ((textLength > textBoxCursorIndex) && (GUI_KEY_PRESSED(KEY_RIGHT) || (GUI_KEY_DOWN(KEY_RIGHT) && autoCursorShouldTrigger))) { int nextCodepointSize = 0; GetCodepointNext(text + textBoxCursorIndex, &nextCodepointSize); @@ -2847,14 +2889,14 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) // Check if mouse cursor is at the last position int textEndWidth = GuiGetTextWidth(text + textIndexOffset); - if (GetMousePosition().x >= (textBounds.x + textEndWidth - glyphWidth/2)) + if (GUI_POINTER_POSITION.x >= (textBounds.x + textEndWidth - glyphWidth/2)) { mouseCursor.x = textBounds.x + textEndWidth; mouseCursorIndex = textLength; } // Place cursor at required index on mouse click - if ((mouseCursor.x >= 0) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + if ((mouseCursor.x >= 0) && GUI_BUTTON_PRESSED) { cursor.x = mouseCursor.x; textBoxCursorIndex = mouseCursorIndex; @@ -2867,8 +2909,8 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) //if (multiline) cursor.y = GetTextLines() // Finish text editing on ENTER or mouse click outside bounds - if ((!multiline && IsKeyPressed(KEY_ENTER)) || - (!CheckCollisionPointRec(mousePosition, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) + if ((!multiline && GUI_KEY_PRESSED(KEY_ENTER)) || + (!CheckCollisionPointRec(mousePosition, bounds) && GUI_BUTTON_PRESSED)) { textBoxCursorIndex = 0; // GLOBAL: Reset the shared cursor index autoCursorCounter = 0; // GLOBAL: Reset counter for repeated keystrokes @@ -2881,7 +2923,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) { state = STATE_FOCUSED; - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_PRESSED) { textBoxCursorIndex = textLength; // GLOBAL: Place cursor index to the end of current text autoCursorCounter = 0; // GLOBAL: Reset counter for repeated keystrokes @@ -2975,12 +3017,12 @@ int GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; // Check spinner state if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; else state = STATE_FOCUSED; } } @@ -3050,7 +3092,7 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; bool valueHasChanged = false; if (editMode) @@ -3060,7 +3102,7 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in int keyCount = (int)strlen(textValue); // Add or remove minus symbol - if (IsKeyPressed(KEY_MINUS)) + if (GUI_KEY_PRESSED(KEY_MINUS)) { if (textValue[0] == '-') { @@ -3089,8 +3131,8 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in // Add new digit to text value if ((keyCount >= 0) && (keyCount < RAYGUI_VALUEBOX_MAX_CHARS) && (GuiGetTextWidth(textValue) < bounds.width)) { - int key = GetCharPressed(); - + int key = GUI_INPUT_KEY; + // Only allow keys in range [48..57] if ((key >= 48) && (key <= 57)) { @@ -3101,7 +3143,7 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in } // Delete text - if ((keyCount > 0) && IsKeyPressed(KEY_BACKSPACE)) + if ((keyCount > 0) && GUI_KEY_PRESSED(KEY_BACKSPACE)) { keyCount--; textValue[keyCount] = '\0'; @@ -3110,11 +3152,11 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in if (valueHasChanged) *value = TextToInteger(textValue); - // NOTE: We are not clamp values until user input finishes + // NOTE: Values are not clamped until user input finishes //if (*value > maxValue) *value = maxValue; //else if (*value < minValue) *value = minValue; - if ((IsKeyPressed(KEY_ENTER) || IsKeyPressed(KEY_KP_ENTER)) || (!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) + if ((GUI_KEY_PRESSED(KEY_ENTER) || GUI_KEY_PRESSED(KEY_KP_ENTER)) || (!CheckCollisionPointRec(mousePoint, bounds) && GUI_BUTTON_PRESSED)) { if (*value > maxValue) *value = maxValue; else if (*value < minValue) *value = minValue; @@ -3130,7 +3172,7 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in if (CheckCollisionPointRec(mousePoint, bounds)) { state = STATE_FOCUSED; - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) result = 1; + if (GUI_BUTTON_PRESSED) result = 1; } } } @@ -3191,7 +3233,7 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; bool valueHasChanged = false; @@ -3202,7 +3244,7 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float int keyCount = (int)strlen(textValue); // Add or remove minus symbol - if (IsKeyPressed(KEY_MINUS)) + if (GUI_KEY_PRESSED(KEY_MINUS)) { if (textValue[0] == '-') { @@ -3233,7 +3275,7 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float { if (GuiGetTextWidth(textValue) < bounds.width) { - int key = GetCharPressed(); + int key = GUI_INPUT_KEY; if (((key >= 48) && (key <= 57)) || (key == '.') || ((keyCount == 0) && (key == '+')) || // NOTE: Sign can only be in first position @@ -3248,7 +3290,7 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float } // Pressed backspace - if (IsKeyPressed(KEY_BACKSPACE)) + if (GUI_KEY_PRESSED(KEY_BACKSPACE)) { if (keyCount > 0) { @@ -3260,14 +3302,14 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float if (valueHasChanged) *value = TextToFloat(textValue); - if ((IsKeyPressed(KEY_ENTER) || IsKeyPressed(KEY_KP_ENTER)) || (!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) result = 1; + if ((GUI_KEY_PRESSED(KEY_ENTER) || GUI_KEY_PRESSED(KEY_KP_ENTER)) || (!CheckCollisionPointRec(mousePoint, bounds) && GUI_BUTTON_PRESSED)) result = 1; } else { if (CheckCollisionPointRec(mousePoint, bounds)) { state = STATE_FOCUSED; - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) result = 1; + if (GUI_BUTTON_PRESSED) result = 1; } } } @@ -3321,11 +3363,11 @@ int GuiSlider(Rectangle bounds, const char *textLeft, const char *textRight, flo //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) { if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) { @@ -3342,7 +3384,7 @@ int GuiSlider(Rectangle bounds, const char *textLeft, const char *textRight, flo } else if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) { state = STATE_PRESSED; guiControlExclusiveMode = true; @@ -3535,12 +3577,12 @@ int GuiDummyRec(Rectangle bounds, const char *text) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; // Check button state if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; else state = STATE_FOCUSED; } } @@ -3578,7 +3620,7 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd int itemFocused = (focus == NULL)? -1 : *focus; int itemSelected = (active == NULL)? -1 : *active; - // Check if we need a scroll bar + // Check if scroll bar is needed bool useScrollBar = false; if ((GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT) + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING))*count > bounds.height) useScrollBar = true; @@ -3602,7 +3644,7 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; // Check mouse inside list view if (CheckCollisionPointRec(mousePoint, bounds)) @@ -3615,7 +3657,7 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd if (CheckCollisionPointRec(mousePoint, itemBounds)) { itemFocused = startIndex + i; - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_PRESSED) { if (itemSelected == (startIndex + i)) itemSelected = -1; else itemSelected = startIndex + i; @@ -3629,8 +3671,8 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd if (useScrollBar) { - int wheelMove = (int)GetMouseWheelMove(); - startIndex -= wheelMove; + float scrollDelta = GUI_SCROLL_DELTA; + startIndex -= (int)scrollDelta; if (startIndex < 0) startIndex = 0; else if (startIndex > (count - visibleItems)) startIndex = count - visibleItems; @@ -3659,7 +3701,7 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd { if ((startIndex + i) == itemSelected) GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, LIST_ITEMS_BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_DISABLED)), GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_DISABLED))); - GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_DISABLED))); + GuiDrawText(text[startIndex + i], GetTextBounds(LISTVIEW, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_DISABLED))); } else { @@ -3667,18 +3709,18 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd { // Draw item selected GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, LIST_ITEMS_BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_PRESSED)), GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_PRESSED))); - GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_PRESSED))); + GuiDrawText(text[startIndex + i], GetTextBounds(LISTVIEW, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_PRESSED))); } - else if (((startIndex + i) == itemFocused)) // && (focus != NULL)) // NOTE: We want items focused, despite not returned! + else if (((startIndex + i) == itemFocused)) // && (focus != NULL)) // NOTE: Items focused, despite not returned { // Draw item focused GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, LIST_ITEMS_BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_FOCUSED)), GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_FOCUSED))); - GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_FOCUSED))); + GuiDrawText(text[startIndex + i], GetTextBounds(LISTVIEW, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_FOCUSED))); } else { // Draw item normal (no rectangle) - GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_NORMAL))); + GuiDrawText(text[startIndex + i], GetTextBounds(LISTVIEW, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_NORMAL))); } } @@ -3765,11 +3807,11 @@ int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) { if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) { @@ -3788,7 +3830,7 @@ int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha) } else if (CheckCollisionPointRec(mousePoint, bounds) || CheckCollisionPointRec(mousePoint, selector)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) { state = STATE_PRESSED; guiControlExclusiveMode = true; @@ -3850,11 +3892,11 @@ int GuiColorBarHue(Rectangle bounds, const char *text, float *hue) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) { if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) { @@ -3873,7 +3915,7 @@ int GuiColorBarHue(Rectangle bounds, const char *text, float *hue) } else if (CheckCollisionPointRec(mousePoint, bounds) || CheckCollisionPointRec(mousePoint, selector)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) { state = STATE_PRESSED; guiControlExclusiveMode = true; @@ -3886,12 +3928,12 @@ int GuiColorBarHue(Rectangle bounds, const char *text, float *hue) } else state = STATE_FOCUSED; - /*if (IsKeyDown(KEY_UP)) + /*if (GUI_KEY_DOWN(KEY_UP)) { hue -= 2.0f; if (hue <= 0.0f) hue = 0.0f; } - else if (IsKeyDown(KEY_DOWN)) + else if (GUI_KEY_DOWN(KEY_DOWN)) { hue += 2.0f; if (hue >= 360.0f) hue = 360.0f; @@ -4008,11 +4050,11 @@ int GuiColorPanelHSV(Rectangle bounds, const char *text, Vector3 *colorHsv) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) { if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) { @@ -4042,7 +4084,7 @@ int GuiColorPanelHSV(Rectangle bounds, const char *text, Vector3 *colorHsv) } else if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) { state = STATE_PRESSED; guiControlExclusiveMode = true; @@ -4198,6 +4240,9 @@ int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, co GuiSetStyle(LABEL, TEXT_ALIGNMENT, prevTextAlignment); } + int prevTextBoxAlignment = GuiGetStyle(TEXTBOX, TEXT_ALIGNMENT); + GuiSetStyle(TEXTBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); + if (secretViewActive != NULL) { static char stars[] = "****************"; @@ -4211,6 +4256,8 @@ int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, co if (GuiTextBox(textBoxBounds, text, textMaxSize, textEditMode)) textEditMode = !textEditMode; } + GuiSetStyle(TEXTBOX, TEXT_ALIGNMENT, prevTextBoxAlignment); + int prevBtnTextAlignment = GuiGetStyle(BUTTON, TEXT_ALIGNMENT); GuiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); @@ -4231,7 +4278,7 @@ int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, co // Grid control // NOTE: Returns grid mouse-hover selected cell // About drawing lines at subpixel spacing, simple put, not easy solution: -// https://stackoverflow.com/questions/4435450/2d-opengl-drawing-lines-that-dont-exactly-fit-pixel-raster +// REF: https://stackoverflow.com/questions/4435450/2d-opengl-drawing-lines-that-dont-exactly-fit-pixel-raster int GuiGrid(Rectangle bounds, const char *text, float spacing, int subdivs, Vector2 *mouseCell) { // Grid lines alpha amount @@ -4242,7 +4289,7 @@ int GuiGrid(Rectangle bounds, const char *text, float spacing, int subdivs, Vect int result = 0; GuiState state = guiState; - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; Vector2 currentMouseCell = { -1, -1 }; float spaceWidth = spacing/(float)subdivs; @@ -4410,11 +4457,14 @@ void GuiLoadStyle(const char *fileName) if (fileDataSize > 0) { unsigned char *fileData = (unsigned char *)RAYGUI_CALLOC(fileDataSize, sizeof(unsigned char)); - fread(fileData, sizeof(unsigned char), fileDataSize, rgsFile); + if (fileData != NULL) + { + fread(fileData, sizeof(unsigned char), fileDataSize, rgsFile); - GuiLoadStyleFromMemory(fileData, fileDataSize); + GuiLoadStyleFromMemory(fileData, fileDataSize); - RAYGUI_FREE(fileData); + RAYGUI_FREE(fileData); + } } fclose(rgsFile); @@ -4425,7 +4475,7 @@ void GuiLoadStyle(const char *fileName) // Load style default over global style void GuiLoadStyleDefault(void) { - // We set this variable first to avoid cyclic function calls + // Setting this flag first to avoid cyclic function calls // when calling GuiSetStyle() and GuiGetStyle() guiStyleLoaded = true; @@ -4454,7 +4504,7 @@ void GuiLoadStyleDefault(void) GuiSetStyle(DEFAULT, TEXT_SPACING, 1); // DEFAULT, shared by all controls GuiSetStyle(DEFAULT, LINE_COLOR, 0x90abb5ff); // DEFAULT specific property GuiSetStyle(DEFAULT, BACKGROUND_COLOR, 0xf5f5f5ff); // DEFAULT specific property - GuiSetStyle(DEFAULT, TEXT_LINE_SPACING, 15); // DEFAULT, 15 pixels between lines + GuiSetStyle(DEFAULT, TEXT_LINE_SPACING, 5); // DEFAULT, pixels between lines, from bottom of first line to top of second GuiSetStyle(DEFAULT, TEXT_ALIGNMENT_VERTICAL, TEXT_ALIGN_MIDDLE); // DEFAULT, text aligned vertically to middle of text-bounds // Initialize control-specific property values @@ -4520,7 +4570,7 @@ void GuiLoadStyleDefault(void) // NOTE: Default raylib font character 95 is a white square Rectangle whiteChar = guiFont.recs[95]; - // NOTE: We set up a 1px padding on char rectangle to avoid pixel bleeding on MSAA filtering + // NOTE: Setting up a 1px padding on char rectangle to avoid pixel bleeding on MSAA filtering SetShapesTexture(guiFont.texture, RAYGUI_CLITERAL(Rectangle){ whiteChar.x + 1, whiteChar.y + 1, whiteChar.width - 2, whiteChar.height - 2 }); } } @@ -5037,14 +5087,14 @@ static Rectangle GetTextBounds(int control, Rectangle bounds) } // Get text icon if provided and move text cursor -// NOTE: We support up to 999 values for iconId +// NOTE: Up to #999# values supported for iconId static const char *GetTextIcon(const char *text, int *iconId) { #if !defined(RAYGUI_NO_ICONS) *iconId = -1; - if (text[0] == '#') // Maybe we have an icon! + if (text[0] == '#') // Maybe it is stars with an icon, ending # must be found { - char iconValue[4] = { 0 }; // Maximum length for icon value: 3 digits + '\0' + char iconValue[4] = { 0 }; // Maximum length for icon value: 3 digits + '\0' int pos = 1; while ((pos < 4) && (text[pos] >= '0') && (text[pos] <= '9')) @@ -5076,12 +5126,12 @@ static const char **GetTextLines(const char *text, int *count) static const char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 }; for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings - int textSize = (int)strlen(text); + int textLength = (int)strlen(text); lines[0] = text; *count = 1; - for (int i = 0, k = 0; (i < textSize) && (*count < RAYGUI_MAX_TEXT_LINES); i++) + for (int i = 0, k = 0; (i < textLength) && (*count < RAYGUI_MAX_TEXT_LINES); i++) { if (text[i] == '\n') { @@ -5141,7 +5191,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C // - For every line, wordwrap mode is checked (useful for GuitextBox(), read-only) // Get text lines (using '\n' as delimiter) to be processed individually - // WARNING: We can't use GuiTextSplit() function because it can be already used + // WARNING: GuiTextSplit() function can't be used now because it can have already been used // before the GuiDrawText() call and its buffer is static, it would be overriden :( int lineCount = 0; const char **lines = GetTextLines(text, &lineCount); @@ -5152,7 +5202,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C int wrapMode = GuiGetStyle(DEFAULT, TEXT_WRAP_MODE); // Wrap-mode only available in read-only mode, no for text editing // TODO: WARNING: This totalHeight is not valid for vertical alignment in case of word-wrap - float totalHeight = (float)(lineCount*GuiGetStyle(DEFAULT, TEXT_SIZE) + (lineCount - 1)*GuiGetStyle(DEFAULT, TEXT_SIZE)/2); + float totalHeight = (float)(lineCount*GuiGetStyle(DEFAULT, TEXT_SIZE) + (lineCount - 1)*GuiGetStyle(DEFAULT, TEXT_LINE_SPACING)); float posOffsetY = 0.0f; for (int i = 0; i < lineCount; i++) @@ -5165,7 +5215,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C Vector2 textBoundsPosition = { textBounds.x, textBounds.y }; float textBoundsWidthOffset = 0.0f; - // NOTE: We get text size after icon has been processed + // NOTE: Get text size after icon has been processed // WARNING: GuiGetTextWidth() also processes text icon to get width! -> Really needed? int textSizeX = GuiGetTextWidth(lines[i]); @@ -5200,8 +5250,8 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C default: break; } - // NOTE: Make sure we get pixel-perfect coordinates, - // In case of decimals we got weird text positioning + // NOTE: Make sure getting pixel-perfect coordinates, + // In case of decimals, it could result in text positioning artifacts textBoundsPosition.x = (float)((int)textBoundsPosition.x); textBoundsPosition.y = (float)((int)textBoundsPosition.y); //--------------------------------------------------------------------------------- @@ -5211,7 +5261,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C #if !defined(RAYGUI_NO_ICONS) if (iconId >= 0) { - // NOTE: We consider icon height, probably different than text size + // NOTE: Considering icon height, probably different than text size GuiDrawIcon(iconId, (int)textBoundsPosition.x, (int)(textBounds.y + textBounds.height/2 - RAYGUI_ICON_SIZE*guiIconScale/2 + TEXT_VALIGN_PIXEL_OFFSET(textBounds.height)), guiIconScale, tint); textBoundsPosition.x += (float)(RAYGUI_ICON_SIZE*guiIconScale + ICON_TEXT_PADDING); textBoundsWidthOffset = (float)(RAYGUI_ICON_SIZE*guiIconScale + ICON_TEXT_PADDING); @@ -5237,8 +5287,8 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C int codepoint = GetCodepointNext(&lines[i][c], &codepointSize); int index = GetGlyphIndex(guiFont, codepoint); - // NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f) - // but we need to draw all of the bad bytes using the '?' symbol moving one byte + // NOTE: Normally, exiting the decoding sequence as soon as a bad byte is found (and return 0x3f) + // but all of the bad bytes need to be drawn using the '?' symbol, moving one byte if (codepoint == 0x3f) codepointSize = 1; // TODO: Review not recognized codepoints size // Get glyph width to check if it goes out of bounds @@ -5253,7 +5303,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C if ((textOffsetX + glyphWidth) > textBounds.width - textBoundsWidthOffset) { textOffsetX = 0.0f; - textOffsetY += GuiGetStyle(DEFAULT, TEXT_LINE_SPACING); + textOffsetY += (GuiGetStyle(DEFAULT, TEXT_SIZE) + GuiGetStyle(DEFAULT, TEXT_LINE_SPACING)); if (tempWrapCharMode) // Wrap at char level when too long words { @@ -5282,7 +5332,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C else if ((textOffsetX + nextSpaceWidth) > textBounds.width - textBoundsWidthOffset) { textOffsetX = 0.0f; - textOffsetY += GuiGetStyle(DEFAULT, TEXT_LINE_SPACING); + textOffsetY += (GuiGetStyle(DEFAULT, TEXT_SIZE) + GuiGetStyle(DEFAULT, TEXT_LINE_SPACING)); } } @@ -5332,7 +5382,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C } } - if (wrapMode == TEXT_WRAP_NONE) posOffsetY += (float)GuiGetStyle(DEFAULT, TEXT_LINE_SPACING); + if (wrapMode == TEXT_WRAP_NONE) posOffsetY += (float)(GuiGetStyle(DEFAULT, TEXT_SIZE) + GuiGetStyle(DEFAULT, TEXT_LINE_SPACING)); else if ((wrapMode == TEXT_WRAP_CHAR) || (wrapMode == TEXT_WRAP_WORD)) posOffsetY += (textOffsetY + (float)GuiGetStyle(DEFAULT, TEXT_LINE_SPACING)); //--------------------------------------------------------------------------------- } @@ -5374,13 +5424,19 @@ static void GuiTooltip(Rectangle controlRec) if ((controlRec.x + textSize.x + 16) > GetScreenWidth()) controlRec.x -= (textSize.x + 16 - controlRec.width); - GuiPanel(RAYGUI_CLITERAL(Rectangle){ controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, GuiGetStyle(DEFAULT, TEXT_SIZE) + 8.0f }, NULL); + int lineCount = 0; + GetTextLines(guiTooltipPtr, &lineCount); // Only using the line count + if ((controlRec.y + controlRec.height + textSize.y + 4 + 8*lineCount) > GetScreenHeight()) + controlRec.y -= (controlRec.height + textSize.y + 4 + 8*lineCount); + + // TODO: Probably TEXT_LINE_SPACING should be considered on panel size instead of hardcoding 8.0f + GuiPanel(RAYGUI_CLITERAL(Rectangle){ controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, textSize.y + 8.0f*lineCount }, NULL); int textPadding = GuiGetStyle(LABEL, TEXT_PADDING); int textAlignment = GuiGetStyle(LABEL, TEXT_ALIGNMENT); GuiSetStyle(LABEL, TEXT_PADDING, 0); GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); - GuiLabel(RAYGUI_CLITERAL(Rectangle){ controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, GuiGetStyle(DEFAULT, TEXT_SIZE) + 8.0f }, guiTooltipPtr); + GuiLabel(RAYGUI_CLITERAL(Rectangle){ controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, textSize.y + 8.0f*lineCount }, guiTooltipPtr); GuiSetStyle(LABEL, TEXT_ALIGNMENT, textAlignment); GuiSetStyle(LABEL, TEXT_PADDING, textPadding); } @@ -5416,7 +5472,7 @@ static const char **GuiTextSplit(const char *text, char delimiter, int *count, i if (textRow != NULL) textRow[0] = 0; - // Count how many substrings we have on text and point to every one + // Count how many substrings text contains and point to every one of them for (int i = 0; i < RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE; i++) { buffer[i] = text[i]; @@ -5637,11 +5693,11 @@ static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON) && + if (GUI_BUTTON_DOWN && !CheckCollisionPointRec(mousePoint, arrowUpLeft) && !CheckCollisionPointRec(mousePoint, arrowDownRight)) { @@ -5664,11 +5720,11 @@ static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue) state = STATE_FOCUSED; // Handle mouse wheel - int wheel = (int)GetMouseWheelMove(); - if (wheel != 0) value += wheel; + float scrollDelta = GUI_SCROLL_DELTA; + if (scrollDelta != 0) value += (int)scrollDelta; // Handle mouse button down - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_PRESSED) { guiControlExclusiveMode = true; guiControlExclusiveRec = bounds; // Store bounds as an identifier when dragging starts @@ -5690,13 +5746,13 @@ static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue) /* if (isVertical) { - if (IsKeyDown(KEY_DOWN)) value += 5; - else if (IsKeyDown(KEY_UP)) value -= 5; + if (GUI_KEY_DOWN(KEY_DOWN)) value += 5; + else if (GUI_KEY_DOWN(KEY_UP)) value -= 5; } else { - if (IsKeyDown(KEY_RIGHT)) value += 5; - else if (IsKeyDown(KEY_LEFT)) value -= 5; + if (GUI_KEY_DOWN(KEY_RIGHT)) value += 5; + else if (GUI_KEY_DOWN(KEY_LEFT)) value -= 5; } */ } @@ -5833,7 +5889,7 @@ const char **TextSplit(const char *text, char delimiter, int *count) { counter = 1; - // Count how many substrings we have on text and point to every one + // Count how many substrings text contains and point to every one of them for (int i = 0; i < RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE; i++) { buffer[i] = text[i]; @@ -5866,7 +5922,7 @@ static int TextToInteger(const char *text) 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; } @@ -5941,9 +5997,9 @@ static const char *CodepointToUTF8(int codepoint, int *byteSize) } // Get next codepoint in a UTF-8 encoded text, scanning until '\0' is found -// When a invalid UTF-8 byte is encountered we exit as soon as possible and a '?'(0x3f) codepoint is returned +// When a invalid UTF-8 byte is encountered, exiting as soon as possible and returning a '?'(0x3f) codepoint // Total number of bytes processed are returned as a parameter -// NOTE: the standard says U+FFFD should be returned in case of errors +// NOTE: The standard says U+FFFD should be returned in case of errors // but that character is not supported by the default font in raylib static int GetCodepointNext(const char *text, int *codepointSize) { diff --git a/examples/shapes/raygui.h b/examples/shapes/raygui.h index 88fe5cc5b..67c16be45 100644 --- a/examples/shapes/raygui.h +++ b/examples/shapes/raygui.h @@ -1,6 +1,6 @@ /******************************************************************************************* * -* raygui v4.5-dev - A simple and easy-to-use immediate-mode gui library +* raygui v5.0-dev - A simple and easy-to-use immediate-mode gui library * * DESCRIPTION: * raygui is a tools-dev-focused immediate-mode-gui library based on raylib but also @@ -83,8 +83,8 @@ * used for all controls, when any of those base values is set, it is automatically populated to all * controls, so, specific control values overwriting generic style should be set after base values * -* After the first BASE set we have the EXTENDED properties (by default guiStyle[16..23]), those -* properties are actually common to all controls and can not be overwritten individually (like BASE ones) +* After the first BASE properties set, the EXTENDED properties set is defined (by default guiStyle[16..23]), +* those properties are actually common to all controls and can not be overwritten individually (like BASE ones) * Some of those properties are: TEXT_SIZE, TEXT_SPACING, LINE_COLOR, BACKGROUND_COLOR * * Custom control properties can be defined using the EXTENDED properties for each independent control. @@ -141,13 +141,14 @@ * Draw text bounds rectangles for debug * * VERSIONS HISTORY: -* 5.0 (xx-Nov-2025) ADDED: Support up to 32 controls (v500) +* 5.0 (xx-Mar-2026) ADDED: Support up to 32 controls (v500) * ADDED: guiControlExclusiveMode and guiControlExclusiveRec for exclusive modes * ADDED: GuiValueBoxFloat() * ADDED: GuiDropdonwBox() properties: DROPDOWN_ARROW_HIDDEN, DROPDOWN_ROLL_UP * ADDED: GuiListView() property: LIST_ITEMS_BORDER_WIDTH * ADDED: GuiLoadIconsFromMemory() * ADDED: Multiple new icons +* ADDED: Macros for inputs customization, raylib decoupling * REMOVED: GuiSpinner() from controls list, using BUTTON + VALUEBOX properties * REMOVED: GuiSliderPro(), functionality was redundant * REVIEWED: Controls using text labels to use LABEL properties @@ -165,6 +166,7 @@ * REVIEWED: GuiTextBox(), multiple improvements: autocursor and more * REVIEWED: Functions descriptions, removed wrong return value reference * REDESIGNED: GuiColorPanel(), improved HSV <-> RGBA convertion +* REDESIGNED: WARNING: TEXT_LINE_SPACING does not consider text height, only lines spacing * * 4.0 (12-Sep-2023) ADDED: GuiToggleSlider() * ADDED: GuiColorPickerHSV() and GuiColorPanelHSV() @@ -316,7 +318,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2014-2025 Ramon Santamaria (@raysan5) +* Copyright (c) 2014-2026 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -351,10 +353,11 @@ // NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll #if defined(_WIN32) #if defined(BUILD_LIBTYPE_SHARED) - #define RAYGUIAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll) + #define RAYGUIAPI __declspec(dllexport) // Building the library as a Win32 shared library (.dll) #elif defined(USE_LIBTYPE_SHARED) - #define RAYGUIAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll) + #define RAYGUIAPI __declspec(dllimport) // Using the library as a Win32 shared library (.dll) #endif + #define _CRT_SECURE_NO_WARNINGS // Disable unsafe warnings on scanf() functions in MSVC #endif // Function specifiers definition @@ -369,9 +372,48 @@ // NOTE: Avoiding those calls, also avoids const strings memory usage #define RAYGUI_SUPPORT_LOG_INFO #if defined(RAYGUI_SUPPORT_LOG_INFO) - #define RAYGUI_LOG(...) printf(__VA_ARGS__) + #define RAYGUI_LOG(...) printf(__VA_ARGS__) #else - #define RAYGUI_LOG(...) + #define RAYGUI_LOG(...) +#endif + +// Macros to define required UI inputs, including mapping to gamepad controls +// TODO: Define additionally required macros for missing inputs +#if !defined(GUI_BUTTON_DOWN) + #define GUI_BUTTON_DOWN (IsMouseButtonDown(MOUSE_LEFT_BUTTON) || IsGamepadButtonDown(0, GAMEPAD_BUTTON_RIGHT_FACE_DOWN)) +#endif +#if !defined(GUI_BUTTON_DOWN_ALT) + // Mapping to alternative button down pressed + #define GUI_BUTTON_DOWN_ALT (IsMouseButtonDown(MOUSE_RIGHT_BUTTON) || IsGamepadButtonDown(0, GAMEPAD_BUTTON_RIGHT_FACE_RIGHT)) +#endif +#if !defined(GUI_BUTTON_PRESSED) + #define GUI_BUTTON_PRESSED (IsMouseButtonPressed(MOUSE_LEFT_BUTTON) || IsGamepadButtonPressed(0, GAMEPAD_BUTTON_RIGHT_FACE_DOWN)) +#endif +// TODO: WARNING: GuiTabBar() still requires IsMouseButtonPressed(MOUSE_MIDDLE_BUTTON) +#if !defined(GUI_BUTTON_RELEASED) + #define GUI_BUTTON_RELEASED (IsMouseButtonReleased(MOUSE_LEFT_BUTTON) || IsGamepadButtonReleased(0, GAMEPAD_BUTTON_RIGHT_FACE_DOWN)) +#endif +#if !defined(GUI_SCROLL_DELTA) + // Mapping to scroll delta changes + // TODO: Review inconsistencies between platforms + #if defined(PLATFORM_WEB) + // NOTE: Gamepad axis triggers not detected on web platform + #define GUI_SCROLL_DELTA ((float)IsGamepadButtonDown(0, GAMEPAD_BUTTON_RIGHT_TRIGGER_2) - (float)IsGamepadButtonDown(0, GAMEPAD_BUTTON_LEFT_TRIGGER_2)) + #else + #define GUI_SCROLL_DELTA (GetMouseWheelMove() + (GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_TRIGGER) + 1) - (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_TRIGGER) + 1)) + #endif +#endif +#if !defined(GUI_POINTER_POSITION) + #define GUI_POINTER_POSITION GetMousePosition() +#endif +#if !defined(GUI_KEY_DOWN) + #define GUI_KEY_DOWN(key) IsKeyDown(key) +#endif +#if !defined(GUI_KEY_PRESSED) + #define GUI_KEY_PRESSED(key) IsKeyPressed(key) +#endif +#if !defined(GUI_INPUT_KEY) + #define GUI_INPUT_KEY GetCharPressed() #endif //---------------------------------------------------------------------------------- @@ -567,7 +609,7 @@ typedef enum { //---------------------------------------------------------------------------------- // DEFAULT extended properties // NOTE: Those properties are common to all controls or global -// WARNING: We only have 8 slots for those properties by default!!! -> New global control: TEXT? +// WARNING: Only 8 slots vailable for those properties by default typedef enum { TEXT_SIZE = 16, // Text size (glyphs max height) TEXT_SPACING, // Text spacing between glyphs @@ -1091,7 +1133,7 @@ typedef enum { // Icons data is defined by bit array (every bit represents one pixel) // Those arrays are stored as unsigned int data arrays, so, // every array element defines 32 pixels (bits) of information -// One icon is defined by 8 int, (8 int * 32 bit = 256 bit = 16*16 pixels) +// One icon is defined by 8 int, (8 int*32 bit = 256 bit = 16*16 pixels) // NOTE: Number of elemens depend on RAYGUI_ICON_SIZE (by default 16x16 pixels) #define RAYGUI_ICON_DATA_ELEMENTS (RAYGUI_ICON_SIZE*RAYGUI_ICON_SIZE/32) @@ -1450,12 +1492,12 @@ static bool IsMouseButtonReleased(int button); static bool IsKeyDown(int key); static bool IsKeyPressed(int key); -static int GetCharPressed(void); // -- GuiTextBox(), GuiValueBox() +static int GetCharPressed(void); // -- GuiTextBox(), GuiValueBox() //------------------------------------------------------------------------------- // Drawing required functions //------------------------------------------------------------------------------- -static void DrawRectangle(int x, int y, int width, int height, Color color); // -- GuiDrawRectangle() +static void DrawRectangle(int x, int y, int width, int height, Color color); // -- GuiDrawRectangle() static void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4); // -- GuiColorPicker() //------------------------------------------------------------------------------- @@ -1520,11 +1562,11 @@ static Color GuiFade(Color color, float alpha); // Fade color by an alph // Gui Setup Functions Definition //---------------------------------------------------------------------------------- // Enable gui global state -// NOTE: We check for STATE_DISABLED to avoid messing custom global state setups +// NOTE: Checking for STATE_DISABLED to avoid messing custom global state setups void GuiEnable(void) { if (guiState == STATE_DISABLED) guiState = STATE_NORMAL; } // Disable gui global state -// NOTE: We check for STATE_NORMAL to avoid messing custom global state setups +// NOTE: Checking for STATE_NORMAL to avoid messing custom global state setups void GuiDisable(void) { if (guiState == STATE_NORMAL) guiState = STATE_DISABLED; } // Lock gui global state @@ -1557,9 +1599,8 @@ void GuiSetFont(Font font) { if (font.texture.id > 0) { - // NOTE: If we try to setup a font but default style has not been - // lazily loaded before, it will be overwritten, so we need to force - // default style loading first + // NOTE: If a font is tried to be set but default style has not been lazily loaded first, + // it will be overwritten, so default style loading needs to be forced first if (!guiStyleLoaded) GuiLoadStyleDefault(); guiFont = font; @@ -1613,13 +1654,14 @@ int GuiWindowBox(Rectangle bounds, const char *title) //GuiState state = guiState; int statusBarHeight = RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT; + int statusBorderWidth = GuiGetStyle(STATUSBAR, BORDER_WIDTH); Rectangle statusBar = { bounds.x, bounds.y, bounds.width, (float)statusBarHeight }; if (bounds.height < statusBarHeight*2.0f) bounds.height = statusBarHeight*2.0f; const float vPadding = statusBarHeight/2.0f - RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT/2.0f; - Rectangle windowPanel = { bounds.x, bounds.y + (float)statusBarHeight - 1, bounds.width, bounds.height - (float)statusBarHeight + 1 }; - Rectangle closeButtonRec = { statusBar.x + statusBar.width - GuiGetStyle(STATUSBAR, BORDER_WIDTH) - RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT - vPadding, + Rectangle windowPanel = { bounds.x, bounds.y + (float)statusBarHeight - (float)statusBorderWidth, bounds.width, bounds.height - (float)statusBarHeight + (float)statusBorderWidth }; + Rectangle closeButtonRec = { statusBar.x + statusBar.width - (float)statusBorderWidth - RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT - vPadding, statusBar.y + vPadding, RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT, RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT }; // Update control @@ -1629,8 +1671,8 @@ int GuiWindowBox(Rectangle bounds, const char *title) // Draw control //-------------------------------------------------------------------- - GuiStatusBar(statusBar, title); // Draw window header as status bar GuiPanel(windowPanel, NULL); // Draw window base + GuiStatusBar(statusBar, title); // Draw window header as status bar // Draw window close button int tempBorderWidth = GuiGetStyle(BUTTON, BORDER_WIDTH); @@ -1786,7 +1828,7 @@ int GuiTabBar(Rectangle bounds, const char **text, int count, int *active) } // Close tab with middle mouse button pressed - if (CheckCollisionPointRec(GetMousePosition(), tabBounds) && IsMouseButtonPressed(MOUSE_MIDDLE_BUTTON)) result = i; + if (CheckCollisionPointRec(GUI_POINTER_POSITION, tabBounds) && IsMouseButtonPressed(MOUSE_MIDDLE_BUTTON)) result = i; GuiSetStyle(TOGGLE, TEXT_PADDING, textPadding); GuiSetStyle(TOGGLE, TEXT_ALIGNMENT, textAlignment); @@ -1885,37 +1927,37 @@ int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; // Check button state if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; else state = STATE_FOCUSED; #if defined(SUPPORT_SCROLLBAR_KEY_INPUT) if (hasHorizontalScrollBar) { - if (IsKeyDown(KEY_RIGHT)) scrollPos.x -= GuiGetStyle(SCROLLBAR, SCROLL_SPEED); - if (IsKeyDown(KEY_LEFT)) scrollPos.x += GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + if (GUI_KEY_DOWN(KEY_RIGHT)) scrollPos.x -= GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + if (GUI_KEY_DOWN(KEY_LEFT)) scrollPos.x += GuiGetStyle(SCROLLBAR, SCROLL_SPEED); } if (hasVerticalScrollBar) { - if (IsKeyDown(KEY_DOWN)) scrollPos.y -= GuiGetStyle(SCROLLBAR, SCROLL_SPEED); - if (IsKeyDown(KEY_UP)) scrollPos.y += GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + if (GUI_KEY_DOWN(KEY_DOWN)) scrollPos.y -= GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + if (GUI_KEY_DOWN(KEY_UP)) scrollPos.y += GuiGetStyle(SCROLLBAR, SCROLL_SPEED); } #endif - float wheelMove = GetMouseWheelMove(); + float scrollDelta = GUI_SCROLL_DELTA; // Set scrolling speed with mouse wheel based on ratio between bounds and content - Vector2 mouseWheelSpeed = { content.width/bounds.width, content.height/bounds.height }; - if (mouseWheelSpeed.x < RAYGUI_MIN_MOUSE_WHEEL_SPEED) mouseWheelSpeed.x = RAYGUI_MIN_MOUSE_WHEEL_SPEED; - if (mouseWheelSpeed.y < RAYGUI_MIN_MOUSE_WHEEL_SPEED) mouseWheelSpeed.y = RAYGUI_MIN_MOUSE_WHEEL_SPEED; + Vector2 scrollSpeed = { content.width/bounds.width, content.height/bounds.height }; + if (scrollSpeed.x < RAYGUI_MIN_MOUSE_WHEEL_SPEED) scrollSpeed.x = RAYGUI_MIN_MOUSE_WHEEL_SPEED; + if (scrollSpeed.y < RAYGUI_MIN_MOUSE_WHEEL_SPEED) scrollSpeed.y = RAYGUI_MIN_MOUSE_WHEEL_SPEED; // Horizontal and vertical scrolling with mouse wheel - if (hasHorizontalScrollBar && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_LEFT_SHIFT))) scrollPos.x += wheelMove*mouseWheelSpeed.x; - else scrollPos.y += wheelMove*mouseWheelSpeed.y; // Vertical scroll + if (hasHorizontalScrollBar && (GUI_KEY_DOWN(KEY_LEFT_CONTROL) || GUI_KEY_DOWN(KEY_LEFT_SHIFT))) scrollPos.x += scrollDelta*scrollSpeed.x; + else scrollPos.y += scrollDelta*scrollSpeed.y; // Vertical scroll } } @@ -2001,15 +2043,15 @@ int GuiButton(Rectangle bounds, const char *text) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; // Check button state if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; else state = STATE_FOCUSED; - if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) result = 1; + if (GUI_BUTTON_RELEASED) result = 1; } } //-------------------------------------------------------------------- @@ -2031,7 +2073,7 @@ int GuiLabelButton(Rectangle bounds, const char *text) GuiState state = guiState; bool pressed = false; - // NOTE: We force bounds.width to be all text + // NOTE: Force bounds.width to be all text float textWidth = (float)GuiGetTextWidth(text); if ((bounds.width - 2*GuiGetStyle(LABEL, BORDER_WIDTH) - 2*GuiGetStyle(LABEL, TEXT_PADDING)) < textWidth) bounds.width = textWidth + 2*GuiGetStyle(LABEL, BORDER_WIDTH) + 2*GuiGetStyle(LABEL, TEXT_PADDING) + 2; @@ -2039,15 +2081,15 @@ int GuiLabelButton(Rectangle bounds, const char *text) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; // Check checkbox state if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; else state = STATE_FOCUSED; - if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) pressed = true; + if (GUI_BUTTON_RELEASED) pressed = true; } } //-------------------------------------------------------------------- @@ -2073,13 +2115,13 @@ int GuiToggle(Rectangle bounds, const char *text, bool *active) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; // Check toggle button state if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; - else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; + else if (GUI_BUTTON_RELEASED) { state = STATE_NORMAL; *active = !(*active); @@ -2184,12 +2226,12 @@ int GuiToggleSlider(Rectangle bounds, const char *text, int *active) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; - else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; + else if (GUI_BUTTON_RELEASED) { state = STATE_PRESSED; (*active)++; @@ -2255,7 +2297,7 @@ int GuiCheckBox(Rectangle bounds, const char *text, bool *checked) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; Rectangle totalBounds = { (GuiGetStyle(CHECKBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT)? textBounds.x : bounds.x, @@ -2267,10 +2309,10 @@ int GuiCheckBox(Rectangle bounds, const char *text, bool *checked) // Check checkbox state if (CheckCollisionPointRec(mousePoint, totalBounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; else state = STATE_FOCUSED; - if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_RELEASED) { *checked = !(*checked); result = 1; @@ -2323,18 +2365,18 @@ int GuiComboBox(Rectangle bounds, const char *text, int *active) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && (itemCount > 1) && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; if (CheckCollisionPointRec(mousePoint, bounds) || CheckCollisionPointRec(mousePoint, selector)) { - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_PRESSED) { *active += 1; if (*active >= itemCount) *active = 0; // Cyclic combobox } - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; else state = STATE_FOCUSED; } } @@ -2392,7 +2434,7 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && (editMode || !guiLocked) && (itemCount > 1) && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; if (editMode) { @@ -2401,11 +2443,11 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod // Check if mouse has been pressed or released outside limits if (!CheckCollisionPointRec(mousePoint, boundsOpen)) { - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON) || IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) result = 1; + if (GUI_BUTTON_PRESSED || GUI_BUTTON_RELEASED) result = 1; } // Check if already selected item has been pressed again - if (CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) result = 1; + if (CheckCollisionPointRec(mousePoint, bounds) && GUI_BUTTON_PRESSED) result = 1; // Check focused and selected item for (int i = 0; i < itemCount; i++) @@ -2417,7 +2459,7 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod if (CheckCollisionPointRec(mousePoint, itemBounds)) { itemFocused = i; - if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_RELEASED) { itemSelected = i; result = 1; // Item selected @@ -2432,7 +2474,7 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod { if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_PRESSED) { result = 1; state = STATE_PRESSED; @@ -2506,7 +2548,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) int result = 0; GuiState state = guiState; - bool multiline = false; // TODO: Consider multiline text input + bool multiline = false; // TODO: Consider multiline text input int wrapMode = GuiGetStyle(DEFAULT, TEXT_WRAP_MODE); Rectangle textBounds = GetTextBounds(TEXTBOX, bounds); @@ -2514,7 +2556,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) int thisCursorIndex = textBoxCursorIndex; if (thisCursorIndex > textLength) thisCursorIndex = textLength; int textWidth = GuiGetTextWidth(text) - GuiGetTextWidth(text + thisCursorIndex); - int textIndexOffset = 0; // Text index offset to start drawing in the box + int textIndexOffset = 0; // Text index offset to start drawing in the box // Cursor rectangle // NOTE: Position X value should be updated @@ -2547,13 +2589,13 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) !guiControlExclusiveMode && // No gui slider on dragging (wrapMode == TEXT_WRAP_NONE)) // No wrap mode { - Vector2 mousePosition = GetMousePosition(); + Vector2 mousePosition = GUI_POINTER_POSITION; if (editMode) { // GLOBAL: Auto-cursor movement logic // NOTE: Keystrokes are handled repeatedly when button is held down for some time - if (IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_UP) || IsKeyDown(KEY_DOWN) || IsKeyDown(KEY_BACKSPACE) || IsKeyDown(KEY_DELETE)) autoCursorCounter++; + if (GUI_KEY_DOWN(KEY_LEFT) || GUI_KEY_DOWN(KEY_RIGHT) || GUI_KEY_DOWN(KEY_UP) || GUI_KEY_DOWN(KEY_DOWN) || GUI_KEY_DOWN(KEY_BACKSPACE) || GUI_KEY_DOWN(KEY_DELETE)) autoCursorCounter++; else autoCursorCounter = 0; bool autoCursorShouldTrigger = (autoCursorCounter > RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN) && ((autoCursorCounter % RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY) == 0); @@ -2563,7 +2605,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) if (textBoxCursorIndex > textLength) textBoxCursorIndex = textLength; // If text does not fit in the textbox and current cursor position is out of bounds, - // we add an index offset to text for drawing only what requires depending on cursor + // adding an index offset to text for drawing only what requires depending on cursor while (textWidth >= textBounds.width) { int nextCodepointSize = 0; @@ -2574,15 +2616,15 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) textWidth = GuiGetTextWidth(text + textIndexOffset) - GuiGetTextWidth(text + textBoxCursorIndex); } - int codepoint = GetCharPressed(); // Get Unicode codepoint - if (multiline && IsKeyPressed(KEY_ENTER)) codepoint = (int)'\n'; + int codepoint = GUI_INPUT_KEY; // Get Unicode codepoint + if (multiline && GUI_KEY_PRESSED(KEY_ENTER)) codepoint = (int)'\n'; // Encode codepoint as UTF-8 int codepointSize = 0; const char *charEncoded = CodepointToUTF8(codepoint, &codepointSize); // Handle text paste action - if (IsKeyPressed(KEY_V) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))) + if (GUI_KEY_PRESSED(KEY_V) && (GUI_KEY_DOWN(KEY_LEFT_CONTROL) || GUI_KEY_DOWN(KEY_RIGHT_CONTROL))) { const char *pasteText = GetClipboardText(); if (pasteText != NULL) @@ -2632,13 +2674,13 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) } // Move cursor to start - if ((textLength > 0) && IsKeyPressed(KEY_HOME)) textBoxCursorIndex = 0; + if ((textLength > 0) && GUI_KEY_PRESSED(KEY_HOME)) textBoxCursorIndex = 0; // Move cursor to end - if ((textLength > textBoxCursorIndex) && IsKeyPressed(KEY_END)) textBoxCursorIndex = textLength; + if ((textLength > textBoxCursorIndex) && GUI_KEY_PRESSED(KEY_END)) textBoxCursorIndex = textLength; // Delete related codepoints from text, after current cursor position - if ((textLength > textBoxCursorIndex) && IsKeyPressed(KEY_DELETE) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))) + if ((textLength > textBoxCursorIndex) && GUI_KEY_PRESSED(KEY_DELETE) && (GUI_KEY_DOWN(KEY_LEFT_CONTROL) || GUI_KEY_DOWN(KEY_RIGHT_CONTROL))) { int offset = textBoxCursorIndex; int accCodepointSize = 0; @@ -2674,7 +2716,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) textLength -= accCodepointSize; } - else if ((textLength > textBoxCursorIndex) && (IsKeyPressed(KEY_DELETE) || (IsKeyDown(KEY_DELETE) && autoCursorShouldTrigger))) + else if ((textLength > textBoxCursorIndex) && (GUI_KEY_PRESSED(KEY_DELETE) || (GUI_KEY_DOWN(KEY_DELETE) && autoCursorShouldTrigger))) { // Delete single codepoint from text, after current cursor position @@ -2688,12 +2730,12 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) } // Delete related codepoints from text, before current cursor position - if ((textBoxCursorIndex > 0) && IsKeyPressed(KEY_BACKSPACE) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))) + if ((textBoxCursorIndex > 0) && GUI_KEY_PRESSED(KEY_BACKSPACE) && (GUI_KEY_DOWN(KEY_LEFT_CONTROL) || GUI_KEY_DOWN(KEY_RIGHT_CONTROL))) { int offset = textBoxCursorIndex; int accCodepointSize = 0; - int prevCodepointSize; - int prevCodepoint; + int prevCodepointSize = 0; + int prevCodepoint = 0; // Check whitespace to delete (ASCII only) while (offset > 0) @@ -2724,7 +2766,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) textBoxCursorIndex -= accCodepointSize; } - else if ((textBoxCursorIndex > 0) && (IsKeyPressed(KEY_BACKSPACE) || (IsKeyDown(KEY_BACKSPACE) && autoCursorShouldTrigger))) + else if ((textBoxCursorIndex > 0) && (GUI_KEY_PRESSED(KEY_BACKSPACE) || (GUI_KEY_DOWN(KEY_BACKSPACE) && autoCursorShouldTrigger))) { // Delete single codepoint from text, before current cursor position @@ -2740,12 +2782,12 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) } // Move cursor position with keys - if ((textBoxCursorIndex > 0) && IsKeyPressed(KEY_LEFT) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))) + if ((textBoxCursorIndex > 0) && GUI_KEY_PRESSED(KEY_LEFT) && (GUI_KEY_DOWN(KEY_LEFT_CONTROL) || GUI_KEY_DOWN(KEY_RIGHT_CONTROL))) { int offset = textBoxCursorIndex; //int accCodepointSize = 0; - int prevCodepointSize; - int prevCodepoint; + int prevCodepointSize = 0; + int prevCodepoint = 0; // Check whitespace to skip (ASCII only) while (offset > 0) @@ -2771,14 +2813,14 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) textBoxCursorIndex = offset; } - else if ((textBoxCursorIndex > 0) && (IsKeyPressed(KEY_LEFT) || (IsKeyDown(KEY_LEFT) && autoCursorShouldTrigger))) + else if ((textBoxCursorIndex > 0) && (GUI_KEY_PRESSED(KEY_LEFT) || (GUI_KEY_DOWN(KEY_LEFT) && autoCursorShouldTrigger))) { int prevCodepointSize = 0; GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize); textBoxCursorIndex -= prevCodepointSize; } - else if ((textLength > textBoxCursorIndex) && IsKeyPressed(KEY_RIGHT) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))) + else if ((textLength > textBoxCursorIndex) && GUI_KEY_PRESSED(KEY_RIGHT) && (GUI_KEY_DOWN(KEY_LEFT_CONTROL) || GUI_KEY_DOWN(KEY_RIGHT_CONTROL))) { int offset = textBoxCursorIndex; //int accCodepointSize = 0; @@ -2810,7 +2852,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) textBoxCursorIndex = offset; } - else if ((textLength > textBoxCursorIndex) && (IsKeyPressed(KEY_RIGHT) || (IsKeyDown(KEY_RIGHT) && autoCursorShouldTrigger))) + else if ((textLength > textBoxCursorIndex) && (GUI_KEY_PRESSED(KEY_RIGHT) || (GUI_KEY_DOWN(KEY_RIGHT) && autoCursorShouldTrigger))) { int nextCodepointSize = 0; GetCodepointNext(text + textBoxCursorIndex, &nextCodepointSize); @@ -2847,14 +2889,14 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) // Check if mouse cursor is at the last position int textEndWidth = GuiGetTextWidth(text + textIndexOffset); - if (GetMousePosition().x >= (textBounds.x + textEndWidth - glyphWidth/2)) + if (GUI_POINTER_POSITION.x >= (textBounds.x + textEndWidth - glyphWidth/2)) { mouseCursor.x = textBounds.x + textEndWidth; mouseCursorIndex = textLength; } // Place cursor at required index on mouse click - if ((mouseCursor.x >= 0) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + if ((mouseCursor.x >= 0) && GUI_BUTTON_PRESSED) { cursor.x = mouseCursor.x; textBoxCursorIndex = mouseCursorIndex; @@ -2867,8 +2909,8 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) //if (multiline) cursor.y = GetTextLines() // Finish text editing on ENTER or mouse click outside bounds - if ((!multiline && IsKeyPressed(KEY_ENTER)) || - (!CheckCollisionPointRec(mousePosition, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) + if ((!multiline && GUI_KEY_PRESSED(KEY_ENTER)) || + (!CheckCollisionPointRec(mousePosition, bounds) && GUI_BUTTON_PRESSED)) { textBoxCursorIndex = 0; // GLOBAL: Reset the shared cursor index autoCursorCounter = 0; // GLOBAL: Reset counter for repeated keystrokes @@ -2881,7 +2923,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) { state = STATE_FOCUSED; - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_PRESSED) { textBoxCursorIndex = textLength; // GLOBAL: Place cursor index to the end of current text autoCursorCounter = 0; // GLOBAL: Reset counter for repeated keystrokes @@ -2975,12 +3017,12 @@ int GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; // Check spinner state if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; else state = STATE_FOCUSED; } } @@ -3050,7 +3092,7 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; bool valueHasChanged = false; if (editMode) @@ -3060,7 +3102,7 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in int keyCount = (int)strlen(textValue); // Add or remove minus symbol - if (IsKeyPressed(KEY_MINUS)) + if (GUI_KEY_PRESSED(KEY_MINUS)) { if (textValue[0] == '-') { @@ -3089,8 +3131,8 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in // Add new digit to text value if ((keyCount >= 0) && (keyCount < RAYGUI_VALUEBOX_MAX_CHARS) && (GuiGetTextWidth(textValue) < bounds.width)) { - int key = GetCharPressed(); - + int key = GUI_INPUT_KEY; + // Only allow keys in range [48..57] if ((key >= 48) && (key <= 57)) { @@ -3101,7 +3143,7 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in } // Delete text - if ((keyCount > 0) && IsKeyPressed(KEY_BACKSPACE)) + if ((keyCount > 0) && GUI_KEY_PRESSED(KEY_BACKSPACE)) { keyCount--; textValue[keyCount] = '\0'; @@ -3110,11 +3152,11 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in if (valueHasChanged) *value = TextToInteger(textValue); - // NOTE: We are not clamp values until user input finishes + // NOTE: Values are not clamped until user input finishes //if (*value > maxValue) *value = maxValue; //else if (*value < minValue) *value = minValue; - if ((IsKeyPressed(KEY_ENTER) || IsKeyPressed(KEY_KP_ENTER)) || (!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) + if ((GUI_KEY_PRESSED(KEY_ENTER) || GUI_KEY_PRESSED(KEY_KP_ENTER)) || (!CheckCollisionPointRec(mousePoint, bounds) && GUI_BUTTON_PRESSED)) { if (*value > maxValue) *value = maxValue; else if (*value < minValue) *value = minValue; @@ -3130,7 +3172,7 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in if (CheckCollisionPointRec(mousePoint, bounds)) { state = STATE_FOCUSED; - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) result = 1; + if (GUI_BUTTON_PRESSED) result = 1; } } } @@ -3191,7 +3233,7 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; bool valueHasChanged = false; @@ -3202,7 +3244,7 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float int keyCount = (int)strlen(textValue); // Add or remove minus symbol - if (IsKeyPressed(KEY_MINUS)) + if (GUI_KEY_PRESSED(KEY_MINUS)) { if (textValue[0] == '-') { @@ -3233,7 +3275,7 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float { if (GuiGetTextWidth(textValue) < bounds.width) { - int key = GetCharPressed(); + int key = GUI_INPUT_KEY; if (((key >= 48) && (key <= 57)) || (key == '.') || ((keyCount == 0) && (key == '+')) || // NOTE: Sign can only be in first position @@ -3248,7 +3290,7 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float } // Pressed backspace - if (IsKeyPressed(KEY_BACKSPACE)) + if (GUI_KEY_PRESSED(KEY_BACKSPACE)) { if (keyCount > 0) { @@ -3260,14 +3302,14 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float if (valueHasChanged) *value = TextToFloat(textValue); - if ((IsKeyPressed(KEY_ENTER) || IsKeyPressed(KEY_KP_ENTER)) || (!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) result = 1; + if ((GUI_KEY_PRESSED(KEY_ENTER) || GUI_KEY_PRESSED(KEY_KP_ENTER)) || (!CheckCollisionPointRec(mousePoint, bounds) && GUI_BUTTON_PRESSED)) result = 1; } else { if (CheckCollisionPointRec(mousePoint, bounds)) { state = STATE_FOCUSED; - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) result = 1; + if (GUI_BUTTON_PRESSED) result = 1; } } } @@ -3321,11 +3363,11 @@ int GuiSlider(Rectangle bounds, const char *textLeft, const char *textRight, flo //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) { if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) { @@ -3342,7 +3384,7 @@ int GuiSlider(Rectangle bounds, const char *textLeft, const char *textRight, flo } else if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) { state = STATE_PRESSED; guiControlExclusiveMode = true; @@ -3535,12 +3577,12 @@ int GuiDummyRec(Rectangle bounds, const char *text) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; // Check button state if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + if (GUI_BUTTON_DOWN) state = STATE_PRESSED; else state = STATE_FOCUSED; } } @@ -3578,7 +3620,7 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd int itemFocused = (focus == NULL)? -1 : *focus; int itemSelected = (active == NULL)? -1 : *active; - // Check if we need a scroll bar + // Check if scroll bar is needed bool useScrollBar = false; if ((GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT) + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING))*count > bounds.height) useScrollBar = true; @@ -3602,7 +3644,7 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; // Check mouse inside list view if (CheckCollisionPointRec(mousePoint, bounds)) @@ -3615,7 +3657,7 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd if (CheckCollisionPointRec(mousePoint, itemBounds)) { itemFocused = startIndex + i; - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_PRESSED) { if (itemSelected == (startIndex + i)) itemSelected = -1; else itemSelected = startIndex + i; @@ -3629,8 +3671,8 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd if (useScrollBar) { - int wheelMove = (int)GetMouseWheelMove(); - startIndex -= wheelMove; + float scrollDelta = GUI_SCROLL_DELTA; + startIndex -= (int)scrollDelta; if (startIndex < 0) startIndex = 0; else if (startIndex > (count - visibleItems)) startIndex = count - visibleItems; @@ -3659,7 +3701,7 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd { if ((startIndex + i) == itemSelected) GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, LIST_ITEMS_BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_DISABLED)), GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_DISABLED))); - GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_DISABLED))); + GuiDrawText(text[startIndex + i], GetTextBounds(LISTVIEW, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_DISABLED))); } else { @@ -3667,18 +3709,18 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd { // Draw item selected GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, LIST_ITEMS_BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_PRESSED)), GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_PRESSED))); - GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_PRESSED))); + GuiDrawText(text[startIndex + i], GetTextBounds(LISTVIEW, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_PRESSED))); } - else if (((startIndex + i) == itemFocused)) // && (focus != NULL)) // NOTE: We want items focused, despite not returned! + else if (((startIndex + i) == itemFocused)) // && (focus != NULL)) // NOTE: Items focused, despite not returned { // Draw item focused GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, LIST_ITEMS_BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_FOCUSED)), GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_FOCUSED))); - GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_FOCUSED))); + GuiDrawText(text[startIndex + i], GetTextBounds(LISTVIEW, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_FOCUSED))); } else { // Draw item normal (no rectangle) - GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_NORMAL))); + GuiDrawText(text[startIndex + i], GetTextBounds(LISTVIEW, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_NORMAL))); } } @@ -3765,11 +3807,11 @@ int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) { if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) { @@ -3788,7 +3830,7 @@ int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha) } else if (CheckCollisionPointRec(mousePoint, bounds) || CheckCollisionPointRec(mousePoint, selector)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) { state = STATE_PRESSED; guiControlExclusiveMode = true; @@ -3850,11 +3892,11 @@ int GuiColorBarHue(Rectangle bounds, const char *text, float *hue) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) { if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) { @@ -3873,7 +3915,7 @@ int GuiColorBarHue(Rectangle bounds, const char *text, float *hue) } else if (CheckCollisionPointRec(mousePoint, bounds) || CheckCollisionPointRec(mousePoint, selector)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) { state = STATE_PRESSED; guiControlExclusiveMode = true; @@ -3886,12 +3928,12 @@ int GuiColorBarHue(Rectangle bounds, const char *text, float *hue) } else state = STATE_FOCUSED; - /*if (IsKeyDown(KEY_UP)) + /*if (GUI_KEY_DOWN(KEY_UP)) { hue -= 2.0f; if (hue <= 0.0f) hue = 0.0f; } - else if (IsKeyDown(KEY_DOWN)) + else if (GUI_KEY_DOWN(KEY_DOWN)) { hue += 2.0f; if (hue >= 360.0f) hue = 360.0f; @@ -4008,11 +4050,11 @@ int GuiColorPanelHSV(Rectangle bounds, const char *text, Vector3 *colorHsv) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) { if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) { @@ -4042,7 +4084,7 @@ int GuiColorPanelHSV(Rectangle bounds, const char *text, Vector3 *colorHsv) } else if (CheckCollisionPointRec(mousePoint, bounds)) { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_DOWN) { state = STATE_PRESSED; guiControlExclusiveMode = true; @@ -4198,6 +4240,9 @@ int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, co GuiSetStyle(LABEL, TEXT_ALIGNMENT, prevTextAlignment); } + int prevTextBoxAlignment = GuiGetStyle(TEXTBOX, TEXT_ALIGNMENT); + GuiSetStyle(TEXTBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); + if (secretViewActive != NULL) { static char stars[] = "****************"; @@ -4211,6 +4256,8 @@ int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, co if (GuiTextBox(textBoxBounds, text, textMaxSize, textEditMode)) textEditMode = !textEditMode; } + GuiSetStyle(TEXTBOX, TEXT_ALIGNMENT, prevTextBoxAlignment); + int prevBtnTextAlignment = GuiGetStyle(BUTTON, TEXT_ALIGNMENT); GuiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); @@ -4231,7 +4278,7 @@ int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, co // Grid control // NOTE: Returns grid mouse-hover selected cell // About drawing lines at subpixel spacing, simple put, not easy solution: -// https://stackoverflow.com/questions/4435450/2d-opengl-drawing-lines-that-dont-exactly-fit-pixel-raster +// REF: https://stackoverflow.com/questions/4435450/2d-opengl-drawing-lines-that-dont-exactly-fit-pixel-raster int GuiGrid(Rectangle bounds, const char *text, float spacing, int subdivs, Vector2 *mouseCell) { // Grid lines alpha amount @@ -4242,7 +4289,7 @@ int GuiGrid(Rectangle bounds, const char *text, float spacing, int subdivs, Vect int result = 0; GuiState state = guiState; - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; Vector2 currentMouseCell = { -1, -1 }; float spaceWidth = spacing/(float)subdivs; @@ -4410,11 +4457,14 @@ void GuiLoadStyle(const char *fileName) if (fileDataSize > 0) { unsigned char *fileData = (unsigned char *)RAYGUI_CALLOC(fileDataSize, sizeof(unsigned char)); - fread(fileData, sizeof(unsigned char), fileDataSize, rgsFile); + if (fileData != NULL) + { + fread(fileData, sizeof(unsigned char), fileDataSize, rgsFile); - GuiLoadStyleFromMemory(fileData, fileDataSize); + GuiLoadStyleFromMemory(fileData, fileDataSize); - RAYGUI_FREE(fileData); + RAYGUI_FREE(fileData); + } } fclose(rgsFile); @@ -4425,7 +4475,7 @@ void GuiLoadStyle(const char *fileName) // Load style default over global style void GuiLoadStyleDefault(void) { - // We set this variable first to avoid cyclic function calls + // Setting this flag first to avoid cyclic function calls // when calling GuiSetStyle() and GuiGetStyle() guiStyleLoaded = true; @@ -4454,7 +4504,7 @@ void GuiLoadStyleDefault(void) GuiSetStyle(DEFAULT, TEXT_SPACING, 1); // DEFAULT, shared by all controls GuiSetStyle(DEFAULT, LINE_COLOR, 0x90abb5ff); // DEFAULT specific property GuiSetStyle(DEFAULT, BACKGROUND_COLOR, 0xf5f5f5ff); // DEFAULT specific property - GuiSetStyle(DEFAULT, TEXT_LINE_SPACING, 15); // DEFAULT, 15 pixels between lines + GuiSetStyle(DEFAULT, TEXT_LINE_SPACING, 5); // DEFAULT, pixels between lines, from bottom of first line to top of second GuiSetStyle(DEFAULT, TEXT_ALIGNMENT_VERTICAL, TEXT_ALIGN_MIDDLE); // DEFAULT, text aligned vertically to middle of text-bounds // Initialize control-specific property values @@ -4520,7 +4570,7 @@ void GuiLoadStyleDefault(void) // NOTE: Default raylib font character 95 is a white square Rectangle whiteChar = guiFont.recs[95]; - // NOTE: We set up a 1px padding on char rectangle to avoid pixel bleeding on MSAA filtering + // NOTE: Setting up a 1px padding on char rectangle to avoid pixel bleeding on MSAA filtering SetShapesTexture(guiFont.texture, RAYGUI_CLITERAL(Rectangle){ whiteChar.x + 1, whiteChar.y + 1, whiteChar.width - 2, whiteChar.height - 2 }); } } @@ -5037,14 +5087,14 @@ static Rectangle GetTextBounds(int control, Rectangle bounds) } // Get text icon if provided and move text cursor -// NOTE: We support up to 999 values for iconId +// NOTE: Up to #999# values supported for iconId static const char *GetTextIcon(const char *text, int *iconId) { #if !defined(RAYGUI_NO_ICONS) *iconId = -1; - if (text[0] == '#') // Maybe we have an icon! + if (text[0] == '#') // Maybe it is stars with an icon, ending # must be found { - char iconValue[4] = { 0 }; // Maximum length for icon value: 3 digits + '\0' + char iconValue[4] = { 0 }; // Maximum length for icon value: 3 digits + '\0' int pos = 1; while ((pos < 4) && (text[pos] >= '0') && (text[pos] <= '9')) @@ -5076,12 +5126,12 @@ static const char **GetTextLines(const char *text, int *count) static const char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 }; for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings - int textSize = (int)strlen(text); + int textLength = (int)strlen(text); lines[0] = text; *count = 1; - for (int i = 0, k = 0; (i < textSize) && (*count < RAYGUI_MAX_TEXT_LINES); i++) + for (int i = 0, k = 0; (i < textLength) && (*count < RAYGUI_MAX_TEXT_LINES); i++) { if (text[i] == '\n') { @@ -5141,7 +5191,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C // - For every line, wordwrap mode is checked (useful for GuitextBox(), read-only) // Get text lines (using '\n' as delimiter) to be processed individually - // WARNING: We can't use GuiTextSplit() function because it can be already used + // WARNING: GuiTextSplit() function can't be used now because it can have already been used // before the GuiDrawText() call and its buffer is static, it would be overriden :( int lineCount = 0; const char **lines = GetTextLines(text, &lineCount); @@ -5152,7 +5202,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C int wrapMode = GuiGetStyle(DEFAULT, TEXT_WRAP_MODE); // Wrap-mode only available in read-only mode, no for text editing // TODO: WARNING: This totalHeight is not valid for vertical alignment in case of word-wrap - float totalHeight = (float)(lineCount*GuiGetStyle(DEFAULT, TEXT_SIZE) + (lineCount - 1)*GuiGetStyle(DEFAULT, TEXT_SIZE)/2); + float totalHeight = (float)(lineCount*GuiGetStyle(DEFAULT, TEXT_SIZE) + (lineCount - 1)*GuiGetStyle(DEFAULT, TEXT_LINE_SPACING)); float posOffsetY = 0.0f; for (int i = 0; i < lineCount; i++) @@ -5165,7 +5215,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C Vector2 textBoundsPosition = { textBounds.x, textBounds.y }; float textBoundsWidthOffset = 0.0f; - // NOTE: We get text size after icon has been processed + // NOTE: Get text size after icon has been processed // WARNING: GuiGetTextWidth() also processes text icon to get width! -> Really needed? int textSizeX = GuiGetTextWidth(lines[i]); @@ -5200,8 +5250,8 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C default: break; } - // NOTE: Make sure we get pixel-perfect coordinates, - // In case of decimals we got weird text positioning + // NOTE: Make sure getting pixel-perfect coordinates, + // In case of decimals, it could result in text positioning artifacts textBoundsPosition.x = (float)((int)textBoundsPosition.x); textBoundsPosition.y = (float)((int)textBoundsPosition.y); //--------------------------------------------------------------------------------- @@ -5211,7 +5261,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C #if !defined(RAYGUI_NO_ICONS) if (iconId >= 0) { - // NOTE: We consider icon height, probably different than text size + // NOTE: Considering icon height, probably different than text size GuiDrawIcon(iconId, (int)textBoundsPosition.x, (int)(textBounds.y + textBounds.height/2 - RAYGUI_ICON_SIZE*guiIconScale/2 + TEXT_VALIGN_PIXEL_OFFSET(textBounds.height)), guiIconScale, tint); textBoundsPosition.x += (float)(RAYGUI_ICON_SIZE*guiIconScale + ICON_TEXT_PADDING); textBoundsWidthOffset = (float)(RAYGUI_ICON_SIZE*guiIconScale + ICON_TEXT_PADDING); @@ -5237,8 +5287,8 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C int codepoint = GetCodepointNext(&lines[i][c], &codepointSize); int index = GetGlyphIndex(guiFont, codepoint); - // NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f) - // but we need to draw all of the bad bytes using the '?' symbol moving one byte + // NOTE: Normally, exiting the decoding sequence as soon as a bad byte is found (and return 0x3f) + // but all of the bad bytes need to be drawn using the '?' symbol, moving one byte if (codepoint == 0x3f) codepointSize = 1; // TODO: Review not recognized codepoints size // Get glyph width to check if it goes out of bounds @@ -5253,7 +5303,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C if ((textOffsetX + glyphWidth) > textBounds.width - textBoundsWidthOffset) { textOffsetX = 0.0f; - textOffsetY += GuiGetStyle(DEFAULT, TEXT_LINE_SPACING); + textOffsetY += (GuiGetStyle(DEFAULT, TEXT_SIZE) + GuiGetStyle(DEFAULT, TEXT_LINE_SPACING)); if (tempWrapCharMode) // Wrap at char level when too long words { @@ -5282,7 +5332,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C else if ((textOffsetX + nextSpaceWidth) > textBounds.width - textBoundsWidthOffset) { textOffsetX = 0.0f; - textOffsetY += GuiGetStyle(DEFAULT, TEXT_LINE_SPACING); + textOffsetY += (GuiGetStyle(DEFAULT, TEXT_SIZE) + GuiGetStyle(DEFAULT, TEXT_LINE_SPACING)); } } @@ -5332,7 +5382,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C } } - if (wrapMode == TEXT_WRAP_NONE) posOffsetY += (float)GuiGetStyle(DEFAULT, TEXT_LINE_SPACING); + if (wrapMode == TEXT_WRAP_NONE) posOffsetY += (float)(GuiGetStyle(DEFAULT, TEXT_SIZE) + GuiGetStyle(DEFAULT, TEXT_LINE_SPACING)); else if ((wrapMode == TEXT_WRAP_CHAR) || (wrapMode == TEXT_WRAP_WORD)) posOffsetY += (textOffsetY + (float)GuiGetStyle(DEFAULT, TEXT_LINE_SPACING)); //--------------------------------------------------------------------------------- } @@ -5374,13 +5424,19 @@ static void GuiTooltip(Rectangle controlRec) if ((controlRec.x + textSize.x + 16) > GetScreenWidth()) controlRec.x -= (textSize.x + 16 - controlRec.width); - GuiPanel(RAYGUI_CLITERAL(Rectangle){ controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, GuiGetStyle(DEFAULT, TEXT_SIZE) + 8.0f }, NULL); + int lineCount = 0; + GetTextLines(guiTooltipPtr, &lineCount); // Only using the line count + if ((controlRec.y + controlRec.height + textSize.y + 4 + 8*lineCount) > GetScreenHeight()) + controlRec.y -= (controlRec.height + textSize.y + 4 + 8*lineCount); + + // TODO: Probably TEXT_LINE_SPACING should be considered on panel size instead of hardcoding 8.0f + GuiPanel(RAYGUI_CLITERAL(Rectangle){ controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, textSize.y + 8.0f*lineCount }, NULL); int textPadding = GuiGetStyle(LABEL, TEXT_PADDING); int textAlignment = GuiGetStyle(LABEL, TEXT_ALIGNMENT); GuiSetStyle(LABEL, TEXT_PADDING, 0); GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); - GuiLabel(RAYGUI_CLITERAL(Rectangle){ controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, GuiGetStyle(DEFAULT, TEXT_SIZE) + 8.0f }, guiTooltipPtr); + GuiLabel(RAYGUI_CLITERAL(Rectangle){ controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, textSize.y + 8.0f*lineCount }, guiTooltipPtr); GuiSetStyle(LABEL, TEXT_ALIGNMENT, textAlignment); GuiSetStyle(LABEL, TEXT_PADDING, textPadding); } @@ -5416,7 +5472,7 @@ static const char **GuiTextSplit(const char *text, char delimiter, int *count, i if (textRow != NULL) textRow[0] = 0; - // Count how many substrings we have on text and point to every one + // Count how many substrings text contains and point to every one of them for (int i = 0; i < RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE; i++) { buffer[i] = text[i]; @@ -5637,11 +5693,11 @@ static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue) //-------------------------------------------------------------------- if ((state != STATE_DISABLED) && !guiLocked) { - Vector2 mousePoint = GetMousePosition(); + Vector2 mousePoint = GUI_POINTER_POSITION; if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds { - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON) && + if (GUI_BUTTON_DOWN && !CheckCollisionPointRec(mousePoint, arrowUpLeft) && !CheckCollisionPointRec(mousePoint, arrowDownRight)) { @@ -5664,11 +5720,11 @@ static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue) state = STATE_FOCUSED; // Handle mouse wheel - int wheel = (int)GetMouseWheelMove(); - if (wheel != 0) value += wheel; + float scrollDelta = GUI_SCROLL_DELTA; + if (scrollDelta != 0) value += (int)scrollDelta; // Handle mouse button down - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + if (GUI_BUTTON_PRESSED) { guiControlExclusiveMode = true; guiControlExclusiveRec = bounds; // Store bounds as an identifier when dragging starts @@ -5690,13 +5746,13 @@ static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue) /* if (isVertical) { - if (IsKeyDown(KEY_DOWN)) value += 5; - else if (IsKeyDown(KEY_UP)) value -= 5; + if (GUI_KEY_DOWN(KEY_DOWN)) value += 5; + else if (GUI_KEY_DOWN(KEY_UP)) value -= 5; } else { - if (IsKeyDown(KEY_RIGHT)) value += 5; - else if (IsKeyDown(KEY_LEFT)) value -= 5; + if (GUI_KEY_DOWN(KEY_RIGHT)) value += 5; + else if (GUI_KEY_DOWN(KEY_LEFT)) value -= 5; } */ } @@ -5833,7 +5889,7 @@ const char **TextSplit(const char *text, char delimiter, int *count) { counter = 1; - // Count how many substrings we have on text and point to every one + // Count how many substrings text contains and point to every one of them for (int i = 0; i < RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE; i++) { buffer[i] = text[i]; @@ -5866,7 +5922,7 @@ static int TextToInteger(const char *text) 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; } @@ -5941,9 +5997,9 @@ static const char *CodepointToUTF8(int codepoint, int *byteSize) } // Get next codepoint in a UTF-8 encoded text, scanning until '\0' is found -// When a invalid UTF-8 byte is encountered we exit as soon as possible and a '?'(0x3f) codepoint is returned +// When a invalid UTF-8 byte is encountered, exiting as soon as possible and returning a '?'(0x3f) codepoint // Total number of bytes processed are returned as a parameter -// NOTE: the standard says U+FFFD should be returned in case of errors +// NOTE: The standard says U+FFFD should be returned in case of errors // but that character is not supported by the default font in raylib static int GetCodepointNext(const char *text, int *codepointSize) { From 872cfae7ca4eb28d48201fd1478ea6235ecf1e6d Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 17 Feb 2026 16:51:50 +0100 Subject: [PATCH 202/232] REVIEWED: `LoadDirectoryFilesEx()`, minor tweak #5569 --- examples/core/core_directory_files.c | 5 +++-- src/rcore.c | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/core/core_directory_files.c b/examples/core/core_directory_files.c index 5bc7b7e57..f879b933e 100644 --- a/examples/core/core_directory_files.c +++ b/examples/core/core_directory_files.c @@ -40,7 +40,8 @@ int main(void) // Load file-paths on current working directory // NOTE: LoadDirectoryFiles() loads files and directories by default, // use LoadDirectoryFilesEx() for custom filters and recursive directories loading - FilePathList files = LoadDirectoryFiles(directory); + //FilePathList files = LoadDirectoryFiles(directory); + FilePathList files = LoadDirectoryFilesEx(directory, ".png;.c", false); int btnBackPressed = false; @@ -77,7 +78,7 @@ int main(void) GuiSetStyle(LISTVIEW, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); GuiSetStyle(LISTVIEW, TEXT_PADDING, 40); - GuiListViewEx((Rectangle){ 0, 50, GetScreenWidth(), GetScreenHeight() - 40 }, + GuiListViewEx((Rectangle){ 0, 50, GetScreenWidth(), GetScreenHeight() - 50 }, files.paths, files.count, &listScrollIndex, &listItemActive, &listItemFocused); /* diff --git a/src/rcore.c b/src/rcore.c index 97a6cce0e..c29fb1e19 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -2773,6 +2773,8 @@ FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool if (DirectoryExists(basePath)) // It's a directory { + if ((filter != NULL) && (filter[0] == '\0')) filter = NULL; + // SCAN 1: Count files unsigned int fileCounter = GetDirectoryFileCountEx(basePath, filter, scanSubdirs); From e8ce00dc0bf1a64e6d2ff191c91c2f17aee2a378 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 17 Feb 2026 17:02:19 +0100 Subject: [PATCH 203/232] REVIEWED: `LoadGLTF()`, log warning about draco compression not supported #5567 --- src/rmodels.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/rmodels.c b/src/rmodels.c index eadc16f07..0ee103212 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -5373,6 +5373,7 @@ static Model LoadGLTF(const char *fileName) if (result != cgltf_result_success) TRACELOG(LOG_INFO, "MODEL: [%s] Failed to load mesh/material buffers", fileName); int primitivesCount = 0; + bool dracoCompression = false; // NOTE: We will load every primitive in the glTF as a separate raylib Mesh // Determine total number of meshes needed from the node hierarchy @@ -5384,9 +5385,22 @@ static Model LoadGLTF(const char *fileName) for (unsigned int p = 0; p < mesh->primitives_count; p++) { - if (mesh->primitives[p].type == cgltf_primitive_type_triangles) primitivesCount++; + if (mesh->primitives[p].has_draco_mesh_compression) + { + dracoCompression = true; + TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to load mesh data, Draco compression not supported", fileName); + break; + } + else if (mesh->primitives[p].type == cgltf_primitive_type_triangles) primitivesCount++; } } + + if (dracoCompression) + { + return model; + TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to load glTF data", fileName); + } + TRACELOG(LOG_DEBUG, " > Primitives (triangles only) count based on hierarchy : %i", primitivesCount); // Load our model data: meshes and materials From 97023def48c4be1e27bbaab70242521dd0d829df Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 17 Feb 2026 18:45:14 +0100 Subject: [PATCH 204/232] REVIEWED: `GenImageFontAtlas()`, scale image to fit all characters, in case it fails size estimation #5542 --- src/rtext.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/rtext.c b/src/rtext.c index 8e7fafec2..0fd2d8e6b 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -796,7 +796,7 @@ Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyp if (glyphs == NULL) { - TRACELOG(LOG_WARNING, "FONT: Provided chars info not valid, returning empty image atlas"); + TRACELOG(LOG_WARNING, "FONT: Provided glyphs info not valid, returning empty image atlas"); return atlas; } @@ -881,16 +881,17 @@ Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyp if (offsetY > (atlas.height - fontSize - padding)) { - for (int j = i + 1; j < glyphCount; j++) - { - TRACELOG(LOG_WARNING, "FONT: Failed to package character (0x%02x)", glyphs[j].value); - // Make sure remaining recs contain valid data - recs[j].x = 0; - recs[j].y = 0; - recs[j].width = 0; - recs[j].height = 0; - } - break; // Break for() loop, stop processing glyphs + TRACELOG(LOG_WARNING, "FONT: Updating atlas size to fit all characters"); + + // TODO: Increment atlas size (atlas.height*2) and continue adding glyphs + int updatedAtlasHeight = atlas.height*2; + int updatedAtlasDataSize = atlas.width*atlas.height; + unsigned char *updatedAtlasData = (unsigned char *)RL_CALLOC(updatedAtlasDataSize, 1); + + memcpy(updatedAtlasData, atlas.data, atlasDataSize); + RL_FREE(atlas.data); + atlas.height = updatedAtlasHeight; + atlasDataSize = updatedAtlasDataSize; } } @@ -967,7 +968,7 @@ Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyp } } } - else TRACELOG(LOG_WARNING, "FONT: Failed to package character (0x%02x)", glyphs[i].value); + else TRACELOG(LOG_WARNING, "FONT: Failed to package glyph (0x%02x)", glyphs[i].value); } RL_FREE(rects); From 0e6cb0993d1b86c75771969cb998b682c77d546f Mon Sep 17 00:00:00 2001 From: Kirandeep-Singh-Khehra <107160937+Kirandeep-Singh-Khehra@users.noreply.github.com> Date: Thu, 19 Feb 2026 17:27:05 +0530 Subject: [PATCH 205/232] [rmodels] Added implementation of `UpdateModelAnimationBonesWithBlending()` function (#4578) * [rmodels] Added implementation of `UpdateModelAnimationBonesWithBlending()` function Signed-off-by: Kirandeep-Singh-Khehra * [rmodels] Added example for animation blending and fixed wrap issue for blend factor Signed-off-by: Kirandeep-Singh-Khehra * [rmodels] Updated build information for animation blending example Signed-off-by: Kirandeep-Singh-Khehra * [rmodels] Fixed typos in anmation blending example Signed-off-by: Kirandeep-Singh-Khehra * [rmodels] Updated blend function signature and added function to update verts from bones Signed-off-by: Kirandeep-Singh-Khehra * [rmodels] Updated documentation Signed-off-by: Kirandeep-Singh-Khehra * rlparser: update raylib_api.* by CI * rlparser: update raylib_api.* by CI --------- Signed-off-by: Kirandeep-Singh-Khehra Co-authored-by: Ray Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- examples/models/models_animation_blending.c | 152 + examples/models/models_animation_blending.png | Bin 0 -> 26143 bytes .../models_animation_blending.vcxproj | 387 + projects/VS2022/raylib.sln | 11340 ++++++++-------- src/raylib.h | 2 + src/rmodels.c | 77 +- tools/rlparser/output/raylib_api.json | 42 + tools/rlparser/output/raylib_api.lua | 21 + tools/rlparser/output/raylib_api.txt | 171 +- tools/rlparser/output/raylib_api.xml | 13 +- 10 files changed, 6451 insertions(+), 5754 deletions(-) create mode 100644 examples/models/models_animation_blending.c create mode 100644 examples/models/models_animation_blending.png create mode 100644 projects/VS2022/examples/models_animation_blending.vcxproj diff --git a/examples/models/models_animation_blending.c b/examples/models/models_animation_blending.c new file mode 100644 index 000000000..225c1bfbb --- /dev/null +++ b/examples/models/models_animation_blending.c @@ -0,0 +1,152 @@ +/******************************************************************************************* +* +* raylib [core] example - Model animation blending +* +* Example originally created with raylib 5.5 +* +* Example contributed by Kirandeep (@Kirandeep-Singh-Khehra) +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2024 Kirandeep (@Kirandeep-Singh-Khehra) +* +* Note: Due to limitations in the Apple OpenGL driver, this feature does not work on MacOS +* Note: This example uses CPU for updating meshes. +* For GPU skinning see comments with 'INFO:'. +* +********************************************************************************************/ + +#include "raylib.h" + +#define clamp(x,a,b) ((x < a)? a : (x > b)? b : x) + +#if defined(PLATFORM_DESKTOP) + #define GLSL_VERSION 330 +#else // PLATFORM_ANDROID, PLATFORM_WEB + #define GLSL_VERSION 100 +#endif + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [models] example - Model Animation Blending"); + + // Define the camera to look into our 3d world + Camera camera = { 0 }; + camera.position = (Vector3){ 8.0f, 8.0f, 8.0f }; // Camera position + camera.target = (Vector3){ 0.0f, 2.0f, 0.0f }; // Camera looking at point + camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target) + camera.fovy = 45.0f; // Camera field-of-view Y + camera.projection = CAMERA_PERSPECTIVE; // Camera projection type + + // Load gltf model + Model characterModel = LoadModel("resources/models/gltf/robot.glb"); // Load character model + +/* INFO: Uncomment this to use GPU skinning + // Load skinning shader + Shader skinningShader = LoadShader(TextFormat("resources/shaders/glsl%i/skinning.vs", GLSL_VERSION), + TextFormat("resources/shaders/glsl%i/skinning.fs", GLSL_VERSION)); + + for (int i = 0; i < characterModel.materialCount; i++) + { + characterModel.materials[i].shader = skinningShader; + } +*/ + + // Load gltf model animations + int animsCount = 0; + unsigned int animIndex0 = 0; + unsigned int animIndex1 = 0; + unsigned int animCurrentFrame = 0; + ModelAnimation *modelAnimations = LoadModelAnimations("resources/models/gltf/robot.glb", &animsCount); + + float blendFactor = 0.5f; + + DisableCursor(); // Limit cursor to relative movement inside the window + + SetTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + UpdateCamera(&camera, CAMERA_THIRD_PERSON); + + // Select current animation + if (IsKeyPressed(KEY_T)) animIndex0 = (animIndex0 + 1)%animsCount; + else if (IsKeyPressed(KEY_G)) animIndex0 = (animIndex0 + animsCount - 1)%animsCount; + if (IsKeyPressed(KEY_Y)) animIndex1 = (animIndex1 + 1)%animsCount; + else if (IsKeyPressed(KEY_H)) animIndex1 = (animIndex1 + animsCount - 1)%animsCount; + + // Select blend factor + if (IsKeyPressed(KEY_U)) blendFactor = clamp(blendFactor - 0.1, 0.0f, 1.0f); + else if (IsKeyPressed(KEY_J)) blendFactor = clamp(blendFactor + 0.1, 0.0f, 1.0f); + + // Update animation + animCurrentFrame++; + + // Update bones + // Note: Same animation frame index is used below. By default it loops both animations + UpdateModelAnimationBonesLerp(characterModel, modelAnimations[animIndex0], animCurrentFrame, modelAnimations[animIndex1], animCurrentFrame, blendFactor); + +// INFO: Comment the following line to use GPU skinning + UpdateModelVertsToCurrentBones(characterModel); + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + BeginMode3D(camera); + +/* INFO: Uncomment this to use GPU skinning + // Draw character mesh, pose calculation is done in shader (GPU skinning) + for (int i = 0; i < characterModel.meshCount; i++) + { + DrawMesh(characterModel.meshes[i], characterModel.materials[characterModel.meshMaterial[i]], characterModel.transform); + } +*/ + +// INFO: Comment the following line to use GPU skinning + DrawModel(characterModel, (Vector3){0.0f, 0.0f, 0.0f}, 1.0f, WHITE); + + + DrawGrid(10, 1.0f); + + EndMode3D(); + + DrawText("Use the U/J to adjust blend factor", 10, 10, 20, GRAY); + DrawText("Use the T/G to switch first animation", 10, 30, 20, GRAY); + DrawText("Use the Y/H to switch second animation", 10, 50, 20, GRAY); + DrawText(TextFormat("Animations: %s, %s", modelAnimations[animIndex0].name, modelAnimations[animIndex1].name), 10, 70, 20, BLACK); + DrawText(TextFormat("Blend Factor: %f", blendFactor), 10, 86, 20, BLACK); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadModelAnimations(modelAnimations, animsCount); // Unload model animation + UnloadModel(characterModel); // Unload model and meshes/material + +// INFO: Uncomment the following line to use GPU skinning + // UnloadShader(skinningShader); // Unload GPU skinning shader + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} diff --git a/examples/models/models_animation_blending.png b/examples/models/models_animation_blending.png new file mode 100644 index 0000000000000000000000000000000000000000..0d70c1a88436a01b3689693035840c34133cd936 GIT binary patch literal 26143 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 + + + + Debug.DLL + Win32 + + + Debug.DLL + x64 + + + Debug + Win32 + + + Debug + x64 + + + Release.DLL + Win32 + + + Release.DLL + x64 + + + Release + Win32 + + + Release + x64 + + + + {AFDDE100-2D36-4749-817D-12E54C56312F} + Win32Proj + models_animation_blending + 10.0 + models_animation_blending + + + + 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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)\ + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + 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) + + + 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)\ + + + 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/raylib.sln b/projects/VS2022/raylib.sln index 47e83ef4c..8483dc563 100644 --- a/projects/VS2022/raylib.sln +++ b/projects/VS2022/raylib.sln @@ -1,5670 +1,5670 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31912.275 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "raylib", "raylib\raylib.vcxproj", "{E89D61AC-55DE-4482-AFD4-DF7242EBC859}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "core", "core", "{6C82BAAE-BDDF-457D-8FA8-7E2490B07035}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shapes", "shapes", "{278D8859-20B1-428F-8448-064F46E1F021}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "textures", "textures", "{DA049009-21FF-4AC0-84E4-830DD1BCD0CE}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "text", "text", "{8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "models", "models", "{AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shaders", "shaders", "{5317807F-61D4-4E0F-B6DC-2D9F12621ED9}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "audio", "audio", "{CC132A4D-D081-4C26-BFB9-AB11984054F8}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "others", "others", "{E9D708A5-9C1F-4B84-A795-C5F191801762}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_basic_window", "examples\core_basic_window.vcxproj", "{0981CA98-E4A5-4DF1-987F-A41D09131EFC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_sprite_animation", "examples\textures_sprite_animation.vcxproj", "{C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_srcrec_dstrec", "examples\textures_srcrec_dstrec.vcxproj", "{103B292B-049B-4B15-85A1-9F902840DB2C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_image_drawing", "examples\textures_image_drawing.vcxproj", "{0C2D2F82-AE67-400C-B19C-8C9B957B132A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "audio_module_playing", "examples\audio_module_playing.vcxproj", "{E6784F91-4E4E-4956-A079-73FAB1AC7BE6}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "audio_music_stream", "examples\audio_music_stream.vcxproj", "{BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "audio_raw_stream", "examples\audio_raw_stream.vcxproj", "{93A1F656-0D29-4C5E-B140-11F23FF5D6AB}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "audio_sound_loading", "examples\audio_sound_loading.vcxproj", "{F81C5819-85B6-4D2E-B6DC-104A7634461B}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_2d_camera", "examples\core_2d_camera.vcxproj", "{66CC5B13-881A-412F-8C51-746622A91C5A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_2d_camera_platformer", "examples\core_2d_camera_platformer.vcxproj", "{CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_3d_camera_first_person", "examples\core_3d_camera_first_person.vcxproj", "{557138B0-7BE2-4392-B2E2-B45734031A62}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_3d_camera_free", "examples\core_3d_camera_free.vcxproj", "{9EED87BB-527F-4D05-9384-6D16CFD627A8}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_3d_camera_mode", "examples\core_3d_camera_mode.vcxproj", "{6D1CA2F1-7FCA-4249-9220-075C2DF4F965}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_3d_camera_split_screen", "examples\core_3d_camera_split_screen.vcxproj", "{946A1700-C7AA-46F0-AEF2-67C98B5722AC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_3d_picking", "examples\core_3d_picking.vcxproj", "{FD193822-3D5C-4161-A147-884C2ABDE483}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_custom_logging", "examples\core_custom_logging.vcxproj", "{20AD0AC9-9159-4744-99CC-6AC5779D6B87}" -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_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 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_input_gestures", "examples\core_input_gestures.vcxproj", "{51A00565-5787-4911-9CC0-28403AA4909D}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_input_keys", "examples\core_input_keys.vcxproj", "{92B64AE7-D773-4F05-89F1-CE59BBF4F053}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_input_mouse", "examples\core_input_mouse.vcxproj", "{A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_input_multitouch", "examples\core_input_multitouch.vcxproj", "{A643BB06-735D-47F3-BFE7-B6D3C36F7097}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_random_sequence", "examples\core_random_sequence.vcxproj", "{6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_random_values", "examples\core_random_values.vcxproj", "{B332DCA8-3599-4A99-917A-82261BDC27AC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_scissor_test", "examples\core_scissor_test.vcxproj", "{59089B0C-AAB4-4532-B294-44DEAE7178B7}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_storage_values", "examples\core_storage_values.vcxproj", "{C298876B-6C12-4EA4-903B-33450BCD9884}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_vr_simulator", "examples\core_vr_simulator.vcxproj", "{83F586FA-C801-4979-ACCA-006BD628CC88}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_window_flags", "examples\core_window_flags.vcxproj", "{86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_window_letterbox", "examples\core_window_letterbox.vcxproj", "{FF2970AE-E2E9-405F-B321-D523A1BD44A0}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_world_screen", "examples\core_world_screen.vcxproj", "{79417CE2-FEEB-42F0-BC53-62D5267B19B1}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_animation_playing", "examples\models_animation_playing.vcxproj", "{AFDDE100-2D36-4749-817D-12E54C56312F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_billboard_rendering", "examples\models_billboard_rendering.vcxproj", "{B7812167-50FB-4934-996F-DF6FE4CBBFDF}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_box_collisions", "examples\models_box_collisions.vcxproj", "{39DB56C7-05F8-492C-A8D4-F19E40FECB59}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_cubicmap_rendering", "examples\models_cubicmap_rendering.vcxproj", "{82F3D34B-8DB2-4C6A-98B1-132245DD9D99}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_first_person_maze", "examples\models_first_person_maze.vcxproj", "{CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_geometric_shapes", "examples\models_geometric_shapes.vcxproj", "{14BA7F98-02CC-4648-9236-676BFF9458AF}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_heightmap_rendering", "examples\models_heightmap_rendering.vcxproj", "{0859A973-E4FE-4688-8D16-0253163FDE24}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_loading", "examples\models_loading.vcxproj", "{F3412853-2B6A-4334-8CF2-B796CDAE0850}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_mesh_generation", "examples\models_mesh_generation.vcxproj", "{BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_mesh_picking", "examples\models_mesh_picking.vcxproj", "{D03F2C82-9553-4AFA-8F49-9234009122B6}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_orthographic_projection", "examples\models_orthographic_projection.vcxproj", "{FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_rlgl_solar_system", "examples\models_rlgl_solar_system.vcxproj", "{A53CCF42-A972-478F-9336-0F618B3EC06A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_skybox_rendering", "examples\models_skybox_rendering.vcxproj", "{0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_waving_cubes", "examples\models_waving_cubes.vcxproj", "{870723DD-945A-4136-B65B-4AF3BF85369C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_yaw_pitch_roll", "examples\models_yaw_pitch_roll.vcxproj", "{EA6488AD-445B-4835-87FB-EBC9E2EDAF97}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_to_image", "examples\textures_to_image.vcxproj", "{E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_sprite_explosion", "examples\textures_sprite_explosion.vcxproj", "{472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_sprite_button", "examples\textures_sprite_button.vcxproj", "{589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_raw_data", "examples\textures_raw_data.vcxproj", "{3AD868E6-8355-4F29-B5ED-7DE94AD786E7}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_particles_blending", "examples\textures_particles_blending.vcxproj", "{2B78CF0A-5403-45E2-99BD-493F1679BCDB}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_npatch_drawing", "examples\textures_npatch_drawing.vcxproj", "{0AB968E0-E993-45CE-8875-7453C96DF583}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_mouse_painting", "examples\textures_mouse_painting.vcxproj", "{25923141-9859-4AFE-8168-0DF78322FC63}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_logo_raylib", "examples\textures_logo_raylib.vcxproj", "{7E855020-7FA4-482D-B510-2E709354FE8B}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_image_text", "examples\textures_image_text.vcxproj", "{9782E0C8-2BD3-4F67-B420-21CF19CA2435}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_image_processing", "examples\textures_image_processing.vcxproj", "{9F4135E3-9814-452C-9B35-0EFBCD792B49}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_image_loading", "examples\textures_image_loading.vcxproj", "{C45343E6-DAB6-4F3A-A00A-8BED71A098BE}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_image_generation", "examples\textures_image_generation.vcxproj", "{B19DD336-538E-4091-A559-EAA717FEC899}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_tiled_drawing", "examples\textures_tiled_drawing.vcxproj", "{0BF60202-43F7-48E9-8717-D31E56FA5BE0}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_bunnymark", "examples\textures_bunnymark.vcxproj", "{4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_blend_modes", "examples\textures_blend_modes.vcxproj", "{6D75CD88-1A03-4955-B8C7-ACFC3742154F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_background_scrolling", "examples\textures_background_scrolling.vcxproj", "{8DD0EB7E-668E-452D-91D7-906C64A9C8AC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_writing_anim", "examples\text_writing_anim.vcxproj", "{F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_unicode_emojis", "examples\text_unicode_emojis.vcxproj", "{1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_rectangle_bounds", "examples\text_rectangle_bounds.vcxproj", "{25BCB876-B60A-499B-9046-E9801CFD7780}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_sprite_fonts", "examples\text_sprite_fonts.vcxproj", "{56FB0A45-145F-4EAE-B2C8-E5833E682D8F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_input_box", "examples\text_input_box.vcxproj", "{2BB0C1D4-9298-45AC-B244-67A99769A292}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_format_text", "examples\text_format_text.vcxproj", "{99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_font_spritefont", "examples\text_font_spritefont.vcxproj", "{81064BCE-EEC1-43B0-9912-F05F2B54B11A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_font_sdf", "examples\text_font_sdf.vcxproj", "{31B41997-3890-45E3-93FE-C57B363E9C0D}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_font_loading", "examples\text_font_loading.vcxproj", "{D550AB93-DF31-4B76-873F-F075018352F4}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_font_filters", "examples\text_font_filters.vcxproj", "{8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_rectangle_scaling", "examples\shapes_rectangle_scaling.vcxproj", "{F90FCDC5-EE14-4B89-96DB-4392E28F34AF}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_logo_raylib_anim", "examples\shapes_logo_raylib_anim.vcxproj", "{93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_logo_raylib", "examples\shapes_logo_raylib.vcxproj", "{56E68E37-B3FC-4799-91AF-0CA10B6D55A5}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_lines_bezier", "examples\shapes_lines_bezier.vcxproj", "{03E7018C-44A2-4C46-9CE7-F2A135A2692B}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_following_eyes", "examples\shapes_following_eyes.vcxproj", "{F3F6FE4D-9D9E-451A-B0BA-81456104B672}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_basic_shapes", "examples\shapes_basic_shapes.vcxproj", "{C27794B5-1293-4EA7-BC0E-0F18E6325539}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_bouncing_ball", "examples\shapes_bouncing_ball.vcxproj", "{02F41059-12A2-4A96-8D77-07EFE4B108FD}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_collision_area", "examples\shapes_collision_area.vcxproj", "{B774E0B9-9514-4E88-975F-4EB6C3B8D519}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_colors_palette", "examples\shapes_colors_palette.vcxproj", "{D91367C2-2189-4859-A7FE-D2CAB84FA15C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_circle_sector_drawing", "examples\shapes_circle_sector_drawing.vcxproj", "{33459B4E-1839-4856-BF6B-22480D11FE31}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_rounded_rectangle_drawing", "examples\shapes_rounded_rectangle_drawing.vcxproj", "{48871156-181A-475A-BD8D-200086A09675}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_ring_drawing", "examples\shapes_ring_drawing.vcxproj", "{C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_easings_ball", "examples\shapes_easings_ball.vcxproj", "{1C49E35A-2838-49D9-9D5F-4B8134960EF6}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_easings_box", "examples\shapes_easings_box.vcxproj", "{F91142E2-A999-47F0-9E74-38C1E2930EBE}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_easings_rectangles", "examples\shapes_easings_rectangles.vcxproj", "{1EDD4BCF-345C-4065-8CBD-7285224293C3}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_basic_lighting", "examples\shaders_basic_lighting.vcxproj", "{A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_custom_uniform", "examples\shaders_custom_uniform.vcxproj", "{B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_eratosthenes_sieve", "examples\shaders_eratosthenes_sieve.vcxproj", "{D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_fog_rendering", "examples\shaders_fog_rendering.vcxproj", "{4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_hot_reloading", "examples\shaders_hot_reloading.vcxproj", "{CF3755C4-937D-4ABF-B7B3-95140808717F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_julia_set", "examples\shaders_julia_set.vcxproj", "{D34939FE-8873-4C53-8D6C-74DED78EA3C4}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_model_shader", "examples\shaders_model_shader.vcxproj", "{D408A730-363A-4ABF-BCEF-5D63DCC66042}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_multi_sample2d", "examples\shaders_multi_sample2d.vcxproj", "{F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_palette_switch", "examples\shaders_palette_switch.vcxproj", "{52FB7463-C128-42AF-A02F-78F48473EA9A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_postprocessing", "examples\shaders_postprocessing.vcxproj", "{7381D91E-5C72-48F0-AAB4-95C9B10D7484}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_raymarching_rendering", "examples\shaders_raymarching_rendering.vcxproj", "{D36EC43E-B31F-4CF4-8285-93A7A9D90189}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_mesh_instancing", "examples\shaders_mesh_instancing.vcxproj", "{274C0319-7E1E-4188-936B-8DF3331230B3}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_shapes_textures", "examples\shaders_shapes_textures.vcxproj", "{41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_simple_mask", "examples\shaders_simple_mask.vcxproj", "{600C3D4F-0670-4DB4-B30F-520A729053B5}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_spotlight_rendering", "examples\shaders_spotlight_rendering.vcxproj", "{11F33A39-74B7-4018-B5F9-CC285A673A8F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_texture_rendering", "examples\shaders_texture_rendering.vcxproj", "{A6F5E35E-B4A7-41B3-853A-75558E6E0715}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_texture_waves", "examples\shaders_texture_waves.vcxproj", "{291B4975-8EFF-4C7C-8AF3-44A77B8491B8}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "embedded_files_loading", "examples\embedded_files_loading.vcxproj", "{FDE6080B-E203-4066-910D-AD0302566008}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "easings_testbed", "examples\easings_testbed.vcxproj", "{E1B6D565-9D7C-46B7-9202-ECF54974DE50}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rlgl_standalone", "examples\rlgl_standalone.vcxproj", "{C8765523-58F8-4C8E-9914-693396F6F0FF}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_loading_vox", "examples\models_loading_vox.vcxproj", "{2F1B955B-275E-4D8E-8864-06FEC44D7912}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_loading_gltf", "examples\models_loading_gltf.vcxproj", "{F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_codepoints_loading", "examples\text_codepoints_loading.vcxproj", "{F2DB2E59-76BF-4D81-859A-AFC289C046C0}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_window_should_close", "examples\core_window_should_close.vcxproj", "{3FE7E9B6-49AC-4246-A789-28DB4644567B}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_fog_of_war", "examples\textures_fog_of_war.vcxproj", "{EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_gif_player", "examples\textures_gif_player.vcxproj", "{191A5289-BA65-4638-A215-C521F0187313}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_2d_camera_mouse_zoom", "examples\core_2d_camera_mouse_zoom.vcxproj", "{3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_basic_screen_manager", "examples\core_basic_screen_manager.vcxproj", "{8B1AF423-00F1-4924-AC54-F77D402D2AC9}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_custom_frame_control", "examples\core_custom_frame_control.vcxproj", "{658A1B85-554E-4A5D-973A-FFE592CDD5F2}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rlgl_compute_shader", "examples\rlgl_compute_shader.vcxproj", "{07CA51AD-72AE-46A2-AAED-DC3E3F807976}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_3d_drawing", "examples\text_3d_drawing.vcxproj", "{27B110CC-43C0-400A-89D9-245E681647D7}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_polygon_drawing", "examples\textures_polygon_drawing.vcxproj", "{1DE84812-E143-4C4B-A61D-9267AAD55401}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "audio_stream_effects", "examples\audio_stream_effects.vcxproj", "{4A87569C-4BD3-4113-B4B9-573D65B3D3F8}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_textured_curve", "examples\textures_textured_curve.vcxproj", "{769FF0C1-4424-4FA3-BC44-D7A7DA312A06}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_loading_m3d", "examples\models_loading_m3d.vcxproj", "{6D9E00D8-2893-45E4-9363-3F7F61D416BD}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_depth_writing", "examples\shaders_depth_writing.vcxproj", "{70B35F59-AFC2-4D8F-8833-5314D2047A81}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_depth_rendering", "examples\shaders_depth_rendering.vcxproj", "{DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_hybrid_rendering", "examples\shaders_hybrid_rendering.vcxproj", "{3755E9F4-CB48-4EC3-B561-3B85964EBDEF}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "audio_sound_multi", "examples\audio_sound_multi.vcxproj", "{F81C5819-85B4-4D2E-B6DC-104A7634461B}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_2d_camera_split_screen", "examples\core_2d_camera_split_screen.vcxproj", "{CC62F7DB-D089-4677-8575-CAB7A7815C43}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_automation_events", "examples\core_automation_events.vcxproj", "{7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "audio_mixed_processor", "examples\audio_mixed_processor.vcxproj", "{A4B0D971-3CD6-41C9-8AB2-055D25A33373}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_input_mouse_wheel", "examples\core_input_mouse_wheel.vcxproj", "{15CDD310-6980-42A6-8082-3A6B7730D13F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_smooth_pixelperfect", "examples\core_smooth_pixelperfect.vcxproj", "{71DB4284-5B1C-4E86-9AF5-B91542D44A6F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_textured_cube", "examples\models_textured_cube.vcxproj", "{4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_deferred_rendering", "examples\shaders_deferred_rendering.vcxproj", "{88DE5AD6-0074-4A5A-BE22-C840153E35D5}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_texture_outline", "examples\shaders_texture_outline.vcxproj", "{A546E75A-5242-46E6-9A9E-6C91554EAB84}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_texture_tiling", "examples\shaders_texture_tiling.vcxproj", "{EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_splines_drawing", "examples\shapes_splines_drawing.vcxproj", "{DF25E545-00FF-4E64-844C-7DF98991F901}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_top_down_lights", "examples\shapes_top_down_lights.vcxproj", "{703BE7BA-5B99-4F70-806D-3A259F6A991E}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_rectangle_advanced", "examples\shapes_rectangle_advanced.vcxproj", "{FAFEE2F9-24B0-4AF1-B512-433E9590033F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_animation_gpu_skinning", "examples\models_animation_gpu_skinning.vcxproj", "{8245DAD9-D402-4D5C-8F45-32229CD3B263}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_shadowmap_rendering", "examples\shaders_shadowmap_rendering.vcxproj", "{41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_bone_socket", "examples\models_bone_socket.vcxproj", "{3A7FE53D-35F7-49DC-9C9A-A5204A53523F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_vertex_displacement", "examples\shaders_vertex_displacement.vcxproj", "{CCA63A76-D9FC-4130-9F67-4D97F9770D53}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_rounded_rectangle", "examples\shaders_rounded_rectangle.vcxproj", "{D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_digital_clock", "examples\shapes_digital_clock.vcxproj", "{3384C257-3CFE-4A8F-838C-19DAC5C955DA}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_double_pendulum", "examples\shapes_double_pendulum.vcxproj", "{2B140378-125F-4DE9-AC37-2CC1B73D7254}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_image_kernel", "examples\textures_image_kernel.vcxproj", "{F4C55B99-E1C5-496A-8AC2-40188C38F4F6}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_image_rotate", "examples\textures_image_rotate.vcxproj", "{2AA91EED-2D32-4B09-84A3-53D41EED1005}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_image_channel", "examples\textures_image_channel.vcxproj", "{EC0910F6-8D66-4509-BF57-A5EE7AE9485F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_point_rendering", "examples\models_point_rendering.vcxproj", "{921391C6-7626-4212-9928-BC82BC785461}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_tesseract_view", "examples\models_tesseract_view.vcxproj", "{6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_basic_pbr", "examples\shaders_basic_pbr.vcxproj", "{4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_lightmap_rendering", "examples\shaders_lightmap_rendering.vcxproj", "{C54703BF-D68A-480D-BE27-49B62E45D582}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "audio_sound_positioning", "examples\audio_sound_positioning.vcxproj", "{9CD8BCAD-F212-4BCC-BA98-899743CE3279}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_input_virtual_controls", "examples\core_input_virtual_controls.vcxproj", "{0981CA28-E4A5-4DF1-987F-A41D09131EFC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_3d_camera_fps", "examples\core_3d_camera_fps.vcxproj", "{6B1A933E-71B8-4C1F-9E79-02D98830E671}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_normalmap_rendering", "examples\shaders_normalmap_rendering.vcxproj", "{6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_unicode_ranges", "examples\text_unicode_ranges.vcxproj", "{6777EC3C-077C-42FC-B4AD-B799CE55CCE4}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_input_gestures_testbed", "examples\core_input_gestures_testbed.vcxproj", "{A61DAD9C-271C-4E95-81AA-DB4CD58564D4}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_render_texture", "examples\core_render_texture.vcxproj", "{49C67F03-1A56-4F96-B278-39B66EC93678}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_inline_styling", "examples\text_inline_styling.vcxproj", "{D496308F-3C3C-40B3-A3ED-EA327D244B3E}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_undo_redo", "examples\core_undo_redo.vcxproj", "{3B27F358-2679-4F38-B297-17B536F580BB}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_input_actions", "examples\core_input_actions.vcxproj", "{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_delta_time", "examples\core_delta_time.vcxproj", "{19CA0070-B4B2-4394-90B7-D0C259AA35BA}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_bullet_hell", "examples\shapes_bullet_hell.vcxproj", "{2CCCD9E4-9058-4291-BD89-39C979F0CA1E}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_vector_angle", "examples\shapes_vector_angle.vcxproj", "{9DB1F875-6E65-4195-B23F-ED8095C0B99C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_basic_voxel", "examples\models_basic_voxel.vcxproj", "{52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_dashed_line", "examples\shapes_dashed_line.vcxproj", "{8E132D5A-2C00-48D0-8747-97E41356F26F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_rotating_cube", "examples\models_rotating_cube.vcxproj", "{A4662163-83E7-4309-8CAA-B0BF13655FE6}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_ascii_rendering", "examples\shaders_ascii_rendering.vcxproj", "{5F4B766F-DD52-4B53-B6C3-BC7611E17F20}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_monitor_detector", "examples\core_monitor_detector.vcxproj", "{FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "web_basic_window", "examples\web_basic_window.vcxproj", "{A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_kaleidoscope", "examples\shapes_kaleidoscope.vcxproj", "{0C442799-B09C-4CD1-9538-711B6E85E9BF}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_recursive_tree", "examples\shapes_recursive_tree.vcxproj", "{DFB40A10-F8B7-412A-BCC3-5EE49294D816}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_triangle_strip", "examples\shapes_triangle_strip.vcxproj", "{BB58A5FB-1A35-4471-86D0-A5189EC541B3}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_pie_chart", "examples\shapes_pie_chart.vcxproj", "{61997220-5383-4AE5-ABD4-5F45AE1B0F2A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_directory_files", "examples\core_directory_files.vcxproj", "{7467E9AE-844F-444D-8A3F-17397544BA21}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_simple_particles", "examples\shapes_simple_particles.vcxproj", "{497FDF54-9762-4048-A833-61CC3980A0FB}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_words_alignment", "examples\text_words_alignment.vcxproj", "{29B00F47-BE91-4A1F-B87D-B1302F038316}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_clipboard_text", "examples\core_clipboard_text.vcxproj", "{124935CC-73BB-489E-92E8-4F922A85DB5D}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_clock_of_clocks", "examples\shapes_clock_of_clocks.vcxproj", "{AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_mouse_trail", "examples\shapes_mouse_trail.vcxproj", "{0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_starfield_effect", "examples\shapes_starfield_effect.vcxproj", "{EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_highdpi_testbed", "examples\core_highdpi_testbed.vcxproj", "{1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_screen_recording", "examples\core_screen_recording.vcxproj", "{9DE2FC01-A839-4F89-8319-9071D4C54821}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_text_file_loading", "examples\core_text_file_loading.vcxproj", "{2F578155-D51F-4C03-AB7F-5C5122CA46CC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_mandelbrot_set", "examples\shaders_mandelbrot_set.vcxproj", "{1C829D1A-892C-451C-AF0B-AC65C85F5CC6}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_math_angle_rotation", "examples\shapes_math_angle_rotation.vcxproj", "{84DE22BB-C25F-425C-A7FE-0120CF107B83}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_color_correction", "examples\shaders_color_correction.vcxproj", "{98152EDD-7E28-4FA3-89D8-B636ED5D5F65}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_math_sine_cosine", "examples\shapes_math_sine_cosine.vcxproj", "{B7FDD40F-DDA4-468E-9C40-EEB175964A26}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_decals", "examples\models_decals.vcxproj", "{028F0967-B253-45DA-B1C4-FACCE45D0D8D}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_lines_drawing", "examples\shapes_lines_drawing.vcxproj", "{666346D7-C84B-498D-AE17-53B20C62DB1A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_viewport_scaling", "examples\core_viewport_scaling.vcxproj", "{AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_compute_hash", "examples\core_compute_hash.vcxproj", "{6C897101-BE52-4387-8AA2-062123A76BA1}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_screen_buffer", "examples\textures_screen_buffer.vcxproj", "{4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "audio_spectrum_visualizer", "examples\audio_spectrum_visualizer.vcxproj", "{2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_directional_billboard", "examples\models_directional_billboard.vcxproj", "{30011884-25EE-42C9-BB15-888CAFB1AA6E}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_rlgl_color_wheel", "examples\shapes_rlgl_color_wheel.vcxproj", "{32FE2658-1D70-442E-8672-0AC5C6F0BD7B}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_rlgl_triangle", "examples\shapes_rlgl_triangle.vcxproj", "{842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}" -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", "{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 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_hilbert_curve", "examples\shapes_hilbert_curve.vcxproj", "{DC163251-16C3-4B72-B965-ACDBA0F02BD1}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_keyboard_testbed", "examples\core_keyboard_testbed.vcxproj", "{D35D2FDA-B53F-4F70-81CA-24D95812B89C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_framebuffer_rendering", "examples\textures_framebuffer_rendering.vcxproj", "{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug.DLL|ARM64 = Debug.DLL|ARM64 - Debug.DLL|x64 = Debug.DLL|x64 - Debug.DLL|x86 = Debug.DLL|x86 - Debug|ARM64 = Debug|ARM64 - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release.DLL|ARM64 = Release.DLL|ARM64 - Release.DLL|x64 = Release.DLL|x64 - Release.DLL|x86 = Release.DLL|x86 - Release|ARM64 = Release|ARM64 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug|ARM64.Build.0 = Debug|ARM64 - {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug|x64.ActiveCfg = Debug|x64 - {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug|x64.Build.0 = Debug|x64 - {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug|x86.ActiveCfg = Debug|Win32 - {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug|x86.Build.0 = Debug|Win32 - {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release|ARM64.ActiveCfg = Release|ARM64 - {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release|ARM64.Build.0 = Release|ARM64 - {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release|x64.ActiveCfg = Release|x64 - {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release|x64.Build.0 = Release|x64 - {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release|x86.ActiveCfg = Release|Win32 - {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release|x86.Build.0 = Release|Win32 - {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug|ARM64.Build.0 = Debug|ARM64 - {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug|x64.ActiveCfg = Debug|x64 - {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug|x64.Build.0 = Debug|x64 - {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug|x86.ActiveCfg = Debug|Win32 - {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug|x86.Build.0 = Debug|Win32 - {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release|ARM64.ActiveCfg = Release|ARM64 - {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release|ARM64.Build.0 = Release|ARM64 - {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release|x64.ActiveCfg = Release|x64 - {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release|x64.Build.0 = Release|x64 - {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release|x86.ActiveCfg = Release|Win32 - {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release|x86.Build.0 = Release|Win32 - {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Debug|ARM64.Build.0 = Debug|ARM64 - {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Debug|x64.ActiveCfg = Debug|x64 - {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Debug|x64.Build.0 = Debug|x64 - {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Debug|x86.ActiveCfg = Debug|Win32 - {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Debug|x86.Build.0 = Debug|Win32 - {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Release|ARM64.ActiveCfg = Release|ARM64 - {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Release|ARM64.Build.0 = Release|ARM64 - {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Release|x64.ActiveCfg = Release|x64 - {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Release|x64.Build.0 = Release|x64 - {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Release|x86.ActiveCfg = Release|Win32 - {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Release|x86.Build.0 = Release|Win32 - {103B292B-049B-4B15-85A1-9F902840DB2C}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {103B292B-049B-4B15-85A1-9F902840DB2C}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {103B292B-049B-4B15-85A1-9F902840DB2C}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {103B292B-049B-4B15-85A1-9F902840DB2C}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {103B292B-049B-4B15-85A1-9F902840DB2C}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {103B292B-049B-4B15-85A1-9F902840DB2C}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {103B292B-049B-4B15-85A1-9F902840DB2C}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {103B292B-049B-4B15-85A1-9F902840DB2C}.Debug|ARM64.Build.0 = Debug|ARM64 - {103B292B-049B-4B15-85A1-9F902840DB2C}.Debug|x64.ActiveCfg = Debug|x64 - {103B292B-049B-4B15-85A1-9F902840DB2C}.Debug|x64.Build.0 = Debug|x64 - {103B292B-049B-4B15-85A1-9F902840DB2C}.Debug|x86.ActiveCfg = Debug|Win32 - {103B292B-049B-4B15-85A1-9F902840DB2C}.Debug|x86.Build.0 = Debug|Win32 - {103B292B-049B-4B15-85A1-9F902840DB2C}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {103B292B-049B-4B15-85A1-9F902840DB2C}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {103B292B-049B-4B15-85A1-9F902840DB2C}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {103B292B-049B-4B15-85A1-9F902840DB2C}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {103B292B-049B-4B15-85A1-9F902840DB2C}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {103B292B-049B-4B15-85A1-9F902840DB2C}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {103B292B-049B-4B15-85A1-9F902840DB2C}.Release|ARM64.ActiveCfg = Release|ARM64 - {103B292B-049B-4B15-85A1-9F902840DB2C}.Release|ARM64.Build.0 = Release|ARM64 - {103B292B-049B-4B15-85A1-9F902840DB2C}.Release|x64.ActiveCfg = Release|x64 - {103B292B-049B-4B15-85A1-9F902840DB2C}.Release|x64.Build.0 = Release|x64 - {103B292B-049B-4B15-85A1-9F902840DB2C}.Release|x86.ActiveCfg = Release|Win32 - {103B292B-049B-4B15-85A1-9F902840DB2C}.Release|x86.Build.0 = Release|Win32 - {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Debug|ARM64.Build.0 = Debug|ARM64 - {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Debug|x64.ActiveCfg = Debug|x64 - {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Debug|x64.Build.0 = Debug|x64 - {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Debug|x86.ActiveCfg = Debug|Win32 - {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Debug|x86.Build.0 = Debug|Win32 - {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Release|ARM64.ActiveCfg = Release|ARM64 - {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Release|ARM64.Build.0 = Release|ARM64 - {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Release|x64.ActiveCfg = Release|x64 - {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Release|x64.Build.0 = Release|x64 - {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Release|x86.ActiveCfg = Release|Win32 - {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Release|x86.Build.0 = Release|Win32 - {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Debug|ARM64.Build.0 = Debug|ARM64 - {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Debug|x64.ActiveCfg = Debug|x64 - {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Debug|x64.Build.0 = Debug|x64 - {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Debug|x86.ActiveCfg = Debug|Win32 - {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Debug|x86.Build.0 = Debug|Win32 - {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Release|ARM64.ActiveCfg = Release|ARM64 - {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Release|ARM64.Build.0 = Release|ARM64 - {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Release|x64.ActiveCfg = Release|x64 - {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Release|x64.Build.0 = Release|x64 - {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Release|x86.ActiveCfg = Release|Win32 - {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Release|x86.Build.0 = Release|Win32 - {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Debug|ARM64.Build.0 = Debug|ARM64 - {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Debug|x64.ActiveCfg = Debug|x64 - {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Debug|x64.Build.0 = Debug|x64 - {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Debug|x86.ActiveCfg = Debug|Win32 - {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Debug|x86.Build.0 = Debug|Win32 - {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Release|ARM64.ActiveCfg = Release|ARM64 - {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Release|ARM64.Build.0 = Release|ARM64 - {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Release|x64.ActiveCfg = Release|x64 - {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Release|x64.Build.0 = Release|x64 - {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Release|x86.ActiveCfg = Release|Win32 - {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Release|x86.Build.0 = Release|Win32 - {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Debug|ARM64.Build.0 = Debug|ARM64 - {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Debug|x64.ActiveCfg = Debug|x64 - {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Debug|x64.Build.0 = Debug|x64 - {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Debug|x86.ActiveCfg = Debug|Win32 - {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Debug|x86.Build.0 = Debug|Win32 - {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Release|ARM64.ActiveCfg = Release|ARM64 - {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Release|ARM64.Build.0 = Release|ARM64 - {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Release|x64.ActiveCfg = Release|x64 - {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Release|x64.Build.0 = Release|x64 - {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Release|x86.ActiveCfg = Release|Win32 - {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Release|x86.Build.0 = Release|Win32 - {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Debug|ARM64.Build.0 = Debug|ARM64 - {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Debug|x64.ActiveCfg = Debug|x64 - {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Debug|x64.Build.0 = Debug|x64 - {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Debug|x86.ActiveCfg = Debug|Win32 - {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Debug|x86.Build.0 = Debug|Win32 - {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Release|ARM64.ActiveCfg = Release|ARM64 - {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Release|ARM64.Build.0 = Release|ARM64 - {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Release|x64.ActiveCfg = Release|x64 - {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Release|x64.Build.0 = Release|x64 - {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Release|x86.ActiveCfg = Release|Win32 - {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Release|x86.Build.0 = Release|Win32 - {66CC5B13-881A-412F-8C51-746622A91C5A}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {66CC5B13-881A-412F-8C51-746622A91C5A}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {66CC5B13-881A-412F-8C51-746622A91C5A}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {66CC5B13-881A-412F-8C51-746622A91C5A}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {66CC5B13-881A-412F-8C51-746622A91C5A}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {66CC5B13-881A-412F-8C51-746622A91C5A}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {66CC5B13-881A-412F-8C51-746622A91C5A}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {66CC5B13-881A-412F-8C51-746622A91C5A}.Debug|ARM64.Build.0 = Debug|ARM64 - {66CC5B13-881A-412F-8C51-746622A91C5A}.Debug|x64.ActiveCfg = Debug|x64 - {66CC5B13-881A-412F-8C51-746622A91C5A}.Debug|x64.Build.0 = Debug|x64 - {66CC5B13-881A-412F-8C51-746622A91C5A}.Debug|x86.ActiveCfg = Debug|Win32 - {66CC5B13-881A-412F-8C51-746622A91C5A}.Debug|x86.Build.0 = Debug|Win32 - {66CC5B13-881A-412F-8C51-746622A91C5A}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {66CC5B13-881A-412F-8C51-746622A91C5A}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {66CC5B13-881A-412F-8C51-746622A91C5A}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {66CC5B13-881A-412F-8C51-746622A91C5A}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {66CC5B13-881A-412F-8C51-746622A91C5A}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {66CC5B13-881A-412F-8C51-746622A91C5A}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {66CC5B13-881A-412F-8C51-746622A91C5A}.Release|ARM64.ActiveCfg = Release|ARM64 - {66CC5B13-881A-412F-8C51-746622A91C5A}.Release|ARM64.Build.0 = Release|ARM64 - {66CC5B13-881A-412F-8C51-746622A91C5A}.Release|x64.ActiveCfg = Release|x64 - {66CC5B13-881A-412F-8C51-746622A91C5A}.Release|x64.Build.0 = Release|x64 - {66CC5B13-881A-412F-8C51-746622A91C5A}.Release|x86.ActiveCfg = Release|Win32 - {66CC5B13-881A-412F-8C51-746622A91C5A}.Release|x86.Build.0 = Release|Win32 - {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Debug|ARM64.Build.0 = Debug|ARM64 - {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Debug|x64.ActiveCfg = Debug|x64 - {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Debug|x64.Build.0 = Debug|x64 - {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Debug|x86.ActiveCfg = Debug|Win32 - {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Debug|x86.Build.0 = Debug|Win32 - {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Release|ARM64.ActiveCfg = Release|ARM64 - {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Release|ARM64.Build.0 = Release|ARM64 - {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Release|x64.ActiveCfg = Release|x64 - {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Release|x64.Build.0 = Release|x64 - {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Release|x86.ActiveCfg = Release|Win32 - {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Release|x86.Build.0 = Release|Win32 - {557138B0-7BE2-4392-B2E2-B45734031A62}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {557138B0-7BE2-4392-B2E2-B45734031A62}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {557138B0-7BE2-4392-B2E2-B45734031A62}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {557138B0-7BE2-4392-B2E2-B45734031A62}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {557138B0-7BE2-4392-B2E2-B45734031A62}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {557138B0-7BE2-4392-B2E2-B45734031A62}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {557138B0-7BE2-4392-B2E2-B45734031A62}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {557138B0-7BE2-4392-B2E2-B45734031A62}.Debug|ARM64.Build.0 = Debug|ARM64 - {557138B0-7BE2-4392-B2E2-B45734031A62}.Debug|x64.ActiveCfg = Debug|x64 - {557138B0-7BE2-4392-B2E2-B45734031A62}.Debug|x64.Build.0 = Debug|x64 - {557138B0-7BE2-4392-B2E2-B45734031A62}.Debug|x86.ActiveCfg = Debug|Win32 - {557138B0-7BE2-4392-B2E2-B45734031A62}.Debug|x86.Build.0 = Debug|Win32 - {557138B0-7BE2-4392-B2E2-B45734031A62}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {557138B0-7BE2-4392-B2E2-B45734031A62}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {557138B0-7BE2-4392-B2E2-B45734031A62}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {557138B0-7BE2-4392-B2E2-B45734031A62}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {557138B0-7BE2-4392-B2E2-B45734031A62}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {557138B0-7BE2-4392-B2E2-B45734031A62}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {557138B0-7BE2-4392-B2E2-B45734031A62}.Release|ARM64.ActiveCfg = Release|ARM64 - {557138B0-7BE2-4392-B2E2-B45734031A62}.Release|ARM64.Build.0 = Release|ARM64 - {557138B0-7BE2-4392-B2E2-B45734031A62}.Release|x64.ActiveCfg = Release|x64 - {557138B0-7BE2-4392-B2E2-B45734031A62}.Release|x64.Build.0 = Release|x64 - {557138B0-7BE2-4392-B2E2-B45734031A62}.Release|x86.ActiveCfg = Release|Win32 - {557138B0-7BE2-4392-B2E2-B45734031A62}.Release|x86.Build.0 = Release|Win32 - {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Debug|ARM64.Build.0 = Debug|ARM64 - {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Debug|x64.ActiveCfg = Debug|x64 - {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Debug|x64.Build.0 = Debug|x64 - {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Debug|x86.ActiveCfg = Debug|Win32 - {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Debug|x86.Build.0 = Debug|Win32 - {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Release|ARM64.ActiveCfg = Release|ARM64 - {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Release|ARM64.Build.0 = Release|ARM64 - {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Release|x64.ActiveCfg = Release|x64 - {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Release|x64.Build.0 = Release|x64 - {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Release|x86.ActiveCfg = Release|Win32 - {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Release|x86.Build.0 = Release|Win32 - {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Debug|ARM64.Build.0 = Debug|ARM64 - {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Debug|x64.ActiveCfg = Debug|x64 - {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Debug|x64.Build.0 = Debug|x64 - {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Debug|x86.ActiveCfg = Debug|Win32 - {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Debug|x86.Build.0 = Debug|Win32 - {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Release|ARM64.ActiveCfg = Release|ARM64 - {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Release|ARM64.Build.0 = Release|ARM64 - {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Release|x64.ActiveCfg = Release|x64 - {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Release|x64.Build.0 = Release|x64 - {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Release|x86.ActiveCfg = Release|Win32 - {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Release|x86.Build.0 = Release|Win32 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug|ARM64.Build.0 = Debug|ARM64 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug|x64.ActiveCfg = Debug|x64 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug|x64.Build.0 = Debug|x64 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug|x86.ActiveCfg = Debug|Win32 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug|x86.Build.0 = Debug|Win32 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release|ARM64.ActiveCfg = Release|ARM64 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release|ARM64.Build.0 = Release|ARM64 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release|x64.ActiveCfg = Release|x64 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release|x64.Build.0 = Release|x64 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release|x86.ActiveCfg = Release|Win32 - {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release|x86.Build.0 = Release|Win32 - {FD193822-3D5C-4161-A147-884C2ABDE483}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {FD193822-3D5C-4161-A147-884C2ABDE483}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {FD193822-3D5C-4161-A147-884C2ABDE483}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {FD193822-3D5C-4161-A147-884C2ABDE483}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {FD193822-3D5C-4161-A147-884C2ABDE483}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {FD193822-3D5C-4161-A147-884C2ABDE483}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {FD193822-3D5C-4161-A147-884C2ABDE483}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {FD193822-3D5C-4161-A147-884C2ABDE483}.Debug|ARM64.Build.0 = Debug|ARM64 - {FD193822-3D5C-4161-A147-884C2ABDE483}.Debug|x64.ActiveCfg = Debug|x64 - {FD193822-3D5C-4161-A147-884C2ABDE483}.Debug|x64.Build.0 = Debug|x64 - {FD193822-3D5C-4161-A147-884C2ABDE483}.Debug|x86.ActiveCfg = Debug|Win32 - {FD193822-3D5C-4161-A147-884C2ABDE483}.Debug|x86.Build.0 = Debug|Win32 - {FD193822-3D5C-4161-A147-884C2ABDE483}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {FD193822-3D5C-4161-A147-884C2ABDE483}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {FD193822-3D5C-4161-A147-884C2ABDE483}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {FD193822-3D5C-4161-A147-884C2ABDE483}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {FD193822-3D5C-4161-A147-884C2ABDE483}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {FD193822-3D5C-4161-A147-884C2ABDE483}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {FD193822-3D5C-4161-A147-884C2ABDE483}.Release|ARM64.ActiveCfg = Release|ARM64 - {FD193822-3D5C-4161-A147-884C2ABDE483}.Release|ARM64.Build.0 = Release|ARM64 - {FD193822-3D5C-4161-A147-884C2ABDE483}.Release|x64.ActiveCfg = Release|x64 - {FD193822-3D5C-4161-A147-884C2ABDE483}.Release|x64.Build.0 = Release|x64 - {FD193822-3D5C-4161-A147-884C2ABDE483}.Release|x86.ActiveCfg = Release|Win32 - {FD193822-3D5C-4161-A147-884C2ABDE483}.Release|x86.Build.0 = Release|Win32 - {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Debug|ARM64.Build.0 = Debug|ARM64 - {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Debug|x64.ActiveCfg = Debug|x64 - {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Debug|x64.Build.0 = Debug|x64 - {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Debug|x86.ActiveCfg = Debug|Win32 - {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Debug|x86.Build.0 = Debug|Win32 - {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Release|ARM64.ActiveCfg = Release|ARM64 - {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Release|ARM64.Build.0 = Release|ARM64 - {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Release|x64.ActiveCfg = Release|x64 - {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Release|x64.Build.0 = Release|x64 - {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Release|x86.ActiveCfg = Release|Win32 - {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Release|x86.Build.0 = Release|Win32 - {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Debug|ARM64.Build.0 = Debug|ARM64 - {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Debug|x64.ActiveCfg = Debug|x64 - {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Debug|x64.Build.0 = Debug|x64 - {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Debug|x86.ActiveCfg = Debug|Win32 - {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Debug|x86.Build.0 = Debug|Win32 - {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Release|ARM64.ActiveCfg = Release|ARM64 - {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Release|ARM64.Build.0 = Release|ARM64 - {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Release|x64.ActiveCfg = Release|x64 - {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Release|x64.Build.0 = Release|x64 - {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Release|x86.ActiveCfg = Release|Win32 - {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Release|x86.Build.0 = Release|Win32 - {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Debug|ARM64.Build.0 = Debug|ARM64 - {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Debug|x64.ActiveCfg = Debug|x64 - {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Debug|x64.Build.0 = Debug|x64 - {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Debug|x86.ActiveCfg = Debug|Win32 - {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Debug|x86.Build.0 = Debug|Win32 - {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Release|ARM64.ActiveCfg = Release|ARM64 - {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Release|ARM64.Build.0 = Release|ARM64 - {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Release|x64.ActiveCfg = Release|x64 - {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Release|x64.Build.0 = Release|x64 - {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Release|x86.ActiveCfg = Release|Win32 - {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Release|x86.Build.0 = Release|Win32 - {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Debug|ARM64.Build.0 = Debug|ARM64 - {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Debug|x64.ActiveCfg = Debug|x64 - {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Debug|x64.Build.0 = Debug|x64 - {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Debug|x86.ActiveCfg = Debug|Win32 - {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Debug|x86.Build.0 = Debug|Win32 - {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Release|ARM64.ActiveCfg = Release|ARM64 - {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Release|ARM64.Build.0 = Release|ARM64 - {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Release|x64.ActiveCfg = Release|x64 - {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Release|x64.Build.0 = Release|x64 - {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Release|x86.ActiveCfg = Release|Win32 - {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Release|x86.Build.0 = Release|Win32 - {51A00565-5787-4911-9CC0-28403AA4909D}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {51A00565-5787-4911-9CC0-28403AA4909D}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {51A00565-5787-4911-9CC0-28403AA4909D}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {51A00565-5787-4911-9CC0-28403AA4909D}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {51A00565-5787-4911-9CC0-28403AA4909D}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {51A00565-5787-4911-9CC0-28403AA4909D}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {51A00565-5787-4911-9CC0-28403AA4909D}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {51A00565-5787-4911-9CC0-28403AA4909D}.Debug|ARM64.Build.0 = Debug|ARM64 - {51A00565-5787-4911-9CC0-28403AA4909D}.Debug|x64.ActiveCfg = Debug|x64 - {51A00565-5787-4911-9CC0-28403AA4909D}.Debug|x64.Build.0 = Debug|x64 - {51A00565-5787-4911-9CC0-28403AA4909D}.Debug|x86.ActiveCfg = Debug|Win32 - {51A00565-5787-4911-9CC0-28403AA4909D}.Debug|x86.Build.0 = Debug|Win32 - {51A00565-5787-4911-9CC0-28403AA4909D}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {51A00565-5787-4911-9CC0-28403AA4909D}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {51A00565-5787-4911-9CC0-28403AA4909D}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {51A00565-5787-4911-9CC0-28403AA4909D}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {51A00565-5787-4911-9CC0-28403AA4909D}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {51A00565-5787-4911-9CC0-28403AA4909D}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {51A00565-5787-4911-9CC0-28403AA4909D}.Release|ARM64.ActiveCfg = Release|ARM64 - {51A00565-5787-4911-9CC0-28403AA4909D}.Release|ARM64.Build.0 = Release|ARM64 - {51A00565-5787-4911-9CC0-28403AA4909D}.Release|x64.ActiveCfg = Release|x64 - {51A00565-5787-4911-9CC0-28403AA4909D}.Release|x64.Build.0 = Release|x64 - {51A00565-5787-4911-9CC0-28403AA4909D}.Release|x86.ActiveCfg = Release|Win32 - {51A00565-5787-4911-9CC0-28403AA4909D}.Release|x86.Build.0 = Release|Win32 - {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Debug|ARM64.Build.0 = Debug|ARM64 - {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Debug|x64.ActiveCfg = Debug|x64 - {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Debug|x64.Build.0 = Debug|x64 - {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Debug|x86.ActiveCfg = Debug|Win32 - {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Debug|x86.Build.0 = Debug|Win32 - {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Release|ARM64.ActiveCfg = Release|ARM64 - {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Release|ARM64.Build.0 = Release|ARM64 - {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Release|x64.ActiveCfg = Release|x64 - {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Release|x64.Build.0 = Release|x64 - {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Release|x86.ActiveCfg = Release|Win32 - {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Release|x86.Build.0 = Release|Win32 - {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Debug|ARM64.Build.0 = Debug|ARM64 - {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Debug|x64.ActiveCfg = Debug|x64 - {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Debug|x64.Build.0 = Debug|x64 - {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Debug|x86.ActiveCfg = Debug|Win32 - {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Debug|x86.Build.0 = Debug|Win32 - {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Release|ARM64.ActiveCfg = Release|ARM64 - {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Release|ARM64.Build.0 = Release|ARM64 - {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Release|x64.ActiveCfg = Release|x64 - {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Release|x64.Build.0 = Release|x64 - {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Release|x86.ActiveCfg = Release|Win32 - {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Release|x86.Build.0 = Release|Win32 - {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Debug|ARM64.Build.0 = Debug|ARM64 - {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Debug|x64.ActiveCfg = Debug|x64 - {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Debug|x64.Build.0 = Debug|x64 - {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Debug|x86.ActiveCfg = Debug|Win32 - {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Debug|x86.Build.0 = Debug|Win32 - {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Release|ARM64.ActiveCfg = Release|ARM64 - {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Release|ARM64.Build.0 = Release|ARM64 - {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Release|x64.ActiveCfg = Release|x64 - {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Release|x64.Build.0 = Release|x64 - {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Release|x86.ActiveCfg = Release|Win32 - {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Release|x86.Build.0 = Release|Win32 - {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug|ARM64.Build.0 = Debug|ARM64 - {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug|x64.ActiveCfg = Debug|x64 - {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug|x64.Build.0 = Debug|x64 - {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug|x86.ActiveCfg = Debug|Win32 - {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug|x86.Build.0 = Debug|Win32 - {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Release|ARM64.ActiveCfg = Release|ARM64 - {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Release|ARM64.Build.0 = Release|ARM64 - {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Release|x64.ActiveCfg = Release|x64 - {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Release|x64.Build.0 = Release|x64 - {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Release|x86.ActiveCfg = Release|Win32 - {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Release|x86.Build.0 = Release|Win32 - {B332DCA8-3599-4A99-917A-82261BDC27AC}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {B332DCA8-3599-4A99-917A-82261BDC27AC}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {B332DCA8-3599-4A99-917A-82261BDC27AC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {B332DCA8-3599-4A99-917A-82261BDC27AC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {B332DCA8-3599-4A99-917A-82261BDC27AC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {B332DCA8-3599-4A99-917A-82261BDC27AC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {B332DCA8-3599-4A99-917A-82261BDC27AC}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {B332DCA8-3599-4A99-917A-82261BDC27AC}.Debug|ARM64.Build.0 = Debug|ARM64 - {B332DCA8-3599-4A99-917A-82261BDC27AC}.Debug|x64.ActiveCfg = Debug|x64 - {B332DCA8-3599-4A99-917A-82261BDC27AC}.Debug|x64.Build.0 = Debug|x64 - {B332DCA8-3599-4A99-917A-82261BDC27AC}.Debug|x86.ActiveCfg = Debug|Win32 - {B332DCA8-3599-4A99-917A-82261BDC27AC}.Debug|x86.Build.0 = Debug|Win32 - {B332DCA8-3599-4A99-917A-82261BDC27AC}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {B332DCA8-3599-4A99-917A-82261BDC27AC}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {B332DCA8-3599-4A99-917A-82261BDC27AC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {B332DCA8-3599-4A99-917A-82261BDC27AC}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {B332DCA8-3599-4A99-917A-82261BDC27AC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {B332DCA8-3599-4A99-917A-82261BDC27AC}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {B332DCA8-3599-4A99-917A-82261BDC27AC}.Release|ARM64.ActiveCfg = Release|ARM64 - {B332DCA8-3599-4A99-917A-82261BDC27AC}.Release|ARM64.Build.0 = Release|ARM64 - {B332DCA8-3599-4A99-917A-82261BDC27AC}.Release|x64.ActiveCfg = Release|x64 - {B332DCA8-3599-4A99-917A-82261BDC27AC}.Release|x64.Build.0 = Release|x64 - {B332DCA8-3599-4A99-917A-82261BDC27AC}.Release|x86.ActiveCfg = Release|Win32 - {B332DCA8-3599-4A99-917A-82261BDC27AC}.Release|x86.Build.0 = Release|Win32 - {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Debug|ARM64.Build.0 = Debug|ARM64 - {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Debug|x64.ActiveCfg = Debug|x64 - {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Debug|x64.Build.0 = Debug|x64 - {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Debug|x86.ActiveCfg = Debug|Win32 - {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Debug|x86.Build.0 = Debug|Win32 - {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Release|ARM64.ActiveCfg = Release|ARM64 - {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Release|ARM64.Build.0 = Release|ARM64 - {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Release|x64.ActiveCfg = Release|x64 - {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Release|x64.Build.0 = Release|x64 - {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Release|x86.ActiveCfg = Release|Win32 - {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Release|x86.Build.0 = Release|Win32 - {C298876B-6C12-4EA4-903B-33450BCD9884}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {C298876B-6C12-4EA4-903B-33450BCD9884}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {C298876B-6C12-4EA4-903B-33450BCD9884}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {C298876B-6C12-4EA4-903B-33450BCD9884}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {C298876B-6C12-4EA4-903B-33450BCD9884}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {C298876B-6C12-4EA4-903B-33450BCD9884}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {C298876B-6C12-4EA4-903B-33450BCD9884}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {C298876B-6C12-4EA4-903B-33450BCD9884}.Debug|ARM64.Build.0 = Debug|ARM64 - {C298876B-6C12-4EA4-903B-33450BCD9884}.Debug|x64.ActiveCfg = Debug|x64 - {C298876B-6C12-4EA4-903B-33450BCD9884}.Debug|x64.Build.0 = Debug|x64 - {C298876B-6C12-4EA4-903B-33450BCD9884}.Debug|x86.ActiveCfg = Debug|Win32 - {C298876B-6C12-4EA4-903B-33450BCD9884}.Debug|x86.Build.0 = Debug|Win32 - {C298876B-6C12-4EA4-903B-33450BCD9884}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {C298876B-6C12-4EA4-903B-33450BCD9884}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {C298876B-6C12-4EA4-903B-33450BCD9884}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {C298876B-6C12-4EA4-903B-33450BCD9884}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {C298876B-6C12-4EA4-903B-33450BCD9884}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {C298876B-6C12-4EA4-903B-33450BCD9884}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {C298876B-6C12-4EA4-903B-33450BCD9884}.Release|ARM64.ActiveCfg = Release|ARM64 - {C298876B-6C12-4EA4-903B-33450BCD9884}.Release|ARM64.Build.0 = Release|ARM64 - {C298876B-6C12-4EA4-903B-33450BCD9884}.Release|x64.ActiveCfg = Release|x64 - {C298876B-6C12-4EA4-903B-33450BCD9884}.Release|x64.Build.0 = Release|x64 - {C298876B-6C12-4EA4-903B-33450BCD9884}.Release|x86.ActiveCfg = Release|Win32 - {C298876B-6C12-4EA4-903B-33450BCD9884}.Release|x86.Build.0 = Release|Win32 - {83F586FA-C801-4979-ACCA-006BD628CC88}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {83F586FA-C801-4979-ACCA-006BD628CC88}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {83F586FA-C801-4979-ACCA-006BD628CC88}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {83F586FA-C801-4979-ACCA-006BD628CC88}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {83F586FA-C801-4979-ACCA-006BD628CC88}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {83F586FA-C801-4979-ACCA-006BD628CC88}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {83F586FA-C801-4979-ACCA-006BD628CC88}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {83F586FA-C801-4979-ACCA-006BD628CC88}.Debug|ARM64.Build.0 = Debug|ARM64 - {83F586FA-C801-4979-ACCA-006BD628CC88}.Debug|x64.ActiveCfg = Debug|x64 - {83F586FA-C801-4979-ACCA-006BD628CC88}.Debug|x64.Build.0 = Debug|x64 - {83F586FA-C801-4979-ACCA-006BD628CC88}.Debug|x86.ActiveCfg = Debug|Win32 - {83F586FA-C801-4979-ACCA-006BD628CC88}.Debug|x86.Build.0 = Debug|Win32 - {83F586FA-C801-4979-ACCA-006BD628CC88}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {83F586FA-C801-4979-ACCA-006BD628CC88}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {83F586FA-C801-4979-ACCA-006BD628CC88}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {83F586FA-C801-4979-ACCA-006BD628CC88}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {83F586FA-C801-4979-ACCA-006BD628CC88}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {83F586FA-C801-4979-ACCA-006BD628CC88}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {83F586FA-C801-4979-ACCA-006BD628CC88}.Release|ARM64.ActiveCfg = Release|ARM64 - {83F586FA-C801-4979-ACCA-006BD628CC88}.Release|ARM64.Build.0 = Release|ARM64 - {83F586FA-C801-4979-ACCA-006BD628CC88}.Release|x64.ActiveCfg = Release|x64 - {83F586FA-C801-4979-ACCA-006BD628CC88}.Release|x64.Build.0 = Release|x64 - {83F586FA-C801-4979-ACCA-006BD628CC88}.Release|x86.ActiveCfg = Release|Win32 - {83F586FA-C801-4979-ACCA-006BD628CC88}.Release|x86.Build.0 = Release|Win32 - {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Debug|ARM64.Build.0 = Debug|ARM64 - {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Debug|x64.ActiveCfg = Debug|x64 - {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Debug|x64.Build.0 = Debug|x64 - {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Debug|x86.ActiveCfg = Debug|Win32 - {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Debug|x86.Build.0 = Debug|Win32 - {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Release|ARM64.ActiveCfg = Release|ARM64 - {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Release|ARM64.Build.0 = Release|ARM64 - {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Release|x64.ActiveCfg = Release|x64 - {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Release|x64.Build.0 = Release|x64 - {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Release|x86.ActiveCfg = Release|Win32 - {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Release|x86.Build.0 = Release|Win32 - {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Debug|ARM64.Build.0 = Debug|ARM64 - {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Debug|x64.ActiveCfg = Debug|x64 - {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Debug|x64.Build.0 = Debug|x64 - {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Debug|x86.ActiveCfg = Debug|Win32 - {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Debug|x86.Build.0 = Debug|Win32 - {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Release|ARM64.ActiveCfg = Release|ARM64 - {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Release|ARM64.Build.0 = Release|ARM64 - {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Release|x64.ActiveCfg = Release|x64 - {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Release|x64.Build.0 = Release|x64 - {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Release|x86.ActiveCfg = Release|Win32 - {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Release|x86.Build.0 = Release|Win32 - {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Debug|ARM64.Build.0 = Debug|ARM64 - {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Debug|x64.ActiveCfg = Debug|x64 - {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Debug|x64.Build.0 = Debug|x64 - {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Debug|x86.ActiveCfg = Debug|Win32 - {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Debug|x86.Build.0 = Debug|Win32 - {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Release|ARM64.ActiveCfg = Release|ARM64 - {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Release|ARM64.Build.0 = Release|ARM64 - {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Release|x64.ActiveCfg = Release|x64 - {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Release|x64.Build.0 = Release|x64 - {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Release|x86.ActiveCfg = Release|Win32 - {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Release|x86.Build.0 = Release|Win32 - {AFDDE100-2D36-4749-817D-12E54C56312F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {AFDDE100-2D36-4749-817D-12E54C56312F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {AFDDE100-2D36-4749-817D-12E54C56312F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {AFDDE100-2D36-4749-817D-12E54C56312F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {AFDDE100-2D36-4749-817D-12E54C56312F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {AFDDE100-2D36-4749-817D-12E54C56312F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {AFDDE100-2D36-4749-817D-12E54C56312F}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {AFDDE100-2D36-4749-817D-12E54C56312F}.Debug|ARM64.Build.0 = Debug|ARM64 - {AFDDE100-2D36-4749-817D-12E54C56312F}.Debug|x64.ActiveCfg = Debug|x64 - {AFDDE100-2D36-4749-817D-12E54C56312F}.Debug|x64.Build.0 = Debug|x64 - {AFDDE100-2D36-4749-817D-12E54C56312F}.Debug|x86.ActiveCfg = Debug|Win32 - {AFDDE100-2D36-4749-817D-12E54C56312F}.Debug|x86.Build.0 = Debug|Win32 - {AFDDE100-2D36-4749-817D-12E54C56312F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {AFDDE100-2D36-4749-817D-12E54C56312F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {AFDDE100-2D36-4749-817D-12E54C56312F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {AFDDE100-2D36-4749-817D-12E54C56312F}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {AFDDE100-2D36-4749-817D-12E54C56312F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {AFDDE100-2D36-4749-817D-12E54C56312F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {AFDDE100-2D36-4749-817D-12E54C56312F}.Release|ARM64.ActiveCfg = Release|ARM64 - {AFDDE100-2D36-4749-817D-12E54C56312F}.Release|ARM64.Build.0 = Release|ARM64 - {AFDDE100-2D36-4749-817D-12E54C56312F}.Release|x64.ActiveCfg = Release|x64 - {AFDDE100-2D36-4749-817D-12E54C56312F}.Release|x64.Build.0 = Release|x64 - {AFDDE100-2D36-4749-817D-12E54C56312F}.Release|x86.ActiveCfg = Release|Win32 - {AFDDE100-2D36-4749-817D-12E54C56312F}.Release|x86.Build.0 = Release|Win32 - {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Debug|ARM64.Build.0 = Debug|ARM64 - {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Debug|x64.ActiveCfg = Debug|x64 - {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Debug|x64.Build.0 = Debug|x64 - {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Debug|x86.ActiveCfg = Debug|Win32 - {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Debug|x86.Build.0 = Debug|Win32 - {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Release|ARM64.ActiveCfg = Release|ARM64 - {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Release|ARM64.Build.0 = Release|ARM64 - {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Release|x64.ActiveCfg = Release|x64 - {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Release|x64.Build.0 = Release|x64 - {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Release|x86.ActiveCfg = Release|Win32 - {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Release|x86.Build.0 = Release|Win32 - {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Debug|ARM64.Build.0 = Debug|ARM64 - {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Debug|x64.ActiveCfg = Debug|x64 - {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Debug|x64.Build.0 = Debug|x64 - {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Debug|x86.ActiveCfg = Debug|Win32 - {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Debug|x86.Build.0 = Debug|Win32 - {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Release|ARM64.ActiveCfg = Release|ARM64 - {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Release|ARM64.Build.0 = Release|ARM64 - {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Release|x64.ActiveCfg = Release|x64 - {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Release|x64.Build.0 = Release|x64 - {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Release|x86.ActiveCfg = Release|Win32 - {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Release|x86.Build.0 = Release|Win32 - {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Debug|ARM64.Build.0 = Debug|ARM64 - {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Debug|x64.ActiveCfg = Debug|x64 - {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Debug|x64.Build.0 = Debug|x64 - {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Debug|x86.ActiveCfg = Debug|Win32 - {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Debug|x86.Build.0 = Debug|Win32 - {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Release|ARM64.ActiveCfg = Release|ARM64 - {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Release|ARM64.Build.0 = Release|ARM64 - {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Release|x64.ActiveCfg = Release|x64 - {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Release|x64.Build.0 = Release|x64 - {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Release|x86.ActiveCfg = Release|Win32 - {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Release|x86.Build.0 = Release|Win32 - {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Debug|ARM64.Build.0 = Debug|ARM64 - {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Debug|x64.ActiveCfg = Debug|x64 - {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Debug|x64.Build.0 = Debug|x64 - {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Debug|x86.ActiveCfg = Debug|Win32 - {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Debug|x86.Build.0 = Debug|Win32 - {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Release|ARM64.ActiveCfg = Release|ARM64 - {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Release|ARM64.Build.0 = Release|ARM64 - {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Release|x64.ActiveCfg = Release|x64 - {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Release|x64.Build.0 = Release|x64 - {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Release|x86.ActiveCfg = Release|Win32 - {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Release|x86.Build.0 = Release|Win32 - {14BA7F98-02CC-4648-9236-676BFF9458AF}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {14BA7F98-02CC-4648-9236-676BFF9458AF}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {14BA7F98-02CC-4648-9236-676BFF9458AF}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {14BA7F98-02CC-4648-9236-676BFF9458AF}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {14BA7F98-02CC-4648-9236-676BFF9458AF}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {14BA7F98-02CC-4648-9236-676BFF9458AF}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {14BA7F98-02CC-4648-9236-676BFF9458AF}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {14BA7F98-02CC-4648-9236-676BFF9458AF}.Debug|ARM64.Build.0 = Debug|ARM64 - {14BA7F98-02CC-4648-9236-676BFF9458AF}.Debug|x64.ActiveCfg = Debug|x64 - {14BA7F98-02CC-4648-9236-676BFF9458AF}.Debug|x64.Build.0 = Debug|x64 - {14BA7F98-02CC-4648-9236-676BFF9458AF}.Debug|x86.ActiveCfg = Debug|Win32 - {14BA7F98-02CC-4648-9236-676BFF9458AF}.Debug|x86.Build.0 = Debug|Win32 - {14BA7F98-02CC-4648-9236-676BFF9458AF}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {14BA7F98-02CC-4648-9236-676BFF9458AF}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {14BA7F98-02CC-4648-9236-676BFF9458AF}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {14BA7F98-02CC-4648-9236-676BFF9458AF}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {14BA7F98-02CC-4648-9236-676BFF9458AF}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {14BA7F98-02CC-4648-9236-676BFF9458AF}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {14BA7F98-02CC-4648-9236-676BFF9458AF}.Release|ARM64.ActiveCfg = Release|ARM64 - {14BA7F98-02CC-4648-9236-676BFF9458AF}.Release|ARM64.Build.0 = Release|ARM64 - {14BA7F98-02CC-4648-9236-676BFF9458AF}.Release|x64.ActiveCfg = Release|x64 - {14BA7F98-02CC-4648-9236-676BFF9458AF}.Release|x64.Build.0 = Release|x64 - {14BA7F98-02CC-4648-9236-676BFF9458AF}.Release|x86.ActiveCfg = Release|Win32 - {14BA7F98-02CC-4648-9236-676BFF9458AF}.Release|x86.Build.0 = Release|Win32 - {0859A973-E4FE-4688-8D16-0253163FDE24}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {0859A973-E4FE-4688-8D16-0253163FDE24}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {0859A973-E4FE-4688-8D16-0253163FDE24}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {0859A973-E4FE-4688-8D16-0253163FDE24}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {0859A973-E4FE-4688-8D16-0253163FDE24}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {0859A973-E4FE-4688-8D16-0253163FDE24}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {0859A973-E4FE-4688-8D16-0253163FDE24}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {0859A973-E4FE-4688-8D16-0253163FDE24}.Debug|ARM64.Build.0 = Debug|ARM64 - {0859A973-E4FE-4688-8D16-0253163FDE24}.Debug|x64.ActiveCfg = Debug|x64 - {0859A973-E4FE-4688-8D16-0253163FDE24}.Debug|x64.Build.0 = Debug|x64 - {0859A973-E4FE-4688-8D16-0253163FDE24}.Debug|x86.ActiveCfg = Debug|Win32 - {0859A973-E4FE-4688-8D16-0253163FDE24}.Debug|x86.Build.0 = Debug|Win32 - {0859A973-E4FE-4688-8D16-0253163FDE24}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {0859A973-E4FE-4688-8D16-0253163FDE24}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {0859A973-E4FE-4688-8D16-0253163FDE24}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {0859A973-E4FE-4688-8D16-0253163FDE24}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {0859A973-E4FE-4688-8D16-0253163FDE24}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {0859A973-E4FE-4688-8D16-0253163FDE24}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {0859A973-E4FE-4688-8D16-0253163FDE24}.Release|ARM64.ActiveCfg = Release|ARM64 - {0859A973-E4FE-4688-8D16-0253163FDE24}.Release|ARM64.Build.0 = Release|ARM64 - {0859A973-E4FE-4688-8D16-0253163FDE24}.Release|x64.ActiveCfg = Release|x64 - {0859A973-E4FE-4688-8D16-0253163FDE24}.Release|x64.Build.0 = Release|x64 - {0859A973-E4FE-4688-8D16-0253163FDE24}.Release|x86.ActiveCfg = Release|Win32 - {0859A973-E4FE-4688-8D16-0253163FDE24}.Release|x86.Build.0 = Release|Win32 - {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Debug|ARM64.Build.0 = Debug|ARM64 - {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Debug|x64.ActiveCfg = Debug|x64 - {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Debug|x64.Build.0 = Debug|x64 - {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Debug|x86.ActiveCfg = Debug|Win32 - {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Debug|x86.Build.0 = Debug|Win32 - {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Release|ARM64.ActiveCfg = Release|ARM64 - {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Release|ARM64.Build.0 = Release|ARM64 - {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Release|x64.ActiveCfg = Release|x64 - {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Release|x64.Build.0 = Release|x64 - {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Release|x86.ActiveCfg = Release|Win32 - {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Release|x86.Build.0 = Release|Win32 - {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Debug|ARM64.Build.0 = Debug|ARM64 - {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Debug|x64.ActiveCfg = Debug|x64 - {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Debug|x64.Build.0 = Debug|x64 - {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Debug|x86.ActiveCfg = Debug|Win32 - {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Debug|x86.Build.0 = Debug|Win32 - {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Release|ARM64.ActiveCfg = Release|ARM64 - {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Release|ARM64.Build.0 = Release|ARM64 - {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Release|x64.ActiveCfg = Release|x64 - {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Release|x64.Build.0 = Release|x64 - {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Release|x86.ActiveCfg = Release|Win32 - {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Release|x86.Build.0 = Release|Win32 - {D03F2C82-9553-4AFA-8F49-9234009122B6}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {D03F2C82-9553-4AFA-8F49-9234009122B6}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {D03F2C82-9553-4AFA-8F49-9234009122B6}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {D03F2C82-9553-4AFA-8F49-9234009122B6}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {D03F2C82-9553-4AFA-8F49-9234009122B6}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {D03F2C82-9553-4AFA-8F49-9234009122B6}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {D03F2C82-9553-4AFA-8F49-9234009122B6}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {D03F2C82-9553-4AFA-8F49-9234009122B6}.Debug|ARM64.Build.0 = Debug|ARM64 - {D03F2C82-9553-4AFA-8F49-9234009122B6}.Debug|x64.ActiveCfg = Debug|x64 - {D03F2C82-9553-4AFA-8F49-9234009122B6}.Debug|x64.Build.0 = Debug|x64 - {D03F2C82-9553-4AFA-8F49-9234009122B6}.Debug|x86.ActiveCfg = Debug|Win32 - {D03F2C82-9553-4AFA-8F49-9234009122B6}.Debug|x86.Build.0 = Debug|Win32 - {D03F2C82-9553-4AFA-8F49-9234009122B6}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {D03F2C82-9553-4AFA-8F49-9234009122B6}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {D03F2C82-9553-4AFA-8F49-9234009122B6}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {D03F2C82-9553-4AFA-8F49-9234009122B6}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {D03F2C82-9553-4AFA-8F49-9234009122B6}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {D03F2C82-9553-4AFA-8F49-9234009122B6}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {D03F2C82-9553-4AFA-8F49-9234009122B6}.Release|ARM64.ActiveCfg = Release|ARM64 - {D03F2C82-9553-4AFA-8F49-9234009122B6}.Release|ARM64.Build.0 = Release|ARM64 - {D03F2C82-9553-4AFA-8F49-9234009122B6}.Release|x64.ActiveCfg = Release|x64 - {D03F2C82-9553-4AFA-8F49-9234009122B6}.Release|x64.Build.0 = Release|x64 - {D03F2C82-9553-4AFA-8F49-9234009122B6}.Release|x86.ActiveCfg = Release|Win32 - {D03F2C82-9553-4AFA-8F49-9234009122B6}.Release|x86.Build.0 = Release|Win32 - {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Debug|ARM64.Build.0 = Debug|ARM64 - {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Debug|x64.ActiveCfg = Debug|x64 - {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Debug|x64.Build.0 = Debug|x64 - {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Debug|x86.ActiveCfg = Debug|Win32 - {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Debug|x86.Build.0 = Debug|Win32 - {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Release|ARM64.ActiveCfg = Release|ARM64 - {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Release|ARM64.Build.0 = Release|ARM64 - {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Release|x64.ActiveCfg = Release|x64 - {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Release|x64.Build.0 = Release|x64 - {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Release|x86.ActiveCfg = Release|Win32 - {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Release|x86.Build.0 = Release|Win32 - {A53CCF42-A972-478F-9336-0F618B3EC06A}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {A53CCF42-A972-478F-9336-0F618B3EC06A}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {A53CCF42-A972-478F-9336-0F618B3EC06A}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {A53CCF42-A972-478F-9336-0F618B3EC06A}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {A53CCF42-A972-478F-9336-0F618B3EC06A}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {A53CCF42-A972-478F-9336-0F618B3EC06A}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {A53CCF42-A972-478F-9336-0F618B3EC06A}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {A53CCF42-A972-478F-9336-0F618B3EC06A}.Debug|ARM64.Build.0 = Debug|ARM64 - {A53CCF42-A972-478F-9336-0F618B3EC06A}.Debug|x64.ActiveCfg = Debug|x64 - {A53CCF42-A972-478F-9336-0F618B3EC06A}.Debug|x64.Build.0 = Debug|x64 - {A53CCF42-A972-478F-9336-0F618B3EC06A}.Debug|x86.ActiveCfg = Debug|Win32 - {A53CCF42-A972-478F-9336-0F618B3EC06A}.Debug|x86.Build.0 = Debug|Win32 - {A53CCF42-A972-478F-9336-0F618B3EC06A}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {A53CCF42-A972-478F-9336-0F618B3EC06A}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {A53CCF42-A972-478F-9336-0F618B3EC06A}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {A53CCF42-A972-478F-9336-0F618B3EC06A}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {A53CCF42-A972-478F-9336-0F618B3EC06A}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {A53CCF42-A972-478F-9336-0F618B3EC06A}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {A53CCF42-A972-478F-9336-0F618B3EC06A}.Release|ARM64.ActiveCfg = Release|ARM64 - {A53CCF42-A972-478F-9336-0F618B3EC06A}.Release|ARM64.Build.0 = Release|ARM64 - {A53CCF42-A972-478F-9336-0F618B3EC06A}.Release|x64.ActiveCfg = Release|x64 - {A53CCF42-A972-478F-9336-0F618B3EC06A}.Release|x64.Build.0 = Release|x64 - {A53CCF42-A972-478F-9336-0F618B3EC06A}.Release|x86.ActiveCfg = Release|Win32 - {A53CCF42-A972-478F-9336-0F618B3EC06A}.Release|x86.Build.0 = Release|Win32 - {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Debug|ARM64.Build.0 = Debug|ARM64 - {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Debug|x64.ActiveCfg = Debug|x64 - {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Debug|x64.Build.0 = Debug|x64 - {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Debug|x86.ActiveCfg = Debug|Win32 - {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Debug|x86.Build.0 = Debug|Win32 - {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Release|ARM64.ActiveCfg = Release|ARM64 - {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Release|ARM64.Build.0 = Release|ARM64 - {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Release|x64.ActiveCfg = Release|x64 - {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Release|x64.Build.0 = Release|x64 - {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Release|x86.ActiveCfg = Release|Win32 - {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Release|x86.Build.0 = Release|Win32 - {870723DD-945A-4136-B65B-4AF3BF85369C}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {870723DD-945A-4136-B65B-4AF3BF85369C}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {870723DD-945A-4136-B65B-4AF3BF85369C}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {870723DD-945A-4136-B65B-4AF3BF85369C}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {870723DD-945A-4136-B65B-4AF3BF85369C}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {870723DD-945A-4136-B65B-4AF3BF85369C}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {870723DD-945A-4136-B65B-4AF3BF85369C}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {870723DD-945A-4136-B65B-4AF3BF85369C}.Debug|ARM64.Build.0 = Debug|ARM64 - {870723DD-945A-4136-B65B-4AF3BF85369C}.Debug|x64.ActiveCfg = Debug|x64 - {870723DD-945A-4136-B65B-4AF3BF85369C}.Debug|x64.Build.0 = Debug|x64 - {870723DD-945A-4136-B65B-4AF3BF85369C}.Debug|x86.ActiveCfg = Debug|Win32 - {870723DD-945A-4136-B65B-4AF3BF85369C}.Debug|x86.Build.0 = Debug|Win32 - {870723DD-945A-4136-B65B-4AF3BF85369C}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {870723DD-945A-4136-B65B-4AF3BF85369C}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {870723DD-945A-4136-B65B-4AF3BF85369C}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {870723DD-945A-4136-B65B-4AF3BF85369C}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {870723DD-945A-4136-B65B-4AF3BF85369C}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {870723DD-945A-4136-B65B-4AF3BF85369C}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {870723DD-945A-4136-B65B-4AF3BF85369C}.Release|ARM64.ActiveCfg = Release|ARM64 - {870723DD-945A-4136-B65B-4AF3BF85369C}.Release|ARM64.Build.0 = Release|ARM64 - {870723DD-945A-4136-B65B-4AF3BF85369C}.Release|x64.ActiveCfg = Release|x64 - {870723DD-945A-4136-B65B-4AF3BF85369C}.Release|x64.Build.0 = Release|x64 - {870723DD-945A-4136-B65B-4AF3BF85369C}.Release|x86.ActiveCfg = Release|Win32 - {870723DD-945A-4136-B65B-4AF3BF85369C}.Release|x86.Build.0 = Release|Win32 - {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Debug|ARM64.Build.0 = Debug|ARM64 - {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Debug|x64.ActiveCfg = Debug|x64 - {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Debug|x64.Build.0 = Debug|x64 - {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Debug|x86.ActiveCfg = Debug|Win32 - {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Debug|x86.Build.0 = Debug|Win32 - {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Release|ARM64.ActiveCfg = Release|ARM64 - {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Release|ARM64.Build.0 = Release|ARM64 - {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Release|x64.ActiveCfg = Release|x64 - {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Release|x64.Build.0 = Release|x64 - {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Release|x86.ActiveCfg = Release|Win32 - {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Release|x86.Build.0 = Release|Win32 - {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Debug|ARM64.Build.0 = Debug|ARM64 - {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Debug|x64.ActiveCfg = Debug|x64 - {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Debug|x64.Build.0 = Debug|x64 - {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Debug|x86.ActiveCfg = Debug|Win32 - {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Debug|x86.Build.0 = Debug|Win32 - {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Release|ARM64.ActiveCfg = Release|ARM64 - {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Release|ARM64.Build.0 = Release|ARM64 - {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Release|x64.ActiveCfg = Release|x64 - {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Release|x64.Build.0 = Release|x64 - {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Release|x86.ActiveCfg = Release|Win32 - {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Release|x86.Build.0 = Release|Win32 - {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Debug|ARM64.Build.0 = Debug|ARM64 - {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Debug|x64.ActiveCfg = Debug|x64 - {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Debug|x64.Build.0 = Debug|x64 - {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Debug|x86.ActiveCfg = Debug|Win32 - {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Debug|x86.Build.0 = Debug|Win32 - {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Release|ARM64.ActiveCfg = Release|ARM64 - {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Release|ARM64.Build.0 = Release|ARM64 - {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Release|x64.ActiveCfg = Release|x64 - {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Release|x64.Build.0 = Release|x64 - {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Release|x86.ActiveCfg = Release|Win32 - {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Release|x86.Build.0 = Release|Win32 - {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Debug|ARM64.Build.0 = Debug|ARM64 - {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Debug|x64.ActiveCfg = Debug|x64 - {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Debug|x64.Build.0 = Debug|x64 - {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Debug|x86.ActiveCfg = Debug|Win32 - {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Debug|x86.Build.0 = Debug|Win32 - {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Release|ARM64.ActiveCfg = Release|ARM64 - {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Release|ARM64.Build.0 = Release|ARM64 - {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Release|x64.ActiveCfg = Release|x64 - {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Release|x64.Build.0 = Release|x64 - {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Release|x86.ActiveCfg = Release|Win32 - {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Release|x86.Build.0 = Release|Win32 - {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Debug|ARM64.Build.0 = Debug|ARM64 - {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Debug|x64.ActiveCfg = Debug|x64 - {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Debug|x64.Build.0 = Debug|x64 - {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Debug|x86.ActiveCfg = Debug|Win32 - {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Debug|x86.Build.0 = Debug|Win32 - {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Release|ARM64.ActiveCfg = Release|ARM64 - {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Release|ARM64.Build.0 = Release|ARM64 - {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Release|x64.ActiveCfg = Release|x64 - {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Release|x64.Build.0 = Release|x64 - {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Release|x86.ActiveCfg = Release|Win32 - {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Release|x86.Build.0 = Release|Win32 - {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Debug|ARM64.Build.0 = Debug|ARM64 - {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Debug|x64.ActiveCfg = Debug|x64 - {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Debug|x64.Build.0 = Debug|x64 - {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Debug|x86.ActiveCfg = Debug|Win32 - {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Debug|x86.Build.0 = Debug|Win32 - {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Release|ARM64.ActiveCfg = Release|ARM64 - {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Release|ARM64.Build.0 = Release|ARM64 - {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Release|x64.ActiveCfg = Release|x64 - {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Release|x64.Build.0 = Release|x64 - {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Release|x86.ActiveCfg = Release|Win32 - {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Release|x86.Build.0 = Release|Win32 - {0AB968E0-E993-45CE-8875-7453C96DF583}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {0AB968E0-E993-45CE-8875-7453C96DF583}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {0AB968E0-E993-45CE-8875-7453C96DF583}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {0AB968E0-E993-45CE-8875-7453C96DF583}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {0AB968E0-E993-45CE-8875-7453C96DF583}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {0AB968E0-E993-45CE-8875-7453C96DF583}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {0AB968E0-E993-45CE-8875-7453C96DF583}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {0AB968E0-E993-45CE-8875-7453C96DF583}.Debug|ARM64.Build.0 = Debug|ARM64 - {0AB968E0-E993-45CE-8875-7453C96DF583}.Debug|x64.ActiveCfg = Debug|x64 - {0AB968E0-E993-45CE-8875-7453C96DF583}.Debug|x64.Build.0 = Debug|x64 - {0AB968E0-E993-45CE-8875-7453C96DF583}.Debug|x86.ActiveCfg = Debug|Win32 - {0AB968E0-E993-45CE-8875-7453C96DF583}.Debug|x86.Build.0 = Debug|Win32 - {0AB968E0-E993-45CE-8875-7453C96DF583}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {0AB968E0-E993-45CE-8875-7453C96DF583}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {0AB968E0-E993-45CE-8875-7453C96DF583}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {0AB968E0-E993-45CE-8875-7453C96DF583}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {0AB968E0-E993-45CE-8875-7453C96DF583}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {0AB968E0-E993-45CE-8875-7453C96DF583}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {0AB968E0-E993-45CE-8875-7453C96DF583}.Release|ARM64.ActiveCfg = Release|ARM64 - {0AB968E0-E993-45CE-8875-7453C96DF583}.Release|ARM64.Build.0 = Release|ARM64 - {0AB968E0-E993-45CE-8875-7453C96DF583}.Release|x64.ActiveCfg = Release|x64 - {0AB968E0-E993-45CE-8875-7453C96DF583}.Release|x64.Build.0 = Release|x64 - {0AB968E0-E993-45CE-8875-7453C96DF583}.Release|x86.ActiveCfg = Release|Win32 - {0AB968E0-E993-45CE-8875-7453C96DF583}.Release|x86.Build.0 = Release|Win32 - {25923141-9859-4AFE-8168-0DF78322FC63}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {25923141-9859-4AFE-8168-0DF78322FC63}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {25923141-9859-4AFE-8168-0DF78322FC63}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {25923141-9859-4AFE-8168-0DF78322FC63}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {25923141-9859-4AFE-8168-0DF78322FC63}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {25923141-9859-4AFE-8168-0DF78322FC63}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {25923141-9859-4AFE-8168-0DF78322FC63}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {25923141-9859-4AFE-8168-0DF78322FC63}.Debug|ARM64.Build.0 = Debug|ARM64 - {25923141-9859-4AFE-8168-0DF78322FC63}.Debug|x64.ActiveCfg = Debug|x64 - {25923141-9859-4AFE-8168-0DF78322FC63}.Debug|x64.Build.0 = Debug|x64 - {25923141-9859-4AFE-8168-0DF78322FC63}.Debug|x86.ActiveCfg = Debug|Win32 - {25923141-9859-4AFE-8168-0DF78322FC63}.Debug|x86.Build.0 = Debug|Win32 - {25923141-9859-4AFE-8168-0DF78322FC63}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {25923141-9859-4AFE-8168-0DF78322FC63}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {25923141-9859-4AFE-8168-0DF78322FC63}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {25923141-9859-4AFE-8168-0DF78322FC63}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {25923141-9859-4AFE-8168-0DF78322FC63}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {25923141-9859-4AFE-8168-0DF78322FC63}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {25923141-9859-4AFE-8168-0DF78322FC63}.Release|ARM64.ActiveCfg = Release|ARM64 - {25923141-9859-4AFE-8168-0DF78322FC63}.Release|ARM64.Build.0 = Release|ARM64 - {25923141-9859-4AFE-8168-0DF78322FC63}.Release|x64.ActiveCfg = Release|x64 - {25923141-9859-4AFE-8168-0DF78322FC63}.Release|x64.Build.0 = Release|x64 - {25923141-9859-4AFE-8168-0DF78322FC63}.Release|x86.ActiveCfg = Release|Win32 - {25923141-9859-4AFE-8168-0DF78322FC63}.Release|x86.Build.0 = Release|Win32 - {7E855020-7FA4-482D-B510-2E709354FE8B}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {7E855020-7FA4-482D-B510-2E709354FE8B}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {7E855020-7FA4-482D-B510-2E709354FE8B}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {7E855020-7FA4-482D-B510-2E709354FE8B}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {7E855020-7FA4-482D-B510-2E709354FE8B}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {7E855020-7FA4-482D-B510-2E709354FE8B}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {7E855020-7FA4-482D-B510-2E709354FE8B}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {7E855020-7FA4-482D-B510-2E709354FE8B}.Debug|ARM64.Build.0 = Debug|ARM64 - {7E855020-7FA4-482D-B510-2E709354FE8B}.Debug|x64.ActiveCfg = Debug|x64 - {7E855020-7FA4-482D-B510-2E709354FE8B}.Debug|x64.Build.0 = Debug|x64 - {7E855020-7FA4-482D-B510-2E709354FE8B}.Debug|x86.ActiveCfg = Debug|Win32 - {7E855020-7FA4-482D-B510-2E709354FE8B}.Debug|x86.Build.0 = Debug|Win32 - {7E855020-7FA4-482D-B510-2E709354FE8B}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {7E855020-7FA4-482D-B510-2E709354FE8B}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {7E855020-7FA4-482D-B510-2E709354FE8B}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {7E855020-7FA4-482D-B510-2E709354FE8B}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {7E855020-7FA4-482D-B510-2E709354FE8B}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {7E855020-7FA4-482D-B510-2E709354FE8B}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {7E855020-7FA4-482D-B510-2E709354FE8B}.Release|ARM64.ActiveCfg = Release|ARM64 - {7E855020-7FA4-482D-B510-2E709354FE8B}.Release|ARM64.Build.0 = Release|ARM64 - {7E855020-7FA4-482D-B510-2E709354FE8B}.Release|x64.ActiveCfg = Release|x64 - {7E855020-7FA4-482D-B510-2E709354FE8B}.Release|x64.Build.0 = Release|x64 - {7E855020-7FA4-482D-B510-2E709354FE8B}.Release|x86.ActiveCfg = Release|Win32 - {7E855020-7FA4-482D-B510-2E709354FE8B}.Release|x86.Build.0 = Release|Win32 - {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Debug|ARM64.Build.0 = Debug|ARM64 - {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Debug|x64.ActiveCfg = Debug|x64 - {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Debug|x64.Build.0 = Debug|x64 - {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Debug|x86.ActiveCfg = Debug|Win32 - {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Debug|x86.Build.0 = Debug|Win32 - {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Release|ARM64.ActiveCfg = Release|ARM64 - {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Release|ARM64.Build.0 = Release|ARM64 - {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Release|x64.ActiveCfg = Release|x64 - {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Release|x64.Build.0 = Release|x64 - {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Release|x86.ActiveCfg = Release|Win32 - {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Release|x86.Build.0 = Release|Win32 - {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Debug|ARM64.Build.0 = Debug|ARM64 - {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Debug|x64.ActiveCfg = Debug|x64 - {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Debug|x64.Build.0 = Debug|x64 - {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Debug|x86.ActiveCfg = Debug|Win32 - {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Debug|x86.Build.0 = Debug|Win32 - {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Release|ARM64.ActiveCfg = Release|ARM64 - {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Release|ARM64.Build.0 = Release|ARM64 - {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Release|x64.ActiveCfg = Release|x64 - {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Release|x64.Build.0 = Release|x64 - {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Release|x86.ActiveCfg = Release|Win32 - {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Release|x86.Build.0 = Release|Win32 - {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Debug|ARM64.Build.0 = Debug|ARM64 - {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Debug|x64.ActiveCfg = Debug|x64 - {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Debug|x64.Build.0 = Debug|x64 - {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Debug|x86.ActiveCfg = Debug|Win32 - {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Debug|x86.Build.0 = Debug|Win32 - {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Release|ARM64.ActiveCfg = Release|ARM64 - {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Release|ARM64.Build.0 = Release|ARM64 - {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Release|x64.ActiveCfg = Release|x64 - {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Release|x64.Build.0 = Release|x64 - {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Release|x86.ActiveCfg = Release|Win32 - {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Release|x86.Build.0 = Release|Win32 - {B19DD336-538E-4091-A559-EAA717FEC899}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {B19DD336-538E-4091-A559-EAA717FEC899}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {B19DD336-538E-4091-A559-EAA717FEC899}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {B19DD336-538E-4091-A559-EAA717FEC899}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {B19DD336-538E-4091-A559-EAA717FEC899}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {B19DD336-538E-4091-A559-EAA717FEC899}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {B19DD336-538E-4091-A559-EAA717FEC899}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {B19DD336-538E-4091-A559-EAA717FEC899}.Debug|ARM64.Build.0 = Debug|ARM64 - {B19DD336-538E-4091-A559-EAA717FEC899}.Debug|x64.ActiveCfg = Debug|x64 - {B19DD336-538E-4091-A559-EAA717FEC899}.Debug|x64.Build.0 = Debug|x64 - {B19DD336-538E-4091-A559-EAA717FEC899}.Debug|x86.ActiveCfg = Debug|Win32 - {B19DD336-538E-4091-A559-EAA717FEC899}.Debug|x86.Build.0 = Debug|Win32 - {B19DD336-538E-4091-A559-EAA717FEC899}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {B19DD336-538E-4091-A559-EAA717FEC899}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {B19DD336-538E-4091-A559-EAA717FEC899}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {B19DD336-538E-4091-A559-EAA717FEC899}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {B19DD336-538E-4091-A559-EAA717FEC899}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {B19DD336-538E-4091-A559-EAA717FEC899}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {B19DD336-538E-4091-A559-EAA717FEC899}.Release|ARM64.ActiveCfg = Release|ARM64 - {B19DD336-538E-4091-A559-EAA717FEC899}.Release|ARM64.Build.0 = Release|ARM64 - {B19DD336-538E-4091-A559-EAA717FEC899}.Release|x64.ActiveCfg = Release|x64 - {B19DD336-538E-4091-A559-EAA717FEC899}.Release|x64.Build.0 = Release|x64 - {B19DD336-538E-4091-A559-EAA717FEC899}.Release|x86.ActiveCfg = Release|Win32 - {B19DD336-538E-4091-A559-EAA717FEC899}.Release|x86.Build.0 = Release|Win32 - {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Debug|ARM64.Build.0 = Debug|ARM64 - {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Debug|x64.ActiveCfg = Debug|x64 - {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Debug|x64.Build.0 = Debug|x64 - {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Debug|x86.ActiveCfg = Debug|Win32 - {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Debug|x86.Build.0 = Debug|Win32 - {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Release|ARM64.ActiveCfg = Release|ARM64 - {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Release|ARM64.Build.0 = Release|ARM64 - {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Release|x64.ActiveCfg = Release|x64 - {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Release|x64.Build.0 = Release|x64 - {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Release|x86.ActiveCfg = Release|Win32 - {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Release|x86.Build.0 = Release|Win32 - {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Debug|ARM64.Build.0 = Debug|ARM64 - {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Debug|x64.ActiveCfg = Debug|x64 - {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Debug|x64.Build.0 = Debug|x64 - {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Debug|x86.ActiveCfg = Debug|Win32 - {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Debug|x86.Build.0 = Debug|Win32 - {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Release|ARM64.ActiveCfg = Release|ARM64 - {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Release|ARM64.Build.0 = Release|ARM64 - {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Release|x64.ActiveCfg = Release|x64 - {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Release|x64.Build.0 = Release|x64 - {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Release|x86.ActiveCfg = Release|Win32 - {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Release|x86.Build.0 = Release|Win32 - {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Debug|ARM64.Build.0 = Debug|ARM64 - {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Debug|x64.ActiveCfg = Debug|x64 - {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Debug|x64.Build.0 = Debug|x64 - {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Debug|x86.ActiveCfg = Debug|Win32 - {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Debug|x86.Build.0 = Debug|Win32 - {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Release|ARM64.ActiveCfg = Release|ARM64 - {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Release|ARM64.Build.0 = Release|ARM64 - {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Release|x64.ActiveCfg = Release|x64 - {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Release|x64.Build.0 = Release|x64 - {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Release|x86.ActiveCfg = Release|Win32 - {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Release|x86.Build.0 = Release|Win32 - {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Debug|ARM64.Build.0 = Debug|ARM64 - {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Debug|x64.ActiveCfg = Debug|x64 - {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Debug|x64.Build.0 = Debug|x64 - {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Debug|x86.ActiveCfg = Debug|Win32 - {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Debug|x86.Build.0 = Debug|Win32 - {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Release|ARM64.ActiveCfg = Release|ARM64 - {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Release|ARM64.Build.0 = Release|ARM64 - {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Release|x64.ActiveCfg = Release|x64 - {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Release|x64.Build.0 = Release|x64 - {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Release|x86.ActiveCfg = Release|Win32 - {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Release|x86.Build.0 = Release|Win32 - {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Debug|ARM64.Build.0 = Debug|ARM64 - {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Debug|x64.ActiveCfg = Debug|x64 - {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Debug|x64.Build.0 = Debug|x64 - {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Debug|x86.ActiveCfg = Debug|Win32 - {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Debug|x86.Build.0 = Debug|Win32 - {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Release|ARM64.ActiveCfg = Release|ARM64 - {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Release|ARM64.Build.0 = Release|ARM64 - {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Release|x64.ActiveCfg = Release|x64 - {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Release|x64.Build.0 = Release|x64 - {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Release|x86.ActiveCfg = Release|Win32 - {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Release|x86.Build.0 = Release|Win32 - {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Debug|ARM64.Build.0 = Debug|ARM64 - {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Debug|x64.ActiveCfg = Debug|x64 - {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Debug|x64.Build.0 = Debug|x64 - {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Debug|x86.ActiveCfg = Debug|Win32 - {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Debug|x86.Build.0 = Debug|Win32 - {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Release|ARM64.ActiveCfg = Release|ARM64 - {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Release|ARM64.Build.0 = Release|ARM64 - {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Release|x64.ActiveCfg = Release|x64 - {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Release|x64.Build.0 = Release|x64 - {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Release|x86.ActiveCfg = Release|Win32 - {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Release|x86.Build.0 = Release|Win32 - {25BCB876-B60A-499B-9046-E9801CFD7780}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {25BCB876-B60A-499B-9046-E9801CFD7780}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {25BCB876-B60A-499B-9046-E9801CFD7780}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {25BCB876-B60A-499B-9046-E9801CFD7780}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {25BCB876-B60A-499B-9046-E9801CFD7780}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {25BCB876-B60A-499B-9046-E9801CFD7780}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {25BCB876-B60A-499B-9046-E9801CFD7780}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {25BCB876-B60A-499B-9046-E9801CFD7780}.Debug|ARM64.Build.0 = Debug|ARM64 - {25BCB876-B60A-499B-9046-E9801CFD7780}.Debug|x64.ActiveCfg = Debug|x64 - {25BCB876-B60A-499B-9046-E9801CFD7780}.Debug|x64.Build.0 = Debug|x64 - {25BCB876-B60A-499B-9046-E9801CFD7780}.Debug|x86.ActiveCfg = Debug|Win32 - {25BCB876-B60A-499B-9046-E9801CFD7780}.Debug|x86.Build.0 = Debug|Win32 - {25BCB876-B60A-499B-9046-E9801CFD7780}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {25BCB876-B60A-499B-9046-E9801CFD7780}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {25BCB876-B60A-499B-9046-E9801CFD7780}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {25BCB876-B60A-499B-9046-E9801CFD7780}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {25BCB876-B60A-499B-9046-E9801CFD7780}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {25BCB876-B60A-499B-9046-E9801CFD7780}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {25BCB876-B60A-499B-9046-E9801CFD7780}.Release|ARM64.ActiveCfg = Release|ARM64 - {25BCB876-B60A-499B-9046-E9801CFD7780}.Release|ARM64.Build.0 = Release|ARM64 - {25BCB876-B60A-499B-9046-E9801CFD7780}.Release|x64.ActiveCfg = Release|x64 - {25BCB876-B60A-499B-9046-E9801CFD7780}.Release|x64.Build.0 = Release|x64 - {25BCB876-B60A-499B-9046-E9801CFD7780}.Release|x86.ActiveCfg = Release|Win32 - {25BCB876-B60A-499B-9046-E9801CFD7780}.Release|x86.Build.0 = Release|Win32 - {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Debug|ARM64.Build.0 = Debug|ARM64 - {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Debug|x64.ActiveCfg = Debug|x64 - {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Debug|x64.Build.0 = Debug|x64 - {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Debug|x86.ActiveCfg = Debug|Win32 - {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Debug|x86.Build.0 = Debug|Win32 - {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Release|ARM64.ActiveCfg = Release|ARM64 - {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Release|ARM64.Build.0 = Release|ARM64 - {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Release|x64.ActiveCfg = Release|x64 - {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Release|x64.Build.0 = Release|x64 - {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Release|x86.ActiveCfg = Release|Win32 - {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Release|x86.Build.0 = Release|Win32 - {2BB0C1D4-9298-45AC-B244-67A99769A292}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {2BB0C1D4-9298-45AC-B244-67A99769A292}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {2BB0C1D4-9298-45AC-B244-67A99769A292}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {2BB0C1D4-9298-45AC-B244-67A99769A292}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {2BB0C1D4-9298-45AC-B244-67A99769A292}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {2BB0C1D4-9298-45AC-B244-67A99769A292}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {2BB0C1D4-9298-45AC-B244-67A99769A292}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {2BB0C1D4-9298-45AC-B244-67A99769A292}.Debug|ARM64.Build.0 = Debug|ARM64 - {2BB0C1D4-9298-45AC-B244-67A99769A292}.Debug|x64.ActiveCfg = Debug|x64 - {2BB0C1D4-9298-45AC-B244-67A99769A292}.Debug|x64.Build.0 = Debug|x64 - {2BB0C1D4-9298-45AC-B244-67A99769A292}.Debug|x86.ActiveCfg = Debug|Win32 - {2BB0C1D4-9298-45AC-B244-67A99769A292}.Debug|x86.Build.0 = Debug|Win32 - {2BB0C1D4-9298-45AC-B244-67A99769A292}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {2BB0C1D4-9298-45AC-B244-67A99769A292}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {2BB0C1D4-9298-45AC-B244-67A99769A292}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {2BB0C1D4-9298-45AC-B244-67A99769A292}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {2BB0C1D4-9298-45AC-B244-67A99769A292}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {2BB0C1D4-9298-45AC-B244-67A99769A292}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {2BB0C1D4-9298-45AC-B244-67A99769A292}.Release|ARM64.ActiveCfg = Release|ARM64 - {2BB0C1D4-9298-45AC-B244-67A99769A292}.Release|ARM64.Build.0 = Release|ARM64 - {2BB0C1D4-9298-45AC-B244-67A99769A292}.Release|x64.ActiveCfg = Release|x64 - {2BB0C1D4-9298-45AC-B244-67A99769A292}.Release|x64.Build.0 = Release|x64 - {2BB0C1D4-9298-45AC-B244-67A99769A292}.Release|x86.ActiveCfg = Release|Win32 - {2BB0C1D4-9298-45AC-B244-67A99769A292}.Release|x86.Build.0 = Release|Win32 - {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Debug|ARM64.Build.0 = Debug|ARM64 - {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Debug|x64.ActiveCfg = Debug|x64 - {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Debug|x64.Build.0 = Debug|x64 - {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Debug|x86.ActiveCfg = Debug|Win32 - {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Debug|x86.Build.0 = Debug|Win32 - {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Release|ARM64.ActiveCfg = Release|ARM64 - {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Release|ARM64.Build.0 = Release|ARM64 - {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Release|x64.ActiveCfg = Release|x64 - {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Release|x64.Build.0 = Release|x64 - {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Release|x86.ActiveCfg = Release|Win32 - {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Release|x86.Build.0 = Release|Win32 - {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Debug|ARM64.Build.0 = Debug|ARM64 - {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Debug|x64.ActiveCfg = Debug|x64 - {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Debug|x64.Build.0 = Debug|x64 - {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Debug|x86.ActiveCfg = Debug|Win32 - {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Debug|x86.Build.0 = Debug|Win32 - {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Release|ARM64.ActiveCfg = Release|ARM64 - {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Release|ARM64.Build.0 = Release|ARM64 - {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Release|x64.ActiveCfg = Release|x64 - {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Release|x64.Build.0 = Release|x64 - {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Release|x86.ActiveCfg = Release|Win32 - {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Release|x86.Build.0 = Release|Win32 - {31B41997-3890-45E3-93FE-C57B363E9C0D}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {31B41997-3890-45E3-93FE-C57B363E9C0D}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {31B41997-3890-45E3-93FE-C57B363E9C0D}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {31B41997-3890-45E3-93FE-C57B363E9C0D}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {31B41997-3890-45E3-93FE-C57B363E9C0D}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {31B41997-3890-45E3-93FE-C57B363E9C0D}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {31B41997-3890-45E3-93FE-C57B363E9C0D}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {31B41997-3890-45E3-93FE-C57B363E9C0D}.Debug|ARM64.Build.0 = Debug|ARM64 - {31B41997-3890-45E3-93FE-C57B363E9C0D}.Debug|x64.ActiveCfg = Debug|x64 - {31B41997-3890-45E3-93FE-C57B363E9C0D}.Debug|x64.Build.0 = Debug|x64 - {31B41997-3890-45E3-93FE-C57B363E9C0D}.Debug|x86.ActiveCfg = Debug|Win32 - {31B41997-3890-45E3-93FE-C57B363E9C0D}.Debug|x86.Build.0 = Debug|Win32 - {31B41997-3890-45E3-93FE-C57B363E9C0D}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {31B41997-3890-45E3-93FE-C57B363E9C0D}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {31B41997-3890-45E3-93FE-C57B363E9C0D}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {31B41997-3890-45E3-93FE-C57B363E9C0D}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {31B41997-3890-45E3-93FE-C57B363E9C0D}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {31B41997-3890-45E3-93FE-C57B363E9C0D}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {31B41997-3890-45E3-93FE-C57B363E9C0D}.Release|ARM64.ActiveCfg = Release|ARM64 - {31B41997-3890-45E3-93FE-C57B363E9C0D}.Release|ARM64.Build.0 = Release|ARM64 - {31B41997-3890-45E3-93FE-C57B363E9C0D}.Release|x64.ActiveCfg = Release|x64 - {31B41997-3890-45E3-93FE-C57B363E9C0D}.Release|x64.Build.0 = Release|x64 - {31B41997-3890-45E3-93FE-C57B363E9C0D}.Release|x86.ActiveCfg = Release|Win32 - {31B41997-3890-45E3-93FE-C57B363E9C0D}.Release|x86.Build.0 = Release|Win32 - {D550AB93-DF31-4B76-873F-F075018352F4}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {D550AB93-DF31-4B76-873F-F075018352F4}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {D550AB93-DF31-4B76-873F-F075018352F4}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {D550AB93-DF31-4B76-873F-F075018352F4}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {D550AB93-DF31-4B76-873F-F075018352F4}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {D550AB93-DF31-4B76-873F-F075018352F4}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {D550AB93-DF31-4B76-873F-F075018352F4}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {D550AB93-DF31-4B76-873F-F075018352F4}.Debug|ARM64.Build.0 = Debug|ARM64 - {D550AB93-DF31-4B76-873F-F075018352F4}.Debug|x64.ActiveCfg = Debug|x64 - {D550AB93-DF31-4B76-873F-F075018352F4}.Debug|x64.Build.0 = Debug|x64 - {D550AB93-DF31-4B76-873F-F075018352F4}.Debug|x86.ActiveCfg = Debug|Win32 - {D550AB93-DF31-4B76-873F-F075018352F4}.Debug|x86.Build.0 = Debug|Win32 - {D550AB93-DF31-4B76-873F-F075018352F4}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {D550AB93-DF31-4B76-873F-F075018352F4}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {D550AB93-DF31-4B76-873F-F075018352F4}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {D550AB93-DF31-4B76-873F-F075018352F4}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {D550AB93-DF31-4B76-873F-F075018352F4}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {D550AB93-DF31-4B76-873F-F075018352F4}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {D550AB93-DF31-4B76-873F-F075018352F4}.Release|ARM64.ActiveCfg = Release|ARM64 - {D550AB93-DF31-4B76-873F-F075018352F4}.Release|ARM64.Build.0 = Release|ARM64 - {D550AB93-DF31-4B76-873F-F075018352F4}.Release|x64.ActiveCfg = Release|x64 - {D550AB93-DF31-4B76-873F-F075018352F4}.Release|x64.Build.0 = Release|x64 - {D550AB93-DF31-4B76-873F-F075018352F4}.Release|x86.ActiveCfg = Release|Win32 - {D550AB93-DF31-4B76-873F-F075018352F4}.Release|x86.Build.0 = Release|Win32 - {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Debug|ARM64.Build.0 = Debug|ARM64 - {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Debug|x64.ActiveCfg = Debug|x64 - {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Debug|x64.Build.0 = Debug|x64 - {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Debug|x86.ActiveCfg = Debug|Win32 - {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Debug|x86.Build.0 = Debug|Win32 - {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Release|ARM64.ActiveCfg = Release|ARM64 - {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Release|ARM64.Build.0 = Release|ARM64 - {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Release|x64.ActiveCfg = Release|x64 - {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Release|x64.Build.0 = Release|x64 - {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Release|x86.ActiveCfg = Release|Win32 - {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Release|x86.Build.0 = Release|Win32 - {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Debug|ARM64.Build.0 = Debug|ARM64 - {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Debug|x64.ActiveCfg = Debug|x64 - {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Debug|x64.Build.0 = Debug|x64 - {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Debug|x86.ActiveCfg = Debug|Win32 - {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Debug|x86.Build.0 = Debug|Win32 - {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Release|ARM64.ActiveCfg = Release|ARM64 - {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Release|ARM64.Build.0 = Release|ARM64 - {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Release|x64.ActiveCfg = Release|x64 - {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Release|x64.Build.0 = Release|x64 - {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Release|x86.ActiveCfg = Release|Win32 - {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Release|x86.Build.0 = Release|Win32 - {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Debug|ARM64.Build.0 = Debug|ARM64 - {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Debug|x64.ActiveCfg = Debug|x64 - {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Debug|x64.Build.0 = Debug|x64 - {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Debug|x86.ActiveCfg = Debug|Win32 - {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Debug|x86.Build.0 = Debug|Win32 - {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Release|ARM64.ActiveCfg = Release|ARM64 - {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Release|ARM64.Build.0 = Release|ARM64 - {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Release|x64.ActiveCfg = Release|x64 - {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Release|x64.Build.0 = Release|x64 - {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Release|x86.ActiveCfg = Release|Win32 - {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Release|x86.Build.0 = Release|Win32 - {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Debug|ARM64.Build.0 = Debug|ARM64 - {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Debug|x64.ActiveCfg = Debug|x64 - {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Debug|x64.Build.0 = Debug|x64 - {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Debug|x86.ActiveCfg = Debug|Win32 - {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Debug|x86.Build.0 = Debug|Win32 - {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Release|ARM64.ActiveCfg = Release|ARM64 - {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Release|ARM64.Build.0 = Release|ARM64 - {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Release|x64.ActiveCfg = Release|x64 - {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Release|x64.Build.0 = Release|x64 - {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Release|x86.ActiveCfg = Release|Win32 - {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Release|x86.Build.0 = Release|Win32 - {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Debug|ARM64.Build.0 = Debug|ARM64 - {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Debug|x64.ActiveCfg = Debug|x64 - {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Debug|x64.Build.0 = Debug|x64 - {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Debug|x86.ActiveCfg = Debug|Win32 - {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Debug|x86.Build.0 = Debug|Win32 - {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Release|ARM64.ActiveCfg = Release|ARM64 - {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Release|ARM64.Build.0 = Release|ARM64 - {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Release|x64.ActiveCfg = Release|x64 - {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Release|x64.Build.0 = Release|x64 - {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Release|x86.ActiveCfg = Release|Win32 - {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Release|x86.Build.0 = Release|Win32 - {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Debug|ARM64.Build.0 = Debug|ARM64 - {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Debug|x64.ActiveCfg = Debug|x64 - {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Debug|x64.Build.0 = Debug|x64 - {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Debug|x86.ActiveCfg = Debug|Win32 - {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Debug|x86.Build.0 = Debug|Win32 - {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Release|ARM64.ActiveCfg = Release|ARM64 - {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Release|ARM64.Build.0 = Release|ARM64 - {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Release|x64.ActiveCfg = Release|x64 - {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Release|x64.Build.0 = Release|x64 - {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Release|x86.ActiveCfg = Release|Win32 - {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Release|x86.Build.0 = Release|Win32 - {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Debug|ARM64.Build.0 = Debug|ARM64 - {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Debug|x64.ActiveCfg = Debug|x64 - {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Debug|x64.Build.0 = Debug|x64 - {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Debug|x86.ActiveCfg = Debug|Win32 - {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Debug|x86.Build.0 = Debug|Win32 - {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Release|ARM64.ActiveCfg = Release|ARM64 - {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Release|ARM64.Build.0 = Release|ARM64 - {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Release|x64.ActiveCfg = Release|x64 - {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Release|x64.Build.0 = Release|x64 - {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Release|x86.ActiveCfg = Release|Win32 - {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Release|x86.Build.0 = Release|Win32 - {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Debug|ARM64.Build.0 = Debug|ARM64 - {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Debug|x64.ActiveCfg = Debug|x64 - {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Debug|x64.Build.0 = Debug|x64 - {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Debug|x86.ActiveCfg = Debug|Win32 - {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Debug|x86.Build.0 = Debug|Win32 - {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Release|ARM64.ActiveCfg = Release|ARM64 - {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Release|ARM64.Build.0 = Release|ARM64 - {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Release|x64.ActiveCfg = Release|x64 - {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Release|x64.Build.0 = Release|x64 - {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Release|x86.ActiveCfg = Release|Win32 - {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Release|x86.Build.0 = Release|Win32 - {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Debug|ARM64.Build.0 = Debug|ARM64 - {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Debug|x64.ActiveCfg = Debug|x64 - {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Debug|x64.Build.0 = Debug|x64 - {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Debug|x86.ActiveCfg = Debug|Win32 - {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Debug|x86.Build.0 = Debug|Win32 - {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Release|ARM64.ActiveCfg = Release|ARM64 - {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Release|ARM64.Build.0 = Release|ARM64 - {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Release|x64.ActiveCfg = Release|x64 - {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Release|x64.Build.0 = Release|x64 - {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Release|x86.ActiveCfg = Release|Win32 - {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Release|x86.Build.0 = Release|Win32 - {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Debug|ARM64.Build.0 = Debug|ARM64 - {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Debug|x64.ActiveCfg = Debug|x64 - {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Debug|x64.Build.0 = Debug|x64 - {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Debug|x86.ActiveCfg = Debug|Win32 - {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Debug|x86.Build.0 = Debug|Win32 - {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Release|ARM64.ActiveCfg = Release|ARM64 - {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Release|ARM64.Build.0 = Release|ARM64 - {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Release|x64.ActiveCfg = Release|x64 - {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Release|x64.Build.0 = Release|x64 - {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Release|x86.ActiveCfg = Release|Win32 - {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Release|x86.Build.0 = Release|Win32 - {33459B4E-1839-4856-BF6B-22480D11FE31}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {33459B4E-1839-4856-BF6B-22480D11FE31}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {33459B4E-1839-4856-BF6B-22480D11FE31}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {33459B4E-1839-4856-BF6B-22480D11FE31}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {33459B4E-1839-4856-BF6B-22480D11FE31}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {33459B4E-1839-4856-BF6B-22480D11FE31}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {33459B4E-1839-4856-BF6B-22480D11FE31}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {33459B4E-1839-4856-BF6B-22480D11FE31}.Debug|ARM64.Build.0 = Debug|ARM64 - {33459B4E-1839-4856-BF6B-22480D11FE31}.Debug|x64.ActiveCfg = Debug|x64 - {33459B4E-1839-4856-BF6B-22480D11FE31}.Debug|x64.Build.0 = Debug|x64 - {33459B4E-1839-4856-BF6B-22480D11FE31}.Debug|x86.ActiveCfg = Debug|Win32 - {33459B4E-1839-4856-BF6B-22480D11FE31}.Debug|x86.Build.0 = Debug|Win32 - {33459B4E-1839-4856-BF6B-22480D11FE31}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {33459B4E-1839-4856-BF6B-22480D11FE31}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {33459B4E-1839-4856-BF6B-22480D11FE31}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {33459B4E-1839-4856-BF6B-22480D11FE31}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {33459B4E-1839-4856-BF6B-22480D11FE31}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {33459B4E-1839-4856-BF6B-22480D11FE31}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {33459B4E-1839-4856-BF6B-22480D11FE31}.Release|ARM64.ActiveCfg = Release|ARM64 - {33459B4E-1839-4856-BF6B-22480D11FE31}.Release|ARM64.Build.0 = Release|ARM64 - {33459B4E-1839-4856-BF6B-22480D11FE31}.Release|x64.ActiveCfg = Release|x64 - {33459B4E-1839-4856-BF6B-22480D11FE31}.Release|x64.Build.0 = Release|x64 - {33459B4E-1839-4856-BF6B-22480D11FE31}.Release|x86.ActiveCfg = Release|Win32 - {33459B4E-1839-4856-BF6B-22480D11FE31}.Release|x86.Build.0 = Release|Win32 - {48871156-181A-475A-BD8D-200086A09675}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {48871156-181A-475A-BD8D-200086A09675}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {48871156-181A-475A-BD8D-200086A09675}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {48871156-181A-475A-BD8D-200086A09675}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {48871156-181A-475A-BD8D-200086A09675}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {48871156-181A-475A-BD8D-200086A09675}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {48871156-181A-475A-BD8D-200086A09675}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {48871156-181A-475A-BD8D-200086A09675}.Debug|ARM64.Build.0 = Debug|ARM64 - {48871156-181A-475A-BD8D-200086A09675}.Debug|x64.ActiveCfg = Debug|x64 - {48871156-181A-475A-BD8D-200086A09675}.Debug|x64.Build.0 = Debug|x64 - {48871156-181A-475A-BD8D-200086A09675}.Debug|x86.ActiveCfg = Debug|Win32 - {48871156-181A-475A-BD8D-200086A09675}.Debug|x86.Build.0 = Debug|Win32 - {48871156-181A-475A-BD8D-200086A09675}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {48871156-181A-475A-BD8D-200086A09675}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {48871156-181A-475A-BD8D-200086A09675}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {48871156-181A-475A-BD8D-200086A09675}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {48871156-181A-475A-BD8D-200086A09675}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {48871156-181A-475A-BD8D-200086A09675}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {48871156-181A-475A-BD8D-200086A09675}.Release|ARM64.ActiveCfg = Release|ARM64 - {48871156-181A-475A-BD8D-200086A09675}.Release|ARM64.Build.0 = Release|ARM64 - {48871156-181A-475A-BD8D-200086A09675}.Release|x64.ActiveCfg = Release|x64 - {48871156-181A-475A-BD8D-200086A09675}.Release|x64.Build.0 = Release|x64 - {48871156-181A-475A-BD8D-200086A09675}.Release|x86.ActiveCfg = Release|Win32 - {48871156-181A-475A-BD8D-200086A09675}.Release|x86.Build.0 = Release|Win32 - {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Debug|ARM64.Build.0 = Debug|ARM64 - {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Debug|x64.ActiveCfg = Debug|x64 - {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Debug|x64.Build.0 = Debug|x64 - {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Debug|x86.ActiveCfg = Debug|Win32 - {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Debug|x86.Build.0 = Debug|Win32 - {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Release|ARM64.ActiveCfg = Release|ARM64 - {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Release|ARM64.Build.0 = Release|ARM64 - {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Release|x64.ActiveCfg = Release|x64 - {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Release|x64.Build.0 = Release|x64 - {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Release|x86.ActiveCfg = Release|Win32 - {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Release|x86.Build.0 = Release|Win32 - {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Debug|ARM64.Build.0 = Debug|ARM64 - {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Debug|x64.ActiveCfg = Debug|x64 - {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Debug|x64.Build.0 = Debug|x64 - {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Debug|x86.ActiveCfg = Debug|Win32 - {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Debug|x86.Build.0 = Debug|Win32 - {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Release|ARM64.ActiveCfg = Release|ARM64 - {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Release|ARM64.Build.0 = Release|ARM64 - {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Release|x64.ActiveCfg = Release|x64 - {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Release|x64.Build.0 = Release|x64 - {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Release|x86.ActiveCfg = Release|Win32 - {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Release|x86.Build.0 = Release|Win32 - {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Debug|ARM64.Build.0 = Debug|ARM64 - {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Debug|x64.ActiveCfg = Debug|x64 - {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Debug|x64.Build.0 = Debug|x64 - {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Debug|x86.ActiveCfg = Debug|Win32 - {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Debug|x86.Build.0 = Debug|Win32 - {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Release|ARM64.ActiveCfg = Release|ARM64 - {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Release|ARM64.Build.0 = Release|ARM64 - {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Release|x64.ActiveCfg = Release|x64 - {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Release|x64.Build.0 = Release|x64 - {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Release|x86.ActiveCfg = Release|Win32 - {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Release|x86.Build.0 = Release|Win32 - {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Debug|ARM64.Build.0 = Debug|ARM64 - {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Debug|x64.ActiveCfg = Debug|x64 - {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Debug|x64.Build.0 = Debug|x64 - {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Debug|x86.ActiveCfg = Debug|Win32 - {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Debug|x86.Build.0 = Debug|Win32 - {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Release|ARM64.ActiveCfg = Release|ARM64 - {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Release|ARM64.Build.0 = Release|ARM64 - {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Release|x64.ActiveCfg = Release|x64 - {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Release|x64.Build.0 = Release|x64 - {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Release|x86.ActiveCfg = Release|Win32 - {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Release|x86.Build.0 = Release|Win32 - {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Debug|ARM64.Build.0 = Debug|ARM64 - {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Debug|x64.ActiveCfg = Debug|x64 - {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Debug|x64.Build.0 = Debug|x64 - {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Debug|x86.ActiveCfg = Debug|Win32 - {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Debug|x86.Build.0 = Debug|Win32 - {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Release|ARM64.ActiveCfg = Release|ARM64 - {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Release|ARM64.Build.0 = Release|ARM64 - {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Release|x64.ActiveCfg = Release|x64 - {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Release|x64.Build.0 = Release|x64 - {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Release|x86.ActiveCfg = Release|Win32 - {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Release|x86.Build.0 = Release|Win32 - {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Debug|ARM64.Build.0 = Debug|ARM64 - {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Debug|x64.ActiveCfg = Debug|x64 - {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Debug|x64.Build.0 = Debug|x64 - {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Debug|x86.ActiveCfg = Debug|Win32 - {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Debug|x86.Build.0 = Debug|Win32 - {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Release|ARM64.ActiveCfg = Release|ARM64 - {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Release|ARM64.Build.0 = Release|ARM64 - {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Release|x64.ActiveCfg = Release|x64 - {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Release|x64.Build.0 = Release|x64 - {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Release|x86.ActiveCfg = Release|Win32 - {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Release|x86.Build.0 = Release|Win32 - {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Debug|ARM64.Build.0 = Debug|ARM64 - {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Debug|x64.ActiveCfg = Debug|x64 - {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Debug|x64.Build.0 = Debug|x64 - {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Debug|x86.ActiveCfg = Debug|Win32 - {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Debug|x86.Build.0 = Debug|Win32 - {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Release|ARM64.ActiveCfg = Release|ARM64 - {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Release|ARM64.Build.0 = Release|ARM64 - {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Release|x64.ActiveCfg = Release|x64 - {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Release|x64.Build.0 = Release|x64 - {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Release|x86.ActiveCfg = Release|Win32 - {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Release|x86.Build.0 = Release|Win32 - {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Debug|ARM64.Build.0 = Debug|ARM64 - {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Debug|x64.ActiveCfg = Debug|x64 - {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Debug|x64.Build.0 = Debug|x64 - {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Debug|x86.ActiveCfg = Debug|Win32 - {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Debug|x86.Build.0 = Debug|Win32 - {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Release|ARM64.ActiveCfg = Release|ARM64 - {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Release|ARM64.Build.0 = Release|ARM64 - {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Release|x64.ActiveCfg = Release|x64 - {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Release|x64.Build.0 = Release|x64 - {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Release|x86.ActiveCfg = Release|Win32 - {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Release|x86.Build.0 = Release|Win32 - {CF3755C4-937D-4ABF-B7B3-95140808717F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {CF3755C4-937D-4ABF-B7B3-95140808717F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {CF3755C4-937D-4ABF-B7B3-95140808717F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {CF3755C4-937D-4ABF-B7B3-95140808717F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {CF3755C4-937D-4ABF-B7B3-95140808717F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {CF3755C4-937D-4ABF-B7B3-95140808717F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {CF3755C4-937D-4ABF-B7B3-95140808717F}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {CF3755C4-937D-4ABF-B7B3-95140808717F}.Debug|ARM64.Build.0 = Debug|ARM64 - {CF3755C4-937D-4ABF-B7B3-95140808717F}.Debug|x64.ActiveCfg = Debug|x64 - {CF3755C4-937D-4ABF-B7B3-95140808717F}.Debug|x64.Build.0 = Debug|x64 - {CF3755C4-937D-4ABF-B7B3-95140808717F}.Debug|x86.ActiveCfg = Debug|Win32 - {CF3755C4-937D-4ABF-B7B3-95140808717F}.Debug|x86.Build.0 = Debug|Win32 - {CF3755C4-937D-4ABF-B7B3-95140808717F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {CF3755C4-937D-4ABF-B7B3-95140808717F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {CF3755C4-937D-4ABF-B7B3-95140808717F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {CF3755C4-937D-4ABF-B7B3-95140808717F}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {CF3755C4-937D-4ABF-B7B3-95140808717F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {CF3755C4-937D-4ABF-B7B3-95140808717F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {CF3755C4-937D-4ABF-B7B3-95140808717F}.Release|ARM64.ActiveCfg = Release|ARM64 - {CF3755C4-937D-4ABF-B7B3-95140808717F}.Release|ARM64.Build.0 = Release|ARM64 - {CF3755C4-937D-4ABF-B7B3-95140808717F}.Release|x64.ActiveCfg = Release|x64 - {CF3755C4-937D-4ABF-B7B3-95140808717F}.Release|x64.Build.0 = Release|x64 - {CF3755C4-937D-4ABF-B7B3-95140808717F}.Release|x86.ActiveCfg = Release|Win32 - {CF3755C4-937D-4ABF-B7B3-95140808717F}.Release|x86.Build.0 = Release|Win32 - {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Debug|ARM64.Build.0 = Debug|ARM64 - {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Debug|x64.ActiveCfg = Debug|x64 - {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Debug|x64.Build.0 = Debug|x64 - {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Debug|x86.ActiveCfg = Debug|Win32 - {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Debug|x86.Build.0 = Debug|Win32 - {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Release|ARM64.ActiveCfg = Release|ARM64 - {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Release|ARM64.Build.0 = Release|ARM64 - {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Release|x64.ActiveCfg = Release|x64 - {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Release|x64.Build.0 = Release|x64 - {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Release|x86.ActiveCfg = Release|Win32 - {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Release|x86.Build.0 = Release|Win32 - {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Debug|ARM64.Build.0 = Debug|ARM64 - {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Debug|x64.ActiveCfg = Debug|x64 - {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Debug|x64.Build.0 = Debug|x64 - {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Debug|x86.ActiveCfg = Debug|Win32 - {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Debug|x86.Build.0 = Debug|Win32 - {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Release|ARM64.ActiveCfg = Release|ARM64 - {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Release|ARM64.Build.0 = Release|ARM64 - {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Release|x64.ActiveCfg = Release|x64 - {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Release|x64.Build.0 = Release|x64 - {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Release|x86.ActiveCfg = Release|Win32 - {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Release|x86.Build.0 = Release|Win32 - {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Debug|ARM64.Build.0 = Debug|ARM64 - {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Debug|x64.ActiveCfg = Debug|x64 - {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Debug|x64.Build.0 = Debug|x64 - {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Debug|x86.ActiveCfg = Debug|Win32 - {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Debug|x86.Build.0 = Debug|Win32 - {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Release|ARM64.ActiveCfg = Release|ARM64 - {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Release|ARM64.Build.0 = Release|ARM64 - {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Release|x64.ActiveCfg = Release|x64 - {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Release|x64.Build.0 = Release|x64 - {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Release|x86.ActiveCfg = Release|Win32 - {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Release|x86.Build.0 = Release|Win32 - {52FB7463-C128-42AF-A02F-78F48473EA9A}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {52FB7463-C128-42AF-A02F-78F48473EA9A}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {52FB7463-C128-42AF-A02F-78F48473EA9A}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {52FB7463-C128-42AF-A02F-78F48473EA9A}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {52FB7463-C128-42AF-A02F-78F48473EA9A}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {52FB7463-C128-42AF-A02F-78F48473EA9A}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {52FB7463-C128-42AF-A02F-78F48473EA9A}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {52FB7463-C128-42AF-A02F-78F48473EA9A}.Debug|ARM64.Build.0 = Debug|ARM64 - {52FB7463-C128-42AF-A02F-78F48473EA9A}.Debug|x64.ActiveCfg = Debug|x64 - {52FB7463-C128-42AF-A02F-78F48473EA9A}.Debug|x64.Build.0 = Debug|x64 - {52FB7463-C128-42AF-A02F-78F48473EA9A}.Debug|x86.ActiveCfg = Debug|Win32 - {52FB7463-C128-42AF-A02F-78F48473EA9A}.Debug|x86.Build.0 = Debug|Win32 - {52FB7463-C128-42AF-A02F-78F48473EA9A}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {52FB7463-C128-42AF-A02F-78F48473EA9A}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {52FB7463-C128-42AF-A02F-78F48473EA9A}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {52FB7463-C128-42AF-A02F-78F48473EA9A}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {52FB7463-C128-42AF-A02F-78F48473EA9A}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {52FB7463-C128-42AF-A02F-78F48473EA9A}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {52FB7463-C128-42AF-A02F-78F48473EA9A}.Release|ARM64.ActiveCfg = Release|ARM64 - {52FB7463-C128-42AF-A02F-78F48473EA9A}.Release|ARM64.Build.0 = Release|ARM64 - {52FB7463-C128-42AF-A02F-78F48473EA9A}.Release|x64.ActiveCfg = Release|x64 - {52FB7463-C128-42AF-A02F-78F48473EA9A}.Release|x64.Build.0 = Release|x64 - {52FB7463-C128-42AF-A02F-78F48473EA9A}.Release|x86.ActiveCfg = Release|Win32 - {52FB7463-C128-42AF-A02F-78F48473EA9A}.Release|x86.Build.0 = Release|Win32 - {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Debug|ARM64.Build.0 = Debug|ARM64 - {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Debug|x64.ActiveCfg = Debug|x64 - {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Debug|x64.Build.0 = Debug|x64 - {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Debug|x86.ActiveCfg = Debug|Win32 - {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Debug|x86.Build.0 = Debug|Win32 - {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Release|ARM64.ActiveCfg = Release|ARM64 - {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Release|ARM64.Build.0 = Release|ARM64 - {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Release|x64.ActiveCfg = Release|x64 - {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Release|x64.Build.0 = Release|x64 - {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Release|x86.ActiveCfg = Release|Win32 - {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Release|x86.Build.0 = Release|Win32 - {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Debug|ARM64.Build.0 = Debug|ARM64 - {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Debug|x64.ActiveCfg = Debug|x64 - {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Debug|x64.Build.0 = Debug|x64 - {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Debug|x86.ActiveCfg = Debug|Win32 - {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Debug|x86.Build.0 = Debug|Win32 - {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Release|ARM64.ActiveCfg = Release|ARM64 - {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Release|ARM64.Build.0 = Release|ARM64 - {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Release|x64.ActiveCfg = Release|x64 - {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Release|x64.Build.0 = Release|x64 - {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Release|x86.ActiveCfg = Release|Win32 - {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Release|x86.Build.0 = Release|Win32 - {274C0319-7E1E-4188-936B-8DF3331230B3}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {274C0319-7E1E-4188-936B-8DF3331230B3}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {274C0319-7E1E-4188-936B-8DF3331230B3}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {274C0319-7E1E-4188-936B-8DF3331230B3}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {274C0319-7E1E-4188-936B-8DF3331230B3}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {274C0319-7E1E-4188-936B-8DF3331230B3}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {274C0319-7E1E-4188-936B-8DF3331230B3}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {274C0319-7E1E-4188-936B-8DF3331230B3}.Debug|ARM64.Build.0 = Debug|ARM64 - {274C0319-7E1E-4188-936B-8DF3331230B3}.Debug|x64.ActiveCfg = Debug|x64 - {274C0319-7E1E-4188-936B-8DF3331230B3}.Debug|x64.Build.0 = Debug|x64 - {274C0319-7E1E-4188-936B-8DF3331230B3}.Debug|x86.ActiveCfg = Debug|Win32 - {274C0319-7E1E-4188-936B-8DF3331230B3}.Debug|x86.Build.0 = Debug|Win32 - {274C0319-7E1E-4188-936B-8DF3331230B3}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {274C0319-7E1E-4188-936B-8DF3331230B3}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {274C0319-7E1E-4188-936B-8DF3331230B3}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {274C0319-7E1E-4188-936B-8DF3331230B3}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {274C0319-7E1E-4188-936B-8DF3331230B3}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {274C0319-7E1E-4188-936B-8DF3331230B3}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {274C0319-7E1E-4188-936B-8DF3331230B3}.Release|ARM64.ActiveCfg = Release|ARM64 - {274C0319-7E1E-4188-936B-8DF3331230B3}.Release|ARM64.Build.0 = Release|ARM64 - {274C0319-7E1E-4188-936B-8DF3331230B3}.Release|x64.ActiveCfg = Release|x64 - {274C0319-7E1E-4188-936B-8DF3331230B3}.Release|x64.Build.0 = Release|x64 - {274C0319-7E1E-4188-936B-8DF3331230B3}.Release|x86.ActiveCfg = Release|Win32 - {274C0319-7E1E-4188-936B-8DF3331230B3}.Release|x86.Build.0 = Release|Win32 - {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Debug|ARM64.Build.0 = Debug|ARM64 - {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Debug|x64.ActiveCfg = Debug|x64 - {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Debug|x64.Build.0 = Debug|x64 - {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Debug|x86.ActiveCfg = Debug|Win32 - {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Debug|x86.Build.0 = Debug|Win32 - {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Release|ARM64.ActiveCfg = Release|ARM64 - {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Release|ARM64.Build.0 = Release|ARM64 - {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Release|x64.ActiveCfg = Release|x64 - {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Release|x64.Build.0 = Release|x64 - {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Release|x86.ActiveCfg = Release|Win32 - {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Release|x86.Build.0 = Release|Win32 - {600C3D4F-0670-4DB4-B30F-520A729053B5}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {600C3D4F-0670-4DB4-B30F-520A729053B5}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {600C3D4F-0670-4DB4-B30F-520A729053B5}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {600C3D4F-0670-4DB4-B30F-520A729053B5}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {600C3D4F-0670-4DB4-B30F-520A729053B5}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {600C3D4F-0670-4DB4-B30F-520A729053B5}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {600C3D4F-0670-4DB4-B30F-520A729053B5}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {600C3D4F-0670-4DB4-B30F-520A729053B5}.Debug|ARM64.Build.0 = Debug|ARM64 - {600C3D4F-0670-4DB4-B30F-520A729053B5}.Debug|x64.ActiveCfg = Debug|x64 - {600C3D4F-0670-4DB4-B30F-520A729053B5}.Debug|x64.Build.0 = Debug|x64 - {600C3D4F-0670-4DB4-B30F-520A729053B5}.Debug|x86.ActiveCfg = Debug|Win32 - {600C3D4F-0670-4DB4-B30F-520A729053B5}.Debug|x86.Build.0 = Debug|Win32 - {600C3D4F-0670-4DB4-B30F-520A729053B5}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {600C3D4F-0670-4DB4-B30F-520A729053B5}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {600C3D4F-0670-4DB4-B30F-520A729053B5}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {600C3D4F-0670-4DB4-B30F-520A729053B5}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {600C3D4F-0670-4DB4-B30F-520A729053B5}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {600C3D4F-0670-4DB4-B30F-520A729053B5}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {600C3D4F-0670-4DB4-B30F-520A729053B5}.Release|ARM64.ActiveCfg = Release|ARM64 - {600C3D4F-0670-4DB4-B30F-520A729053B5}.Release|ARM64.Build.0 = Release|ARM64 - {600C3D4F-0670-4DB4-B30F-520A729053B5}.Release|x64.ActiveCfg = Release|x64 - {600C3D4F-0670-4DB4-B30F-520A729053B5}.Release|x64.Build.0 = Release|x64 - {600C3D4F-0670-4DB4-B30F-520A729053B5}.Release|x86.ActiveCfg = Release|Win32 - {600C3D4F-0670-4DB4-B30F-520A729053B5}.Release|x86.Build.0 = Release|Win32 - {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Debug|ARM64.Build.0 = Debug|ARM64 - {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Debug|x64.ActiveCfg = Debug|x64 - {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Debug|x64.Build.0 = Debug|x64 - {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Debug|x86.ActiveCfg = Debug|Win32 - {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Debug|x86.Build.0 = Debug|Win32 - {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Release|ARM64.ActiveCfg = Release|ARM64 - {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Release|ARM64.Build.0 = Release|ARM64 - {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Release|x64.ActiveCfg = Release|x64 - {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Release|x64.Build.0 = Release|x64 - {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Release|x86.ActiveCfg = Release|Win32 - {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Release|x86.Build.0 = Release|Win32 - {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Debug|ARM64.Build.0 = Debug|ARM64 - {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Debug|x64.ActiveCfg = Debug|x64 - {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Debug|x64.Build.0 = Debug|x64 - {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Debug|x86.ActiveCfg = Debug|Win32 - {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Debug|x86.Build.0 = Debug|Win32 - {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Release|ARM64.ActiveCfg = Release|ARM64 - {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Release|ARM64.Build.0 = Release|ARM64 - {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Release|x64.ActiveCfg = Release|x64 - {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Release|x64.Build.0 = Release|x64 - {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Release|x86.ActiveCfg = Release|Win32 - {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Release|x86.Build.0 = Release|Win32 - {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Debug|ARM64.Build.0 = Debug|ARM64 - {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Debug|x64.ActiveCfg = Debug|x64 - {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Debug|x64.Build.0 = Debug|x64 - {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Debug|x86.ActiveCfg = Debug|Win32 - {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Debug|x86.Build.0 = Debug|Win32 - {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Release|ARM64.ActiveCfg = Release|ARM64 - {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Release|ARM64.Build.0 = Release|ARM64 - {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Release|x64.ActiveCfg = Release|x64 - {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Release|x64.Build.0 = Release|x64 - {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Release|x86.ActiveCfg = Release|Win32 - {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Release|x86.Build.0 = Release|Win32 - {FDE6080B-E203-4066-910D-AD0302566008}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {FDE6080B-E203-4066-910D-AD0302566008}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {FDE6080B-E203-4066-910D-AD0302566008}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {FDE6080B-E203-4066-910D-AD0302566008}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {FDE6080B-E203-4066-910D-AD0302566008}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {FDE6080B-E203-4066-910D-AD0302566008}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {FDE6080B-E203-4066-910D-AD0302566008}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {FDE6080B-E203-4066-910D-AD0302566008}.Debug|ARM64.Build.0 = Debug|ARM64 - {FDE6080B-E203-4066-910D-AD0302566008}.Debug|x64.ActiveCfg = Debug|x64 - {FDE6080B-E203-4066-910D-AD0302566008}.Debug|x64.Build.0 = Debug|x64 - {FDE6080B-E203-4066-910D-AD0302566008}.Debug|x86.ActiveCfg = Debug|Win32 - {FDE6080B-E203-4066-910D-AD0302566008}.Debug|x86.Build.0 = Debug|Win32 - {FDE6080B-E203-4066-910D-AD0302566008}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {FDE6080B-E203-4066-910D-AD0302566008}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {FDE6080B-E203-4066-910D-AD0302566008}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {FDE6080B-E203-4066-910D-AD0302566008}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {FDE6080B-E203-4066-910D-AD0302566008}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {FDE6080B-E203-4066-910D-AD0302566008}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {FDE6080B-E203-4066-910D-AD0302566008}.Release|ARM64.ActiveCfg = Release|ARM64 - {FDE6080B-E203-4066-910D-AD0302566008}.Release|ARM64.Build.0 = Release|ARM64 - {FDE6080B-E203-4066-910D-AD0302566008}.Release|x64.ActiveCfg = Release|x64 - {FDE6080B-E203-4066-910D-AD0302566008}.Release|x64.Build.0 = Release|x64 - {FDE6080B-E203-4066-910D-AD0302566008}.Release|x86.ActiveCfg = Release|Win32 - {FDE6080B-E203-4066-910D-AD0302566008}.Release|x86.Build.0 = Release|Win32 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug|ARM64.Build.0 = Debug|ARM64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug|x64.ActiveCfg = Debug|x64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug|x64.Build.0 = Debug|x64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug|x86.ActiveCfg = Debug|Win32 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug|x86.Build.0 = Debug|Win32 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release|ARM64.ActiveCfg = Release|ARM64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release|ARM64.Build.0 = Release|ARM64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release|x64.ActiveCfg = Release|x64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release|x64.Build.0 = Release|x64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release|x86.ActiveCfg = Release|Win32 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release|x86.Build.0 = Release|Win32 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug|ARM64.Build.0 = Debug|ARM64 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug|x64.ActiveCfg = Debug|x64 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug|x64.Build.0 = Debug|x64 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug|x86.ActiveCfg = Debug|Win32 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug|x86.Build.0 = Debug|Win32 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release|ARM64.ActiveCfg = Release|ARM64 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release|ARM64.Build.0 = Release|ARM64 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release|x64.ActiveCfg = Release|x64 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release|x64.Build.0 = Release|x64 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release|x86.ActiveCfg = Release|Win32 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release|x86.Build.0 = Release|Win32 - {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug|ARM64.Build.0 = Debug|ARM64 - {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug|x64.ActiveCfg = Debug|x64 - {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug|x64.Build.0 = Debug|x64 - {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug|x86.ActiveCfg = Debug|Win32 - {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug|x86.Build.0 = Debug|Win32 - {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release|ARM64.ActiveCfg = Release|ARM64 - {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release|ARM64.Build.0 = Release|ARM64 - {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release|x64.ActiveCfg = Release|x64 - {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release|x64.Build.0 = Release|x64 - {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release|x86.ActiveCfg = Release|Win32 - {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release|x86.Build.0 = Release|Win32 - {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug|ARM64.Build.0 = Debug|ARM64 - {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug|x64.ActiveCfg = Debug|x64 - {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug|x64.Build.0 = Debug|x64 - {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug|x86.ActiveCfg = Debug|Win32 - {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug|x86.Build.0 = Debug|Win32 - {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release|ARM64.ActiveCfg = Release|ARM64 - {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release|ARM64.Build.0 = Release|ARM64 - {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release|x64.ActiveCfg = Release|x64 - {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release|x64.Build.0 = Release|x64 - {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release|x86.ActiveCfg = Release|Win32 - {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release|x86.Build.0 = Release|Win32 - {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Debug|ARM64.Build.0 = Debug|ARM64 - {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Debug|x64.ActiveCfg = Debug|x64 - {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Debug|x64.Build.0 = Debug|x64 - {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Debug|x86.ActiveCfg = Debug|Win32 - {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Debug|x86.Build.0 = Debug|Win32 - {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Release|ARM64.ActiveCfg = Release|ARM64 - {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Release|ARM64.Build.0 = Release|ARM64 - {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Release|x64.ActiveCfg = Release|x64 - {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Release|x64.Build.0 = Release|x64 - {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Release|x86.ActiveCfg = Release|Win32 - {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Release|x86.Build.0 = Release|Win32 - {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Debug|ARM64.Build.0 = Debug|ARM64 - {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Debug|x64.ActiveCfg = Debug|x64 - {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Debug|x64.Build.0 = Debug|x64 - {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Debug|x86.ActiveCfg = Debug|Win32 - {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Debug|x86.Build.0 = Debug|Win32 - {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Release|ARM64.ActiveCfg = Release|ARM64 - {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Release|ARM64.Build.0 = Release|ARM64 - {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Release|x64.ActiveCfg = Release|x64 - {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Release|x64.Build.0 = Release|x64 - {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Release|x86.ActiveCfg = Release|Win32 - {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Release|x86.Build.0 = Release|Win32 - {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Debug|ARM64.Build.0 = Debug|ARM64 - {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Debug|x64.ActiveCfg = Debug|x64 - {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Debug|x64.Build.0 = Debug|x64 - {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Debug|x86.ActiveCfg = Debug|Win32 - {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Debug|x86.Build.0 = Debug|Win32 - {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Release|ARM64.ActiveCfg = Release|ARM64 - {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Release|ARM64.Build.0 = Release|ARM64 - {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Release|x64.ActiveCfg = Release|x64 - {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Release|x64.Build.0 = Release|x64 - {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Release|x86.ActiveCfg = Release|Win32 - {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Release|x86.Build.0 = Release|Win32 - {191A5289-BA65-4638-A215-C521F0187313}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {191A5289-BA65-4638-A215-C521F0187313}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {191A5289-BA65-4638-A215-C521F0187313}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {191A5289-BA65-4638-A215-C521F0187313}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {191A5289-BA65-4638-A215-C521F0187313}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {191A5289-BA65-4638-A215-C521F0187313}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {191A5289-BA65-4638-A215-C521F0187313}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {191A5289-BA65-4638-A215-C521F0187313}.Debug|ARM64.Build.0 = Debug|ARM64 - {191A5289-BA65-4638-A215-C521F0187313}.Debug|x64.ActiveCfg = Debug|x64 - {191A5289-BA65-4638-A215-C521F0187313}.Debug|x64.Build.0 = Debug|x64 - {191A5289-BA65-4638-A215-C521F0187313}.Debug|x86.ActiveCfg = Debug|Win32 - {191A5289-BA65-4638-A215-C521F0187313}.Debug|x86.Build.0 = Debug|Win32 - {191A5289-BA65-4638-A215-C521F0187313}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {191A5289-BA65-4638-A215-C521F0187313}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {191A5289-BA65-4638-A215-C521F0187313}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {191A5289-BA65-4638-A215-C521F0187313}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {191A5289-BA65-4638-A215-C521F0187313}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {191A5289-BA65-4638-A215-C521F0187313}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {191A5289-BA65-4638-A215-C521F0187313}.Release|ARM64.ActiveCfg = Release|ARM64 - {191A5289-BA65-4638-A215-C521F0187313}.Release|ARM64.Build.0 = Release|ARM64 - {191A5289-BA65-4638-A215-C521F0187313}.Release|x64.ActiveCfg = Release|x64 - {191A5289-BA65-4638-A215-C521F0187313}.Release|x64.Build.0 = Release|x64 - {191A5289-BA65-4638-A215-C521F0187313}.Release|x86.ActiveCfg = Release|Win32 - {191A5289-BA65-4638-A215-C521F0187313}.Release|x86.Build.0 = Release|Win32 - {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Debug|ARM64.Build.0 = Debug|ARM64 - {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Debug|x64.ActiveCfg = Debug|x64 - {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Debug|x64.Build.0 = Debug|x64 - {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Debug|x86.ActiveCfg = Debug|Win32 - {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Debug|x86.Build.0 = Debug|Win32 - {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Release|ARM64.ActiveCfg = Release|ARM64 - {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Release|ARM64.Build.0 = Release|ARM64 - {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Release|x64.ActiveCfg = Release|x64 - {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Release|x64.Build.0 = Release|x64 - {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Release|x86.ActiveCfg = Release|Win32 - {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Release|x86.Build.0 = Release|Win32 - {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Debug|ARM64.Build.0 = Debug|ARM64 - {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Debug|x64.ActiveCfg = Debug|x64 - {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Debug|x64.Build.0 = Debug|x64 - {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Debug|x86.ActiveCfg = Debug|Win32 - {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Debug|x86.Build.0 = Debug|Win32 - {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Release|ARM64.ActiveCfg = Release|ARM64 - {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Release|ARM64.Build.0 = Release|ARM64 - {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Release|x64.ActiveCfg = Release|x64 - {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Release|x64.Build.0 = Release|x64 - {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Release|x86.ActiveCfg = Release|Win32 - {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Release|x86.Build.0 = Release|Win32 - {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Debug|ARM64.Build.0 = Debug|ARM64 - {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Debug|x64.ActiveCfg = Debug|x64 - {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Debug|x64.Build.0 = Debug|x64 - {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Debug|x86.ActiveCfg = Debug|Win32 - {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Debug|x86.Build.0 = Debug|Win32 - {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Release|ARM64.ActiveCfg = Release|ARM64 - {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Release|ARM64.Build.0 = Release|ARM64 - {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Release|x64.ActiveCfg = Release|x64 - {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Release|x64.Build.0 = Release|x64 - {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Release|x86.ActiveCfg = Release|Win32 - {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Release|x86.Build.0 = Release|Win32 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug|ARM64.Build.0 = Debug|ARM64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug|x64.ActiveCfg = Debug|x64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug|x64.Build.0 = Debug|x64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug|x86.ActiveCfg = Debug|Win32 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug|x86.Build.0 = Debug|Win32 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release|ARM64.ActiveCfg = Release|ARM64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release|ARM64.Build.0 = Release|ARM64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release|x64.ActiveCfg = Release|x64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release|x64.Build.0 = Release|x64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release|x86.ActiveCfg = Release|Win32 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release|x86.Build.0 = Release|Win32 - {27B110CC-43C0-400A-89D9-245E681647D7}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {27B110CC-43C0-400A-89D9-245E681647D7}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {27B110CC-43C0-400A-89D9-245E681647D7}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {27B110CC-43C0-400A-89D9-245E681647D7}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {27B110CC-43C0-400A-89D9-245E681647D7}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {27B110CC-43C0-400A-89D9-245E681647D7}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {27B110CC-43C0-400A-89D9-245E681647D7}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {27B110CC-43C0-400A-89D9-245E681647D7}.Debug|ARM64.Build.0 = Debug|ARM64 - {27B110CC-43C0-400A-89D9-245E681647D7}.Debug|x64.ActiveCfg = Debug|x64 - {27B110CC-43C0-400A-89D9-245E681647D7}.Debug|x64.Build.0 = Debug|x64 - {27B110CC-43C0-400A-89D9-245E681647D7}.Debug|x86.ActiveCfg = Debug|Win32 - {27B110CC-43C0-400A-89D9-245E681647D7}.Debug|x86.Build.0 = Debug|Win32 - {27B110CC-43C0-400A-89D9-245E681647D7}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {27B110CC-43C0-400A-89D9-245E681647D7}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {27B110CC-43C0-400A-89D9-245E681647D7}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {27B110CC-43C0-400A-89D9-245E681647D7}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {27B110CC-43C0-400A-89D9-245E681647D7}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {27B110CC-43C0-400A-89D9-245E681647D7}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {27B110CC-43C0-400A-89D9-245E681647D7}.Release|ARM64.ActiveCfg = Release|ARM64 - {27B110CC-43C0-400A-89D9-245E681647D7}.Release|ARM64.Build.0 = Release|ARM64 - {27B110CC-43C0-400A-89D9-245E681647D7}.Release|x64.ActiveCfg = Release|x64 - {27B110CC-43C0-400A-89D9-245E681647D7}.Release|x64.Build.0 = Release|x64 - {27B110CC-43C0-400A-89D9-245E681647D7}.Release|x86.ActiveCfg = Release|Win32 - {27B110CC-43C0-400A-89D9-245E681647D7}.Release|x86.Build.0 = Release|Win32 - {1DE84812-E143-4C4B-A61D-9267AAD55401}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {1DE84812-E143-4C4B-A61D-9267AAD55401}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {1DE84812-E143-4C4B-A61D-9267AAD55401}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {1DE84812-E143-4C4B-A61D-9267AAD55401}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {1DE84812-E143-4C4B-A61D-9267AAD55401}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {1DE84812-E143-4C4B-A61D-9267AAD55401}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {1DE84812-E143-4C4B-A61D-9267AAD55401}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {1DE84812-E143-4C4B-A61D-9267AAD55401}.Debug|ARM64.Build.0 = Debug|ARM64 - {1DE84812-E143-4C4B-A61D-9267AAD55401}.Debug|x64.ActiveCfg = Debug|x64 - {1DE84812-E143-4C4B-A61D-9267AAD55401}.Debug|x64.Build.0 = Debug|x64 - {1DE84812-E143-4C4B-A61D-9267AAD55401}.Debug|x86.ActiveCfg = Debug|Win32 - {1DE84812-E143-4C4B-A61D-9267AAD55401}.Debug|x86.Build.0 = Debug|Win32 - {1DE84812-E143-4C4B-A61D-9267AAD55401}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {1DE84812-E143-4C4B-A61D-9267AAD55401}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {1DE84812-E143-4C4B-A61D-9267AAD55401}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {1DE84812-E143-4C4B-A61D-9267AAD55401}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {1DE84812-E143-4C4B-A61D-9267AAD55401}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {1DE84812-E143-4C4B-A61D-9267AAD55401}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {1DE84812-E143-4C4B-A61D-9267AAD55401}.Release|ARM64.ActiveCfg = Release|ARM64 - {1DE84812-E143-4C4B-A61D-9267AAD55401}.Release|ARM64.Build.0 = Release|ARM64 - {1DE84812-E143-4C4B-A61D-9267AAD55401}.Release|x64.ActiveCfg = Release|x64 - {1DE84812-E143-4C4B-A61D-9267AAD55401}.Release|x64.Build.0 = Release|x64 - {1DE84812-E143-4C4B-A61D-9267AAD55401}.Release|x86.ActiveCfg = Release|Win32 - {1DE84812-E143-4C4B-A61D-9267AAD55401}.Release|x86.Build.0 = Release|Win32 - {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Debug|ARM64.Build.0 = Debug|ARM64 - {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Debug|x64.ActiveCfg = Debug|x64 - {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Debug|x64.Build.0 = Debug|x64 - {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Debug|x86.ActiveCfg = Debug|Win32 - {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Debug|x86.Build.0 = Debug|Win32 - {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Release|ARM64.ActiveCfg = Release|ARM64 - {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Release|ARM64.Build.0 = Release|ARM64 - {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Release|x64.ActiveCfg = Release|x64 - {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Release|x64.Build.0 = Release|x64 - {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Release|x86.ActiveCfg = Release|Win32 - {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Release|x86.Build.0 = Release|Win32 - {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Debug|ARM64.Build.0 = Debug|ARM64 - {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Debug|x64.ActiveCfg = Debug|x64 - {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Debug|x64.Build.0 = Debug|x64 - {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Debug|x86.ActiveCfg = Debug|Win32 - {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Debug|x86.Build.0 = Debug|Win32 - {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Release|ARM64.ActiveCfg = Release|ARM64 - {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Release|ARM64.Build.0 = Release|ARM64 - {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Release|x64.ActiveCfg = Release|x64 - {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Release|x64.Build.0 = Release|x64 - {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Release|x86.ActiveCfg = Release|Win32 - {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Release|x86.Build.0 = Release|Win32 - {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Debug|ARM64.Build.0 = Debug|ARM64 - {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Debug|x64.ActiveCfg = Debug|x64 - {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Debug|x64.Build.0 = Debug|x64 - {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Debug|x86.ActiveCfg = Debug|Win32 - {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Debug|x86.Build.0 = Debug|Win32 - {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Release|ARM64.ActiveCfg = Release|ARM64 - {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Release|ARM64.Build.0 = Release|ARM64 - {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Release|x64.ActiveCfg = Release|x64 - {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Release|x64.Build.0 = Release|x64 - {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Release|x86.ActiveCfg = Release|Win32 - {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Release|x86.Build.0 = Release|Win32 - {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Debug|ARM64.Build.0 = Debug|ARM64 - {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Debug|x64.ActiveCfg = Debug|x64 - {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Debug|x64.Build.0 = Debug|x64 - {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Debug|x86.ActiveCfg = Debug|Win32 - {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Debug|x86.Build.0 = Debug|Win32 - {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Release|ARM64.ActiveCfg = Release|ARM64 - {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Release|ARM64.Build.0 = Release|ARM64 - {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Release|x64.ActiveCfg = Release|x64 - {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Release|x64.Build.0 = Release|x64 - {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Release|x86.ActiveCfg = Release|Win32 - {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Release|x86.Build.0 = Release|Win32 - {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Debug|ARM64.Build.0 = Debug|ARM64 - {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Debug|x64.ActiveCfg = Debug|x64 - {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Debug|x64.Build.0 = Debug|x64 - {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Debug|x86.ActiveCfg = Debug|Win32 - {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Debug|x86.Build.0 = Debug|Win32 - {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Release|ARM64.ActiveCfg = Release|ARM64 - {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Release|ARM64.Build.0 = Release|ARM64 - {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Release|x64.ActiveCfg = Release|x64 - {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Release|x64.Build.0 = Release|x64 - {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Release|x86.ActiveCfg = Release|Win32 - {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Release|x86.Build.0 = Release|Win32 - {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Debug|ARM64.Build.0 = Debug|ARM64 - {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Debug|x64.ActiveCfg = Debug|x64 - {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Debug|x64.Build.0 = Debug|x64 - {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Debug|x86.ActiveCfg = Debug|Win32 - {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Debug|x86.Build.0 = Debug|Win32 - {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Release|ARM64.ActiveCfg = Release|ARM64 - {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Release|ARM64.Build.0 = Release|ARM64 - {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Release|x64.ActiveCfg = Release|x64 - {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Release|x64.Build.0 = Release|x64 - {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Release|x86.ActiveCfg = Release|Win32 - {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Release|x86.Build.0 = Release|Win32 - {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Debug|ARM64.Build.0 = Debug|ARM64 - {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Debug|x64.ActiveCfg = Debug|x64 - {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Debug|x64.Build.0 = Debug|x64 - {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Debug|x86.ActiveCfg = Debug|Win32 - {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Debug|x86.Build.0 = Debug|Win32 - {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Release|ARM64.ActiveCfg = Release|ARM64 - {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Release|ARM64.Build.0 = Release|ARM64 - {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Release|x64.ActiveCfg = Release|x64 - {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Release|x64.Build.0 = Release|x64 - {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Release|x86.ActiveCfg = Release|Win32 - {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Release|x86.Build.0 = Release|Win32 - {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug|ARM64.Build.0 = Debug|ARM64 - {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug|x64.ActiveCfg = Debug|x64 - {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug|x64.Build.0 = Debug|x64 - {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug|x86.ActiveCfg = Debug|Win32 - {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug|x86.Build.0 = Debug|Win32 - {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release|ARM64.ActiveCfg = Release|ARM64 - {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release|ARM64.Build.0 = Release|ARM64 - {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release|x64.ActiveCfg = Release|x64 - {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release|x64.Build.0 = Release|x64 - {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release|x86.ActiveCfg = Release|Win32 - {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release|x86.Build.0 = Release|Win32 - {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug|ARM64.Build.0 = Debug|ARM64 - {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug|x64.ActiveCfg = Debug|x64 - {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug|x64.Build.0 = Debug|x64 - {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug|x86.ActiveCfg = Debug|Win32 - {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug|x86.Build.0 = Debug|Win32 - {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release|ARM64.ActiveCfg = Release|ARM64 - {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release|ARM64.Build.0 = Release|ARM64 - {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release|x64.ActiveCfg = Release|x64 - {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release|x64.Build.0 = Release|x64 - {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release|x86.ActiveCfg = Release|Win32 - {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release|x86.Build.0 = Release|Win32 - {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug|ARM64.Build.0 = Debug|ARM64 - {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug|x64.ActiveCfg = Debug|x64 - {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug|x64.Build.0 = Debug|x64 - {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug|x86.ActiveCfg = Debug|Win32 - {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug|x86.Build.0 = Debug|Win32 - {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release|ARM64.ActiveCfg = Release|ARM64 - {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release|ARM64.Build.0 = Release|ARM64 - {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release|x64.ActiveCfg = Release|x64 - {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release|x64.Build.0 = Release|x64 - {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release|x86.ActiveCfg = Release|Win32 - {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release|x86.Build.0 = Release|Win32 - {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug|ARM64.Build.0 = Debug|ARM64 - {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug|x64.ActiveCfg = Debug|x64 - {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug|x64.Build.0 = Debug|x64 - {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug|x86.ActiveCfg = Debug|Win32 - {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug|x86.Build.0 = Debug|Win32 - {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release|ARM64.ActiveCfg = Release|ARM64 - {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release|ARM64.Build.0 = Release|ARM64 - {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release|x64.ActiveCfg = Release|x64 - {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release|x64.Build.0 = Release|x64 - {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release|x86.ActiveCfg = Release|Win32 - {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release|x86.Build.0 = Release|Win32 - {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug|ARM64.Build.0 = Debug|ARM64 - {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug|x64.ActiveCfg = Debug|x64 - {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug|x64.Build.0 = Debug|x64 - {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug|x86.ActiveCfg = Debug|Win32 - {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug|x86.Build.0 = Debug|Win32 - {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release|ARM64.ActiveCfg = Release|ARM64 - {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release|ARM64.Build.0 = Release|ARM64 - {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release|x64.ActiveCfg = Release|x64 - {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release|x64.Build.0 = Release|x64 - {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release|x86.ActiveCfg = Release|Win32 - {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release|x86.Build.0 = Release|Win32 - {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug|ARM64.Build.0 = Debug|ARM64 - {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug|x64.ActiveCfg = Debug|x64 - {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug|x64.Build.0 = Debug|x64 - {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug|x86.ActiveCfg = Debug|Win32 - {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug|x86.Build.0 = Debug|Win32 - {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release|ARM64.ActiveCfg = Release|ARM64 - {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release|ARM64.Build.0 = Release|ARM64 - {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release|x64.ActiveCfg = Release|x64 - {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release|x64.Build.0 = Release|x64 - {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release|x86.ActiveCfg = Release|Win32 - {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release|x86.Build.0 = Release|Win32 - {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug|ARM64.Build.0 = Debug|ARM64 - {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug|x64.ActiveCfg = Debug|x64 - {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug|x64.Build.0 = Debug|x64 - {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug|x86.ActiveCfg = Debug|Win32 - {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug|x86.Build.0 = Debug|Win32 - {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release|ARM64.ActiveCfg = Release|ARM64 - {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release|ARM64.Build.0 = Release|ARM64 - {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release|x64.ActiveCfg = Release|x64 - {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release|x64.Build.0 = Release|x64 - {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release|x86.ActiveCfg = Release|Win32 - {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release|x86.Build.0 = Release|Win32 - {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug|ARM64.Build.0 = Debug|ARM64 - {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug|x64.ActiveCfg = Debug|x64 - {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug|x64.Build.0 = Debug|x64 - {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug|x86.ActiveCfg = Debug|Win32 - {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug|x86.Build.0 = Debug|Win32 - {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release|ARM64.ActiveCfg = Release|ARM64 - {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release|ARM64.Build.0 = Release|ARM64 - {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release|x64.ActiveCfg = Release|x64 - {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release|x64.Build.0 = Release|x64 - {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release|x86.ActiveCfg = Release|Win32 - {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release|x86.Build.0 = Release|Win32 - {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug|ARM64.Build.0 = Debug|ARM64 - {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug|x64.ActiveCfg = Debug|x64 - {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug|x64.Build.0 = Debug|x64 - {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug|x86.ActiveCfg = Debug|Win32 - {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug|x86.Build.0 = Debug|Win32 - {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release|ARM64.ActiveCfg = Release|ARM64 - {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release|ARM64.Build.0 = Release|ARM64 - {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release|x64.ActiveCfg = Release|x64 - {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release|x64.Build.0 = Release|x64 - {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release|x86.ActiveCfg = Release|Win32 - {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release|x86.Build.0 = Release|Win32 - {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug|ARM64.Build.0 = Debug|ARM64 - {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug|x64.ActiveCfg = Debug|x64 - {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug|x64.Build.0 = Debug|x64 - {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug|x86.ActiveCfg = Debug|Win32 - {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug|x86.Build.0 = Debug|Win32 - {DF25E545-00FF-4E64-844C-7DF98991F901}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {DF25E545-00FF-4E64-844C-7DF98991F901}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {DF25E545-00FF-4E64-844C-7DF98991F901}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {DF25E545-00FF-4E64-844C-7DF98991F901}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {DF25E545-00FF-4E64-844C-7DF98991F901}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {DF25E545-00FF-4E64-844C-7DF98991F901}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {DF25E545-00FF-4E64-844C-7DF98991F901}.Release|ARM64.ActiveCfg = Release|ARM64 - {DF25E545-00FF-4E64-844C-7DF98991F901}.Release|ARM64.Build.0 = Release|ARM64 - {DF25E545-00FF-4E64-844C-7DF98991F901}.Release|x64.ActiveCfg = Release|x64 - {DF25E545-00FF-4E64-844C-7DF98991F901}.Release|x64.Build.0 = Release|x64 - {DF25E545-00FF-4E64-844C-7DF98991F901}.Release|x86.ActiveCfg = Release|Win32 - {DF25E545-00FF-4E64-844C-7DF98991F901}.Release|x86.Build.0 = Release|Win32 - {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug|ARM64.Build.0 = Debug|ARM64 - {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug|x64.ActiveCfg = Debug|x64 - {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug|x64.Build.0 = Debug|x64 - {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug|x86.ActiveCfg = Debug|Win32 - {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug|x86.Build.0 = Debug|Win32 - {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release|ARM64.ActiveCfg = Release|ARM64 - {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release|ARM64.Build.0 = Release|ARM64 - {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release|x64.ActiveCfg = Release|x64 - {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release|x64.Build.0 = Release|x64 - {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release|x86.ActiveCfg = Release|Win32 - {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release|x86.Build.0 = Release|Win32 - {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Debug|ARM64.Build.0 = Debug|ARM64 - {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Debug|x64.ActiveCfg = Debug|x64 - {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Debug|x64.Build.0 = Debug|x64 - {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Debug|x86.ActiveCfg = Debug|Win32 - {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Debug|x86.Build.0 = Debug|Win32 - {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Release|ARM64.ActiveCfg = Release|ARM64 - {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Release|ARM64.Build.0 = Release|ARM64 - {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Release|x64.ActiveCfg = Release|x64 - {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Release|x64.Build.0 = Release|x64 - {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Release|x86.ActiveCfg = Release|Win32 - {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Release|x86.Build.0 = Release|Win32 - {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug|ARM64.Build.0 = Debug|ARM64 - {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug|x64.ActiveCfg = Debug|x64 - {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug|x64.Build.0 = Debug|x64 - {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug|x86.ActiveCfg = Debug|Win32 - {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug|x86.Build.0 = Debug|Win32 - {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release|ARM64.ActiveCfg = Release|ARM64 - {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release|ARM64.Build.0 = Release|ARM64 - {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release|x64.ActiveCfg = Release|x64 - {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release|x64.Build.0 = Release|x64 - {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release|x86.ActiveCfg = Release|Win32 - {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release|x86.Build.0 = Release|Win32 - {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug|ARM64.Build.0 = Debug|ARM64 - {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug|x64.ActiveCfg = Debug|x64 - {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug|x64.Build.0 = Debug|x64 - {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug|x86.ActiveCfg = Debug|Win32 - {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug|x86.Build.0 = Debug|Win32 - {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release|ARM64.ActiveCfg = Release|ARM64 - {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release|ARM64.Build.0 = Release|ARM64 - {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release|x64.ActiveCfg = Release|x64 - {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release|x64.Build.0 = Release|x64 - {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release|x86.ActiveCfg = Release|Win32 - {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release|x86.Build.0 = Release|Win32 - {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Debug|ARM64.Build.0 = Debug|ARM64 - {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Debug|x64.ActiveCfg = Debug|x64 - {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Debug|x64.Build.0 = Debug|x64 - {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Debug|x86.ActiveCfg = Debug|Win32 - {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Debug|x86.Build.0 = Debug|Win32 - {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Release|ARM64.ActiveCfg = Release|ARM64 - {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Release|ARM64.Build.0 = Release|ARM64 - {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Release|x64.ActiveCfg = Release|x64 - {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Release|x64.Build.0 = Release|x64 - {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Release|x86.ActiveCfg = Release|Win32 - {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Release|x86.Build.0 = Release|Win32 - {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Debug|ARM64.Build.0 = Debug|ARM64 - {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Debug|x64.ActiveCfg = Debug|x64 - {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Debug|x64.Build.0 = Debug|x64 - {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Debug|x86.ActiveCfg = Debug|Win32 - {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Debug|x86.Build.0 = Debug|Win32 - {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Release|ARM64.ActiveCfg = Release|ARM64 - {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Release|ARM64.Build.0 = Release|ARM64 - {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Release|x64.ActiveCfg = Release|x64 - {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Release|x64.Build.0 = Release|x64 - {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Release|x86.ActiveCfg = Release|Win32 - {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Release|x86.Build.0 = Release|Win32 - {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug|ARM64.Build.0 = Debug|ARM64 - {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug|x64.ActiveCfg = Debug|x64 - {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug|x64.Build.0 = Debug|x64 - {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug|x86.ActiveCfg = Debug|Win32 - {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug|x86.Build.0 = Debug|Win32 - {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release|ARM64.ActiveCfg = Release|ARM64 - {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release|ARM64.Build.0 = Release|ARM64 - {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release|x64.ActiveCfg = Release|x64 - {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release|x64.Build.0 = Release|x64 - {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release|x86.ActiveCfg = Release|Win32 - {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release|x86.Build.0 = Release|Win32 - {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Debug|ARM64.Build.0 = Debug|ARM64 - {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Debug|x64.ActiveCfg = Debug|x64 - {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Debug|x64.Build.0 = Debug|x64 - {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Debug|x86.ActiveCfg = Debug|Win32 - {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Debug|x86.Build.0 = Debug|Win32 - {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Release|ARM64.ActiveCfg = Release|ARM64 - {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Release|ARM64.Build.0 = Release|ARM64 - {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Release|x64.ActiveCfg = Release|x64 - {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Release|x64.Build.0 = Release|x64 - {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Release|x86.ActiveCfg = Release|Win32 - {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Release|x86.Build.0 = Release|Win32 - {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Debug|ARM64.Build.0 = Debug|ARM64 - {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Debug|x64.ActiveCfg = Debug|x64 - {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Debug|x64.Build.0 = Debug|x64 - {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Debug|x86.ActiveCfg = Debug|Win32 - {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Debug|x86.Build.0 = Debug|Win32 - {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Release|ARM64.ActiveCfg = Release|ARM64 - {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Release|ARM64.Build.0 = Release|ARM64 - {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Release|x64.ActiveCfg = Release|x64 - {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Release|x64.Build.0 = Release|x64 - {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Release|x86.ActiveCfg = Release|Win32 - {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Release|x86.Build.0 = Release|Win32 - {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Debug|ARM64.Build.0 = Debug|ARM64 - {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Debug|x64.ActiveCfg = Debug|x64 - {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Debug|x64.Build.0 = Debug|x64 - {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Debug|x86.ActiveCfg = Debug|Win32 - {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Debug|x86.Build.0 = Debug|Win32 - {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Release|ARM64.ActiveCfg = Release|ARM64 - {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Release|ARM64.Build.0 = Release|ARM64 - {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Release|x64.ActiveCfg = Release|x64 - {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Release|x64.Build.0 = Release|x64 - {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Release|x86.ActiveCfg = Release|Win32 - {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Release|x86.Build.0 = Release|Win32 - {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Debug|ARM64.Build.0 = Debug|ARM64 - {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Debug|x64.ActiveCfg = Debug|x64 - {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Debug|x64.Build.0 = Debug|x64 - {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Debug|x86.ActiveCfg = Debug|Win32 - {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Debug|x86.Build.0 = Debug|Win32 - {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Release|ARM64.ActiveCfg = Release|ARM64 - {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Release|ARM64.Build.0 = Release|ARM64 - {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Release|x64.ActiveCfg = Release|x64 - {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Release|x64.Build.0 = Release|x64 - {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Release|x86.ActiveCfg = Release|Win32 - {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Release|x86.Build.0 = Release|Win32 - {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Debug|ARM64.Build.0 = Debug|ARM64 - {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Debug|x64.ActiveCfg = Debug|x64 - {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Debug|x64.Build.0 = Debug|x64 - {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Debug|x86.ActiveCfg = Debug|Win32 - {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Debug|x86.Build.0 = Debug|Win32 - {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Release|ARM64.ActiveCfg = Release|ARM64 - {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Release|ARM64.Build.0 = Release|ARM64 - {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Release|x64.ActiveCfg = Release|x64 - {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Release|x64.Build.0 = Release|x64 - {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Release|x86.ActiveCfg = Release|Win32 - {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Release|x86.Build.0 = Release|Win32 - {921391C6-7626-4212-9928-BC82BC785461}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {921391C6-7626-4212-9928-BC82BC785461}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {921391C6-7626-4212-9928-BC82BC785461}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {921391C6-7626-4212-9928-BC82BC785461}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {921391C6-7626-4212-9928-BC82BC785461}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {921391C6-7626-4212-9928-BC82BC785461}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {921391C6-7626-4212-9928-BC82BC785461}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {921391C6-7626-4212-9928-BC82BC785461}.Debug|ARM64.Build.0 = Debug|ARM64 - {921391C6-7626-4212-9928-BC82BC785461}.Debug|x64.ActiveCfg = Debug|x64 - {921391C6-7626-4212-9928-BC82BC785461}.Debug|x64.Build.0 = Debug|x64 - {921391C6-7626-4212-9928-BC82BC785461}.Debug|x86.ActiveCfg = Debug|Win32 - {921391C6-7626-4212-9928-BC82BC785461}.Debug|x86.Build.0 = Debug|Win32 - {921391C6-7626-4212-9928-BC82BC785461}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {921391C6-7626-4212-9928-BC82BC785461}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {921391C6-7626-4212-9928-BC82BC785461}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {921391C6-7626-4212-9928-BC82BC785461}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {921391C6-7626-4212-9928-BC82BC785461}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {921391C6-7626-4212-9928-BC82BC785461}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {921391C6-7626-4212-9928-BC82BC785461}.Release|ARM64.ActiveCfg = Release|ARM64 - {921391C6-7626-4212-9928-BC82BC785461}.Release|ARM64.Build.0 = Release|ARM64 - {921391C6-7626-4212-9928-BC82BC785461}.Release|x64.ActiveCfg = Release|x64 - {921391C6-7626-4212-9928-BC82BC785461}.Release|x64.Build.0 = Release|x64 - {921391C6-7626-4212-9928-BC82BC785461}.Release|x86.ActiveCfg = Release|Win32 - {921391C6-7626-4212-9928-BC82BC785461}.Release|x86.Build.0 = Release|Win32 - {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Debug|ARM64.Build.0 = Debug|ARM64 - {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Debug|x64.ActiveCfg = Debug|x64 - {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Debug|x64.Build.0 = Debug|x64 - {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Debug|x86.ActiveCfg = Debug|Win32 - {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Debug|x86.Build.0 = Debug|Win32 - {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Release|ARM64.ActiveCfg = Release|ARM64 - {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Release|ARM64.Build.0 = Release|ARM64 - {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Release|x64.ActiveCfg = Release|x64 - {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Release|x64.Build.0 = Release|x64 - {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Release|x86.ActiveCfg = Release|Win32 - {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Release|x86.Build.0 = Release|Win32 - {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Debug|ARM64.Build.0 = Debug|ARM64 - {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Debug|x64.ActiveCfg = Debug|x64 - {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Debug|x64.Build.0 = Debug|x64 - {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Debug|x86.ActiveCfg = Debug|Win32 - {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Debug|x86.Build.0 = Debug|Win32 - {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Release|ARM64.ActiveCfg = Release|ARM64 - {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Release|ARM64.Build.0 = Release|ARM64 - {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Release|x64.ActiveCfg = Release|x64 - {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Release|x64.Build.0 = Release|x64 - {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Release|x86.ActiveCfg = Release|Win32 - {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Release|x86.Build.0 = Release|Win32 - {C54703BF-D68A-480D-BE27-49B62E45D582}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {C54703BF-D68A-480D-BE27-49B62E45D582}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {C54703BF-D68A-480D-BE27-49B62E45D582}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {C54703BF-D68A-480D-BE27-49B62E45D582}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {C54703BF-D68A-480D-BE27-49B62E45D582}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {C54703BF-D68A-480D-BE27-49B62E45D582}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {C54703BF-D68A-480D-BE27-49B62E45D582}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {C54703BF-D68A-480D-BE27-49B62E45D582}.Debug|ARM64.Build.0 = Debug|ARM64 - {C54703BF-D68A-480D-BE27-49B62E45D582}.Debug|x64.ActiveCfg = Debug|x64 - {C54703BF-D68A-480D-BE27-49B62E45D582}.Debug|x64.Build.0 = Debug|x64 - {C54703BF-D68A-480D-BE27-49B62E45D582}.Debug|x86.ActiveCfg = Debug|Win32 - {C54703BF-D68A-480D-BE27-49B62E45D582}.Debug|x86.Build.0 = Debug|Win32 - {C54703BF-D68A-480D-BE27-49B62E45D582}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {C54703BF-D68A-480D-BE27-49B62E45D582}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {C54703BF-D68A-480D-BE27-49B62E45D582}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {C54703BF-D68A-480D-BE27-49B62E45D582}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {C54703BF-D68A-480D-BE27-49B62E45D582}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {C54703BF-D68A-480D-BE27-49B62E45D582}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {C54703BF-D68A-480D-BE27-49B62E45D582}.Release|ARM64.ActiveCfg = Release|ARM64 - {C54703BF-D68A-480D-BE27-49B62E45D582}.Release|ARM64.Build.0 = Release|ARM64 - {C54703BF-D68A-480D-BE27-49B62E45D582}.Release|x64.ActiveCfg = Release|x64 - {C54703BF-D68A-480D-BE27-49B62E45D582}.Release|x64.Build.0 = Release|x64 - {C54703BF-D68A-480D-BE27-49B62E45D582}.Release|x86.ActiveCfg = Release|Win32 - {C54703BF-D68A-480D-BE27-49B62E45D582}.Release|x86.Build.0 = Release|Win32 - {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Debug|ARM64.Build.0 = Debug|ARM64 - {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Debug|x64.ActiveCfg = Debug|x64 - {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Debug|x64.Build.0 = Debug|x64 - {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Debug|x86.ActiveCfg = Debug|Win32 - {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Debug|x86.Build.0 = Debug|Win32 - {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Release|ARM64.ActiveCfg = Release|ARM64 - {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Release|ARM64.Build.0 = Release|ARM64 - {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Release|x64.ActiveCfg = Release|x64 - {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Release|x64.Build.0 = Release|x64 - {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Release|x86.ActiveCfg = Release|Win32 - {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Release|x86.Build.0 = Release|Win32 - {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug|ARM64.Build.0 = Debug|ARM64 - {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug|x64.ActiveCfg = Debug|x64 - {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug|x64.Build.0 = Debug|x64 - {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug|x86.ActiveCfg = Debug|Win32 - {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug|x86.Build.0 = Debug|Win32 - {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release|ARM64.ActiveCfg = Release|ARM64 - {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release|ARM64.Build.0 = Release|ARM64 - {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release|x64.ActiveCfg = Release|x64 - {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release|x64.Build.0 = Release|x64 - {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release|x86.ActiveCfg = Release|Win32 - {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.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 - {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug|ARM64.Build.0 = Debug|ARM64 - {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug|x64.ActiveCfg = Debug|x64 - {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug|x64.Build.0 = Debug|x64 - {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug|x86.ActiveCfg = Debug|Win32 - {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug|x86.Build.0 = Debug|Win32 - {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release|ARM64.ActiveCfg = Release|ARM64 - {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release|ARM64.Build.0 = Release|ARM64 - {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release|x64.ActiveCfg = Release|x64 - {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release|x64.Build.0 = Release|x64 - {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release|x86.ActiveCfg = Release|Win32 - {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release|x86.Build.0 = Release|Win32 - {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug|ARM64.Build.0 = Debug|ARM64 - {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug|x64.ActiveCfg = Debug|x64 - {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug|x64.Build.0 = Debug|x64 - {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug|x86.ActiveCfg = Debug|Win32 - {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug|x86.Build.0 = Debug|Win32 - {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release|ARM64.ActiveCfg = Release|ARM64 - {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release|ARM64.Build.0 = Release|ARM64 - {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release|x64.ActiveCfg = Release|x64 - {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release|x64.Build.0 = Release|x64 - {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release|x86.ActiveCfg = Release|Win32 - {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release|x86.Build.0 = Release|Win32 - {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Debug|ARM64.Build.0 = Debug|ARM64 - {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Debug|x64.ActiveCfg = Debug|x64 - {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Debug|x64.Build.0 = Debug|x64 - {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Debug|x86.ActiveCfg = Debug|Win32 - {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Debug|x86.Build.0 = Debug|Win32 - {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Release|ARM64.ActiveCfg = Release|ARM64 - {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Release|ARM64.Build.0 = Release|ARM64 - {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Release|x64.ActiveCfg = Release|x64 - {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Release|x64.Build.0 = Release|x64 - {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Release|x86.ActiveCfg = Release|Win32 - {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Release|x86.Build.0 = Release|Win32 - {49C67F03-1A56-4F96-B278-39B66EC93678}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {49C67F03-1A56-4F96-B278-39B66EC93678}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {49C67F03-1A56-4F96-B278-39B66EC93678}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {49C67F03-1A56-4F96-B278-39B66EC93678}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {49C67F03-1A56-4F96-B278-39B66EC93678}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {49C67F03-1A56-4F96-B278-39B66EC93678}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {49C67F03-1A56-4F96-B278-39B66EC93678}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {49C67F03-1A56-4F96-B278-39B66EC93678}.Debug|ARM64.Build.0 = Debug|ARM64 - {49C67F03-1A56-4F96-B278-39B66EC93678}.Debug|x64.ActiveCfg = Debug|x64 - {49C67F03-1A56-4F96-B278-39B66EC93678}.Debug|x64.Build.0 = Debug|x64 - {49C67F03-1A56-4F96-B278-39B66EC93678}.Debug|x86.ActiveCfg = Debug|Win32 - {49C67F03-1A56-4F96-B278-39B66EC93678}.Debug|x86.Build.0 = Debug|Win32 - {49C67F03-1A56-4F96-B278-39B66EC93678}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {49C67F03-1A56-4F96-B278-39B66EC93678}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {49C67F03-1A56-4F96-B278-39B66EC93678}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {49C67F03-1A56-4F96-B278-39B66EC93678}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {49C67F03-1A56-4F96-B278-39B66EC93678}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {49C67F03-1A56-4F96-B278-39B66EC93678}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {49C67F03-1A56-4F96-B278-39B66EC93678}.Release|ARM64.ActiveCfg = Release|ARM64 - {49C67F03-1A56-4F96-B278-39B66EC93678}.Release|ARM64.Build.0 = Release|ARM64 - {49C67F03-1A56-4F96-B278-39B66EC93678}.Release|x64.ActiveCfg = Release|x64 - {49C67F03-1A56-4F96-B278-39B66EC93678}.Release|x64.Build.0 = Release|x64 - {49C67F03-1A56-4F96-B278-39B66EC93678}.Release|x86.ActiveCfg = Release|Win32 - {49C67F03-1A56-4F96-B278-39B66EC93678}.Release|x86.Build.0 = Release|Win32 - {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Debug|ARM64.Build.0 = Debug|ARM64 - {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Debug|x64.ActiveCfg = Debug|x64 - {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Debug|x64.Build.0 = Debug|x64 - {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Debug|x86.ActiveCfg = Debug|Win32 - {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Debug|x86.Build.0 = Debug|Win32 - {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Release|ARM64.ActiveCfg = Release|ARM64 - {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Release|ARM64.Build.0 = Release|ARM64 - {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Release|x64.ActiveCfg = Release|x64 - {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Release|x64.Build.0 = Release|x64 - {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Release|x86.ActiveCfg = Release|Win32 - {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Release|x86.Build.0 = Release|Win32 - {3B27F358-2679-4F38-B297-17B536F580BB}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {3B27F358-2679-4F38-B297-17B536F580BB}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {3B27F358-2679-4F38-B297-17B536F580BB}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {3B27F358-2679-4F38-B297-17B536F580BB}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {3B27F358-2679-4F38-B297-17B536F580BB}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {3B27F358-2679-4F38-B297-17B536F580BB}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {3B27F358-2679-4F38-B297-17B536F580BB}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {3B27F358-2679-4F38-B297-17B536F580BB}.Debug|ARM64.Build.0 = Debug|ARM64 - {3B27F358-2679-4F38-B297-17B536F580BB}.Debug|x64.ActiveCfg = Debug|x64 - {3B27F358-2679-4F38-B297-17B536F580BB}.Debug|x64.Build.0 = Debug|x64 - {3B27F358-2679-4F38-B297-17B536F580BB}.Debug|x86.ActiveCfg = Debug|Win32 - {3B27F358-2679-4F38-B297-17B536F580BB}.Debug|x86.Build.0 = Debug|Win32 - {3B27F358-2679-4F38-B297-17B536F580BB}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {3B27F358-2679-4F38-B297-17B536F580BB}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {3B27F358-2679-4F38-B297-17B536F580BB}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {3B27F358-2679-4F38-B297-17B536F580BB}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {3B27F358-2679-4F38-B297-17B536F580BB}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {3B27F358-2679-4F38-B297-17B536F580BB}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {3B27F358-2679-4F38-B297-17B536F580BB}.Release|ARM64.ActiveCfg = Release|ARM64 - {3B27F358-2679-4F38-B297-17B536F580BB}.Release|ARM64.Build.0 = Release|ARM64 - {3B27F358-2679-4F38-B297-17B536F580BB}.Release|x64.ActiveCfg = Release|x64 - {3B27F358-2679-4F38-B297-17B536F580BB}.Release|x64.Build.0 = Release|x64 - {3B27F358-2679-4F38-B297-17B536F580BB}.Release|x86.ActiveCfg = Release|Win32 - {3B27F358-2679-4F38-B297-17B536F580BB}.Release|x86.Build.0 = Release|Win32 - {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug|ARM64.Build.0 = Debug|ARM64 - {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug|x64.ActiveCfg = Debug|x64 - {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug|x64.Build.0 = Debug|x64 - {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug|x86.ActiveCfg = Debug|Win32 - {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug|x86.Build.0 = Debug|Win32 - {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release|ARM64.ActiveCfg = Release|ARM64 - {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release|ARM64.Build.0 = Release|ARM64 - {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release|x64.ActiveCfg = Release|x64 - {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release|x64.Build.0 = Release|x64 - {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release|x86.ActiveCfg = Release|Win32 - {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release|x86.Build.0 = Release|Win32 - {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug|ARM64.Build.0 = Debug|ARM64 - {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug|x64.ActiveCfg = Debug|x64 - {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug|x64.Build.0 = Debug|x64 - {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug|x86.ActiveCfg = Debug|Win32 - {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug|x86.Build.0 = Debug|Win32 - {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release|ARM64.ActiveCfg = Release|ARM64 - {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release|ARM64.Build.0 = Release|ARM64 - {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release|x64.ActiveCfg = Release|x64 - {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release|x64.Build.0 = Release|x64 - {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release|x86.ActiveCfg = Release|Win32 - {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release|x86.Build.0 = Release|Win32 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|ARM64.Build.0 = Debug|ARM64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|x64.ActiveCfg = Debug|x64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|x64.Build.0 = Debug|x64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|x86.ActiveCfg = Debug|Win32 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|x86.Build.0 = Debug|Win32 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|ARM64.ActiveCfg = Release|ARM64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|ARM64.Build.0 = Release|ARM64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|x64.ActiveCfg = Release|x64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|x64.Build.0 = Release|x64 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|x86.ActiveCfg = Release|Win32 - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|x86.Build.0 = Release|Win32 - {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug|ARM64.Build.0 = Debug|ARM64 - {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug|x64.ActiveCfg = Debug|x64 - {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug|x64.Build.0 = Debug|x64 - {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug|x86.ActiveCfg = Debug|Win32 - {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug|x86.Build.0 = Debug|Win32 - {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release|ARM64.ActiveCfg = Release|ARM64 - {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release|ARM64.Build.0 = Release|ARM64 - {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release|x64.ActiveCfg = Release|x64 - {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release|x64.Build.0 = Release|x64 - {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release|x86.ActiveCfg = Release|Win32 - {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release|x86.Build.0 = Release|Win32 - {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug|ARM64.Build.0 = Debug|ARM64 - {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug|x64.ActiveCfg = Debug|x64 - {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug|x64.Build.0 = Debug|x64 - {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug|x86.ActiveCfg = Debug|Win32 - {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug|x86.Build.0 = Debug|Win32 - {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release|ARM64.ActiveCfg = Release|ARM64 - {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release|ARM64.Build.0 = Release|ARM64 - {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release|x64.ActiveCfg = Release|x64 - {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release|x64.Build.0 = Release|x64 - {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release|x86.ActiveCfg = Release|Win32 - {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release|x86.Build.0 = Release|Win32 - {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug|ARM64.Build.0 = Debug|ARM64 - {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug|x64.ActiveCfg = Debug|x64 - {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug|x64.Build.0 = Debug|x64 - {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug|x86.ActiveCfg = Debug|Win32 - {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug|x86.Build.0 = Debug|Win32 - {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release|ARM64.ActiveCfg = Release|ARM64 - {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release|ARM64.Build.0 = Release|ARM64 - {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release|x64.ActiveCfg = Release|x64 - {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release|x64.Build.0 = Release|x64 - {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release|x86.ActiveCfg = Release|Win32 - {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release|x86.Build.0 = Release|Win32 - {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug|ARM64.Build.0 = Debug|ARM64 - {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug|x64.ActiveCfg = Debug|x64 - {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug|x64.Build.0 = Debug|x64 - {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug|x86.ActiveCfg = Debug|Win32 - {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug|x86.Build.0 = Debug|Win32 - {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release|ARM64.ActiveCfg = Release|ARM64 - {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release|ARM64.Build.0 = Release|ARM64 - {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release|x64.ActiveCfg = Release|x64 - {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release|x64.Build.0 = Release|x64 - {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release|x86.ActiveCfg = Release|Win32 - {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release|x86.Build.0 = Release|Win32 - {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug|ARM64.Build.0 = Debug|ARM64 - {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug|x64.ActiveCfg = Debug|x64 - {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug|x64.Build.0 = Debug|x64 - {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug|x86.ActiveCfg = Debug|Win32 - {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug|x86.Build.0 = Debug|Win32 - {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release|ARM64.ActiveCfg = Release|ARM64 - {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release|ARM64.Build.0 = Release|ARM64 - {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release|x64.ActiveCfg = Release|x64 - {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release|x64.Build.0 = Release|x64 - {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release|x86.ActiveCfg = Release|Win32 - {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release|x86.Build.0 = Release|Win32 - {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug|ARM64.Build.0 = Debug|ARM64 - {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug|x64.ActiveCfg = Debug|x64 - {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug|x64.Build.0 = Debug|x64 - {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug|x86.ActiveCfg = Debug|Win32 - {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug|x86.Build.0 = Debug|Win32 - {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release|ARM64.ActiveCfg = Release|ARM64 - {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release|ARM64.Build.0 = Release|ARM64 - {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release|x64.ActiveCfg = Release|x64 - {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release|x64.Build.0 = Release|x64 - {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release|x86.ActiveCfg = Release|Win32 - {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release|x86.Build.0 = Release|Win32 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug|ARM64.Build.0 = Debug|ARM64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug|x64.ActiveCfg = Debug|x64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug|x64.Build.0 = Debug|x64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug|x86.ActiveCfg = Debug|Win32 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug|x86.Build.0 = Debug|Win32 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release|ARM64.ActiveCfg = Release|ARM64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release|ARM64.Build.0 = Release|ARM64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release|x64.ActiveCfg = Release|x64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release|x64.Build.0 = Release|x64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release|x86.ActiveCfg = Release|Win32 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release|x86.Build.0 = Release|Win32 - {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug|ARM64.Build.0 = Debug|ARM64 - {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug|x64.ActiveCfg = Debug|x64 - {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug|x64.Build.0 = Debug|x64 - {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug|x86.ActiveCfg = Debug|Win32 - {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug|x86.Build.0 = Debug|Win32 - {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release|ARM64.ActiveCfg = Release|ARM64 - {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release|ARM64.Build.0 = Release|ARM64 - {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release|x64.ActiveCfg = Release|x64 - {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release|x64.Build.0 = Release|x64 - {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release|x86.ActiveCfg = Release|Win32 - {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release|x86.Build.0 = Release|Win32 - {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug|ARM64.Build.0 = Debug|ARM64 - {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug|x64.ActiveCfg = Debug|x64 - {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug|x64.Build.0 = Debug|x64 - {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug|x86.ActiveCfg = Debug|Win32 - {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug|x86.Build.0 = Debug|Win32 - {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release|ARM64.ActiveCfg = Release|ARM64 - {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release|ARM64.Build.0 = Release|ARM64 - {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release|x64.ActiveCfg = Release|x64 - {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release|x64.Build.0 = Release|x64 - {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release|x86.ActiveCfg = Release|Win32 - {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release|x86.Build.0 = Release|Win32 - {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug|ARM64.Build.0 = Debug|ARM64 - {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug|x64.ActiveCfg = Debug|x64 - {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug|x64.Build.0 = Debug|x64 - {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug|x86.ActiveCfg = Debug|Win32 - {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug|x86.Build.0 = Debug|Win32 - {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release|ARM64.ActiveCfg = Release|ARM64 - {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release|ARM64.Build.0 = Release|ARM64 - {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release|x64.ActiveCfg = Release|x64 - {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release|x64.Build.0 = Release|x64 - {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release|x86.ActiveCfg = Release|Win32 - {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release|x86.Build.0 = Release|Win32 - {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug|ARM64.Build.0 = Debug|ARM64 - {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug|x64.ActiveCfg = Debug|x64 - {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug|x64.Build.0 = Debug|x64 - {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug|x86.ActiveCfg = Debug|Win32 - {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug|x86.Build.0 = Debug|Win32 - {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release|ARM64.ActiveCfg = Release|ARM64 - {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release|ARM64.Build.0 = Release|ARM64 - {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release|x64.ActiveCfg = Release|x64 - {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release|x64.Build.0 = Release|x64 - {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release|x86.ActiveCfg = Release|Win32 - {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release|x86.Build.0 = Release|Win32 - {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug|ARM64.Build.0 = Debug|ARM64 - {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug|x64.ActiveCfg = Debug|x64 - {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug|x64.Build.0 = Debug|x64 - {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug|x86.ActiveCfg = Debug|Win32 - {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug|x86.Build.0 = Debug|Win32 - {7467E9AE-844F-444D-8A3F-17397544BA21}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {7467E9AE-844F-444D-8A3F-17397544BA21}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {7467E9AE-844F-444D-8A3F-17397544BA21}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {7467E9AE-844F-444D-8A3F-17397544BA21}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {7467E9AE-844F-444D-8A3F-17397544BA21}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {7467E9AE-844F-444D-8A3F-17397544BA21}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {7467E9AE-844F-444D-8A3F-17397544BA21}.Release|ARM64.ActiveCfg = Release|ARM64 - {7467E9AE-844F-444D-8A3F-17397544BA21}.Release|ARM64.Build.0 = Release|ARM64 - {7467E9AE-844F-444D-8A3F-17397544BA21}.Release|x64.ActiveCfg = Release|x64 - {7467E9AE-844F-444D-8A3F-17397544BA21}.Release|x64.Build.0 = Release|x64 - {7467E9AE-844F-444D-8A3F-17397544BA21}.Release|x86.ActiveCfg = Release|Win32 - {7467E9AE-844F-444D-8A3F-17397544BA21}.Release|x86.Build.0 = Release|Win32 - {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug|ARM64.Build.0 = Debug|ARM64 - {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug|x64.ActiveCfg = Debug|x64 - {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug|x64.Build.0 = Debug|x64 - {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug|x86.ActiveCfg = Debug|Win32 - {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug|x86.Build.0 = Debug|Win32 - {497FDF54-9762-4048-A833-61CC3980A0FB}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {497FDF54-9762-4048-A833-61CC3980A0FB}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {497FDF54-9762-4048-A833-61CC3980A0FB}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {497FDF54-9762-4048-A833-61CC3980A0FB}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {497FDF54-9762-4048-A833-61CC3980A0FB}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {497FDF54-9762-4048-A833-61CC3980A0FB}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {497FDF54-9762-4048-A833-61CC3980A0FB}.Release|ARM64.ActiveCfg = Release|ARM64 - {497FDF54-9762-4048-A833-61CC3980A0FB}.Release|ARM64.Build.0 = Release|ARM64 - {497FDF54-9762-4048-A833-61CC3980A0FB}.Release|x64.ActiveCfg = Release|x64 - {497FDF54-9762-4048-A833-61CC3980A0FB}.Release|x64.Build.0 = Release|x64 - {497FDF54-9762-4048-A833-61CC3980A0FB}.Release|x86.ActiveCfg = Release|Win32 - {497FDF54-9762-4048-A833-61CC3980A0FB}.Release|x86.Build.0 = Release|Win32 - {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug|ARM64.Build.0 = Debug|ARM64 - {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug|x64.ActiveCfg = Debug|x64 - {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug|x64.Build.0 = Debug|x64 - {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug|x86.ActiveCfg = Debug|Win32 - {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug|x86.Build.0 = Debug|Win32 - {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release|ARM64.ActiveCfg = Release|ARM64 - {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release|ARM64.Build.0 = Release|ARM64 - {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release|x64.ActiveCfg = Release|x64 - {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release|x64.Build.0 = Release|x64 - {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release|x86.ActiveCfg = Release|Win32 - {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release|x86.Build.0 = Release|Win32 - {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug|ARM64.Build.0 = Debug|ARM64 - {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug|x64.ActiveCfg = Debug|x64 - {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug|x64.Build.0 = Debug|x64 - {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug|x86.ActiveCfg = Debug|Win32 - {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug|x86.Build.0 = Debug|Win32 - {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release|ARM64.ActiveCfg = Release|ARM64 - {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release|ARM64.Build.0 = Release|ARM64 - {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release|x64.ActiveCfg = Release|x64 - {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release|x64.Build.0 = Release|x64 - {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release|x86.ActiveCfg = Release|Win32 - {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release|x86.Build.0 = Release|Win32 - {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug|ARM64.Build.0 = Debug|ARM64 - {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug|x64.ActiveCfg = Debug|x64 - {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug|x64.Build.0 = Debug|x64 - {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug|x86.ActiveCfg = Debug|Win32 - {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug|x86.Build.0 = Debug|Win32 - {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release|ARM64.ActiveCfg = Release|ARM64 - {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release|ARM64.Build.0 = Release|ARM64 - {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release|x64.ActiveCfg = Release|x64 - {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release|x64.Build.0 = Release|x64 - {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release|x86.ActiveCfg = Release|Win32 - {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release|x86.Build.0 = Release|Win32 - {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug|ARM64.Build.0 = Debug|ARM64 - {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug|x64.ActiveCfg = Debug|x64 - {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug|x64.Build.0 = Debug|x64 - {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug|x86.ActiveCfg = Debug|Win32 - {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug|x86.Build.0 = Debug|Win32 - {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release|ARM64.ActiveCfg = Release|ARM64 - {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release|ARM64.Build.0 = Release|ARM64 - {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release|x64.ActiveCfg = Release|x64 - {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release|x64.Build.0 = Release|x64 - {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release|x86.ActiveCfg = Release|Win32 - {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release|x86.Build.0 = Release|Win32 - {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug|ARM64.Build.0 = Debug|ARM64 - {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug|x64.ActiveCfg = Debug|x64 - {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug|x64.Build.0 = Debug|x64 - {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug|x86.ActiveCfg = Debug|Win32 - {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug|x86.Build.0 = Debug|Win32 - {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release|ARM64.ActiveCfg = Release|ARM64 - {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release|ARM64.Build.0 = Release|ARM64 - {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release|x64.ActiveCfg = Release|x64 - {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release|x64.Build.0 = Release|x64 - {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release|x86.ActiveCfg = Release|Win32 - {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release|x86.Build.0 = Release|Win32 - {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug|ARM64.Build.0 = Debug|ARM64 - {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug|x64.ActiveCfg = Debug|x64 - {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug|x64.Build.0 = Debug|x64 - {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug|x86.ActiveCfg = Debug|Win32 - {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug|x86.Build.0 = Debug|Win32 - {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release|ARM64.ActiveCfg = Release|ARM64 - {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release|ARM64.Build.0 = Release|ARM64 - {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release|x64.ActiveCfg = Release|x64 - {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release|x64.Build.0 = Release|x64 - {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release|x86.ActiveCfg = Release|Win32 - {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release|x86.Build.0 = Release|Win32 - {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug|ARM64.Build.0 = Debug|ARM64 - {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug|x64.ActiveCfg = Debug|x64 - {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug|x64.Build.0 = Debug|x64 - {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug|x86.ActiveCfg = Debug|Win32 - {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug|x86.Build.0 = Debug|Win32 - {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release|ARM64.ActiveCfg = Release|ARM64 - {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release|ARM64.Build.0 = Release|ARM64 - {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release|x64.ActiveCfg = Release|x64 - {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release|x64.Build.0 = Release|x64 - {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release|x86.ActiveCfg = Release|Win32 - {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release|x86.Build.0 = Release|Win32 - {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug|ARM64.Build.0 = Debug|ARM64 - {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug|x64.ActiveCfg = Debug|x64 - {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug|x64.Build.0 = Debug|x64 - {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug|x86.ActiveCfg = Debug|Win32 - {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug|x86.Build.0 = Debug|Win32 - {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release|ARM64.ActiveCfg = Release|ARM64 - {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release|ARM64.Build.0 = Release|ARM64 - {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release|x64.ActiveCfg = Release|x64 - {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release|x64.Build.0 = Release|x64 - {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release|x86.ActiveCfg = Release|Win32 - {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release|x86.Build.0 = Release|Win32 - {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug|ARM64.Build.0 = Debug|ARM64 - {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug|x64.ActiveCfg = Debug|x64 - {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug|x64.Build.0 = Debug|x64 - {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug|x86.ActiveCfg = Debug|Win32 - {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug|x86.Build.0 = Debug|Win32 - {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release|ARM64.ActiveCfg = Release|ARM64 - {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release|ARM64.Build.0 = Release|ARM64 - {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release|x64.ActiveCfg = Release|x64 - {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release|x64.Build.0 = Release|x64 - {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release|x86.ActiveCfg = Release|Win32 - {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release|x86.Build.0 = Release|Win32 - {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Debug|ARM64.Build.0 = Debug|ARM64 - {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Debug|x64.ActiveCfg = Debug|x64 - {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Debug|x64.Build.0 = Debug|x64 - {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Debug|x86.ActiveCfg = Debug|Win32 - {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Debug|x86.Build.0 = Debug|Win32 - {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Release|ARM64.ActiveCfg = Release|ARM64 - {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Release|ARM64.Build.0 = Release|ARM64 - {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Release|x64.ActiveCfg = Release|x64 - {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Release|x64.Build.0 = Release|x64 - {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Release|x86.ActiveCfg = Release|Win32 - {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Release|x86.Build.0 = Release|Win32 - {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Debug|ARM64.Build.0 = Debug|ARM64 - {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Debug|x64.ActiveCfg = Debug|x64 - {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Debug|x64.Build.0 = Debug|x64 - {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Debug|x86.ActiveCfg = Debug|Win32 - {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Debug|x86.Build.0 = Debug|Win32 - {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Release|ARM64.ActiveCfg = Release|ARM64 - {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Release|ARM64.Build.0 = Release|ARM64 - {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Release|x64.ActiveCfg = Release|x64 - {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Release|x64.Build.0 = Release|x64 - {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Release|x86.ActiveCfg = Release|Win32 - {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Release|x86.Build.0 = Release|Win32 - {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Debug|ARM64.Build.0 = Debug|ARM64 - {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Debug|x64.ActiveCfg = Debug|x64 - {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Debug|x64.Build.0 = Debug|x64 - {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Debug|x86.ActiveCfg = Debug|Win32 - {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Debug|x86.Build.0 = Debug|Win32 - {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Release|ARM64.ActiveCfg = Release|ARM64 - {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Release|ARM64.Build.0 = Release|ARM64 - {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Release|x64.ActiveCfg = Release|x64 - {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Release|x64.Build.0 = Release|x64 - {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Release|x86.ActiveCfg = Release|Win32 - {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Release|x86.Build.0 = Release|Win32 - {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Debug|ARM64.Build.0 = Debug|ARM64 - {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Debug|x64.ActiveCfg = Debug|x64 - {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Debug|x64.Build.0 = Debug|x64 - {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Debug|x86.ActiveCfg = Debug|Win32 - {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Debug|x86.Build.0 = Debug|Win32 - {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Release|ARM64.ActiveCfg = Release|ARM64 - {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Release|ARM64.Build.0 = Release|ARM64 - {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Release|x64.ActiveCfg = Release|x64 - {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Release|x64.Build.0 = Release|x64 - {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Release|x86.ActiveCfg = Release|Win32 - {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Release|x86.Build.0 = Release|Win32 - {666346D7-C84B-498D-AE17-53B20C62DB1A}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {666346D7-C84B-498D-AE17-53B20C62DB1A}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {666346D7-C84B-498D-AE17-53B20C62DB1A}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {666346D7-C84B-498D-AE17-53B20C62DB1A}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {666346D7-C84B-498D-AE17-53B20C62DB1A}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {666346D7-C84B-498D-AE17-53B20C62DB1A}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {666346D7-C84B-498D-AE17-53B20C62DB1A}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {666346D7-C84B-498D-AE17-53B20C62DB1A}.Debug|ARM64.Build.0 = Debug|ARM64 - {666346D7-C84B-498D-AE17-53B20C62DB1A}.Debug|x64.ActiveCfg = Debug|x64 - {666346D7-C84B-498D-AE17-53B20C62DB1A}.Debug|x64.Build.0 = Debug|x64 - {666346D7-C84B-498D-AE17-53B20C62DB1A}.Debug|x86.ActiveCfg = Debug|Win32 - {666346D7-C84B-498D-AE17-53B20C62DB1A}.Debug|x86.Build.0 = Debug|Win32 - {666346D7-C84B-498D-AE17-53B20C62DB1A}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {666346D7-C84B-498D-AE17-53B20C62DB1A}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {666346D7-C84B-498D-AE17-53B20C62DB1A}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {666346D7-C84B-498D-AE17-53B20C62DB1A}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {666346D7-C84B-498D-AE17-53B20C62DB1A}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {666346D7-C84B-498D-AE17-53B20C62DB1A}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {666346D7-C84B-498D-AE17-53B20C62DB1A}.Release|ARM64.ActiveCfg = Release|ARM64 - {666346D7-C84B-498D-AE17-53B20C62DB1A}.Release|ARM64.Build.0 = Release|ARM64 - {666346D7-C84B-498D-AE17-53B20C62DB1A}.Release|x64.ActiveCfg = Release|x64 - {666346D7-C84B-498D-AE17-53B20C62DB1A}.Release|x64.Build.0 = Release|x64 - {666346D7-C84B-498D-AE17-53B20C62DB1A}.Release|x86.ActiveCfg = Release|Win32 - {666346D7-C84B-498D-AE17-53B20C62DB1A}.Release|x86.Build.0 = Release|Win32 - {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Debug|ARM64.Build.0 = Debug|ARM64 - {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Debug|x64.ActiveCfg = Debug|x64 - {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Debug|x64.Build.0 = Debug|x64 - {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Debug|x86.ActiveCfg = Debug|Win32 - {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Debug|x86.Build.0 = Debug|Win32 - {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Release|ARM64.ActiveCfg = Release|ARM64 - {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Release|ARM64.Build.0 = Release|ARM64 - {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Release|x64.ActiveCfg = Release|x64 - {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Release|x64.Build.0 = Release|x64 - {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Release|x86.ActiveCfg = Release|Win32 - {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Release|x86.Build.0 = Release|Win32 - {6C897101-BE52-4387-8AA2-062123A76BA1}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {6C897101-BE52-4387-8AA2-062123A76BA1}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {6C897101-BE52-4387-8AA2-062123A76BA1}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {6C897101-BE52-4387-8AA2-062123A76BA1}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {6C897101-BE52-4387-8AA2-062123A76BA1}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {6C897101-BE52-4387-8AA2-062123A76BA1}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {6C897101-BE52-4387-8AA2-062123A76BA1}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {6C897101-BE52-4387-8AA2-062123A76BA1}.Debug|ARM64.Build.0 = Debug|ARM64 - {6C897101-BE52-4387-8AA2-062123A76BA1}.Debug|x64.ActiveCfg = Debug|x64 - {6C897101-BE52-4387-8AA2-062123A76BA1}.Debug|x64.Build.0 = Debug|x64 - {6C897101-BE52-4387-8AA2-062123A76BA1}.Debug|x86.ActiveCfg = Debug|Win32 - {6C897101-BE52-4387-8AA2-062123A76BA1}.Debug|x86.Build.0 = Debug|Win32 - {6C897101-BE52-4387-8AA2-062123A76BA1}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {6C897101-BE52-4387-8AA2-062123A76BA1}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {6C897101-BE52-4387-8AA2-062123A76BA1}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {6C897101-BE52-4387-8AA2-062123A76BA1}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {6C897101-BE52-4387-8AA2-062123A76BA1}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {6C897101-BE52-4387-8AA2-062123A76BA1}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {6C897101-BE52-4387-8AA2-062123A76BA1}.Release|ARM64.ActiveCfg = Release|ARM64 - {6C897101-BE52-4387-8AA2-062123A76BA1}.Release|ARM64.Build.0 = Release|ARM64 - {6C897101-BE52-4387-8AA2-062123A76BA1}.Release|x64.ActiveCfg = Release|x64 - {6C897101-BE52-4387-8AA2-062123A76BA1}.Release|x64.Build.0 = Release|x64 - {6C897101-BE52-4387-8AA2-062123A76BA1}.Release|x86.ActiveCfg = Release|Win32 - {6C897101-BE52-4387-8AA2-062123A76BA1}.Release|x86.Build.0 = Release|Win32 - {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Debug|ARM64.Build.0 = Debug|ARM64 - {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Debug|x64.ActiveCfg = Debug|x64 - {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Debug|x64.Build.0 = Debug|x64 - {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Debug|x86.ActiveCfg = Debug|Win32 - {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Debug|x86.Build.0 = Debug|Win32 - {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Release|ARM64.ActiveCfg = Release|ARM64 - {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Release|ARM64.Build.0 = Release|ARM64 - {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Release|x64.ActiveCfg = Release|x64 - {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Release|x64.Build.0 = Release|x64 - {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Release|x86.ActiveCfg = Release|Win32 - {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Release|x86.Build.0 = Release|Win32 - {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Debug|ARM64.Build.0 = Debug|ARM64 - {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Debug|x64.ActiveCfg = Debug|x64 - {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Debug|x64.Build.0 = Debug|x64 - {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Debug|x86.ActiveCfg = Debug|Win32 - {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Debug|x86.Build.0 = Debug|Win32 - {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Release|ARM64.ActiveCfg = Release|ARM64 - {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Release|ARM64.Build.0 = Release|ARM64 - {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Release|x64.ActiveCfg = Release|x64 - {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Release|x64.Build.0 = Release|x64 - {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Release|x86.ActiveCfg = Release|Win32 - {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Release|x86.Build.0 = Release|Win32 - {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Debug|ARM64.Build.0 = Debug|ARM64 - {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Debug|x64.ActiveCfg = Debug|x64 - {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Debug|x64.Build.0 = Debug|x64 - {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Debug|x86.ActiveCfg = Debug|Win32 - {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Debug|x86.Build.0 = Debug|Win32 - {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Release|ARM64.ActiveCfg = Release|ARM64 - {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Release|ARM64.Build.0 = Release|ARM64 - {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Release|x64.ActiveCfg = Release|x64 - {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Release|x64.Build.0 = Release|x64 - {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Release|x86.ActiveCfg = Release|Win32 - {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Release|x86.Build.0 = Release|Win32 - {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Debug|ARM64.Build.0 = Debug|ARM64 - {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Debug|x64.ActiveCfg = Debug|x64 - {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Debug|x64.Build.0 = Debug|x64 - {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Debug|x86.ActiveCfg = Debug|Win32 - {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Debug|x86.Build.0 = Debug|Win32 - {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Release|ARM64.ActiveCfg = Release|ARM64 - {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Release|ARM64.Build.0 = Release|ARM64 - {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Release|x64.ActiveCfg = Release|x64 - {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Release|x64.Build.0 = Release|x64 - {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Release|x86.ActiveCfg = Release|Win32 - {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Release|x86.Build.0 = Release|Win32 - {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Debug|ARM64.Build.0 = Debug|ARM64 - {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Debug|x64.ActiveCfg = Debug|x64 - {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Debug|x64.Build.0 = Debug|x64 - {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Debug|x86.ActiveCfg = Debug|Win32 - {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Debug|x86.Build.0 = Debug|Win32 - {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Release|ARM64.ActiveCfg = Release|ARM64 - {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Release|ARM64.Build.0 = Release|ARM64 - {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Release|x64.ActiveCfg = Release|x64 - {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Release|x64.Build.0 = Release|x64 - {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Release|x86.ActiveCfg = Release|Win32 - {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Release|x86.Build.0 = Release|Win32 - {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Debug|ARM64.Build.0 = Debug|ARM64 - {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Debug|x64.ActiveCfg = Debug|x64 - {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Debug|x64.Build.0 = Debug|x64 - {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Debug|x86.ActiveCfg = Debug|Win32 - {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Debug|x86.Build.0 = Debug|Win32 - {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Release|ARM64.ActiveCfg = Release|ARM64 - {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Release|ARM64.Build.0 = Release|ARM64 - {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Release|x64.ActiveCfg = Release|x64 - {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 - {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 - {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|ARM64.Build.0 = Debug|ARM64 - {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|x64.ActiveCfg = Debug|x64 - {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|x64.Build.0 = Debug|x64 - {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|x86.ActiveCfg = Debug|Win32 - {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|x86.Build.0 = Debug|Win32 - {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|ARM64.ActiveCfg = Release|ARM64 - {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|ARM64.Build.0 = Release|ARM64 - {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|x64.ActiveCfg = Release|x64 - {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|x64.Build.0 = Release|x64 - {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|x86.ActiveCfg = Release|Win32 - {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|x86.Build.0 = Release|Win32 - {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|ARM64.Build.0 = Debug|ARM64 - {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|x64.ActiveCfg = Debug|x64 - {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|x64.Build.0 = Debug|x64 - {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|x86.ActiveCfg = Debug|Win32 - {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|x86.Build.0 = Debug|Win32 - {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|ARM64.ActiveCfg = Release|ARM64 - {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|ARM64.Build.0 = Release|ARM64 - {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|x64.ActiveCfg = Release|x64 - {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|x64.Build.0 = Release|x64 - {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|x86.ActiveCfg = Release|Win32 - {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|x86.Build.0 = Release|Win32 - {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|ARM64.Build.0 = Debug|ARM64 - {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|x64.ActiveCfg = Debug|x64 - {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|x64.Build.0 = Debug|x64 - {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|x86.ActiveCfg = Debug|Win32 - {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|x86.Build.0 = Debug|Win32 - {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|ARM64.ActiveCfg = Release|ARM64 - {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|ARM64.Build.0 = Release|ARM64 - {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|x64.ActiveCfg = Release|x64 - {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|x64.Build.0 = Release|x64 - {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|x86.ActiveCfg = Release|Win32 - {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1} - {278D8859-20B1-428F-8448-064F46E1F021} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1} - {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1} - {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1} - {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1} - {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1} - {CC132A4D-D081-4C26-BFB9-AB11984054F8} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1} - {E9D708A5-9C1F-4B84-A795-C5F191801762} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1} - {0981CA98-E4A5-4DF1-987F-A41D09131EFC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {103B292B-049B-4B15-85A1-9F902840DB2C} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {0C2D2F82-AE67-400C-B19C-8C9B957B132A} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {E6784F91-4E4E-4956-A079-73FAB1AC7BE6} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} - {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} - {93A1F656-0D29-4C5E-B140-11F23FF5D6AB} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} - {F81C5819-85B6-4D2E-B6DC-104A7634461B} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} - {66CC5B13-881A-412F-8C51-746622A91C5A} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {557138B0-7BE2-4392-B2E2-B45734031A62} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {9EED87BB-527F-4D05-9384-6D16CFD627A8} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {6D1CA2F1-7FCA-4249-9220-075C2DF4F965} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {946A1700-C7AA-46F0-AEF2-67C98B5722AC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {FD193822-3D5C-4161-A147-884C2ABDE483} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {20AD0AC9-9159-4744-99CC-6AC5779D6B87} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {0199E349-0701-40BC-8A7F-06A54FFA3E7C} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {BCB71111-8505-4B35-8CEF-EC6115DC9D4D} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {8F19E3DA-8929-4000-87B5-3CA6929636CC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {51A00565-5787-4911-9CC0-28403AA4909D} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {92B64AE7-D773-4F05-89F1-CE59BBF4F053} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {A643BB06-735D-47F3-BFE7-B6D3C36F7097} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {B332DCA8-3599-4A99-917A-82261BDC27AC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {59089B0C-AAB4-4532-B294-44DEAE7178B7} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {C298876B-6C12-4EA4-903B-33450BCD9884} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {83F586FA-C801-4979-ACCA-006BD628CC88} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {FF2970AE-E2E9-405F-B321-D523A1BD44A0} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {79417CE2-FEEB-42F0-BC53-62D5267B19B1} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {AFDDE100-2D36-4749-817D-12E54C56312F} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} - {B7812167-50FB-4934-996F-DF6FE4CBBFDF} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} - {39DB56C7-05F8-492C-A8D4-F19E40FECB59} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} - {82F3D34B-8DB2-4C6A-98B1-132245DD9D99} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} - {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} - {14BA7F98-02CC-4648-9236-676BFF9458AF} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} - {0859A973-E4FE-4688-8D16-0253163FDE24} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} - {F3412853-2B6A-4334-8CF2-B796CDAE0850} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} - {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} - {D03F2C82-9553-4AFA-8F49-9234009122B6} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} - {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} - {A53CCF42-A972-478F-9336-0F618B3EC06A} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} - {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} - {870723DD-945A-4136-B65B-4AF3BF85369C} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} - {EA6488AD-445B-4835-87FB-EBC9E2EDAF97} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} - {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {3AD868E6-8355-4F29-B5ED-7DE94AD786E7} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {2B78CF0A-5403-45E2-99BD-493F1679BCDB} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {0AB968E0-E993-45CE-8875-7453C96DF583} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {25923141-9859-4AFE-8168-0DF78322FC63} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {7E855020-7FA4-482D-B510-2E709354FE8B} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {9782E0C8-2BD3-4F67-B420-21CF19CA2435} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {9F4135E3-9814-452C-9B35-0EFBCD792B49} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {C45343E6-DAB6-4F3A-A00A-8BED71A098BE} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {B19DD336-538E-4091-A559-EAA717FEC899} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {0BF60202-43F7-48E9-8717-D31E56FA5BE0} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {6D75CD88-1A03-4955-B8C7-ACFC3742154F} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {8DD0EB7E-668E-452D-91D7-906C64A9C8AC} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} - {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} - {25BCB876-B60A-499B-9046-E9801CFD7780} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} - {56FB0A45-145F-4EAE-B2C8-E5833E682D8F} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} - {2BB0C1D4-9298-45AC-B244-67A99769A292} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} - {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} - {81064BCE-EEC1-43B0-9912-F05F2B54B11A} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} - {31B41997-3890-45E3-93FE-C57B363E9C0D} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} - {D550AB93-DF31-4B76-873F-F075018352F4} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} - {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} - {F90FCDC5-EE14-4B89-96DB-4392E28F34AF} = {278D8859-20B1-428F-8448-064F46E1F021} - {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79} = {278D8859-20B1-428F-8448-064F46E1F021} - {56E68E37-B3FC-4799-91AF-0CA10B6D55A5} = {278D8859-20B1-428F-8448-064F46E1F021} - {03E7018C-44A2-4C46-9CE7-F2A135A2692B} = {278D8859-20B1-428F-8448-064F46E1F021} - {F3F6FE4D-9D9E-451A-B0BA-81456104B672} = {278D8859-20B1-428F-8448-064F46E1F021} - {C27794B5-1293-4EA7-BC0E-0F18E6325539} = {278D8859-20B1-428F-8448-064F46E1F021} - {02F41059-12A2-4A96-8D77-07EFE4B108FD} = {278D8859-20B1-428F-8448-064F46E1F021} - {B774E0B9-9514-4E88-975F-4EB6C3B8D519} = {278D8859-20B1-428F-8448-064F46E1F021} - {D91367C2-2189-4859-A7FE-D2CAB84FA15C} = {278D8859-20B1-428F-8448-064F46E1F021} - {33459B4E-1839-4856-BF6B-22480D11FE31} = {278D8859-20B1-428F-8448-064F46E1F021} - {48871156-181A-475A-BD8D-200086A09675} = {278D8859-20B1-428F-8448-064F46E1F021} - {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1} = {278D8859-20B1-428F-8448-064F46E1F021} - {1C49E35A-2838-49D9-9D5F-4B8134960EF6} = {278D8859-20B1-428F-8448-064F46E1F021} - {F91142E2-A999-47F0-9E74-38C1E2930EBE} = {278D8859-20B1-428F-8448-064F46E1F021} - {1EDD4BCF-345C-4065-8CBD-7285224293C3} = {278D8859-20B1-428F-8448-064F46E1F021} - {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {CF3755C4-937D-4ABF-B7B3-95140808717F} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {D34939FE-8873-4C53-8D6C-74DED78EA3C4} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {D408A730-363A-4ABF-BCEF-5D63DCC66042} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {52FB7463-C128-42AF-A02F-78F48473EA9A} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {7381D91E-5C72-48F0-AAB4-95C9B10D7484} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {D36EC43E-B31F-4CF4-8285-93A7A9D90189} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {274C0319-7E1E-4188-936B-8DF3331230B3} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {600C3D4F-0670-4DB4-B30F-520A729053B5} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {11F33A39-74B7-4018-B5F9-CC285A673A8F} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {A6F5E35E-B4A7-41B3-853A-75558E6E0715} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {291B4975-8EFF-4C7C-8AF3-44A77B8491B8} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {FDE6080B-E203-4066-910D-AD0302566008} = {E9D708A5-9C1F-4B84-A795-C5F191801762} - {E1B6D565-9D7C-46B7-9202-ECF54974DE50} = {E9D708A5-9C1F-4B84-A795-C5F191801762} - {C8765523-58F8-4C8E-9914-693396F6F0FF} = {E9D708A5-9C1F-4B84-A795-C5F191801762} - {2F1B955B-275E-4D8E-8864-06FEC44D7912} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} - {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} - {F2DB2E59-76BF-4D81-859A-AFC289C046C0} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} - {3FE7E9B6-49AC-4246-A789-28DB4644567B} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {191A5289-BA65-4638-A215-C521F0187313} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {8B1AF423-00F1-4924-AC54-F77D402D2AC9} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {658A1B85-554E-4A5D-973A-FFE592CDD5F2} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {07CA51AD-72AE-46A2-AAED-DC3E3F807976} = {E9D708A5-9C1F-4B84-A795-C5F191801762} - {27B110CC-43C0-400A-89D9-245E681647D7} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} - {1DE84812-E143-4C4B-A61D-9267AAD55401} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {4A87569C-4BD3-4113-B4B9-573D65B3D3F8} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} - {769FF0C1-4424-4FA3-BC44-D7A7DA312A06} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {6D9E00D8-2893-45E4-9363-3F7F61D416BD} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} - {70B35F59-AFC2-4D8F-8833-5314D2047A81} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {3755E9F4-CB48-4EC3-B561-3B85964EBDEF} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {F81C5819-85B4-4D2E-B6DC-104A7634461B} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} - {CC62F7DB-D089-4677-8575-CAB7A7815C43} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {A4B0D971-3CD6-41C9-8AB2-055D25A33373} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} - {15CDD310-6980-42A6-8082-3A6B7730D13F} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {71DB4284-5B1C-4E86-9AF5-B91542D44A6F} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} - {88DE5AD6-0074-4A5A-BE22-C840153E35D5} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {A546E75A-5242-46E6-9A9E-6C91554EAB84} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {DF25E545-00FF-4E64-844C-7DF98991F901} = {278D8859-20B1-428F-8448-064F46E1F021} - {703BE7BA-5B99-4F70-806D-3A259F6A991E} = {278D8859-20B1-428F-8448-064F46E1F021} - {FAFEE2F9-24B0-4AF1-B512-433E9590033F} = {278D8859-20B1-428F-8448-064F46E1F021} - {8245DAD9-D402-4D5C-8F45-32229CD3B263} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} - {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {3A7FE53D-35F7-49DC-9C9A-A5204A53523F} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} - {CCA63A76-D9FC-4130-9F67-4D97F9770D53} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {3384C257-3CFE-4A8F-838C-19DAC5C955DA} = {278D8859-20B1-428F-8448-064F46E1F021} - {2B140378-125F-4DE9-AC37-2CC1B73D7254} = {278D8859-20B1-428F-8448-064F46E1F021} - {F4C55B99-E1C5-496A-8AC2-40188C38F4F6} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {2AA91EED-2D32-4B09-84A3-53D41EED1005} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {EC0910F6-8D66-4509-BF57-A5EE7AE9485F} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {921391C6-7626-4212-9928-BC82BC785461} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} - {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} - {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {C54703BF-D68A-480D-BE27-49B62E45D582} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {9CD8BCAD-F212-4BCC-BA98-899743CE3279} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} - {0981CA28-E4A5-4DF1-987F-A41D09131EFC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {6777EC3C-077C-42FC-B4AD-B799CE55CCE4} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} - {A61DAD9C-271C-4E95-81AA-DB4CD58564D4} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {49C67F03-1A56-4F96-B278-39B66EC93678} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {D496308F-3C3C-40B3-A3ED-EA327D244B3E} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} - {3B27F358-2679-4F38-B297-17B536F580BB} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {718FCBD0-591D-448C-B7D5-9F1CA8544E7B} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {19CA0070-B4B2-4394-90B7-D0C259AA35BA} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {2CCCD9E4-9058-4291-BD89-39C979F0CA1E} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {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} - {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC} = {E9D708A5-9C1F-4B84-A795-C5F191801762} - {0C442799-B09C-4CD1-9538-711B6E85E9BF} = {278D8859-20B1-428F-8448-064F46E1F021} - {DFB40A10-F8B7-412A-BCC3-5EE49294D816} = {278D8859-20B1-428F-8448-064F46E1F021} - {BB58A5FB-1A35-4471-86D0-A5189EC541B3} = {278D8859-20B1-428F-8448-064F46E1F021} - {61997220-5383-4AE5-ABD4-5F45AE1B0F2A} = {278D8859-20B1-428F-8448-064F46E1F021} - {7467E9AE-844F-444D-8A3F-17397544BA21} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {497FDF54-9762-4048-A833-61CC3980A0FB} = {278D8859-20B1-428F-8448-064F46E1F021} - {29B00F47-BE91-4A1F-B87D-B1302F038316} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} - {124935CC-73BB-489E-92E8-4F922A85DB5D} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F} = {278D8859-20B1-428F-8448-064F46E1F021} - {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2} = {278D8859-20B1-428F-8448-064F46E1F021} - {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91} = {278D8859-20B1-428F-8448-064F46E1F021} - {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {9DE2FC01-A839-4F89-8319-9071D4C54821} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {2F578155-D51F-4C03-AB7F-5C5122CA46CC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {1C829D1A-892C-451C-AF0B-AC65C85F5CC6} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {84DE22BB-C25F-425C-A7FE-0120CF107B83} = {278D8859-20B1-428F-8448-064F46E1F021} - {98152EDD-7E28-4FA3-89D8-B636ED5D5F65} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {B7FDD40F-DDA4-468E-9C40-EEB175964A26} = {278D8859-20B1-428F-8448-064F46E1F021} - {028F0967-B253-45DA-B1C4-FACCE45D0D8D} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} - {666346D7-C84B-498D-AE17-53B20C62DB1A} = {278D8859-20B1-428F-8448-064F46E1F021} - {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {6C897101-BE52-4387-8AA2-062123A76BA1} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} - {30011884-25EE-42C9-BB15-888CAFB1AA6E} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} - {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} - {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} - {DC163251-16C3-4B72-B965-ACDBA0F02BD1} = {278D8859-20B1-428F-8448-064F46E1F021} - {D35D2FDA-B53F-4F70-81CA-24D95812B89C} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31912.275 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "raylib", "raylib\raylib.vcxproj", "{E89D61AC-55DE-4482-AFD4-DF7242EBC859}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "core", "core", "{6C82BAAE-BDDF-457D-8FA8-7E2490B07035}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shapes", "shapes", "{278D8859-20B1-428F-8448-064F46E1F021}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "textures", "textures", "{DA049009-21FF-4AC0-84E4-830DD1BCD0CE}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "text", "text", "{8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "models", "models", "{AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shaders", "shaders", "{5317807F-61D4-4E0F-B6DC-2D9F12621ED9}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "audio", "audio", "{CC132A4D-D081-4C26-BFB9-AB11984054F8}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "others", "others", "{E9D708A5-9C1F-4B84-A795-C5F191801762}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_basic_window", "examples\core_basic_window.vcxproj", "{0981CA98-E4A5-4DF1-987F-A41D09131EFC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_sprite_animation", "examples\textures_sprite_animation.vcxproj", "{C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_srcrec_dstrec", "examples\textures_srcrec_dstrec.vcxproj", "{103B292B-049B-4B15-85A1-9F902840DB2C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_image_drawing", "examples\textures_image_drawing.vcxproj", "{0C2D2F82-AE67-400C-B19C-8C9B957B132A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "audio_module_playing", "examples\audio_module_playing.vcxproj", "{E6784F91-4E4E-4956-A079-73FAB1AC7BE6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "audio_music_stream", "examples\audio_music_stream.vcxproj", "{BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "audio_raw_stream", "examples\audio_raw_stream.vcxproj", "{93A1F656-0D29-4C5E-B140-11F23FF5D6AB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "audio_sound_loading", "examples\audio_sound_loading.vcxproj", "{F81C5819-85B6-4D2E-B6DC-104A7634461B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_2d_camera", "examples\core_2d_camera.vcxproj", "{66CC5B13-881A-412F-8C51-746622A91C5A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_2d_camera_platformer", "examples\core_2d_camera_platformer.vcxproj", "{CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_3d_camera_first_person", "examples\core_3d_camera_first_person.vcxproj", "{557138B0-7BE2-4392-B2E2-B45734031A62}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_3d_camera_free", "examples\core_3d_camera_free.vcxproj", "{9EED87BB-527F-4D05-9384-6D16CFD627A8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_3d_camera_mode", "examples\core_3d_camera_mode.vcxproj", "{6D1CA2F1-7FCA-4249-9220-075C2DF4F965}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_3d_camera_split_screen", "examples\core_3d_camera_split_screen.vcxproj", "{946A1700-C7AA-46F0-AEF2-67C98B5722AC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_3d_picking", "examples\core_3d_picking.vcxproj", "{FD193822-3D5C-4161-A147-884C2ABDE483}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_custom_logging", "examples\core_custom_logging.vcxproj", "{20AD0AC9-9159-4744-99CC-6AC5779D6B87}" +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_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 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_input_gestures", "examples\core_input_gestures.vcxproj", "{51A00565-5787-4911-9CC0-28403AA4909D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_input_keys", "examples\core_input_keys.vcxproj", "{92B64AE7-D773-4F05-89F1-CE59BBF4F053}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_input_mouse", "examples\core_input_mouse.vcxproj", "{A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_input_multitouch", "examples\core_input_multitouch.vcxproj", "{A643BB06-735D-47F3-BFE7-B6D3C36F7097}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_random_sequence", "examples\core_random_sequence.vcxproj", "{6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_random_values", "examples\core_random_values.vcxproj", "{B332DCA8-3599-4A99-917A-82261BDC27AC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_scissor_test", "examples\core_scissor_test.vcxproj", "{59089B0C-AAB4-4532-B294-44DEAE7178B7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_storage_values", "examples\core_storage_values.vcxproj", "{C298876B-6C12-4EA4-903B-33450BCD9884}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_vr_simulator", "examples\core_vr_simulator.vcxproj", "{83F586FA-C801-4979-ACCA-006BD628CC88}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_window_flags", "examples\core_window_flags.vcxproj", "{86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_window_letterbox", "examples\core_window_letterbox.vcxproj", "{FF2970AE-E2E9-405F-B321-D523A1BD44A0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_world_screen", "examples\core_world_screen.vcxproj", "{79417CE2-FEEB-42F0-BC53-62D5267B19B1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_animation_playing", "examples\models_animation_playing.vcxproj", "{AFDDE100-2D36-4749-817D-12E54C56312F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_billboard_rendering", "examples\models_billboard_rendering.vcxproj", "{B7812167-50FB-4934-996F-DF6FE4CBBFDF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_box_collisions", "examples\models_box_collisions.vcxproj", "{39DB56C7-05F8-492C-A8D4-F19E40FECB59}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_cubicmap_rendering", "examples\models_cubicmap_rendering.vcxproj", "{82F3D34B-8DB2-4C6A-98B1-132245DD9D99}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_first_person_maze", "examples\models_first_person_maze.vcxproj", "{CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_geometric_shapes", "examples\models_geometric_shapes.vcxproj", "{14BA7F98-02CC-4648-9236-676BFF9458AF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_heightmap_rendering", "examples\models_heightmap_rendering.vcxproj", "{0859A973-E4FE-4688-8D16-0253163FDE24}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_loading", "examples\models_loading.vcxproj", "{F3412853-2B6A-4334-8CF2-B796CDAE0850}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_mesh_generation", "examples\models_mesh_generation.vcxproj", "{BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_mesh_picking", "examples\models_mesh_picking.vcxproj", "{D03F2C82-9553-4AFA-8F49-9234009122B6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_orthographic_projection", "examples\models_orthographic_projection.vcxproj", "{FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_rlgl_solar_system", "examples\models_rlgl_solar_system.vcxproj", "{A53CCF42-A972-478F-9336-0F618B3EC06A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_skybox_rendering", "examples\models_skybox_rendering.vcxproj", "{0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_waving_cubes", "examples\models_waving_cubes.vcxproj", "{870723DD-945A-4136-B65B-4AF3BF85369C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_yaw_pitch_roll", "examples\models_yaw_pitch_roll.vcxproj", "{EA6488AD-445B-4835-87FB-EBC9E2EDAF97}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_to_image", "examples\textures_to_image.vcxproj", "{E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_sprite_explosion", "examples\textures_sprite_explosion.vcxproj", "{472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_sprite_button", "examples\textures_sprite_button.vcxproj", "{589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_raw_data", "examples\textures_raw_data.vcxproj", "{3AD868E6-8355-4F29-B5ED-7DE94AD786E7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_particles_blending", "examples\textures_particles_blending.vcxproj", "{2B78CF0A-5403-45E2-99BD-493F1679BCDB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_npatch_drawing", "examples\textures_npatch_drawing.vcxproj", "{0AB968E0-E993-45CE-8875-7453C96DF583}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_mouse_painting", "examples\textures_mouse_painting.vcxproj", "{25923141-9859-4AFE-8168-0DF78322FC63}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_logo_raylib", "examples\textures_logo_raylib.vcxproj", "{7E855020-7FA4-482D-B510-2E709354FE8B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_image_text", "examples\textures_image_text.vcxproj", "{9782E0C8-2BD3-4F67-B420-21CF19CA2435}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_image_processing", "examples\textures_image_processing.vcxproj", "{9F4135E3-9814-452C-9B35-0EFBCD792B49}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_image_loading", "examples\textures_image_loading.vcxproj", "{C45343E6-DAB6-4F3A-A00A-8BED71A098BE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_image_generation", "examples\textures_image_generation.vcxproj", "{B19DD336-538E-4091-A559-EAA717FEC899}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_tiled_drawing", "examples\textures_tiled_drawing.vcxproj", "{0BF60202-43F7-48E9-8717-D31E56FA5BE0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_bunnymark", "examples\textures_bunnymark.vcxproj", "{4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_blend_modes", "examples\textures_blend_modes.vcxproj", "{6D75CD88-1A03-4955-B8C7-ACFC3742154F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_background_scrolling", "examples\textures_background_scrolling.vcxproj", "{8DD0EB7E-668E-452D-91D7-906C64A9C8AC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_writing_anim", "examples\text_writing_anim.vcxproj", "{F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_unicode_emojis", "examples\text_unicode_emojis.vcxproj", "{1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_rectangle_bounds", "examples\text_rectangle_bounds.vcxproj", "{25BCB876-B60A-499B-9046-E9801CFD7780}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_sprite_fonts", "examples\text_sprite_fonts.vcxproj", "{56FB0A45-145F-4EAE-B2C8-E5833E682D8F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_input_box", "examples\text_input_box.vcxproj", "{2BB0C1D4-9298-45AC-B244-67A99769A292}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_format_text", "examples\text_format_text.vcxproj", "{99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_font_spritefont", "examples\text_font_spritefont.vcxproj", "{81064BCE-EEC1-43B0-9912-F05F2B54B11A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_font_sdf", "examples\text_font_sdf.vcxproj", "{31B41997-3890-45E3-93FE-C57B363E9C0D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_font_loading", "examples\text_font_loading.vcxproj", "{D550AB93-DF31-4B76-873F-F075018352F4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_font_filters", "examples\text_font_filters.vcxproj", "{8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_rectangle_scaling", "examples\shapes_rectangle_scaling.vcxproj", "{F90FCDC5-EE14-4B89-96DB-4392E28F34AF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_logo_raylib_anim", "examples\shapes_logo_raylib_anim.vcxproj", "{93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_logo_raylib", "examples\shapes_logo_raylib.vcxproj", "{56E68E37-B3FC-4799-91AF-0CA10B6D55A5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_lines_bezier", "examples\shapes_lines_bezier.vcxproj", "{03E7018C-44A2-4C46-9CE7-F2A135A2692B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_following_eyes", "examples\shapes_following_eyes.vcxproj", "{F3F6FE4D-9D9E-451A-B0BA-81456104B672}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_basic_shapes", "examples\shapes_basic_shapes.vcxproj", "{C27794B5-1293-4EA7-BC0E-0F18E6325539}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_bouncing_ball", "examples\shapes_bouncing_ball.vcxproj", "{02F41059-12A2-4A96-8D77-07EFE4B108FD}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_collision_area", "examples\shapes_collision_area.vcxproj", "{B774E0B9-9514-4E88-975F-4EB6C3B8D519}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_colors_palette", "examples\shapes_colors_palette.vcxproj", "{D91367C2-2189-4859-A7FE-D2CAB84FA15C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_circle_sector_drawing", "examples\shapes_circle_sector_drawing.vcxproj", "{33459B4E-1839-4856-BF6B-22480D11FE31}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_rounded_rectangle_drawing", "examples\shapes_rounded_rectangle_drawing.vcxproj", "{48871156-181A-475A-BD8D-200086A09675}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_ring_drawing", "examples\shapes_ring_drawing.vcxproj", "{C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_easings_ball", "examples\shapes_easings_ball.vcxproj", "{1C49E35A-2838-49D9-9D5F-4B8134960EF6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_easings_box", "examples\shapes_easings_box.vcxproj", "{F91142E2-A999-47F0-9E74-38C1E2930EBE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_easings_rectangles", "examples\shapes_easings_rectangles.vcxproj", "{1EDD4BCF-345C-4065-8CBD-7285224293C3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_basic_lighting", "examples\shaders_basic_lighting.vcxproj", "{A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_custom_uniform", "examples\shaders_custom_uniform.vcxproj", "{B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_eratosthenes_sieve", "examples\shaders_eratosthenes_sieve.vcxproj", "{D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_fog_rendering", "examples\shaders_fog_rendering.vcxproj", "{4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_hot_reloading", "examples\shaders_hot_reloading.vcxproj", "{CF3755C4-937D-4ABF-B7B3-95140808717F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_julia_set", "examples\shaders_julia_set.vcxproj", "{D34939FE-8873-4C53-8D6C-74DED78EA3C4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_model_shader", "examples\shaders_model_shader.vcxproj", "{D408A730-363A-4ABF-BCEF-5D63DCC66042}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_multi_sample2d", "examples\shaders_multi_sample2d.vcxproj", "{F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_palette_switch", "examples\shaders_palette_switch.vcxproj", "{52FB7463-C128-42AF-A02F-78F48473EA9A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_postprocessing", "examples\shaders_postprocessing.vcxproj", "{7381D91E-5C72-48F0-AAB4-95C9B10D7484}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_raymarching_rendering", "examples\shaders_raymarching_rendering.vcxproj", "{D36EC43E-B31F-4CF4-8285-93A7A9D90189}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_mesh_instancing", "examples\shaders_mesh_instancing.vcxproj", "{274C0319-7E1E-4188-936B-8DF3331230B3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_shapes_textures", "examples\shaders_shapes_textures.vcxproj", "{41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_simple_mask", "examples\shaders_simple_mask.vcxproj", "{600C3D4F-0670-4DB4-B30F-520A729053B5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_spotlight_rendering", "examples\shaders_spotlight_rendering.vcxproj", "{11F33A39-74B7-4018-B5F9-CC285A673A8F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_texture_rendering", "examples\shaders_texture_rendering.vcxproj", "{A6F5E35E-B4A7-41B3-853A-75558E6E0715}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_texture_waves", "examples\shaders_texture_waves.vcxproj", "{291B4975-8EFF-4C7C-8AF3-44A77B8491B8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "embedded_files_loading", "examples\embedded_files_loading.vcxproj", "{FDE6080B-E203-4066-910D-AD0302566008}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "easings_testbed", "examples\easings_testbed.vcxproj", "{E1B6D565-9D7C-46B7-9202-ECF54974DE50}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rlgl_standalone", "examples\rlgl_standalone.vcxproj", "{C8765523-58F8-4C8E-9914-693396F6F0FF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_loading_vox", "examples\models_loading_vox.vcxproj", "{2F1B955B-275E-4D8E-8864-06FEC44D7912}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_loading_gltf", "examples\models_loading_gltf.vcxproj", "{F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_codepoints_loading", "examples\text_codepoints_loading.vcxproj", "{F2DB2E59-76BF-4D81-859A-AFC289C046C0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_window_should_close", "examples\core_window_should_close.vcxproj", "{3FE7E9B6-49AC-4246-A789-28DB4644567B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_fog_of_war", "examples\textures_fog_of_war.vcxproj", "{EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_gif_player", "examples\textures_gif_player.vcxproj", "{191A5289-BA65-4638-A215-C521F0187313}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_2d_camera_mouse_zoom", "examples\core_2d_camera_mouse_zoom.vcxproj", "{3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_basic_screen_manager", "examples\core_basic_screen_manager.vcxproj", "{8B1AF423-00F1-4924-AC54-F77D402D2AC9}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_custom_frame_control", "examples\core_custom_frame_control.vcxproj", "{658A1B85-554E-4A5D-973A-FFE592CDD5F2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rlgl_compute_shader", "examples\rlgl_compute_shader.vcxproj", "{07CA51AD-72AE-46A2-AAED-DC3E3F807976}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_3d_drawing", "examples\text_3d_drawing.vcxproj", "{27B110CC-43C0-400A-89D9-245E681647D7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_polygon_drawing", "examples\textures_polygon_drawing.vcxproj", "{1DE84812-E143-4C4B-A61D-9267AAD55401}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "audio_stream_effects", "examples\audio_stream_effects.vcxproj", "{4A87569C-4BD3-4113-B4B9-573D65B3D3F8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_textured_curve", "examples\textures_textured_curve.vcxproj", "{769FF0C1-4424-4FA3-BC44-D7A7DA312A06}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_loading_m3d", "examples\models_loading_m3d.vcxproj", "{6D9E00D8-2893-45E4-9363-3F7F61D416BD}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_depth_writing", "examples\shaders_depth_writing.vcxproj", "{70B35F59-AFC2-4D8F-8833-5314D2047A81}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_depth_rendering", "examples\shaders_depth_rendering.vcxproj", "{DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_hybrid_rendering", "examples\shaders_hybrid_rendering.vcxproj", "{3755E9F4-CB48-4EC3-B561-3B85964EBDEF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "audio_sound_multi", "examples\audio_sound_multi.vcxproj", "{F81C5819-85B4-4D2E-B6DC-104A7634461B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_2d_camera_split_screen", "examples\core_2d_camera_split_screen.vcxproj", "{CC62F7DB-D089-4677-8575-CAB7A7815C43}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_automation_events", "examples\core_automation_events.vcxproj", "{7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "audio_mixed_processor", "examples\audio_mixed_processor.vcxproj", "{A4B0D971-3CD6-41C9-8AB2-055D25A33373}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_input_mouse_wheel", "examples\core_input_mouse_wheel.vcxproj", "{15CDD310-6980-42A6-8082-3A6B7730D13F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_smooth_pixelperfect", "examples\core_smooth_pixelperfect.vcxproj", "{71DB4284-5B1C-4E86-9AF5-B91542D44A6F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_textured_cube", "examples\models_textured_cube.vcxproj", "{4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_deferred_rendering", "examples\shaders_deferred_rendering.vcxproj", "{88DE5AD6-0074-4A5A-BE22-C840153E35D5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_texture_outline", "examples\shaders_texture_outline.vcxproj", "{A546E75A-5242-46E6-9A9E-6C91554EAB84}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_texture_tiling", "examples\shaders_texture_tiling.vcxproj", "{EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_splines_drawing", "examples\shapes_splines_drawing.vcxproj", "{DF25E545-00FF-4E64-844C-7DF98991F901}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_top_down_lights", "examples\shapes_top_down_lights.vcxproj", "{703BE7BA-5B99-4F70-806D-3A259F6A991E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_rectangle_advanced", "examples\shapes_rectangle_advanced.vcxproj", "{FAFEE2F9-24B0-4AF1-B512-433E9590033F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_animation_gpu_skinning", "examples\models_animation_gpu_skinning.vcxproj", "{8245DAD9-D402-4D5C-8F45-32229CD3B263}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_shadowmap_rendering", "examples\shaders_shadowmap_rendering.vcxproj", "{41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_bone_socket", "examples\models_bone_socket.vcxproj", "{3A7FE53D-35F7-49DC-9C9A-A5204A53523F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_vertex_displacement", "examples\shaders_vertex_displacement.vcxproj", "{CCA63A76-D9FC-4130-9F67-4D97F9770D53}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_rounded_rectangle", "examples\shaders_rounded_rectangle.vcxproj", "{D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_digital_clock", "examples\shapes_digital_clock.vcxproj", "{3384C257-3CFE-4A8F-838C-19DAC5C955DA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_double_pendulum", "examples\shapes_double_pendulum.vcxproj", "{2B140378-125F-4DE9-AC37-2CC1B73D7254}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_image_kernel", "examples\textures_image_kernel.vcxproj", "{F4C55B99-E1C5-496A-8AC2-40188C38F4F6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_image_rotate", "examples\textures_image_rotate.vcxproj", "{2AA91EED-2D32-4B09-84A3-53D41EED1005}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_image_channel", "examples\textures_image_channel.vcxproj", "{EC0910F6-8D66-4509-BF57-A5EE7AE9485F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_point_rendering", "examples\models_point_rendering.vcxproj", "{921391C6-7626-4212-9928-BC82BC785461}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_tesseract_view", "examples\models_tesseract_view.vcxproj", "{6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_basic_pbr", "examples\shaders_basic_pbr.vcxproj", "{4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_lightmap_rendering", "examples\shaders_lightmap_rendering.vcxproj", "{C54703BF-D68A-480D-BE27-49B62E45D582}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "audio_sound_positioning", "examples\audio_sound_positioning.vcxproj", "{9CD8BCAD-F212-4BCC-BA98-899743CE3279}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_input_virtual_controls", "examples\core_input_virtual_controls.vcxproj", "{0981CA28-E4A5-4DF1-987F-A41D09131EFC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_3d_camera_fps", "examples\core_3d_camera_fps.vcxproj", "{6B1A933E-71B8-4C1F-9E79-02D98830E671}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_normalmap_rendering", "examples\shaders_normalmap_rendering.vcxproj", "{6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_unicode_ranges", "examples\text_unicode_ranges.vcxproj", "{6777EC3C-077C-42FC-B4AD-B799CE55CCE4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_input_gestures_testbed", "examples\core_input_gestures_testbed.vcxproj", "{A61DAD9C-271C-4E95-81AA-DB4CD58564D4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_render_texture", "examples\core_render_texture.vcxproj", "{49C67F03-1A56-4F96-B278-39B66EC93678}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_inline_styling", "examples\text_inline_styling.vcxproj", "{D496308F-3C3C-40B3-A3ED-EA327D244B3E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_undo_redo", "examples\core_undo_redo.vcxproj", "{3B27F358-2679-4F38-B297-17B536F580BB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_input_actions", "examples\core_input_actions.vcxproj", "{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_delta_time", "examples\core_delta_time.vcxproj", "{19CA0070-B4B2-4394-90B7-D0C259AA35BA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_bullet_hell", "examples\shapes_bullet_hell.vcxproj", "{2CCCD9E4-9058-4291-BD89-39C979F0CA1E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_vector_angle", "examples\shapes_vector_angle.vcxproj", "{9DB1F875-6E65-4195-B23F-ED8095C0B99C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_basic_voxel", "examples\models_basic_voxel.vcxproj", "{52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_dashed_line", "examples\shapes_dashed_line.vcxproj", "{8E132D5A-2C00-48D0-8747-97E41356F26F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_rotating_cube", "examples\models_rotating_cube.vcxproj", "{A4662163-83E7-4309-8CAA-B0BF13655FE6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_ascii_rendering", "examples\shaders_ascii_rendering.vcxproj", "{5F4B766F-DD52-4B53-B6C3-BC7611E17F20}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_monitor_detector", "examples\core_monitor_detector.vcxproj", "{FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "web_basic_window", "examples\web_basic_window.vcxproj", "{A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_kaleidoscope", "examples\shapes_kaleidoscope.vcxproj", "{0C442799-B09C-4CD1-9538-711B6E85E9BF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_recursive_tree", "examples\shapes_recursive_tree.vcxproj", "{DFB40A10-F8B7-412A-BCC3-5EE49294D816}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_triangle_strip", "examples\shapes_triangle_strip.vcxproj", "{BB58A5FB-1A35-4471-86D0-A5189EC541B3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_pie_chart", "examples\shapes_pie_chart.vcxproj", "{61997220-5383-4AE5-ABD4-5F45AE1B0F2A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_directory_files", "examples\core_directory_files.vcxproj", "{7467E9AE-844F-444D-8A3F-17397544BA21}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_simple_particles", "examples\shapes_simple_particles.vcxproj", "{497FDF54-9762-4048-A833-61CC3980A0FB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_words_alignment", "examples\text_words_alignment.vcxproj", "{29B00F47-BE91-4A1F-B87D-B1302F038316}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_clipboard_text", "examples\core_clipboard_text.vcxproj", "{124935CC-73BB-489E-92E8-4F922A85DB5D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_clock_of_clocks", "examples\shapes_clock_of_clocks.vcxproj", "{AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_mouse_trail", "examples\shapes_mouse_trail.vcxproj", "{0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_starfield_effect", "examples\shapes_starfield_effect.vcxproj", "{EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_highdpi_testbed", "examples\core_highdpi_testbed.vcxproj", "{1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_screen_recording", "examples\core_screen_recording.vcxproj", "{9DE2FC01-A839-4F89-8319-9071D4C54821}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_text_file_loading", "examples\core_text_file_loading.vcxproj", "{2F578155-D51F-4C03-AB7F-5C5122CA46CC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_mandelbrot_set", "examples\shaders_mandelbrot_set.vcxproj", "{1C829D1A-892C-451C-AF0B-AC65C85F5CC6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_math_angle_rotation", "examples\shapes_math_angle_rotation.vcxproj", "{84DE22BB-C25F-425C-A7FE-0120CF107B83}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_color_correction", "examples\shaders_color_correction.vcxproj", "{98152EDD-7E28-4FA3-89D8-B636ED5D5F65}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_math_sine_cosine", "examples\shapes_math_sine_cosine.vcxproj", "{B7FDD40F-DDA4-468E-9C40-EEB175964A26}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_decals", "examples\models_decals.vcxproj", "{028F0967-B253-45DA-B1C4-FACCE45D0D8D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_lines_drawing", "examples\shapes_lines_drawing.vcxproj", "{666346D7-C84B-498D-AE17-53B20C62DB1A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_viewport_scaling", "examples\core_viewport_scaling.vcxproj", "{AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_compute_hash", "examples\core_compute_hash.vcxproj", "{6C897101-BE52-4387-8AA2-062123A76BA1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_screen_buffer", "examples\textures_screen_buffer.vcxproj", "{4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "audio_spectrum_visualizer", "examples\audio_spectrum_visualizer.vcxproj", "{2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_directional_billboard", "examples\models_directional_billboard.vcxproj", "{30011884-25EE-42C9-BB15-888CAFB1AA6E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_rlgl_color_wheel", "examples\shapes_rlgl_color_wheel.vcxproj", "{32FE2658-1D70-442E-8672-0AC5C6F0BD7B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_rlgl_triangle", "examples\shapes_rlgl_triangle.vcxproj", "{842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}" +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", "{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 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_hilbert_curve", "examples\shapes_hilbert_curve.vcxproj", "{DC163251-16C3-4B72-B965-ACDBA0F02BD1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_keyboard_testbed", "examples\core_keyboard_testbed.vcxproj", "{D35D2FDA-B53F-4F70-81CA-24D95812B89C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_framebuffer_rendering", "examples\textures_framebuffer_rendering.vcxproj", "{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug.DLL|ARM64 = Debug.DLL|ARM64 + Debug.DLL|x64 = Debug.DLL|x64 + Debug.DLL|x86 = Debug.DLL|x86 + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release.DLL|ARM64 = Release.DLL|ARM64 + Release.DLL|x64 = Release.DLL|x64 + Release.DLL|x86 = Release.DLL|x86 + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug|ARM64.Build.0 = Debug|ARM64 + {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug|x64.ActiveCfg = Debug|x64 + {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug|x64.Build.0 = Debug|x64 + {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug|x86.ActiveCfg = Debug|Win32 + {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug|x86.Build.0 = Debug|Win32 + {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release|ARM64.ActiveCfg = Release|ARM64 + {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release|ARM64.Build.0 = Release|ARM64 + {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release|x64.ActiveCfg = Release|x64 + {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release|x64.Build.0 = Release|x64 + {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release|x86.ActiveCfg = Release|Win32 + {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release|x86.Build.0 = Release|Win32 + {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug|ARM64.Build.0 = Debug|ARM64 + {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug|x64.ActiveCfg = Debug|x64 + {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug|x64.Build.0 = Debug|x64 + {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug|x86.ActiveCfg = Debug|Win32 + {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug|x86.Build.0 = Debug|Win32 + {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release|ARM64.ActiveCfg = Release|ARM64 + {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release|ARM64.Build.0 = Release|ARM64 + {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release|x64.ActiveCfg = Release|x64 + {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release|x64.Build.0 = Release|x64 + {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release|x86.ActiveCfg = Release|Win32 + {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release|x86.Build.0 = Release|Win32 + {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Debug|ARM64.Build.0 = Debug|ARM64 + {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Debug|x64.ActiveCfg = Debug|x64 + {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Debug|x64.Build.0 = Debug|x64 + {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Debug|x86.ActiveCfg = Debug|Win32 + {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Debug|x86.Build.0 = Debug|Win32 + {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Release|ARM64.ActiveCfg = Release|ARM64 + {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Release|ARM64.Build.0 = Release|ARM64 + {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Release|x64.ActiveCfg = Release|x64 + {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Release|x64.Build.0 = Release|x64 + {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Release|x86.ActiveCfg = Release|Win32 + {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}.Release|x86.Build.0 = Release|Win32 + {103B292B-049B-4B15-85A1-9F902840DB2C}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {103B292B-049B-4B15-85A1-9F902840DB2C}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {103B292B-049B-4B15-85A1-9F902840DB2C}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {103B292B-049B-4B15-85A1-9F902840DB2C}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {103B292B-049B-4B15-85A1-9F902840DB2C}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {103B292B-049B-4B15-85A1-9F902840DB2C}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {103B292B-049B-4B15-85A1-9F902840DB2C}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {103B292B-049B-4B15-85A1-9F902840DB2C}.Debug|ARM64.Build.0 = Debug|ARM64 + {103B292B-049B-4B15-85A1-9F902840DB2C}.Debug|x64.ActiveCfg = Debug|x64 + {103B292B-049B-4B15-85A1-9F902840DB2C}.Debug|x64.Build.0 = Debug|x64 + {103B292B-049B-4B15-85A1-9F902840DB2C}.Debug|x86.ActiveCfg = Debug|Win32 + {103B292B-049B-4B15-85A1-9F902840DB2C}.Debug|x86.Build.0 = Debug|Win32 + {103B292B-049B-4B15-85A1-9F902840DB2C}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {103B292B-049B-4B15-85A1-9F902840DB2C}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {103B292B-049B-4B15-85A1-9F902840DB2C}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {103B292B-049B-4B15-85A1-9F902840DB2C}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {103B292B-049B-4B15-85A1-9F902840DB2C}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {103B292B-049B-4B15-85A1-9F902840DB2C}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {103B292B-049B-4B15-85A1-9F902840DB2C}.Release|ARM64.ActiveCfg = Release|ARM64 + {103B292B-049B-4B15-85A1-9F902840DB2C}.Release|ARM64.Build.0 = Release|ARM64 + {103B292B-049B-4B15-85A1-9F902840DB2C}.Release|x64.ActiveCfg = Release|x64 + {103B292B-049B-4B15-85A1-9F902840DB2C}.Release|x64.Build.0 = Release|x64 + {103B292B-049B-4B15-85A1-9F902840DB2C}.Release|x86.ActiveCfg = Release|Win32 + {103B292B-049B-4B15-85A1-9F902840DB2C}.Release|x86.Build.0 = Release|Win32 + {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Debug|ARM64.Build.0 = Debug|ARM64 + {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Debug|x64.ActiveCfg = Debug|x64 + {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Debug|x64.Build.0 = Debug|x64 + {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Debug|x86.ActiveCfg = Debug|Win32 + {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Debug|x86.Build.0 = Debug|Win32 + {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Release|ARM64.ActiveCfg = Release|ARM64 + {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Release|ARM64.Build.0 = Release|ARM64 + {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Release|x64.ActiveCfg = Release|x64 + {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Release|x64.Build.0 = Release|x64 + {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Release|x86.ActiveCfg = Release|Win32 + {0C2D2F82-AE67-400C-B19C-8C9B957B132A}.Release|x86.Build.0 = Release|Win32 + {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Debug|ARM64.Build.0 = Debug|ARM64 + {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Debug|x64.ActiveCfg = Debug|x64 + {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Debug|x64.Build.0 = Debug|x64 + {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Debug|x86.ActiveCfg = Debug|Win32 + {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Debug|x86.Build.0 = Debug|Win32 + {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Release|ARM64.ActiveCfg = Release|ARM64 + {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Release|ARM64.Build.0 = Release|ARM64 + {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Release|x64.ActiveCfg = Release|x64 + {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Release|x64.Build.0 = Release|x64 + {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Release|x86.ActiveCfg = Release|Win32 + {E6784F91-4E4E-4956-A079-73FAB1AC7BE6}.Release|x86.Build.0 = Release|Win32 + {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Debug|ARM64.Build.0 = Debug|ARM64 + {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Debug|x64.ActiveCfg = Debug|x64 + {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Debug|x64.Build.0 = Debug|x64 + {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Debug|x86.ActiveCfg = Debug|Win32 + {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Debug|x86.Build.0 = Debug|Win32 + {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Release|ARM64.ActiveCfg = Release|ARM64 + {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Release|ARM64.Build.0 = Release|ARM64 + {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Release|x64.ActiveCfg = Release|x64 + {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Release|x64.Build.0 = Release|x64 + {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Release|x86.ActiveCfg = Release|Win32 + {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9}.Release|x86.Build.0 = Release|Win32 + {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Debug|ARM64.Build.0 = Debug|ARM64 + {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Debug|x64.ActiveCfg = Debug|x64 + {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Debug|x64.Build.0 = Debug|x64 + {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Debug|x86.ActiveCfg = Debug|Win32 + {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Debug|x86.Build.0 = Debug|Win32 + {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Release|ARM64.ActiveCfg = Release|ARM64 + {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Release|ARM64.Build.0 = Release|ARM64 + {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Release|x64.ActiveCfg = Release|x64 + {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Release|x64.Build.0 = Release|x64 + {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Release|x86.ActiveCfg = Release|Win32 + {93A1F656-0D29-4C5E-B140-11F23FF5D6AB}.Release|x86.Build.0 = Release|Win32 + {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Debug|ARM64.Build.0 = Debug|ARM64 + {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Debug|x64.ActiveCfg = Debug|x64 + {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Debug|x64.Build.0 = Debug|x64 + {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Debug|x86.ActiveCfg = Debug|Win32 + {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Debug|x86.Build.0 = Debug|Win32 + {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Release|ARM64.ActiveCfg = Release|ARM64 + {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Release|ARM64.Build.0 = Release|ARM64 + {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Release|x64.ActiveCfg = Release|x64 + {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Release|x64.Build.0 = Release|x64 + {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Release|x86.ActiveCfg = Release|Win32 + {F81C5819-85B6-4D2E-B6DC-104A7634461B}.Release|x86.Build.0 = Release|Win32 + {66CC5B13-881A-412F-8C51-746622A91C5A}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {66CC5B13-881A-412F-8C51-746622A91C5A}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {66CC5B13-881A-412F-8C51-746622A91C5A}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {66CC5B13-881A-412F-8C51-746622A91C5A}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {66CC5B13-881A-412F-8C51-746622A91C5A}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {66CC5B13-881A-412F-8C51-746622A91C5A}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {66CC5B13-881A-412F-8C51-746622A91C5A}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {66CC5B13-881A-412F-8C51-746622A91C5A}.Debug|ARM64.Build.0 = Debug|ARM64 + {66CC5B13-881A-412F-8C51-746622A91C5A}.Debug|x64.ActiveCfg = Debug|x64 + {66CC5B13-881A-412F-8C51-746622A91C5A}.Debug|x64.Build.0 = Debug|x64 + {66CC5B13-881A-412F-8C51-746622A91C5A}.Debug|x86.ActiveCfg = Debug|Win32 + {66CC5B13-881A-412F-8C51-746622A91C5A}.Debug|x86.Build.0 = Debug|Win32 + {66CC5B13-881A-412F-8C51-746622A91C5A}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {66CC5B13-881A-412F-8C51-746622A91C5A}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {66CC5B13-881A-412F-8C51-746622A91C5A}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {66CC5B13-881A-412F-8C51-746622A91C5A}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {66CC5B13-881A-412F-8C51-746622A91C5A}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {66CC5B13-881A-412F-8C51-746622A91C5A}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {66CC5B13-881A-412F-8C51-746622A91C5A}.Release|ARM64.ActiveCfg = Release|ARM64 + {66CC5B13-881A-412F-8C51-746622A91C5A}.Release|ARM64.Build.0 = Release|ARM64 + {66CC5B13-881A-412F-8C51-746622A91C5A}.Release|x64.ActiveCfg = Release|x64 + {66CC5B13-881A-412F-8C51-746622A91C5A}.Release|x64.Build.0 = Release|x64 + {66CC5B13-881A-412F-8C51-746622A91C5A}.Release|x86.ActiveCfg = Release|Win32 + {66CC5B13-881A-412F-8C51-746622A91C5A}.Release|x86.Build.0 = Release|Win32 + {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Debug|ARM64.Build.0 = Debug|ARM64 + {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Debug|x64.ActiveCfg = Debug|x64 + {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Debug|x64.Build.0 = Debug|x64 + {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Debug|x86.ActiveCfg = Debug|Win32 + {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Debug|x86.Build.0 = Debug|Win32 + {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Release|ARM64.ActiveCfg = Release|ARM64 + {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Release|ARM64.Build.0 = Release|ARM64 + {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Release|x64.ActiveCfg = Release|x64 + {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Release|x64.Build.0 = Release|x64 + {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Release|x86.ActiveCfg = Release|Win32 + {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B}.Release|x86.Build.0 = Release|Win32 + {557138B0-7BE2-4392-B2E2-B45734031A62}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {557138B0-7BE2-4392-B2E2-B45734031A62}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {557138B0-7BE2-4392-B2E2-B45734031A62}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {557138B0-7BE2-4392-B2E2-B45734031A62}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {557138B0-7BE2-4392-B2E2-B45734031A62}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {557138B0-7BE2-4392-B2E2-B45734031A62}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {557138B0-7BE2-4392-B2E2-B45734031A62}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {557138B0-7BE2-4392-B2E2-B45734031A62}.Debug|ARM64.Build.0 = Debug|ARM64 + {557138B0-7BE2-4392-B2E2-B45734031A62}.Debug|x64.ActiveCfg = Debug|x64 + {557138B0-7BE2-4392-B2E2-B45734031A62}.Debug|x64.Build.0 = Debug|x64 + {557138B0-7BE2-4392-B2E2-B45734031A62}.Debug|x86.ActiveCfg = Debug|Win32 + {557138B0-7BE2-4392-B2E2-B45734031A62}.Debug|x86.Build.0 = Debug|Win32 + {557138B0-7BE2-4392-B2E2-B45734031A62}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {557138B0-7BE2-4392-B2E2-B45734031A62}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {557138B0-7BE2-4392-B2E2-B45734031A62}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {557138B0-7BE2-4392-B2E2-B45734031A62}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {557138B0-7BE2-4392-B2E2-B45734031A62}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {557138B0-7BE2-4392-B2E2-B45734031A62}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {557138B0-7BE2-4392-B2E2-B45734031A62}.Release|ARM64.ActiveCfg = Release|ARM64 + {557138B0-7BE2-4392-B2E2-B45734031A62}.Release|ARM64.Build.0 = Release|ARM64 + {557138B0-7BE2-4392-B2E2-B45734031A62}.Release|x64.ActiveCfg = Release|x64 + {557138B0-7BE2-4392-B2E2-B45734031A62}.Release|x64.Build.0 = Release|x64 + {557138B0-7BE2-4392-B2E2-B45734031A62}.Release|x86.ActiveCfg = Release|Win32 + {557138B0-7BE2-4392-B2E2-B45734031A62}.Release|x86.Build.0 = Release|Win32 + {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Debug|ARM64.Build.0 = Debug|ARM64 + {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Debug|x64.ActiveCfg = Debug|x64 + {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Debug|x64.Build.0 = Debug|x64 + {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Debug|x86.ActiveCfg = Debug|Win32 + {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Debug|x86.Build.0 = Debug|Win32 + {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Release|ARM64.ActiveCfg = Release|ARM64 + {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Release|ARM64.Build.0 = Release|ARM64 + {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Release|x64.ActiveCfg = Release|x64 + {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Release|x64.Build.0 = Release|x64 + {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Release|x86.ActiveCfg = Release|Win32 + {9EED87BB-527F-4D05-9384-6D16CFD627A8}.Release|x86.Build.0 = Release|Win32 + {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Debug|ARM64.Build.0 = Debug|ARM64 + {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Debug|x64.ActiveCfg = Debug|x64 + {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Debug|x64.Build.0 = Debug|x64 + {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Debug|x86.ActiveCfg = Debug|Win32 + {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Debug|x86.Build.0 = Debug|Win32 + {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Release|ARM64.ActiveCfg = Release|ARM64 + {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Release|ARM64.Build.0 = Release|ARM64 + {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Release|x64.ActiveCfg = Release|x64 + {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Release|x64.Build.0 = Release|x64 + {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Release|x86.ActiveCfg = Release|Win32 + {6D1CA2F1-7FCA-4249-9220-075C2DF4F965}.Release|x86.Build.0 = Release|Win32 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug|ARM64.Build.0 = Debug|ARM64 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug|x64.ActiveCfg = Debug|x64 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug|x64.Build.0 = Debug|x64 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug|x86.ActiveCfg = Debug|Win32 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Debug|x86.Build.0 = Debug|Win32 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release|ARM64.ActiveCfg = Release|ARM64 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release|ARM64.Build.0 = Release|ARM64 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release|x64.ActiveCfg = Release|x64 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release|x64.Build.0 = Release|x64 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release|x86.ActiveCfg = Release|Win32 + {946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release|x86.Build.0 = Release|Win32 + {FD193822-3D5C-4161-A147-884C2ABDE483}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {FD193822-3D5C-4161-A147-884C2ABDE483}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {FD193822-3D5C-4161-A147-884C2ABDE483}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {FD193822-3D5C-4161-A147-884C2ABDE483}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {FD193822-3D5C-4161-A147-884C2ABDE483}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {FD193822-3D5C-4161-A147-884C2ABDE483}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {FD193822-3D5C-4161-A147-884C2ABDE483}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {FD193822-3D5C-4161-A147-884C2ABDE483}.Debug|ARM64.Build.0 = Debug|ARM64 + {FD193822-3D5C-4161-A147-884C2ABDE483}.Debug|x64.ActiveCfg = Debug|x64 + {FD193822-3D5C-4161-A147-884C2ABDE483}.Debug|x64.Build.0 = Debug|x64 + {FD193822-3D5C-4161-A147-884C2ABDE483}.Debug|x86.ActiveCfg = Debug|Win32 + {FD193822-3D5C-4161-A147-884C2ABDE483}.Debug|x86.Build.0 = Debug|Win32 + {FD193822-3D5C-4161-A147-884C2ABDE483}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {FD193822-3D5C-4161-A147-884C2ABDE483}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {FD193822-3D5C-4161-A147-884C2ABDE483}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {FD193822-3D5C-4161-A147-884C2ABDE483}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {FD193822-3D5C-4161-A147-884C2ABDE483}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {FD193822-3D5C-4161-A147-884C2ABDE483}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {FD193822-3D5C-4161-A147-884C2ABDE483}.Release|ARM64.ActiveCfg = Release|ARM64 + {FD193822-3D5C-4161-A147-884C2ABDE483}.Release|ARM64.Build.0 = Release|ARM64 + {FD193822-3D5C-4161-A147-884C2ABDE483}.Release|x64.ActiveCfg = Release|x64 + {FD193822-3D5C-4161-A147-884C2ABDE483}.Release|x64.Build.0 = Release|x64 + {FD193822-3D5C-4161-A147-884C2ABDE483}.Release|x86.ActiveCfg = Release|Win32 + {FD193822-3D5C-4161-A147-884C2ABDE483}.Release|x86.Build.0 = Release|Win32 + {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Debug|ARM64.Build.0 = Debug|ARM64 + {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Debug|x64.ActiveCfg = Debug|x64 + {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Debug|x64.Build.0 = Debug|x64 + {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Debug|x86.ActiveCfg = Debug|Win32 + {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Debug|x86.Build.0 = Debug|Win32 + {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Release|ARM64.ActiveCfg = Release|ARM64 + {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Release|ARM64.Build.0 = Release|ARM64 + {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Release|x64.ActiveCfg = Release|x64 + {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Release|x64.Build.0 = Release|x64 + {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Release|x86.ActiveCfg = Release|Win32 + {20AD0AC9-9159-4744-99CC-6AC5779D6B87}.Release|x86.Build.0 = Release|Win32 + {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Debug|ARM64.Build.0 = Debug|ARM64 + {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Debug|x64.ActiveCfg = Debug|x64 + {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Debug|x64.Build.0 = Debug|x64 + {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Debug|x86.ActiveCfg = Debug|Win32 + {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Debug|x86.Build.0 = Debug|Win32 + {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Release|ARM64.ActiveCfg = Release|ARM64 + {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Release|ARM64.Build.0 = Release|ARM64 + {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Release|x64.ActiveCfg = Release|x64 + {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Release|x64.Build.0 = Release|x64 + {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Release|x86.ActiveCfg = Release|Win32 + {0199E349-0701-40BC-8A7F-06A54FFA3E7C}.Release|x86.Build.0 = Release|Win32 + {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Debug|ARM64.Build.0 = Debug|ARM64 + {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Debug|x64.ActiveCfg = Debug|x64 + {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Debug|x64.Build.0 = Debug|x64 + {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Debug|x86.ActiveCfg = Debug|Win32 + {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Debug|x86.Build.0 = Debug|Win32 + {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Release|ARM64.ActiveCfg = Release|ARM64 + {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Release|ARM64.Build.0 = Release|ARM64 + {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Release|x64.ActiveCfg = Release|x64 + {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Release|x64.Build.0 = Release|x64 + {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Release|x86.ActiveCfg = Release|Win32 + {BCB71111-8505-4B35-8CEF-EC6115DC9D4D}.Release|x86.Build.0 = Release|Win32 + {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Debug|ARM64.Build.0 = Debug|ARM64 + {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Debug|x64.ActiveCfg = Debug|x64 + {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Debug|x64.Build.0 = Debug|x64 + {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Debug|x86.ActiveCfg = Debug|Win32 + {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Debug|x86.Build.0 = Debug|Win32 + {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Release|ARM64.ActiveCfg = Release|ARM64 + {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Release|ARM64.Build.0 = Release|ARM64 + {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Release|x64.ActiveCfg = Release|x64 + {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Release|x64.Build.0 = Release|x64 + {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Release|x86.ActiveCfg = Release|Win32 + {8F19E3DA-8929-4000-87B5-3CA6929636CC}.Release|x86.Build.0 = Release|Win32 + {51A00565-5787-4911-9CC0-28403AA4909D}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {51A00565-5787-4911-9CC0-28403AA4909D}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {51A00565-5787-4911-9CC0-28403AA4909D}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {51A00565-5787-4911-9CC0-28403AA4909D}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {51A00565-5787-4911-9CC0-28403AA4909D}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {51A00565-5787-4911-9CC0-28403AA4909D}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {51A00565-5787-4911-9CC0-28403AA4909D}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {51A00565-5787-4911-9CC0-28403AA4909D}.Debug|ARM64.Build.0 = Debug|ARM64 + {51A00565-5787-4911-9CC0-28403AA4909D}.Debug|x64.ActiveCfg = Debug|x64 + {51A00565-5787-4911-9CC0-28403AA4909D}.Debug|x64.Build.0 = Debug|x64 + {51A00565-5787-4911-9CC0-28403AA4909D}.Debug|x86.ActiveCfg = Debug|Win32 + {51A00565-5787-4911-9CC0-28403AA4909D}.Debug|x86.Build.0 = Debug|Win32 + {51A00565-5787-4911-9CC0-28403AA4909D}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {51A00565-5787-4911-9CC0-28403AA4909D}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {51A00565-5787-4911-9CC0-28403AA4909D}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {51A00565-5787-4911-9CC0-28403AA4909D}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {51A00565-5787-4911-9CC0-28403AA4909D}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {51A00565-5787-4911-9CC0-28403AA4909D}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {51A00565-5787-4911-9CC0-28403AA4909D}.Release|ARM64.ActiveCfg = Release|ARM64 + {51A00565-5787-4911-9CC0-28403AA4909D}.Release|ARM64.Build.0 = Release|ARM64 + {51A00565-5787-4911-9CC0-28403AA4909D}.Release|x64.ActiveCfg = Release|x64 + {51A00565-5787-4911-9CC0-28403AA4909D}.Release|x64.Build.0 = Release|x64 + {51A00565-5787-4911-9CC0-28403AA4909D}.Release|x86.ActiveCfg = Release|Win32 + {51A00565-5787-4911-9CC0-28403AA4909D}.Release|x86.Build.0 = Release|Win32 + {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Debug|ARM64.Build.0 = Debug|ARM64 + {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Debug|x64.ActiveCfg = Debug|x64 + {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Debug|x64.Build.0 = Debug|x64 + {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Debug|x86.ActiveCfg = Debug|Win32 + {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Debug|x86.Build.0 = Debug|Win32 + {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Release|ARM64.ActiveCfg = Release|ARM64 + {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Release|ARM64.Build.0 = Release|ARM64 + {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Release|x64.ActiveCfg = Release|x64 + {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Release|x64.Build.0 = Release|x64 + {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Release|x86.ActiveCfg = Release|Win32 + {92B64AE7-D773-4F05-89F1-CE59BBF4F053}.Release|x86.Build.0 = Release|Win32 + {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Debug|ARM64.Build.0 = Debug|ARM64 + {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Debug|x64.ActiveCfg = Debug|x64 + {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Debug|x64.Build.0 = Debug|x64 + {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Debug|x86.ActiveCfg = Debug|Win32 + {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Debug|x86.Build.0 = Debug|Win32 + {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Release|ARM64.ActiveCfg = Release|ARM64 + {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Release|ARM64.Build.0 = Release|ARM64 + {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Release|x64.ActiveCfg = Release|x64 + {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Release|x64.Build.0 = Release|x64 + {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Release|x86.ActiveCfg = Release|Win32 + {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3}.Release|x86.Build.0 = Release|Win32 + {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Debug|ARM64.Build.0 = Debug|ARM64 + {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Debug|x64.ActiveCfg = Debug|x64 + {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Debug|x64.Build.0 = Debug|x64 + {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Debug|x86.ActiveCfg = Debug|Win32 + {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Debug|x86.Build.0 = Debug|Win32 + {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Release|ARM64.ActiveCfg = Release|ARM64 + {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Release|ARM64.Build.0 = Release|ARM64 + {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Release|x64.ActiveCfg = Release|x64 + {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Release|x64.Build.0 = Release|x64 + {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Release|x86.ActiveCfg = Release|Win32 + {A643BB06-735D-47F3-BFE7-B6D3C36F7097}.Release|x86.Build.0 = Release|Win32 + {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug|ARM64.Build.0 = Debug|ARM64 + {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug|x64.ActiveCfg = Debug|x64 + {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug|x64.Build.0 = Debug|x64 + {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug|x86.ActiveCfg = Debug|Win32 + {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug|x86.Build.0 = Debug|Win32 + {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Release|ARM64.ActiveCfg = Release|ARM64 + {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Release|ARM64.Build.0 = Release|ARM64 + {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Release|x64.ActiveCfg = Release|x64 + {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Release|x64.Build.0 = Release|x64 + {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Release|x86.ActiveCfg = Release|Win32 + {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Release|x86.Build.0 = Release|Win32 + {B332DCA8-3599-4A99-917A-82261BDC27AC}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {B332DCA8-3599-4A99-917A-82261BDC27AC}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {B332DCA8-3599-4A99-917A-82261BDC27AC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {B332DCA8-3599-4A99-917A-82261BDC27AC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {B332DCA8-3599-4A99-917A-82261BDC27AC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {B332DCA8-3599-4A99-917A-82261BDC27AC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {B332DCA8-3599-4A99-917A-82261BDC27AC}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {B332DCA8-3599-4A99-917A-82261BDC27AC}.Debug|ARM64.Build.0 = Debug|ARM64 + {B332DCA8-3599-4A99-917A-82261BDC27AC}.Debug|x64.ActiveCfg = Debug|x64 + {B332DCA8-3599-4A99-917A-82261BDC27AC}.Debug|x64.Build.0 = Debug|x64 + {B332DCA8-3599-4A99-917A-82261BDC27AC}.Debug|x86.ActiveCfg = Debug|Win32 + {B332DCA8-3599-4A99-917A-82261BDC27AC}.Debug|x86.Build.0 = Debug|Win32 + {B332DCA8-3599-4A99-917A-82261BDC27AC}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {B332DCA8-3599-4A99-917A-82261BDC27AC}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {B332DCA8-3599-4A99-917A-82261BDC27AC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {B332DCA8-3599-4A99-917A-82261BDC27AC}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {B332DCA8-3599-4A99-917A-82261BDC27AC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {B332DCA8-3599-4A99-917A-82261BDC27AC}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {B332DCA8-3599-4A99-917A-82261BDC27AC}.Release|ARM64.ActiveCfg = Release|ARM64 + {B332DCA8-3599-4A99-917A-82261BDC27AC}.Release|ARM64.Build.0 = Release|ARM64 + {B332DCA8-3599-4A99-917A-82261BDC27AC}.Release|x64.ActiveCfg = Release|x64 + {B332DCA8-3599-4A99-917A-82261BDC27AC}.Release|x64.Build.0 = Release|x64 + {B332DCA8-3599-4A99-917A-82261BDC27AC}.Release|x86.ActiveCfg = Release|Win32 + {B332DCA8-3599-4A99-917A-82261BDC27AC}.Release|x86.Build.0 = Release|Win32 + {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Debug|ARM64.Build.0 = Debug|ARM64 + {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Debug|x64.ActiveCfg = Debug|x64 + {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Debug|x64.Build.0 = Debug|x64 + {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Debug|x86.ActiveCfg = Debug|Win32 + {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Debug|x86.Build.0 = Debug|Win32 + {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Release|ARM64.ActiveCfg = Release|ARM64 + {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Release|ARM64.Build.0 = Release|ARM64 + {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Release|x64.ActiveCfg = Release|x64 + {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Release|x64.Build.0 = Release|x64 + {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Release|x86.ActiveCfg = Release|Win32 + {59089B0C-AAB4-4532-B294-44DEAE7178B7}.Release|x86.Build.0 = Release|Win32 + {C298876B-6C12-4EA4-903B-33450BCD9884}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {C298876B-6C12-4EA4-903B-33450BCD9884}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {C298876B-6C12-4EA4-903B-33450BCD9884}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {C298876B-6C12-4EA4-903B-33450BCD9884}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {C298876B-6C12-4EA4-903B-33450BCD9884}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {C298876B-6C12-4EA4-903B-33450BCD9884}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {C298876B-6C12-4EA4-903B-33450BCD9884}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {C298876B-6C12-4EA4-903B-33450BCD9884}.Debug|ARM64.Build.0 = Debug|ARM64 + {C298876B-6C12-4EA4-903B-33450BCD9884}.Debug|x64.ActiveCfg = Debug|x64 + {C298876B-6C12-4EA4-903B-33450BCD9884}.Debug|x64.Build.0 = Debug|x64 + {C298876B-6C12-4EA4-903B-33450BCD9884}.Debug|x86.ActiveCfg = Debug|Win32 + {C298876B-6C12-4EA4-903B-33450BCD9884}.Debug|x86.Build.0 = Debug|Win32 + {C298876B-6C12-4EA4-903B-33450BCD9884}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {C298876B-6C12-4EA4-903B-33450BCD9884}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {C298876B-6C12-4EA4-903B-33450BCD9884}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {C298876B-6C12-4EA4-903B-33450BCD9884}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {C298876B-6C12-4EA4-903B-33450BCD9884}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {C298876B-6C12-4EA4-903B-33450BCD9884}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {C298876B-6C12-4EA4-903B-33450BCD9884}.Release|ARM64.ActiveCfg = Release|ARM64 + {C298876B-6C12-4EA4-903B-33450BCD9884}.Release|ARM64.Build.0 = Release|ARM64 + {C298876B-6C12-4EA4-903B-33450BCD9884}.Release|x64.ActiveCfg = Release|x64 + {C298876B-6C12-4EA4-903B-33450BCD9884}.Release|x64.Build.0 = Release|x64 + {C298876B-6C12-4EA4-903B-33450BCD9884}.Release|x86.ActiveCfg = Release|Win32 + {C298876B-6C12-4EA4-903B-33450BCD9884}.Release|x86.Build.0 = Release|Win32 + {83F586FA-C801-4979-ACCA-006BD628CC88}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {83F586FA-C801-4979-ACCA-006BD628CC88}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {83F586FA-C801-4979-ACCA-006BD628CC88}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {83F586FA-C801-4979-ACCA-006BD628CC88}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {83F586FA-C801-4979-ACCA-006BD628CC88}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {83F586FA-C801-4979-ACCA-006BD628CC88}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {83F586FA-C801-4979-ACCA-006BD628CC88}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {83F586FA-C801-4979-ACCA-006BD628CC88}.Debug|ARM64.Build.0 = Debug|ARM64 + {83F586FA-C801-4979-ACCA-006BD628CC88}.Debug|x64.ActiveCfg = Debug|x64 + {83F586FA-C801-4979-ACCA-006BD628CC88}.Debug|x64.Build.0 = Debug|x64 + {83F586FA-C801-4979-ACCA-006BD628CC88}.Debug|x86.ActiveCfg = Debug|Win32 + {83F586FA-C801-4979-ACCA-006BD628CC88}.Debug|x86.Build.0 = Debug|Win32 + {83F586FA-C801-4979-ACCA-006BD628CC88}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {83F586FA-C801-4979-ACCA-006BD628CC88}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {83F586FA-C801-4979-ACCA-006BD628CC88}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {83F586FA-C801-4979-ACCA-006BD628CC88}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {83F586FA-C801-4979-ACCA-006BD628CC88}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {83F586FA-C801-4979-ACCA-006BD628CC88}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {83F586FA-C801-4979-ACCA-006BD628CC88}.Release|ARM64.ActiveCfg = Release|ARM64 + {83F586FA-C801-4979-ACCA-006BD628CC88}.Release|ARM64.Build.0 = Release|ARM64 + {83F586FA-C801-4979-ACCA-006BD628CC88}.Release|x64.ActiveCfg = Release|x64 + {83F586FA-C801-4979-ACCA-006BD628CC88}.Release|x64.Build.0 = Release|x64 + {83F586FA-C801-4979-ACCA-006BD628CC88}.Release|x86.ActiveCfg = Release|Win32 + {83F586FA-C801-4979-ACCA-006BD628CC88}.Release|x86.Build.0 = Release|Win32 + {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Debug|ARM64.Build.0 = Debug|ARM64 + {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Debug|x64.ActiveCfg = Debug|x64 + {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Debug|x64.Build.0 = Debug|x64 + {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Debug|x86.ActiveCfg = Debug|Win32 + {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Debug|x86.Build.0 = Debug|Win32 + {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Release|ARM64.ActiveCfg = Release|ARM64 + {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Release|ARM64.Build.0 = Release|ARM64 + {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Release|x64.ActiveCfg = Release|x64 + {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Release|x64.Build.0 = Release|x64 + {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Release|x86.ActiveCfg = Release|Win32 + {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22}.Release|x86.Build.0 = Release|Win32 + {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Debug|ARM64.Build.0 = Debug|ARM64 + {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Debug|x64.ActiveCfg = Debug|x64 + {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Debug|x64.Build.0 = Debug|x64 + {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Debug|x86.ActiveCfg = Debug|Win32 + {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Debug|x86.Build.0 = Debug|Win32 + {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Release|ARM64.ActiveCfg = Release|ARM64 + {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Release|ARM64.Build.0 = Release|ARM64 + {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Release|x64.ActiveCfg = Release|x64 + {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Release|x64.Build.0 = Release|x64 + {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Release|x86.ActiveCfg = Release|Win32 + {FF2970AE-E2E9-405F-B321-D523A1BD44A0}.Release|x86.Build.0 = Release|Win32 + {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Debug|ARM64.Build.0 = Debug|ARM64 + {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Debug|x64.ActiveCfg = Debug|x64 + {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Debug|x64.Build.0 = Debug|x64 + {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Debug|x86.ActiveCfg = Debug|Win32 + {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Debug|x86.Build.0 = Debug|Win32 + {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Release|ARM64.ActiveCfg = Release|ARM64 + {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Release|ARM64.Build.0 = Release|ARM64 + {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Release|x64.ActiveCfg = Release|x64 + {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Release|x64.Build.0 = Release|x64 + {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Release|x86.ActiveCfg = Release|Win32 + {79417CE2-FEEB-42F0-BC53-62D5267B19B1}.Release|x86.Build.0 = Release|Win32 + {AFDDE100-2D36-4749-817D-12E54C56312F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {AFDDE100-2D36-4749-817D-12E54C56312F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {AFDDE100-2D36-4749-817D-12E54C56312F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {AFDDE100-2D36-4749-817D-12E54C56312F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {AFDDE100-2D36-4749-817D-12E54C56312F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {AFDDE100-2D36-4749-817D-12E54C56312F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {AFDDE100-2D36-4749-817D-12E54C56312F}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {AFDDE100-2D36-4749-817D-12E54C56312F}.Debug|ARM64.Build.0 = Debug|ARM64 + {AFDDE100-2D36-4749-817D-12E54C56312F}.Debug|x64.ActiveCfg = Debug|x64 + {AFDDE100-2D36-4749-817D-12E54C56312F}.Debug|x64.Build.0 = Debug|x64 + {AFDDE100-2D36-4749-817D-12E54C56312F}.Debug|x86.ActiveCfg = Debug|Win32 + {AFDDE100-2D36-4749-817D-12E54C56312F}.Debug|x86.Build.0 = Debug|Win32 + {AFDDE100-2D36-4749-817D-12E54C56312F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {AFDDE100-2D36-4749-817D-12E54C56312F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {AFDDE100-2D36-4749-817D-12E54C56312F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {AFDDE100-2D36-4749-817D-12E54C56312F}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {AFDDE100-2D36-4749-817D-12E54C56312F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {AFDDE100-2D36-4749-817D-12E54C56312F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {AFDDE100-2D36-4749-817D-12E54C56312F}.Release|ARM64.ActiveCfg = Release|ARM64 + {AFDDE100-2D36-4749-817D-12E54C56312F}.Release|ARM64.Build.0 = Release|ARM64 + {AFDDE100-2D36-4749-817D-12E54C56312F}.Release|x64.ActiveCfg = Release|x64 + {AFDDE100-2D36-4749-817D-12E54C56312F}.Release|x64.Build.0 = Release|x64 + {AFDDE100-2D36-4749-817D-12E54C56312F}.Release|x86.ActiveCfg = Release|Win32 + {AFDDE100-2D36-4749-817D-12E54C56312F}.Release|x86.Build.0 = Release|Win32 + {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Debug|ARM64.Build.0 = Debug|ARM64 + {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Debug|x64.ActiveCfg = Debug|x64 + {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Debug|x64.Build.0 = Debug|x64 + {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Debug|x86.ActiveCfg = Debug|Win32 + {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Debug|x86.Build.0 = Debug|Win32 + {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Release|ARM64.ActiveCfg = Release|ARM64 + {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Release|ARM64.Build.0 = Release|ARM64 + {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Release|x64.ActiveCfg = Release|x64 + {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Release|x64.Build.0 = Release|x64 + {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Release|x86.ActiveCfg = Release|Win32 + {B7812167-50FB-4934-996F-DF6FE4CBBFDF}.Release|x86.Build.0 = Release|Win32 + {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Debug|ARM64.Build.0 = Debug|ARM64 + {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Debug|x64.ActiveCfg = Debug|x64 + {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Debug|x64.Build.0 = Debug|x64 + {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Debug|x86.ActiveCfg = Debug|Win32 + {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Debug|x86.Build.0 = Debug|Win32 + {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Release|ARM64.ActiveCfg = Release|ARM64 + {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Release|ARM64.Build.0 = Release|ARM64 + {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Release|x64.ActiveCfg = Release|x64 + {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Release|x64.Build.0 = Release|x64 + {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Release|x86.ActiveCfg = Release|Win32 + {39DB56C7-05F8-492C-A8D4-F19E40FECB59}.Release|x86.Build.0 = Release|Win32 + {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Debug|ARM64.Build.0 = Debug|ARM64 + {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Debug|x64.ActiveCfg = Debug|x64 + {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Debug|x64.Build.0 = Debug|x64 + {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Debug|x86.ActiveCfg = Debug|Win32 + {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Debug|x86.Build.0 = Debug|Win32 + {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Release|ARM64.ActiveCfg = Release|ARM64 + {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Release|ARM64.Build.0 = Release|ARM64 + {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Release|x64.ActiveCfg = Release|x64 + {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Release|x64.Build.0 = Release|x64 + {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Release|x86.ActiveCfg = Release|Win32 + {82F3D34B-8DB2-4C6A-98B1-132245DD9D99}.Release|x86.Build.0 = Release|Win32 + {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Debug|ARM64.Build.0 = Debug|ARM64 + {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Debug|x64.ActiveCfg = Debug|x64 + {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Debug|x64.Build.0 = Debug|x64 + {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Debug|x86.ActiveCfg = Debug|Win32 + {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Debug|x86.Build.0 = Debug|Win32 + {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Release|ARM64.ActiveCfg = Release|ARM64 + {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Release|ARM64.Build.0 = Release|ARM64 + {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Release|x64.ActiveCfg = Release|x64 + {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Release|x64.Build.0 = Release|x64 + {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Release|x86.ActiveCfg = Release|Win32 + {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62}.Release|x86.Build.0 = Release|Win32 + {14BA7F98-02CC-4648-9236-676BFF9458AF}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {14BA7F98-02CC-4648-9236-676BFF9458AF}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {14BA7F98-02CC-4648-9236-676BFF9458AF}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {14BA7F98-02CC-4648-9236-676BFF9458AF}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {14BA7F98-02CC-4648-9236-676BFF9458AF}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {14BA7F98-02CC-4648-9236-676BFF9458AF}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {14BA7F98-02CC-4648-9236-676BFF9458AF}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {14BA7F98-02CC-4648-9236-676BFF9458AF}.Debug|ARM64.Build.0 = Debug|ARM64 + {14BA7F98-02CC-4648-9236-676BFF9458AF}.Debug|x64.ActiveCfg = Debug|x64 + {14BA7F98-02CC-4648-9236-676BFF9458AF}.Debug|x64.Build.0 = Debug|x64 + {14BA7F98-02CC-4648-9236-676BFF9458AF}.Debug|x86.ActiveCfg = Debug|Win32 + {14BA7F98-02CC-4648-9236-676BFF9458AF}.Debug|x86.Build.0 = Debug|Win32 + {14BA7F98-02CC-4648-9236-676BFF9458AF}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {14BA7F98-02CC-4648-9236-676BFF9458AF}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {14BA7F98-02CC-4648-9236-676BFF9458AF}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {14BA7F98-02CC-4648-9236-676BFF9458AF}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {14BA7F98-02CC-4648-9236-676BFF9458AF}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {14BA7F98-02CC-4648-9236-676BFF9458AF}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {14BA7F98-02CC-4648-9236-676BFF9458AF}.Release|ARM64.ActiveCfg = Release|ARM64 + {14BA7F98-02CC-4648-9236-676BFF9458AF}.Release|ARM64.Build.0 = Release|ARM64 + {14BA7F98-02CC-4648-9236-676BFF9458AF}.Release|x64.ActiveCfg = Release|x64 + {14BA7F98-02CC-4648-9236-676BFF9458AF}.Release|x64.Build.0 = Release|x64 + {14BA7F98-02CC-4648-9236-676BFF9458AF}.Release|x86.ActiveCfg = Release|Win32 + {14BA7F98-02CC-4648-9236-676BFF9458AF}.Release|x86.Build.0 = Release|Win32 + {0859A973-E4FE-4688-8D16-0253163FDE24}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {0859A973-E4FE-4688-8D16-0253163FDE24}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {0859A973-E4FE-4688-8D16-0253163FDE24}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {0859A973-E4FE-4688-8D16-0253163FDE24}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {0859A973-E4FE-4688-8D16-0253163FDE24}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {0859A973-E4FE-4688-8D16-0253163FDE24}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {0859A973-E4FE-4688-8D16-0253163FDE24}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {0859A973-E4FE-4688-8D16-0253163FDE24}.Debug|ARM64.Build.0 = Debug|ARM64 + {0859A973-E4FE-4688-8D16-0253163FDE24}.Debug|x64.ActiveCfg = Debug|x64 + {0859A973-E4FE-4688-8D16-0253163FDE24}.Debug|x64.Build.0 = Debug|x64 + {0859A973-E4FE-4688-8D16-0253163FDE24}.Debug|x86.ActiveCfg = Debug|Win32 + {0859A973-E4FE-4688-8D16-0253163FDE24}.Debug|x86.Build.0 = Debug|Win32 + {0859A973-E4FE-4688-8D16-0253163FDE24}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {0859A973-E4FE-4688-8D16-0253163FDE24}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {0859A973-E4FE-4688-8D16-0253163FDE24}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {0859A973-E4FE-4688-8D16-0253163FDE24}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {0859A973-E4FE-4688-8D16-0253163FDE24}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {0859A973-E4FE-4688-8D16-0253163FDE24}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {0859A973-E4FE-4688-8D16-0253163FDE24}.Release|ARM64.ActiveCfg = Release|ARM64 + {0859A973-E4FE-4688-8D16-0253163FDE24}.Release|ARM64.Build.0 = Release|ARM64 + {0859A973-E4FE-4688-8D16-0253163FDE24}.Release|x64.ActiveCfg = Release|x64 + {0859A973-E4FE-4688-8D16-0253163FDE24}.Release|x64.Build.0 = Release|x64 + {0859A973-E4FE-4688-8D16-0253163FDE24}.Release|x86.ActiveCfg = Release|Win32 + {0859A973-E4FE-4688-8D16-0253163FDE24}.Release|x86.Build.0 = Release|Win32 + {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Debug|ARM64.Build.0 = Debug|ARM64 + {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Debug|x64.ActiveCfg = Debug|x64 + {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Debug|x64.Build.0 = Debug|x64 + {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Debug|x86.ActiveCfg = Debug|Win32 + {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Debug|x86.Build.0 = Debug|Win32 + {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Release|ARM64.ActiveCfg = Release|ARM64 + {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Release|ARM64.Build.0 = Release|ARM64 + {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Release|x64.ActiveCfg = Release|x64 + {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Release|x64.Build.0 = Release|x64 + {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Release|x86.ActiveCfg = Release|Win32 + {F3412853-2B6A-4334-8CF2-B796CDAE0850}.Release|x86.Build.0 = Release|Win32 + {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Debug|ARM64.Build.0 = Debug|ARM64 + {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Debug|x64.ActiveCfg = Debug|x64 + {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Debug|x64.Build.0 = Debug|x64 + {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Debug|x86.ActiveCfg = Debug|Win32 + {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Debug|x86.Build.0 = Debug|Win32 + {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Release|ARM64.ActiveCfg = Release|ARM64 + {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Release|ARM64.Build.0 = Release|ARM64 + {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Release|x64.ActiveCfg = Release|x64 + {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Release|x64.Build.0 = Release|x64 + {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Release|x86.ActiveCfg = Release|Win32 + {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Release|x86.Build.0 = Release|Win32 + {D03F2C82-9553-4AFA-8F49-9234009122B6}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {D03F2C82-9553-4AFA-8F49-9234009122B6}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {D03F2C82-9553-4AFA-8F49-9234009122B6}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {D03F2C82-9553-4AFA-8F49-9234009122B6}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {D03F2C82-9553-4AFA-8F49-9234009122B6}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {D03F2C82-9553-4AFA-8F49-9234009122B6}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {D03F2C82-9553-4AFA-8F49-9234009122B6}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {D03F2C82-9553-4AFA-8F49-9234009122B6}.Debug|ARM64.Build.0 = Debug|ARM64 + {D03F2C82-9553-4AFA-8F49-9234009122B6}.Debug|x64.ActiveCfg = Debug|x64 + {D03F2C82-9553-4AFA-8F49-9234009122B6}.Debug|x64.Build.0 = Debug|x64 + {D03F2C82-9553-4AFA-8F49-9234009122B6}.Debug|x86.ActiveCfg = Debug|Win32 + {D03F2C82-9553-4AFA-8F49-9234009122B6}.Debug|x86.Build.0 = Debug|Win32 + {D03F2C82-9553-4AFA-8F49-9234009122B6}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {D03F2C82-9553-4AFA-8F49-9234009122B6}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {D03F2C82-9553-4AFA-8F49-9234009122B6}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {D03F2C82-9553-4AFA-8F49-9234009122B6}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {D03F2C82-9553-4AFA-8F49-9234009122B6}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {D03F2C82-9553-4AFA-8F49-9234009122B6}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {D03F2C82-9553-4AFA-8F49-9234009122B6}.Release|ARM64.ActiveCfg = Release|ARM64 + {D03F2C82-9553-4AFA-8F49-9234009122B6}.Release|ARM64.Build.0 = Release|ARM64 + {D03F2C82-9553-4AFA-8F49-9234009122B6}.Release|x64.ActiveCfg = Release|x64 + {D03F2C82-9553-4AFA-8F49-9234009122B6}.Release|x64.Build.0 = Release|x64 + {D03F2C82-9553-4AFA-8F49-9234009122B6}.Release|x86.ActiveCfg = Release|Win32 + {D03F2C82-9553-4AFA-8F49-9234009122B6}.Release|x86.Build.0 = Release|Win32 + {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Debug|ARM64.Build.0 = Debug|ARM64 + {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Debug|x64.ActiveCfg = Debug|x64 + {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Debug|x64.Build.0 = Debug|x64 + {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Debug|x86.ActiveCfg = Debug|Win32 + {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Debug|x86.Build.0 = Debug|Win32 + {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Release|ARM64.ActiveCfg = Release|ARM64 + {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Release|ARM64.Build.0 = Release|ARM64 + {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Release|x64.ActiveCfg = Release|x64 + {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Release|x64.Build.0 = Release|x64 + {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Release|x86.ActiveCfg = Release|Win32 + {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3}.Release|x86.Build.0 = Release|Win32 + {A53CCF42-A972-478F-9336-0F618B3EC06A}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {A53CCF42-A972-478F-9336-0F618B3EC06A}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {A53CCF42-A972-478F-9336-0F618B3EC06A}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {A53CCF42-A972-478F-9336-0F618B3EC06A}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {A53CCF42-A972-478F-9336-0F618B3EC06A}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {A53CCF42-A972-478F-9336-0F618B3EC06A}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {A53CCF42-A972-478F-9336-0F618B3EC06A}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {A53CCF42-A972-478F-9336-0F618B3EC06A}.Debug|ARM64.Build.0 = Debug|ARM64 + {A53CCF42-A972-478F-9336-0F618B3EC06A}.Debug|x64.ActiveCfg = Debug|x64 + {A53CCF42-A972-478F-9336-0F618B3EC06A}.Debug|x64.Build.0 = Debug|x64 + {A53CCF42-A972-478F-9336-0F618B3EC06A}.Debug|x86.ActiveCfg = Debug|Win32 + {A53CCF42-A972-478F-9336-0F618B3EC06A}.Debug|x86.Build.0 = Debug|Win32 + {A53CCF42-A972-478F-9336-0F618B3EC06A}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {A53CCF42-A972-478F-9336-0F618B3EC06A}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {A53CCF42-A972-478F-9336-0F618B3EC06A}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {A53CCF42-A972-478F-9336-0F618B3EC06A}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {A53CCF42-A972-478F-9336-0F618B3EC06A}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {A53CCF42-A972-478F-9336-0F618B3EC06A}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {A53CCF42-A972-478F-9336-0F618B3EC06A}.Release|ARM64.ActiveCfg = Release|ARM64 + {A53CCF42-A972-478F-9336-0F618B3EC06A}.Release|ARM64.Build.0 = Release|ARM64 + {A53CCF42-A972-478F-9336-0F618B3EC06A}.Release|x64.ActiveCfg = Release|x64 + {A53CCF42-A972-478F-9336-0F618B3EC06A}.Release|x64.Build.0 = Release|x64 + {A53CCF42-A972-478F-9336-0F618B3EC06A}.Release|x86.ActiveCfg = Release|Win32 + {A53CCF42-A972-478F-9336-0F618B3EC06A}.Release|x86.Build.0 = Release|Win32 + {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Debug|ARM64.Build.0 = Debug|ARM64 + {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Debug|x64.ActiveCfg = Debug|x64 + {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Debug|x64.Build.0 = Debug|x64 + {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Debug|x86.ActiveCfg = Debug|Win32 + {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Debug|x86.Build.0 = Debug|Win32 + {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Release|ARM64.ActiveCfg = Release|ARM64 + {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Release|ARM64.Build.0 = Release|ARM64 + {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Release|x64.ActiveCfg = Release|x64 + {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Release|x64.Build.0 = Release|x64 + {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Release|x86.ActiveCfg = Release|Win32 + {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA}.Release|x86.Build.0 = Release|Win32 + {870723DD-945A-4136-B65B-4AF3BF85369C}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {870723DD-945A-4136-B65B-4AF3BF85369C}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {870723DD-945A-4136-B65B-4AF3BF85369C}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {870723DD-945A-4136-B65B-4AF3BF85369C}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {870723DD-945A-4136-B65B-4AF3BF85369C}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {870723DD-945A-4136-B65B-4AF3BF85369C}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {870723DD-945A-4136-B65B-4AF3BF85369C}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {870723DD-945A-4136-B65B-4AF3BF85369C}.Debug|ARM64.Build.0 = Debug|ARM64 + {870723DD-945A-4136-B65B-4AF3BF85369C}.Debug|x64.ActiveCfg = Debug|x64 + {870723DD-945A-4136-B65B-4AF3BF85369C}.Debug|x64.Build.0 = Debug|x64 + {870723DD-945A-4136-B65B-4AF3BF85369C}.Debug|x86.ActiveCfg = Debug|Win32 + {870723DD-945A-4136-B65B-4AF3BF85369C}.Debug|x86.Build.0 = Debug|Win32 + {870723DD-945A-4136-B65B-4AF3BF85369C}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {870723DD-945A-4136-B65B-4AF3BF85369C}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {870723DD-945A-4136-B65B-4AF3BF85369C}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {870723DD-945A-4136-B65B-4AF3BF85369C}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {870723DD-945A-4136-B65B-4AF3BF85369C}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {870723DD-945A-4136-B65B-4AF3BF85369C}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {870723DD-945A-4136-B65B-4AF3BF85369C}.Release|ARM64.ActiveCfg = Release|ARM64 + {870723DD-945A-4136-B65B-4AF3BF85369C}.Release|ARM64.Build.0 = Release|ARM64 + {870723DD-945A-4136-B65B-4AF3BF85369C}.Release|x64.ActiveCfg = Release|x64 + {870723DD-945A-4136-B65B-4AF3BF85369C}.Release|x64.Build.0 = Release|x64 + {870723DD-945A-4136-B65B-4AF3BF85369C}.Release|x86.ActiveCfg = Release|Win32 + {870723DD-945A-4136-B65B-4AF3BF85369C}.Release|x86.Build.0 = Release|Win32 + {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Debug|ARM64.Build.0 = Debug|ARM64 + {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Debug|x64.ActiveCfg = Debug|x64 + {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Debug|x64.Build.0 = Debug|x64 + {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Debug|x86.ActiveCfg = Debug|Win32 + {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Debug|x86.Build.0 = Debug|Win32 + {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Release|ARM64.ActiveCfg = Release|ARM64 + {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Release|ARM64.Build.0 = Release|ARM64 + {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Release|x64.ActiveCfg = Release|x64 + {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Release|x64.Build.0 = Release|x64 + {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Release|x86.ActiveCfg = Release|Win32 + {EA6488AD-445B-4835-87FB-EBC9E2EDAF97}.Release|x86.Build.0 = Release|Win32 + {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Debug|ARM64.Build.0 = Debug|ARM64 + {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Debug|x64.ActiveCfg = Debug|x64 + {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Debug|x64.Build.0 = Debug|x64 + {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Debug|x86.ActiveCfg = Debug|Win32 + {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Debug|x86.Build.0 = Debug|Win32 + {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Release|ARM64.ActiveCfg = Release|ARM64 + {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Release|ARM64.Build.0 = Release|ARM64 + {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Release|x64.ActiveCfg = Release|x64 + {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Release|x64.Build.0 = Release|x64 + {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Release|x86.ActiveCfg = Release|Win32 + {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0}.Release|x86.Build.0 = Release|Win32 + {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Debug|ARM64.Build.0 = Debug|ARM64 + {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Debug|x64.ActiveCfg = Debug|x64 + {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Debug|x64.Build.0 = Debug|x64 + {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Debug|x86.ActiveCfg = Debug|Win32 + {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Debug|x86.Build.0 = Debug|Win32 + {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Release|ARM64.ActiveCfg = Release|ARM64 + {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Release|ARM64.Build.0 = Release|ARM64 + {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Release|x64.ActiveCfg = Release|x64 + {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Release|x64.Build.0 = Release|x64 + {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Release|x86.ActiveCfg = Release|Win32 + {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4}.Release|x86.Build.0 = Release|Win32 + {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Debug|ARM64.Build.0 = Debug|ARM64 + {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Debug|x64.ActiveCfg = Debug|x64 + {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Debug|x64.Build.0 = Debug|x64 + {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Debug|x86.ActiveCfg = Debug|Win32 + {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Debug|x86.Build.0 = Debug|Win32 + {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Release|ARM64.ActiveCfg = Release|ARM64 + {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Release|ARM64.Build.0 = Release|ARM64 + {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Release|x64.ActiveCfg = Release|x64 + {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Release|x64.Build.0 = Release|x64 + {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Release|x86.ActiveCfg = Release|Win32 + {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E}.Release|x86.Build.0 = Release|Win32 + {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Debug|ARM64.Build.0 = Debug|ARM64 + {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Debug|x64.ActiveCfg = Debug|x64 + {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Debug|x64.Build.0 = Debug|x64 + {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Debug|x86.ActiveCfg = Debug|Win32 + {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Debug|x86.Build.0 = Debug|Win32 + {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Release|ARM64.ActiveCfg = Release|ARM64 + {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Release|ARM64.Build.0 = Release|ARM64 + {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Release|x64.ActiveCfg = Release|x64 + {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Release|x64.Build.0 = Release|x64 + {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Release|x86.ActiveCfg = Release|Win32 + {3AD868E6-8355-4F29-B5ED-7DE94AD786E7}.Release|x86.Build.0 = Release|Win32 + {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Debug|ARM64.Build.0 = Debug|ARM64 + {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Debug|x64.ActiveCfg = Debug|x64 + {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Debug|x64.Build.0 = Debug|x64 + {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Debug|x86.ActiveCfg = Debug|Win32 + {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Debug|x86.Build.0 = Debug|Win32 + {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Release|ARM64.ActiveCfg = Release|ARM64 + {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Release|ARM64.Build.0 = Release|ARM64 + {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Release|x64.ActiveCfg = Release|x64 + {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Release|x64.Build.0 = Release|x64 + {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Release|x86.ActiveCfg = Release|Win32 + {2B78CF0A-5403-45E2-99BD-493F1679BCDB}.Release|x86.Build.0 = Release|Win32 + {0AB968E0-E993-45CE-8875-7453C96DF583}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {0AB968E0-E993-45CE-8875-7453C96DF583}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {0AB968E0-E993-45CE-8875-7453C96DF583}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {0AB968E0-E993-45CE-8875-7453C96DF583}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {0AB968E0-E993-45CE-8875-7453C96DF583}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {0AB968E0-E993-45CE-8875-7453C96DF583}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {0AB968E0-E993-45CE-8875-7453C96DF583}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {0AB968E0-E993-45CE-8875-7453C96DF583}.Debug|ARM64.Build.0 = Debug|ARM64 + {0AB968E0-E993-45CE-8875-7453C96DF583}.Debug|x64.ActiveCfg = Debug|x64 + {0AB968E0-E993-45CE-8875-7453C96DF583}.Debug|x64.Build.0 = Debug|x64 + {0AB968E0-E993-45CE-8875-7453C96DF583}.Debug|x86.ActiveCfg = Debug|Win32 + {0AB968E0-E993-45CE-8875-7453C96DF583}.Debug|x86.Build.0 = Debug|Win32 + {0AB968E0-E993-45CE-8875-7453C96DF583}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {0AB968E0-E993-45CE-8875-7453C96DF583}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {0AB968E0-E993-45CE-8875-7453C96DF583}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {0AB968E0-E993-45CE-8875-7453C96DF583}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {0AB968E0-E993-45CE-8875-7453C96DF583}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {0AB968E0-E993-45CE-8875-7453C96DF583}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {0AB968E0-E993-45CE-8875-7453C96DF583}.Release|ARM64.ActiveCfg = Release|ARM64 + {0AB968E0-E993-45CE-8875-7453C96DF583}.Release|ARM64.Build.0 = Release|ARM64 + {0AB968E0-E993-45CE-8875-7453C96DF583}.Release|x64.ActiveCfg = Release|x64 + {0AB968E0-E993-45CE-8875-7453C96DF583}.Release|x64.Build.0 = Release|x64 + {0AB968E0-E993-45CE-8875-7453C96DF583}.Release|x86.ActiveCfg = Release|Win32 + {0AB968E0-E993-45CE-8875-7453C96DF583}.Release|x86.Build.0 = Release|Win32 + {25923141-9859-4AFE-8168-0DF78322FC63}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {25923141-9859-4AFE-8168-0DF78322FC63}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {25923141-9859-4AFE-8168-0DF78322FC63}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {25923141-9859-4AFE-8168-0DF78322FC63}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {25923141-9859-4AFE-8168-0DF78322FC63}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {25923141-9859-4AFE-8168-0DF78322FC63}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {25923141-9859-4AFE-8168-0DF78322FC63}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {25923141-9859-4AFE-8168-0DF78322FC63}.Debug|ARM64.Build.0 = Debug|ARM64 + {25923141-9859-4AFE-8168-0DF78322FC63}.Debug|x64.ActiveCfg = Debug|x64 + {25923141-9859-4AFE-8168-0DF78322FC63}.Debug|x64.Build.0 = Debug|x64 + {25923141-9859-4AFE-8168-0DF78322FC63}.Debug|x86.ActiveCfg = Debug|Win32 + {25923141-9859-4AFE-8168-0DF78322FC63}.Debug|x86.Build.0 = Debug|Win32 + {25923141-9859-4AFE-8168-0DF78322FC63}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {25923141-9859-4AFE-8168-0DF78322FC63}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {25923141-9859-4AFE-8168-0DF78322FC63}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {25923141-9859-4AFE-8168-0DF78322FC63}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {25923141-9859-4AFE-8168-0DF78322FC63}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {25923141-9859-4AFE-8168-0DF78322FC63}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {25923141-9859-4AFE-8168-0DF78322FC63}.Release|ARM64.ActiveCfg = Release|ARM64 + {25923141-9859-4AFE-8168-0DF78322FC63}.Release|ARM64.Build.0 = Release|ARM64 + {25923141-9859-4AFE-8168-0DF78322FC63}.Release|x64.ActiveCfg = Release|x64 + {25923141-9859-4AFE-8168-0DF78322FC63}.Release|x64.Build.0 = Release|x64 + {25923141-9859-4AFE-8168-0DF78322FC63}.Release|x86.ActiveCfg = Release|Win32 + {25923141-9859-4AFE-8168-0DF78322FC63}.Release|x86.Build.0 = Release|Win32 + {7E855020-7FA4-482D-B510-2E709354FE8B}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {7E855020-7FA4-482D-B510-2E709354FE8B}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {7E855020-7FA4-482D-B510-2E709354FE8B}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {7E855020-7FA4-482D-B510-2E709354FE8B}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {7E855020-7FA4-482D-B510-2E709354FE8B}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {7E855020-7FA4-482D-B510-2E709354FE8B}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {7E855020-7FA4-482D-B510-2E709354FE8B}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {7E855020-7FA4-482D-B510-2E709354FE8B}.Debug|ARM64.Build.0 = Debug|ARM64 + {7E855020-7FA4-482D-B510-2E709354FE8B}.Debug|x64.ActiveCfg = Debug|x64 + {7E855020-7FA4-482D-B510-2E709354FE8B}.Debug|x64.Build.0 = Debug|x64 + {7E855020-7FA4-482D-B510-2E709354FE8B}.Debug|x86.ActiveCfg = Debug|Win32 + {7E855020-7FA4-482D-B510-2E709354FE8B}.Debug|x86.Build.0 = Debug|Win32 + {7E855020-7FA4-482D-B510-2E709354FE8B}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {7E855020-7FA4-482D-B510-2E709354FE8B}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {7E855020-7FA4-482D-B510-2E709354FE8B}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {7E855020-7FA4-482D-B510-2E709354FE8B}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {7E855020-7FA4-482D-B510-2E709354FE8B}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {7E855020-7FA4-482D-B510-2E709354FE8B}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {7E855020-7FA4-482D-B510-2E709354FE8B}.Release|ARM64.ActiveCfg = Release|ARM64 + {7E855020-7FA4-482D-B510-2E709354FE8B}.Release|ARM64.Build.0 = Release|ARM64 + {7E855020-7FA4-482D-B510-2E709354FE8B}.Release|x64.ActiveCfg = Release|x64 + {7E855020-7FA4-482D-B510-2E709354FE8B}.Release|x64.Build.0 = Release|x64 + {7E855020-7FA4-482D-B510-2E709354FE8B}.Release|x86.ActiveCfg = Release|Win32 + {7E855020-7FA4-482D-B510-2E709354FE8B}.Release|x86.Build.0 = Release|Win32 + {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Debug|ARM64.Build.0 = Debug|ARM64 + {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Debug|x64.ActiveCfg = Debug|x64 + {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Debug|x64.Build.0 = Debug|x64 + {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Debug|x86.ActiveCfg = Debug|Win32 + {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Debug|x86.Build.0 = Debug|Win32 + {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Release|ARM64.ActiveCfg = Release|ARM64 + {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Release|ARM64.Build.0 = Release|ARM64 + {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Release|x64.ActiveCfg = Release|x64 + {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Release|x64.Build.0 = Release|x64 + {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Release|x86.ActiveCfg = Release|Win32 + {9782E0C8-2BD3-4F67-B420-21CF19CA2435}.Release|x86.Build.0 = Release|Win32 + {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Debug|ARM64.Build.0 = Debug|ARM64 + {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Debug|x64.ActiveCfg = Debug|x64 + {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Debug|x64.Build.0 = Debug|x64 + {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Debug|x86.ActiveCfg = Debug|Win32 + {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Debug|x86.Build.0 = Debug|Win32 + {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Release|ARM64.ActiveCfg = Release|ARM64 + {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Release|ARM64.Build.0 = Release|ARM64 + {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Release|x64.ActiveCfg = Release|x64 + {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Release|x64.Build.0 = Release|x64 + {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Release|x86.ActiveCfg = Release|Win32 + {9F4135E3-9814-452C-9B35-0EFBCD792B49}.Release|x86.Build.0 = Release|Win32 + {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Debug|ARM64.Build.0 = Debug|ARM64 + {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Debug|x64.ActiveCfg = Debug|x64 + {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Debug|x64.Build.0 = Debug|x64 + {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Debug|x86.ActiveCfg = Debug|Win32 + {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Debug|x86.Build.0 = Debug|Win32 + {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Release|ARM64.ActiveCfg = Release|ARM64 + {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Release|ARM64.Build.0 = Release|ARM64 + {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Release|x64.ActiveCfg = Release|x64 + {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Release|x64.Build.0 = Release|x64 + {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Release|x86.ActiveCfg = Release|Win32 + {C45343E6-DAB6-4F3A-A00A-8BED71A098BE}.Release|x86.Build.0 = Release|Win32 + {B19DD336-538E-4091-A559-EAA717FEC899}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {B19DD336-538E-4091-A559-EAA717FEC899}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {B19DD336-538E-4091-A559-EAA717FEC899}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {B19DD336-538E-4091-A559-EAA717FEC899}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {B19DD336-538E-4091-A559-EAA717FEC899}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {B19DD336-538E-4091-A559-EAA717FEC899}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {B19DD336-538E-4091-A559-EAA717FEC899}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {B19DD336-538E-4091-A559-EAA717FEC899}.Debug|ARM64.Build.0 = Debug|ARM64 + {B19DD336-538E-4091-A559-EAA717FEC899}.Debug|x64.ActiveCfg = Debug|x64 + {B19DD336-538E-4091-A559-EAA717FEC899}.Debug|x64.Build.0 = Debug|x64 + {B19DD336-538E-4091-A559-EAA717FEC899}.Debug|x86.ActiveCfg = Debug|Win32 + {B19DD336-538E-4091-A559-EAA717FEC899}.Debug|x86.Build.0 = Debug|Win32 + {B19DD336-538E-4091-A559-EAA717FEC899}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {B19DD336-538E-4091-A559-EAA717FEC899}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {B19DD336-538E-4091-A559-EAA717FEC899}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {B19DD336-538E-4091-A559-EAA717FEC899}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {B19DD336-538E-4091-A559-EAA717FEC899}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {B19DD336-538E-4091-A559-EAA717FEC899}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {B19DD336-538E-4091-A559-EAA717FEC899}.Release|ARM64.ActiveCfg = Release|ARM64 + {B19DD336-538E-4091-A559-EAA717FEC899}.Release|ARM64.Build.0 = Release|ARM64 + {B19DD336-538E-4091-A559-EAA717FEC899}.Release|x64.ActiveCfg = Release|x64 + {B19DD336-538E-4091-A559-EAA717FEC899}.Release|x64.Build.0 = Release|x64 + {B19DD336-538E-4091-A559-EAA717FEC899}.Release|x86.ActiveCfg = Release|Win32 + {B19DD336-538E-4091-A559-EAA717FEC899}.Release|x86.Build.0 = Release|Win32 + {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Debug|ARM64.Build.0 = Debug|ARM64 + {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Debug|x64.ActiveCfg = Debug|x64 + {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Debug|x64.Build.0 = Debug|x64 + {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Debug|x86.ActiveCfg = Debug|Win32 + {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Debug|x86.Build.0 = Debug|Win32 + {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Release|ARM64.ActiveCfg = Release|ARM64 + {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Release|ARM64.Build.0 = Release|ARM64 + {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Release|x64.ActiveCfg = Release|x64 + {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Release|x64.Build.0 = Release|x64 + {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Release|x86.ActiveCfg = Release|Win32 + {0BF60202-43F7-48E9-8717-D31E56FA5BE0}.Release|x86.Build.0 = Release|Win32 + {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Debug|ARM64.Build.0 = Debug|ARM64 + {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Debug|x64.ActiveCfg = Debug|x64 + {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Debug|x64.Build.0 = Debug|x64 + {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Debug|x86.ActiveCfg = Debug|Win32 + {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Debug|x86.Build.0 = Debug|Win32 + {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Release|ARM64.ActiveCfg = Release|ARM64 + {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Release|ARM64.Build.0 = Release|ARM64 + {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Release|x64.ActiveCfg = Release|x64 + {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Release|x64.Build.0 = Release|x64 + {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Release|x86.ActiveCfg = Release|Win32 + {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC}.Release|x86.Build.0 = Release|Win32 + {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Debug|ARM64.Build.0 = Debug|ARM64 + {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Debug|x64.ActiveCfg = Debug|x64 + {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Debug|x64.Build.0 = Debug|x64 + {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Debug|x86.ActiveCfg = Debug|Win32 + {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Debug|x86.Build.0 = Debug|Win32 + {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Release|ARM64.ActiveCfg = Release|ARM64 + {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Release|ARM64.Build.0 = Release|ARM64 + {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Release|x64.ActiveCfg = Release|x64 + {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Release|x64.Build.0 = Release|x64 + {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Release|x86.ActiveCfg = Release|Win32 + {6D75CD88-1A03-4955-B8C7-ACFC3742154F}.Release|x86.Build.0 = Release|Win32 + {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Debug|ARM64.Build.0 = Debug|ARM64 + {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Debug|x64.ActiveCfg = Debug|x64 + {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Debug|x64.Build.0 = Debug|x64 + {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Debug|x86.ActiveCfg = Debug|Win32 + {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Debug|x86.Build.0 = Debug|Win32 + {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Release|ARM64.ActiveCfg = Release|ARM64 + {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Release|ARM64.Build.0 = Release|ARM64 + {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Release|x64.ActiveCfg = Release|x64 + {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Release|x64.Build.0 = Release|x64 + {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Release|x86.ActiveCfg = Release|Win32 + {8DD0EB7E-668E-452D-91D7-906C64A9C8AC}.Release|x86.Build.0 = Release|Win32 + {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Debug|ARM64.Build.0 = Debug|ARM64 + {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Debug|x64.ActiveCfg = Debug|x64 + {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Debug|x64.Build.0 = Debug|x64 + {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Debug|x86.ActiveCfg = Debug|Win32 + {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Debug|x86.Build.0 = Debug|Win32 + {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Release|ARM64.ActiveCfg = Release|ARM64 + {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Release|ARM64.Build.0 = Release|ARM64 + {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Release|x64.ActiveCfg = Release|x64 + {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Release|x64.Build.0 = Release|x64 + {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Release|x86.ActiveCfg = Release|Win32 + {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E}.Release|x86.Build.0 = Release|Win32 + {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Debug|ARM64.Build.0 = Debug|ARM64 + {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Debug|x64.ActiveCfg = Debug|x64 + {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Debug|x64.Build.0 = Debug|x64 + {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Debug|x86.ActiveCfg = Debug|Win32 + {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Debug|x86.Build.0 = Debug|Win32 + {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Release|ARM64.ActiveCfg = Release|ARM64 + {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Release|ARM64.Build.0 = Release|ARM64 + {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Release|x64.ActiveCfg = Release|x64 + {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Release|x64.Build.0 = Release|x64 + {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Release|x86.ActiveCfg = Release|Win32 + {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D}.Release|x86.Build.0 = Release|Win32 + {25BCB876-B60A-499B-9046-E9801CFD7780}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {25BCB876-B60A-499B-9046-E9801CFD7780}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {25BCB876-B60A-499B-9046-E9801CFD7780}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {25BCB876-B60A-499B-9046-E9801CFD7780}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {25BCB876-B60A-499B-9046-E9801CFD7780}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {25BCB876-B60A-499B-9046-E9801CFD7780}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {25BCB876-B60A-499B-9046-E9801CFD7780}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {25BCB876-B60A-499B-9046-E9801CFD7780}.Debug|ARM64.Build.0 = Debug|ARM64 + {25BCB876-B60A-499B-9046-E9801CFD7780}.Debug|x64.ActiveCfg = Debug|x64 + {25BCB876-B60A-499B-9046-E9801CFD7780}.Debug|x64.Build.0 = Debug|x64 + {25BCB876-B60A-499B-9046-E9801CFD7780}.Debug|x86.ActiveCfg = Debug|Win32 + {25BCB876-B60A-499B-9046-E9801CFD7780}.Debug|x86.Build.0 = Debug|Win32 + {25BCB876-B60A-499B-9046-E9801CFD7780}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {25BCB876-B60A-499B-9046-E9801CFD7780}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {25BCB876-B60A-499B-9046-E9801CFD7780}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {25BCB876-B60A-499B-9046-E9801CFD7780}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {25BCB876-B60A-499B-9046-E9801CFD7780}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {25BCB876-B60A-499B-9046-E9801CFD7780}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {25BCB876-B60A-499B-9046-E9801CFD7780}.Release|ARM64.ActiveCfg = Release|ARM64 + {25BCB876-B60A-499B-9046-E9801CFD7780}.Release|ARM64.Build.0 = Release|ARM64 + {25BCB876-B60A-499B-9046-E9801CFD7780}.Release|x64.ActiveCfg = Release|x64 + {25BCB876-B60A-499B-9046-E9801CFD7780}.Release|x64.Build.0 = Release|x64 + {25BCB876-B60A-499B-9046-E9801CFD7780}.Release|x86.ActiveCfg = Release|Win32 + {25BCB876-B60A-499B-9046-E9801CFD7780}.Release|x86.Build.0 = Release|Win32 + {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Debug|ARM64.Build.0 = Debug|ARM64 + {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Debug|x64.ActiveCfg = Debug|x64 + {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Debug|x64.Build.0 = Debug|x64 + {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Debug|x86.ActiveCfg = Debug|Win32 + {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Debug|x86.Build.0 = Debug|Win32 + {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Release|ARM64.ActiveCfg = Release|ARM64 + {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Release|ARM64.Build.0 = Release|ARM64 + {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Release|x64.ActiveCfg = Release|x64 + {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Release|x64.Build.0 = Release|x64 + {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Release|x86.ActiveCfg = Release|Win32 + {56FB0A45-145F-4EAE-B2C8-E5833E682D8F}.Release|x86.Build.0 = Release|Win32 + {2BB0C1D4-9298-45AC-B244-67A99769A292}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {2BB0C1D4-9298-45AC-B244-67A99769A292}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {2BB0C1D4-9298-45AC-B244-67A99769A292}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {2BB0C1D4-9298-45AC-B244-67A99769A292}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {2BB0C1D4-9298-45AC-B244-67A99769A292}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {2BB0C1D4-9298-45AC-B244-67A99769A292}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {2BB0C1D4-9298-45AC-B244-67A99769A292}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {2BB0C1D4-9298-45AC-B244-67A99769A292}.Debug|ARM64.Build.0 = Debug|ARM64 + {2BB0C1D4-9298-45AC-B244-67A99769A292}.Debug|x64.ActiveCfg = Debug|x64 + {2BB0C1D4-9298-45AC-B244-67A99769A292}.Debug|x64.Build.0 = Debug|x64 + {2BB0C1D4-9298-45AC-B244-67A99769A292}.Debug|x86.ActiveCfg = Debug|Win32 + {2BB0C1D4-9298-45AC-B244-67A99769A292}.Debug|x86.Build.0 = Debug|Win32 + {2BB0C1D4-9298-45AC-B244-67A99769A292}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {2BB0C1D4-9298-45AC-B244-67A99769A292}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {2BB0C1D4-9298-45AC-B244-67A99769A292}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {2BB0C1D4-9298-45AC-B244-67A99769A292}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {2BB0C1D4-9298-45AC-B244-67A99769A292}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {2BB0C1D4-9298-45AC-B244-67A99769A292}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {2BB0C1D4-9298-45AC-B244-67A99769A292}.Release|ARM64.ActiveCfg = Release|ARM64 + {2BB0C1D4-9298-45AC-B244-67A99769A292}.Release|ARM64.Build.0 = Release|ARM64 + {2BB0C1D4-9298-45AC-B244-67A99769A292}.Release|x64.ActiveCfg = Release|x64 + {2BB0C1D4-9298-45AC-B244-67A99769A292}.Release|x64.Build.0 = Release|x64 + {2BB0C1D4-9298-45AC-B244-67A99769A292}.Release|x86.ActiveCfg = Release|Win32 + {2BB0C1D4-9298-45AC-B244-67A99769A292}.Release|x86.Build.0 = Release|Win32 + {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Debug|ARM64.Build.0 = Debug|ARM64 + {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Debug|x64.ActiveCfg = Debug|x64 + {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Debug|x64.Build.0 = Debug|x64 + {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Debug|x86.ActiveCfg = Debug|Win32 + {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Debug|x86.Build.0 = Debug|Win32 + {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Release|ARM64.ActiveCfg = Release|ARM64 + {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Release|ARM64.Build.0 = Release|ARM64 + {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Release|x64.ActiveCfg = Release|x64 + {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Release|x64.Build.0 = Release|x64 + {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Release|x86.ActiveCfg = Release|Win32 + {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB}.Release|x86.Build.0 = Release|Win32 + {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Debug|ARM64.Build.0 = Debug|ARM64 + {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Debug|x64.ActiveCfg = Debug|x64 + {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Debug|x64.Build.0 = Debug|x64 + {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Debug|x86.ActiveCfg = Debug|Win32 + {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Debug|x86.Build.0 = Debug|Win32 + {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Release|ARM64.ActiveCfg = Release|ARM64 + {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Release|ARM64.Build.0 = Release|ARM64 + {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Release|x64.ActiveCfg = Release|x64 + {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Release|x64.Build.0 = Release|x64 + {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Release|x86.ActiveCfg = Release|Win32 + {81064BCE-EEC1-43B0-9912-F05F2B54B11A}.Release|x86.Build.0 = Release|Win32 + {31B41997-3890-45E3-93FE-C57B363E9C0D}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {31B41997-3890-45E3-93FE-C57B363E9C0D}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {31B41997-3890-45E3-93FE-C57B363E9C0D}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {31B41997-3890-45E3-93FE-C57B363E9C0D}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {31B41997-3890-45E3-93FE-C57B363E9C0D}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {31B41997-3890-45E3-93FE-C57B363E9C0D}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {31B41997-3890-45E3-93FE-C57B363E9C0D}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {31B41997-3890-45E3-93FE-C57B363E9C0D}.Debug|ARM64.Build.0 = Debug|ARM64 + {31B41997-3890-45E3-93FE-C57B363E9C0D}.Debug|x64.ActiveCfg = Debug|x64 + {31B41997-3890-45E3-93FE-C57B363E9C0D}.Debug|x64.Build.0 = Debug|x64 + {31B41997-3890-45E3-93FE-C57B363E9C0D}.Debug|x86.ActiveCfg = Debug|Win32 + {31B41997-3890-45E3-93FE-C57B363E9C0D}.Debug|x86.Build.0 = Debug|Win32 + {31B41997-3890-45E3-93FE-C57B363E9C0D}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {31B41997-3890-45E3-93FE-C57B363E9C0D}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {31B41997-3890-45E3-93FE-C57B363E9C0D}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {31B41997-3890-45E3-93FE-C57B363E9C0D}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {31B41997-3890-45E3-93FE-C57B363E9C0D}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {31B41997-3890-45E3-93FE-C57B363E9C0D}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {31B41997-3890-45E3-93FE-C57B363E9C0D}.Release|ARM64.ActiveCfg = Release|ARM64 + {31B41997-3890-45E3-93FE-C57B363E9C0D}.Release|ARM64.Build.0 = Release|ARM64 + {31B41997-3890-45E3-93FE-C57B363E9C0D}.Release|x64.ActiveCfg = Release|x64 + {31B41997-3890-45E3-93FE-C57B363E9C0D}.Release|x64.Build.0 = Release|x64 + {31B41997-3890-45E3-93FE-C57B363E9C0D}.Release|x86.ActiveCfg = Release|Win32 + {31B41997-3890-45E3-93FE-C57B363E9C0D}.Release|x86.Build.0 = Release|Win32 + {D550AB93-DF31-4B76-873F-F075018352F4}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {D550AB93-DF31-4B76-873F-F075018352F4}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {D550AB93-DF31-4B76-873F-F075018352F4}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {D550AB93-DF31-4B76-873F-F075018352F4}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {D550AB93-DF31-4B76-873F-F075018352F4}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {D550AB93-DF31-4B76-873F-F075018352F4}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {D550AB93-DF31-4B76-873F-F075018352F4}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {D550AB93-DF31-4B76-873F-F075018352F4}.Debug|ARM64.Build.0 = Debug|ARM64 + {D550AB93-DF31-4B76-873F-F075018352F4}.Debug|x64.ActiveCfg = Debug|x64 + {D550AB93-DF31-4B76-873F-F075018352F4}.Debug|x64.Build.0 = Debug|x64 + {D550AB93-DF31-4B76-873F-F075018352F4}.Debug|x86.ActiveCfg = Debug|Win32 + {D550AB93-DF31-4B76-873F-F075018352F4}.Debug|x86.Build.0 = Debug|Win32 + {D550AB93-DF31-4B76-873F-F075018352F4}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {D550AB93-DF31-4B76-873F-F075018352F4}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {D550AB93-DF31-4B76-873F-F075018352F4}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {D550AB93-DF31-4B76-873F-F075018352F4}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {D550AB93-DF31-4B76-873F-F075018352F4}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {D550AB93-DF31-4B76-873F-F075018352F4}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {D550AB93-DF31-4B76-873F-F075018352F4}.Release|ARM64.ActiveCfg = Release|ARM64 + {D550AB93-DF31-4B76-873F-F075018352F4}.Release|ARM64.Build.0 = Release|ARM64 + {D550AB93-DF31-4B76-873F-F075018352F4}.Release|x64.ActiveCfg = Release|x64 + {D550AB93-DF31-4B76-873F-F075018352F4}.Release|x64.Build.0 = Release|x64 + {D550AB93-DF31-4B76-873F-F075018352F4}.Release|x86.ActiveCfg = Release|Win32 + {D550AB93-DF31-4B76-873F-F075018352F4}.Release|x86.Build.0 = Release|Win32 + {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Debug|ARM64.Build.0 = Debug|ARM64 + {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Debug|x64.ActiveCfg = Debug|x64 + {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Debug|x64.Build.0 = Debug|x64 + {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Debug|x86.ActiveCfg = Debug|Win32 + {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Debug|x86.Build.0 = Debug|Win32 + {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Release|ARM64.ActiveCfg = Release|ARM64 + {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Release|ARM64.Build.0 = Release|ARM64 + {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Release|x64.ActiveCfg = Release|x64 + {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Release|x64.Build.0 = Release|x64 + {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Release|x86.ActiveCfg = Release|Win32 + {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A}.Release|x86.Build.0 = Release|Win32 + {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Debug|ARM64.Build.0 = Debug|ARM64 + {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Debug|x64.ActiveCfg = Debug|x64 + {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Debug|x64.Build.0 = Debug|x64 + {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Debug|x86.ActiveCfg = Debug|Win32 + {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Debug|x86.Build.0 = Debug|Win32 + {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Release|ARM64.ActiveCfg = Release|ARM64 + {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Release|ARM64.Build.0 = Release|ARM64 + {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Release|x64.ActiveCfg = Release|x64 + {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Release|x64.Build.0 = Release|x64 + {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Release|x86.ActiveCfg = Release|Win32 + {F90FCDC5-EE14-4B89-96DB-4392E28F34AF}.Release|x86.Build.0 = Release|Win32 + {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Debug|ARM64.Build.0 = Debug|ARM64 + {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Debug|x64.ActiveCfg = Debug|x64 + {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Debug|x64.Build.0 = Debug|x64 + {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Debug|x86.ActiveCfg = Debug|Win32 + {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Debug|x86.Build.0 = Debug|Win32 + {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Release|ARM64.ActiveCfg = Release|ARM64 + {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Release|ARM64.Build.0 = Release|ARM64 + {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Release|x64.ActiveCfg = Release|x64 + {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Release|x64.Build.0 = Release|x64 + {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Release|x86.ActiveCfg = Release|Win32 + {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79}.Release|x86.Build.0 = Release|Win32 + {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Debug|ARM64.Build.0 = Debug|ARM64 + {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Debug|x64.ActiveCfg = Debug|x64 + {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Debug|x64.Build.0 = Debug|x64 + {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Debug|x86.ActiveCfg = Debug|Win32 + {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Debug|x86.Build.0 = Debug|Win32 + {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Release|ARM64.ActiveCfg = Release|ARM64 + {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Release|ARM64.Build.0 = Release|ARM64 + {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Release|x64.ActiveCfg = Release|x64 + {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Release|x64.Build.0 = Release|x64 + {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Release|x86.ActiveCfg = Release|Win32 + {56E68E37-B3FC-4799-91AF-0CA10B6D55A5}.Release|x86.Build.0 = Release|Win32 + {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Debug|ARM64.Build.0 = Debug|ARM64 + {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Debug|x64.ActiveCfg = Debug|x64 + {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Debug|x64.Build.0 = Debug|x64 + {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Debug|x86.ActiveCfg = Debug|Win32 + {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Debug|x86.Build.0 = Debug|Win32 + {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Release|ARM64.ActiveCfg = Release|ARM64 + {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Release|ARM64.Build.0 = Release|ARM64 + {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Release|x64.ActiveCfg = Release|x64 + {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Release|x64.Build.0 = Release|x64 + {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Release|x86.ActiveCfg = Release|Win32 + {03E7018C-44A2-4C46-9CE7-F2A135A2692B}.Release|x86.Build.0 = Release|Win32 + {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Debug|ARM64.Build.0 = Debug|ARM64 + {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Debug|x64.ActiveCfg = Debug|x64 + {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Debug|x64.Build.0 = Debug|x64 + {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Debug|x86.ActiveCfg = Debug|Win32 + {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Debug|x86.Build.0 = Debug|Win32 + {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Release|ARM64.ActiveCfg = Release|ARM64 + {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Release|ARM64.Build.0 = Release|ARM64 + {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Release|x64.ActiveCfg = Release|x64 + {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Release|x64.Build.0 = Release|x64 + {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Release|x86.ActiveCfg = Release|Win32 + {F3F6FE4D-9D9E-451A-B0BA-81456104B672}.Release|x86.Build.0 = Release|Win32 + {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Debug|ARM64.Build.0 = Debug|ARM64 + {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Debug|x64.ActiveCfg = Debug|x64 + {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Debug|x64.Build.0 = Debug|x64 + {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Debug|x86.ActiveCfg = Debug|Win32 + {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Debug|x86.Build.0 = Debug|Win32 + {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Release|ARM64.ActiveCfg = Release|ARM64 + {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Release|ARM64.Build.0 = Release|ARM64 + {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Release|x64.ActiveCfg = Release|x64 + {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Release|x64.Build.0 = Release|x64 + {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Release|x86.ActiveCfg = Release|Win32 + {C27794B5-1293-4EA7-BC0E-0F18E6325539}.Release|x86.Build.0 = Release|Win32 + {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Debug|ARM64.Build.0 = Debug|ARM64 + {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Debug|x64.ActiveCfg = Debug|x64 + {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Debug|x64.Build.0 = Debug|x64 + {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Debug|x86.ActiveCfg = Debug|Win32 + {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Debug|x86.Build.0 = Debug|Win32 + {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Release|ARM64.ActiveCfg = Release|ARM64 + {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Release|ARM64.Build.0 = Release|ARM64 + {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Release|x64.ActiveCfg = Release|x64 + {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Release|x64.Build.0 = Release|x64 + {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Release|x86.ActiveCfg = Release|Win32 + {02F41059-12A2-4A96-8D77-07EFE4B108FD}.Release|x86.Build.0 = Release|Win32 + {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Debug|ARM64.Build.0 = Debug|ARM64 + {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Debug|x64.ActiveCfg = Debug|x64 + {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Debug|x64.Build.0 = Debug|x64 + {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Debug|x86.ActiveCfg = Debug|Win32 + {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Debug|x86.Build.0 = Debug|Win32 + {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Release|ARM64.ActiveCfg = Release|ARM64 + {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Release|ARM64.Build.0 = Release|ARM64 + {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Release|x64.ActiveCfg = Release|x64 + {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Release|x64.Build.0 = Release|x64 + {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Release|x86.ActiveCfg = Release|Win32 + {B774E0B9-9514-4E88-975F-4EB6C3B8D519}.Release|x86.Build.0 = Release|Win32 + {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Debug|ARM64.Build.0 = Debug|ARM64 + {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Debug|x64.ActiveCfg = Debug|x64 + {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Debug|x64.Build.0 = Debug|x64 + {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Debug|x86.ActiveCfg = Debug|Win32 + {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Debug|x86.Build.0 = Debug|Win32 + {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Release|ARM64.ActiveCfg = Release|ARM64 + {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Release|ARM64.Build.0 = Release|ARM64 + {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Release|x64.ActiveCfg = Release|x64 + {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Release|x64.Build.0 = Release|x64 + {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Release|x86.ActiveCfg = Release|Win32 + {D91367C2-2189-4859-A7FE-D2CAB84FA15C}.Release|x86.Build.0 = Release|Win32 + {33459B4E-1839-4856-BF6B-22480D11FE31}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {33459B4E-1839-4856-BF6B-22480D11FE31}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {33459B4E-1839-4856-BF6B-22480D11FE31}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {33459B4E-1839-4856-BF6B-22480D11FE31}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {33459B4E-1839-4856-BF6B-22480D11FE31}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {33459B4E-1839-4856-BF6B-22480D11FE31}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {33459B4E-1839-4856-BF6B-22480D11FE31}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {33459B4E-1839-4856-BF6B-22480D11FE31}.Debug|ARM64.Build.0 = Debug|ARM64 + {33459B4E-1839-4856-BF6B-22480D11FE31}.Debug|x64.ActiveCfg = Debug|x64 + {33459B4E-1839-4856-BF6B-22480D11FE31}.Debug|x64.Build.0 = Debug|x64 + {33459B4E-1839-4856-BF6B-22480D11FE31}.Debug|x86.ActiveCfg = Debug|Win32 + {33459B4E-1839-4856-BF6B-22480D11FE31}.Debug|x86.Build.0 = Debug|Win32 + {33459B4E-1839-4856-BF6B-22480D11FE31}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {33459B4E-1839-4856-BF6B-22480D11FE31}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {33459B4E-1839-4856-BF6B-22480D11FE31}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {33459B4E-1839-4856-BF6B-22480D11FE31}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {33459B4E-1839-4856-BF6B-22480D11FE31}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {33459B4E-1839-4856-BF6B-22480D11FE31}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {33459B4E-1839-4856-BF6B-22480D11FE31}.Release|ARM64.ActiveCfg = Release|ARM64 + {33459B4E-1839-4856-BF6B-22480D11FE31}.Release|ARM64.Build.0 = Release|ARM64 + {33459B4E-1839-4856-BF6B-22480D11FE31}.Release|x64.ActiveCfg = Release|x64 + {33459B4E-1839-4856-BF6B-22480D11FE31}.Release|x64.Build.0 = Release|x64 + {33459B4E-1839-4856-BF6B-22480D11FE31}.Release|x86.ActiveCfg = Release|Win32 + {33459B4E-1839-4856-BF6B-22480D11FE31}.Release|x86.Build.0 = Release|Win32 + {48871156-181A-475A-BD8D-200086A09675}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {48871156-181A-475A-BD8D-200086A09675}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {48871156-181A-475A-BD8D-200086A09675}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {48871156-181A-475A-BD8D-200086A09675}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {48871156-181A-475A-BD8D-200086A09675}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {48871156-181A-475A-BD8D-200086A09675}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {48871156-181A-475A-BD8D-200086A09675}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {48871156-181A-475A-BD8D-200086A09675}.Debug|ARM64.Build.0 = Debug|ARM64 + {48871156-181A-475A-BD8D-200086A09675}.Debug|x64.ActiveCfg = Debug|x64 + {48871156-181A-475A-BD8D-200086A09675}.Debug|x64.Build.0 = Debug|x64 + {48871156-181A-475A-BD8D-200086A09675}.Debug|x86.ActiveCfg = Debug|Win32 + {48871156-181A-475A-BD8D-200086A09675}.Debug|x86.Build.0 = Debug|Win32 + {48871156-181A-475A-BD8D-200086A09675}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {48871156-181A-475A-BD8D-200086A09675}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {48871156-181A-475A-BD8D-200086A09675}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {48871156-181A-475A-BD8D-200086A09675}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {48871156-181A-475A-BD8D-200086A09675}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {48871156-181A-475A-BD8D-200086A09675}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {48871156-181A-475A-BD8D-200086A09675}.Release|ARM64.ActiveCfg = Release|ARM64 + {48871156-181A-475A-BD8D-200086A09675}.Release|ARM64.Build.0 = Release|ARM64 + {48871156-181A-475A-BD8D-200086A09675}.Release|x64.ActiveCfg = Release|x64 + {48871156-181A-475A-BD8D-200086A09675}.Release|x64.Build.0 = Release|x64 + {48871156-181A-475A-BD8D-200086A09675}.Release|x86.ActiveCfg = Release|Win32 + {48871156-181A-475A-BD8D-200086A09675}.Release|x86.Build.0 = Release|Win32 + {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Debug|ARM64.Build.0 = Debug|ARM64 + {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Debug|x64.ActiveCfg = Debug|x64 + {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Debug|x64.Build.0 = Debug|x64 + {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Debug|x86.ActiveCfg = Debug|Win32 + {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Debug|x86.Build.0 = Debug|Win32 + {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Release|ARM64.ActiveCfg = Release|ARM64 + {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Release|ARM64.Build.0 = Release|ARM64 + {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Release|x64.ActiveCfg = Release|x64 + {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Release|x64.Build.0 = Release|x64 + {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Release|x86.ActiveCfg = Release|Win32 + {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1}.Release|x86.Build.0 = Release|Win32 + {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Debug|ARM64.Build.0 = Debug|ARM64 + {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Debug|x64.ActiveCfg = Debug|x64 + {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Debug|x64.Build.0 = Debug|x64 + {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Debug|x86.ActiveCfg = Debug|Win32 + {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Debug|x86.Build.0 = Debug|Win32 + {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Release|ARM64.ActiveCfg = Release|ARM64 + {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Release|ARM64.Build.0 = Release|ARM64 + {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Release|x64.ActiveCfg = Release|x64 + {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Release|x64.Build.0 = Release|x64 + {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Release|x86.ActiveCfg = Release|Win32 + {1C49E35A-2838-49D9-9D5F-4B8134960EF6}.Release|x86.Build.0 = Release|Win32 + {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Debug|ARM64.Build.0 = Debug|ARM64 + {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Debug|x64.ActiveCfg = Debug|x64 + {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Debug|x64.Build.0 = Debug|x64 + {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Debug|x86.ActiveCfg = Debug|Win32 + {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Debug|x86.Build.0 = Debug|Win32 + {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Release|ARM64.ActiveCfg = Release|ARM64 + {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Release|ARM64.Build.0 = Release|ARM64 + {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Release|x64.ActiveCfg = Release|x64 + {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Release|x64.Build.0 = Release|x64 + {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Release|x86.ActiveCfg = Release|Win32 + {F91142E2-A999-47F0-9E74-38C1E2930EBE}.Release|x86.Build.0 = Release|Win32 + {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Debug|ARM64.Build.0 = Debug|ARM64 + {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Debug|x64.ActiveCfg = Debug|x64 + {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Debug|x64.Build.0 = Debug|x64 + {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Debug|x86.ActiveCfg = Debug|Win32 + {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Debug|x86.Build.0 = Debug|Win32 + {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Release|ARM64.ActiveCfg = Release|ARM64 + {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Release|ARM64.Build.0 = Release|ARM64 + {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Release|x64.ActiveCfg = Release|x64 + {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Release|x64.Build.0 = Release|x64 + {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Release|x86.ActiveCfg = Release|Win32 + {1EDD4BCF-345C-4065-8CBD-7285224293C3}.Release|x86.Build.0 = Release|Win32 + {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Debug|ARM64.Build.0 = Debug|ARM64 + {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Debug|x64.ActiveCfg = Debug|x64 + {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Debug|x64.Build.0 = Debug|x64 + {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Debug|x86.ActiveCfg = Debug|Win32 + {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Debug|x86.Build.0 = Debug|Win32 + {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Release|ARM64.ActiveCfg = Release|ARM64 + {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Release|ARM64.Build.0 = Release|ARM64 + {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Release|x64.ActiveCfg = Release|x64 + {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Release|x64.Build.0 = Release|x64 + {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Release|x86.ActiveCfg = Release|Win32 + {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA}.Release|x86.Build.0 = Release|Win32 + {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Debug|ARM64.Build.0 = Debug|ARM64 + {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Debug|x64.ActiveCfg = Debug|x64 + {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Debug|x64.Build.0 = Debug|x64 + {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Debug|x86.ActiveCfg = Debug|Win32 + {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Debug|x86.Build.0 = Debug|Win32 + {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Release|ARM64.ActiveCfg = Release|ARM64 + {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Release|ARM64.Build.0 = Release|ARM64 + {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Release|x64.ActiveCfg = Release|x64 + {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Release|x64.Build.0 = Release|x64 + {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Release|x86.ActiveCfg = Release|Win32 + {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870}.Release|x86.Build.0 = Release|Win32 + {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Debug|ARM64.Build.0 = Debug|ARM64 + {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Debug|x64.ActiveCfg = Debug|x64 + {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Debug|x64.Build.0 = Debug|x64 + {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Debug|x86.ActiveCfg = Debug|Win32 + {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Debug|x86.Build.0 = Debug|Win32 + {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Release|ARM64.ActiveCfg = Release|ARM64 + {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Release|ARM64.Build.0 = Release|ARM64 + {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Release|x64.ActiveCfg = Release|x64 + {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Release|x64.Build.0 = Release|x64 + {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Release|x86.ActiveCfg = Release|Win32 + {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1}.Release|x86.Build.0 = Release|Win32 + {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Debug|ARM64.Build.0 = Debug|ARM64 + {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Debug|x64.ActiveCfg = Debug|x64 + {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Debug|x64.Build.0 = Debug|x64 + {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Debug|x86.ActiveCfg = Debug|Win32 + {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Debug|x86.Build.0 = Debug|Win32 + {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Release|ARM64.ActiveCfg = Release|ARM64 + {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Release|ARM64.Build.0 = Release|ARM64 + {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Release|x64.ActiveCfg = Release|x64 + {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Release|x64.Build.0 = Release|x64 + {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Release|x86.ActiveCfg = Release|Win32 + {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF}.Release|x86.Build.0 = Release|Win32 + {CF3755C4-937D-4ABF-B7B3-95140808717F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {CF3755C4-937D-4ABF-B7B3-95140808717F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {CF3755C4-937D-4ABF-B7B3-95140808717F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {CF3755C4-937D-4ABF-B7B3-95140808717F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {CF3755C4-937D-4ABF-B7B3-95140808717F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {CF3755C4-937D-4ABF-B7B3-95140808717F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {CF3755C4-937D-4ABF-B7B3-95140808717F}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {CF3755C4-937D-4ABF-B7B3-95140808717F}.Debug|ARM64.Build.0 = Debug|ARM64 + {CF3755C4-937D-4ABF-B7B3-95140808717F}.Debug|x64.ActiveCfg = Debug|x64 + {CF3755C4-937D-4ABF-B7B3-95140808717F}.Debug|x64.Build.0 = Debug|x64 + {CF3755C4-937D-4ABF-B7B3-95140808717F}.Debug|x86.ActiveCfg = Debug|Win32 + {CF3755C4-937D-4ABF-B7B3-95140808717F}.Debug|x86.Build.0 = Debug|Win32 + {CF3755C4-937D-4ABF-B7B3-95140808717F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {CF3755C4-937D-4ABF-B7B3-95140808717F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {CF3755C4-937D-4ABF-B7B3-95140808717F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {CF3755C4-937D-4ABF-B7B3-95140808717F}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {CF3755C4-937D-4ABF-B7B3-95140808717F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {CF3755C4-937D-4ABF-B7B3-95140808717F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {CF3755C4-937D-4ABF-B7B3-95140808717F}.Release|ARM64.ActiveCfg = Release|ARM64 + {CF3755C4-937D-4ABF-B7B3-95140808717F}.Release|ARM64.Build.0 = Release|ARM64 + {CF3755C4-937D-4ABF-B7B3-95140808717F}.Release|x64.ActiveCfg = Release|x64 + {CF3755C4-937D-4ABF-B7B3-95140808717F}.Release|x64.Build.0 = Release|x64 + {CF3755C4-937D-4ABF-B7B3-95140808717F}.Release|x86.ActiveCfg = Release|Win32 + {CF3755C4-937D-4ABF-B7B3-95140808717F}.Release|x86.Build.0 = Release|Win32 + {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Debug|ARM64.Build.0 = Debug|ARM64 + {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Debug|x64.ActiveCfg = Debug|x64 + {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Debug|x64.Build.0 = Debug|x64 + {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Debug|x86.ActiveCfg = Debug|Win32 + {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Debug|x86.Build.0 = Debug|Win32 + {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Release|ARM64.ActiveCfg = Release|ARM64 + {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Release|ARM64.Build.0 = Release|ARM64 + {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Release|x64.ActiveCfg = Release|x64 + {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Release|x64.Build.0 = Release|x64 + {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Release|x86.ActiveCfg = Release|Win32 + {D34939FE-8873-4C53-8D6C-74DED78EA3C4}.Release|x86.Build.0 = Release|Win32 + {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Debug|ARM64.Build.0 = Debug|ARM64 + {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Debug|x64.ActiveCfg = Debug|x64 + {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Debug|x64.Build.0 = Debug|x64 + {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Debug|x86.ActiveCfg = Debug|Win32 + {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Debug|x86.Build.0 = Debug|Win32 + {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Release|ARM64.ActiveCfg = Release|ARM64 + {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Release|ARM64.Build.0 = Release|ARM64 + {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Release|x64.ActiveCfg = Release|x64 + {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Release|x64.Build.0 = Release|x64 + {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Release|x86.ActiveCfg = Release|Win32 + {D408A730-363A-4ABF-BCEF-5D63DCC66042}.Release|x86.Build.0 = Release|Win32 + {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Debug|ARM64.Build.0 = Debug|ARM64 + {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Debug|x64.ActiveCfg = Debug|x64 + {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Debug|x64.Build.0 = Debug|x64 + {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Debug|x86.ActiveCfg = Debug|Win32 + {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Debug|x86.Build.0 = Debug|Win32 + {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Release|ARM64.ActiveCfg = Release|ARM64 + {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Release|ARM64.Build.0 = Release|ARM64 + {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Release|x64.ActiveCfg = Release|x64 + {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Release|x64.Build.0 = Release|x64 + {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Release|x86.ActiveCfg = Release|Win32 + {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED}.Release|x86.Build.0 = Release|Win32 + {52FB7463-C128-42AF-A02F-78F48473EA9A}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {52FB7463-C128-42AF-A02F-78F48473EA9A}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {52FB7463-C128-42AF-A02F-78F48473EA9A}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {52FB7463-C128-42AF-A02F-78F48473EA9A}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {52FB7463-C128-42AF-A02F-78F48473EA9A}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {52FB7463-C128-42AF-A02F-78F48473EA9A}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {52FB7463-C128-42AF-A02F-78F48473EA9A}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {52FB7463-C128-42AF-A02F-78F48473EA9A}.Debug|ARM64.Build.0 = Debug|ARM64 + {52FB7463-C128-42AF-A02F-78F48473EA9A}.Debug|x64.ActiveCfg = Debug|x64 + {52FB7463-C128-42AF-A02F-78F48473EA9A}.Debug|x64.Build.0 = Debug|x64 + {52FB7463-C128-42AF-A02F-78F48473EA9A}.Debug|x86.ActiveCfg = Debug|Win32 + {52FB7463-C128-42AF-A02F-78F48473EA9A}.Debug|x86.Build.0 = Debug|Win32 + {52FB7463-C128-42AF-A02F-78F48473EA9A}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {52FB7463-C128-42AF-A02F-78F48473EA9A}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {52FB7463-C128-42AF-A02F-78F48473EA9A}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {52FB7463-C128-42AF-A02F-78F48473EA9A}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {52FB7463-C128-42AF-A02F-78F48473EA9A}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {52FB7463-C128-42AF-A02F-78F48473EA9A}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {52FB7463-C128-42AF-A02F-78F48473EA9A}.Release|ARM64.ActiveCfg = Release|ARM64 + {52FB7463-C128-42AF-A02F-78F48473EA9A}.Release|ARM64.Build.0 = Release|ARM64 + {52FB7463-C128-42AF-A02F-78F48473EA9A}.Release|x64.ActiveCfg = Release|x64 + {52FB7463-C128-42AF-A02F-78F48473EA9A}.Release|x64.Build.0 = Release|x64 + {52FB7463-C128-42AF-A02F-78F48473EA9A}.Release|x86.ActiveCfg = Release|Win32 + {52FB7463-C128-42AF-A02F-78F48473EA9A}.Release|x86.Build.0 = Release|Win32 + {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Debug|ARM64.Build.0 = Debug|ARM64 + {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Debug|x64.ActiveCfg = Debug|x64 + {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Debug|x64.Build.0 = Debug|x64 + {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Debug|x86.ActiveCfg = Debug|Win32 + {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Debug|x86.Build.0 = Debug|Win32 + {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Release|ARM64.ActiveCfg = Release|ARM64 + {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Release|ARM64.Build.0 = Release|ARM64 + {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Release|x64.ActiveCfg = Release|x64 + {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Release|x64.Build.0 = Release|x64 + {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Release|x86.ActiveCfg = Release|Win32 + {7381D91E-5C72-48F0-AAB4-95C9B10D7484}.Release|x86.Build.0 = Release|Win32 + {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Debug|ARM64.Build.0 = Debug|ARM64 + {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Debug|x64.ActiveCfg = Debug|x64 + {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Debug|x64.Build.0 = Debug|x64 + {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Debug|x86.ActiveCfg = Debug|Win32 + {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Debug|x86.Build.0 = Debug|Win32 + {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Release|ARM64.ActiveCfg = Release|ARM64 + {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Release|ARM64.Build.0 = Release|ARM64 + {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Release|x64.ActiveCfg = Release|x64 + {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Release|x64.Build.0 = Release|x64 + {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Release|x86.ActiveCfg = Release|Win32 + {D36EC43E-B31F-4CF4-8285-93A7A9D90189}.Release|x86.Build.0 = Release|Win32 + {274C0319-7E1E-4188-936B-8DF3331230B3}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {274C0319-7E1E-4188-936B-8DF3331230B3}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {274C0319-7E1E-4188-936B-8DF3331230B3}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {274C0319-7E1E-4188-936B-8DF3331230B3}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {274C0319-7E1E-4188-936B-8DF3331230B3}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {274C0319-7E1E-4188-936B-8DF3331230B3}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {274C0319-7E1E-4188-936B-8DF3331230B3}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {274C0319-7E1E-4188-936B-8DF3331230B3}.Debug|ARM64.Build.0 = Debug|ARM64 + {274C0319-7E1E-4188-936B-8DF3331230B3}.Debug|x64.ActiveCfg = Debug|x64 + {274C0319-7E1E-4188-936B-8DF3331230B3}.Debug|x64.Build.0 = Debug|x64 + {274C0319-7E1E-4188-936B-8DF3331230B3}.Debug|x86.ActiveCfg = Debug|Win32 + {274C0319-7E1E-4188-936B-8DF3331230B3}.Debug|x86.Build.0 = Debug|Win32 + {274C0319-7E1E-4188-936B-8DF3331230B3}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {274C0319-7E1E-4188-936B-8DF3331230B3}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {274C0319-7E1E-4188-936B-8DF3331230B3}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {274C0319-7E1E-4188-936B-8DF3331230B3}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {274C0319-7E1E-4188-936B-8DF3331230B3}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {274C0319-7E1E-4188-936B-8DF3331230B3}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {274C0319-7E1E-4188-936B-8DF3331230B3}.Release|ARM64.ActiveCfg = Release|ARM64 + {274C0319-7E1E-4188-936B-8DF3331230B3}.Release|ARM64.Build.0 = Release|ARM64 + {274C0319-7E1E-4188-936B-8DF3331230B3}.Release|x64.ActiveCfg = Release|x64 + {274C0319-7E1E-4188-936B-8DF3331230B3}.Release|x64.Build.0 = Release|x64 + {274C0319-7E1E-4188-936B-8DF3331230B3}.Release|x86.ActiveCfg = Release|Win32 + {274C0319-7E1E-4188-936B-8DF3331230B3}.Release|x86.Build.0 = Release|Win32 + {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Debug|ARM64.Build.0 = Debug|ARM64 + {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Debug|x64.ActiveCfg = Debug|x64 + {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Debug|x64.Build.0 = Debug|x64 + {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Debug|x86.ActiveCfg = Debug|Win32 + {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Debug|x86.Build.0 = Debug|Win32 + {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Release|ARM64.ActiveCfg = Release|ARM64 + {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Release|ARM64.Build.0 = Release|ARM64 + {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Release|x64.ActiveCfg = Release|x64 + {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Release|x64.Build.0 = Release|x64 + {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Release|x86.ActiveCfg = Release|Win32 + {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629}.Release|x86.Build.0 = Release|Win32 + {600C3D4F-0670-4DB4-B30F-520A729053B5}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {600C3D4F-0670-4DB4-B30F-520A729053B5}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {600C3D4F-0670-4DB4-B30F-520A729053B5}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {600C3D4F-0670-4DB4-B30F-520A729053B5}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {600C3D4F-0670-4DB4-B30F-520A729053B5}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {600C3D4F-0670-4DB4-B30F-520A729053B5}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {600C3D4F-0670-4DB4-B30F-520A729053B5}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {600C3D4F-0670-4DB4-B30F-520A729053B5}.Debug|ARM64.Build.0 = Debug|ARM64 + {600C3D4F-0670-4DB4-B30F-520A729053B5}.Debug|x64.ActiveCfg = Debug|x64 + {600C3D4F-0670-4DB4-B30F-520A729053B5}.Debug|x64.Build.0 = Debug|x64 + {600C3D4F-0670-4DB4-B30F-520A729053B5}.Debug|x86.ActiveCfg = Debug|Win32 + {600C3D4F-0670-4DB4-B30F-520A729053B5}.Debug|x86.Build.0 = Debug|Win32 + {600C3D4F-0670-4DB4-B30F-520A729053B5}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {600C3D4F-0670-4DB4-B30F-520A729053B5}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {600C3D4F-0670-4DB4-B30F-520A729053B5}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {600C3D4F-0670-4DB4-B30F-520A729053B5}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {600C3D4F-0670-4DB4-B30F-520A729053B5}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {600C3D4F-0670-4DB4-B30F-520A729053B5}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {600C3D4F-0670-4DB4-B30F-520A729053B5}.Release|ARM64.ActiveCfg = Release|ARM64 + {600C3D4F-0670-4DB4-B30F-520A729053B5}.Release|ARM64.Build.0 = Release|ARM64 + {600C3D4F-0670-4DB4-B30F-520A729053B5}.Release|x64.ActiveCfg = Release|x64 + {600C3D4F-0670-4DB4-B30F-520A729053B5}.Release|x64.Build.0 = Release|x64 + {600C3D4F-0670-4DB4-B30F-520A729053B5}.Release|x86.ActiveCfg = Release|Win32 + {600C3D4F-0670-4DB4-B30F-520A729053B5}.Release|x86.Build.0 = Release|Win32 + {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Debug|ARM64.Build.0 = Debug|ARM64 + {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Debug|x64.ActiveCfg = Debug|x64 + {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Debug|x64.Build.0 = Debug|x64 + {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Debug|x86.ActiveCfg = Debug|Win32 + {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Debug|x86.Build.0 = Debug|Win32 + {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Release|ARM64.ActiveCfg = Release|ARM64 + {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Release|ARM64.Build.0 = Release|ARM64 + {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Release|x64.ActiveCfg = Release|x64 + {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Release|x64.Build.0 = Release|x64 + {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Release|x86.ActiveCfg = Release|Win32 + {11F33A39-74B7-4018-B5F9-CC285A673A8F}.Release|x86.Build.0 = Release|Win32 + {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Debug|ARM64.Build.0 = Debug|ARM64 + {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Debug|x64.ActiveCfg = Debug|x64 + {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Debug|x64.Build.0 = Debug|x64 + {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Debug|x86.ActiveCfg = Debug|Win32 + {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Debug|x86.Build.0 = Debug|Win32 + {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Release|ARM64.ActiveCfg = Release|ARM64 + {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Release|ARM64.Build.0 = Release|ARM64 + {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Release|x64.ActiveCfg = Release|x64 + {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Release|x64.Build.0 = Release|x64 + {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Release|x86.ActiveCfg = Release|Win32 + {A6F5E35E-B4A7-41B3-853A-75558E6E0715}.Release|x86.Build.0 = Release|Win32 + {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Debug|ARM64.Build.0 = Debug|ARM64 + {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Debug|x64.ActiveCfg = Debug|x64 + {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Debug|x64.Build.0 = Debug|x64 + {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Debug|x86.ActiveCfg = Debug|Win32 + {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Debug|x86.Build.0 = Debug|Win32 + {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Release|ARM64.ActiveCfg = Release|ARM64 + {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Release|ARM64.Build.0 = Release|ARM64 + {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Release|x64.ActiveCfg = Release|x64 + {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Release|x64.Build.0 = Release|x64 + {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Release|x86.ActiveCfg = Release|Win32 + {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Release|x86.Build.0 = Release|Win32 + {FDE6080B-E203-4066-910D-AD0302566008}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {FDE6080B-E203-4066-910D-AD0302566008}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {FDE6080B-E203-4066-910D-AD0302566008}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {FDE6080B-E203-4066-910D-AD0302566008}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {FDE6080B-E203-4066-910D-AD0302566008}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {FDE6080B-E203-4066-910D-AD0302566008}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {FDE6080B-E203-4066-910D-AD0302566008}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {FDE6080B-E203-4066-910D-AD0302566008}.Debug|ARM64.Build.0 = Debug|ARM64 + {FDE6080B-E203-4066-910D-AD0302566008}.Debug|x64.ActiveCfg = Debug|x64 + {FDE6080B-E203-4066-910D-AD0302566008}.Debug|x64.Build.0 = Debug|x64 + {FDE6080B-E203-4066-910D-AD0302566008}.Debug|x86.ActiveCfg = Debug|Win32 + {FDE6080B-E203-4066-910D-AD0302566008}.Debug|x86.Build.0 = Debug|Win32 + {FDE6080B-E203-4066-910D-AD0302566008}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {FDE6080B-E203-4066-910D-AD0302566008}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {FDE6080B-E203-4066-910D-AD0302566008}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {FDE6080B-E203-4066-910D-AD0302566008}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {FDE6080B-E203-4066-910D-AD0302566008}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {FDE6080B-E203-4066-910D-AD0302566008}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {FDE6080B-E203-4066-910D-AD0302566008}.Release|ARM64.ActiveCfg = Release|ARM64 + {FDE6080B-E203-4066-910D-AD0302566008}.Release|ARM64.Build.0 = Release|ARM64 + {FDE6080B-E203-4066-910D-AD0302566008}.Release|x64.ActiveCfg = Release|x64 + {FDE6080B-E203-4066-910D-AD0302566008}.Release|x64.Build.0 = Release|x64 + {FDE6080B-E203-4066-910D-AD0302566008}.Release|x86.ActiveCfg = Release|Win32 + {FDE6080B-E203-4066-910D-AD0302566008}.Release|x86.Build.0 = Release|Win32 + {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug|ARM64.Build.0 = Debug|ARM64 + {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug|x64.ActiveCfg = Debug|x64 + {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug|x64.Build.0 = Debug|x64 + {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug|x86.ActiveCfg = Debug|Win32 + {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug|x86.Build.0 = Debug|Win32 + {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release|ARM64.ActiveCfg = Release|ARM64 + {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release|ARM64.Build.0 = Release|ARM64 + {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release|x64.ActiveCfg = Release|x64 + {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release|x64.Build.0 = Release|x64 + {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release|x86.ActiveCfg = Release|Win32 + {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release|x86.Build.0 = Release|Win32 + {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug|ARM64.Build.0 = Debug|ARM64 + {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug|x64.ActiveCfg = Debug|x64 + {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug|x64.Build.0 = Debug|x64 + {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug|x86.ActiveCfg = Debug|Win32 + {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug|x86.Build.0 = Debug|Win32 + {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release|ARM64.ActiveCfg = Release|ARM64 + {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release|ARM64.Build.0 = Release|ARM64 + {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release|x64.ActiveCfg = Release|x64 + {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release|x64.Build.0 = Release|x64 + {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release|x86.ActiveCfg = Release|Win32 + {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release|x86.Build.0 = Release|Win32 + {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug|ARM64.Build.0 = Debug|ARM64 + {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug|x64.ActiveCfg = Debug|x64 + {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug|x64.Build.0 = Debug|x64 + {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug|x86.ActiveCfg = Debug|Win32 + {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug|x86.Build.0 = Debug|Win32 + {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release|ARM64.ActiveCfg = Release|ARM64 + {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release|ARM64.Build.0 = Release|ARM64 + {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release|x64.ActiveCfg = Release|x64 + {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release|x64.Build.0 = Release|x64 + {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release|x86.ActiveCfg = Release|Win32 + {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release|x86.Build.0 = Release|Win32 + {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug|ARM64.Build.0 = Debug|ARM64 + {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug|x64.ActiveCfg = Debug|x64 + {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug|x64.Build.0 = Debug|x64 + {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug|x86.ActiveCfg = Debug|Win32 + {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug|x86.Build.0 = Debug|Win32 + {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release|ARM64.ActiveCfg = Release|ARM64 + {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release|ARM64.Build.0 = Release|ARM64 + {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release|x64.ActiveCfg = Release|x64 + {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release|x64.Build.0 = Release|x64 + {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release|x86.ActiveCfg = Release|Win32 + {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release|x86.Build.0 = Release|Win32 + {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Debug|ARM64.Build.0 = Debug|ARM64 + {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Debug|x64.ActiveCfg = Debug|x64 + {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Debug|x64.Build.0 = Debug|x64 + {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Debug|x86.ActiveCfg = Debug|Win32 + {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Debug|x86.Build.0 = Debug|Win32 + {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Release|ARM64.ActiveCfg = Release|ARM64 + {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Release|ARM64.Build.0 = Release|ARM64 + {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Release|x64.ActiveCfg = Release|x64 + {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Release|x64.Build.0 = Release|x64 + {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Release|x86.ActiveCfg = Release|Win32 + {F2DB2E59-76BF-4D81-859A-AFC289C046C0}.Release|x86.Build.0 = Release|Win32 + {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Debug|ARM64.Build.0 = Debug|ARM64 + {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Debug|x64.ActiveCfg = Debug|x64 + {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Debug|x64.Build.0 = Debug|x64 + {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Debug|x86.ActiveCfg = Debug|Win32 + {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Debug|x86.Build.0 = Debug|Win32 + {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Release|ARM64.ActiveCfg = Release|ARM64 + {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Release|ARM64.Build.0 = Release|ARM64 + {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Release|x64.ActiveCfg = Release|x64 + {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Release|x64.Build.0 = Release|x64 + {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Release|x86.ActiveCfg = Release|Win32 + {3FE7E9B6-49AC-4246-A789-28DB4644567B}.Release|x86.Build.0 = Release|Win32 + {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Debug|ARM64.Build.0 = Debug|ARM64 + {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Debug|x64.ActiveCfg = Debug|x64 + {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Debug|x64.Build.0 = Debug|x64 + {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Debug|x86.ActiveCfg = Debug|Win32 + {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Debug|x86.Build.0 = Debug|Win32 + {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Release|ARM64.ActiveCfg = Release|ARM64 + {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Release|ARM64.Build.0 = Release|ARM64 + {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Release|x64.ActiveCfg = Release|x64 + {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Release|x64.Build.0 = Release|x64 + {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Release|x86.ActiveCfg = Release|Win32 + {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0}.Release|x86.Build.0 = Release|Win32 + {191A5289-BA65-4638-A215-C521F0187313}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {191A5289-BA65-4638-A215-C521F0187313}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {191A5289-BA65-4638-A215-C521F0187313}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {191A5289-BA65-4638-A215-C521F0187313}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {191A5289-BA65-4638-A215-C521F0187313}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {191A5289-BA65-4638-A215-C521F0187313}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {191A5289-BA65-4638-A215-C521F0187313}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {191A5289-BA65-4638-A215-C521F0187313}.Debug|ARM64.Build.0 = Debug|ARM64 + {191A5289-BA65-4638-A215-C521F0187313}.Debug|x64.ActiveCfg = Debug|x64 + {191A5289-BA65-4638-A215-C521F0187313}.Debug|x64.Build.0 = Debug|x64 + {191A5289-BA65-4638-A215-C521F0187313}.Debug|x86.ActiveCfg = Debug|Win32 + {191A5289-BA65-4638-A215-C521F0187313}.Debug|x86.Build.0 = Debug|Win32 + {191A5289-BA65-4638-A215-C521F0187313}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {191A5289-BA65-4638-A215-C521F0187313}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {191A5289-BA65-4638-A215-C521F0187313}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {191A5289-BA65-4638-A215-C521F0187313}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {191A5289-BA65-4638-A215-C521F0187313}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {191A5289-BA65-4638-A215-C521F0187313}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {191A5289-BA65-4638-A215-C521F0187313}.Release|ARM64.ActiveCfg = Release|ARM64 + {191A5289-BA65-4638-A215-C521F0187313}.Release|ARM64.Build.0 = Release|ARM64 + {191A5289-BA65-4638-A215-C521F0187313}.Release|x64.ActiveCfg = Release|x64 + {191A5289-BA65-4638-A215-C521F0187313}.Release|x64.Build.0 = Release|x64 + {191A5289-BA65-4638-A215-C521F0187313}.Release|x86.ActiveCfg = Release|Win32 + {191A5289-BA65-4638-A215-C521F0187313}.Release|x86.Build.0 = Release|Win32 + {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Debug|ARM64.Build.0 = Debug|ARM64 + {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Debug|x64.ActiveCfg = Debug|x64 + {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Debug|x64.Build.0 = Debug|x64 + {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Debug|x86.ActiveCfg = Debug|Win32 + {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Debug|x86.Build.0 = Debug|Win32 + {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Release|ARM64.ActiveCfg = Release|ARM64 + {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Release|ARM64.Build.0 = Release|ARM64 + {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Release|x64.ActiveCfg = Release|x64 + {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Release|x64.Build.0 = Release|x64 + {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Release|x86.ActiveCfg = Release|Win32 + {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359}.Release|x86.Build.0 = Release|Win32 + {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Debug|ARM64.Build.0 = Debug|ARM64 + {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Debug|x64.ActiveCfg = Debug|x64 + {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Debug|x64.Build.0 = Debug|x64 + {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Debug|x86.ActiveCfg = Debug|Win32 + {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Debug|x86.Build.0 = Debug|Win32 + {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Release|ARM64.ActiveCfg = Release|ARM64 + {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Release|ARM64.Build.0 = Release|ARM64 + {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Release|x64.ActiveCfg = Release|x64 + {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Release|x64.Build.0 = Release|x64 + {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Release|x86.ActiveCfg = Release|Win32 + {8B1AF423-00F1-4924-AC54-F77D402D2AC9}.Release|x86.Build.0 = Release|Win32 + {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Debug|ARM64.Build.0 = Debug|ARM64 + {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Debug|x64.ActiveCfg = Debug|x64 + {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Debug|x64.Build.0 = Debug|x64 + {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Debug|x86.ActiveCfg = Debug|Win32 + {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Debug|x86.Build.0 = Debug|Win32 + {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Release|ARM64.ActiveCfg = Release|ARM64 + {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Release|ARM64.Build.0 = Release|ARM64 + {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Release|x64.ActiveCfg = Release|x64 + {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Release|x64.Build.0 = Release|x64 + {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Release|x86.ActiveCfg = Release|Win32 + {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Release|x86.Build.0 = Release|Win32 + {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug|ARM64.Build.0 = Debug|ARM64 + {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug|x64.ActiveCfg = Debug|x64 + {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug|x64.Build.0 = Debug|x64 + {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug|x86.ActiveCfg = Debug|Win32 + {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug|x86.Build.0 = Debug|Win32 + {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release|ARM64.ActiveCfg = Release|ARM64 + {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release|ARM64.Build.0 = Release|ARM64 + {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release|x64.ActiveCfg = Release|x64 + {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release|x64.Build.0 = Release|x64 + {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release|x86.ActiveCfg = Release|Win32 + {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release|x86.Build.0 = Release|Win32 + {27B110CC-43C0-400A-89D9-245E681647D7}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {27B110CC-43C0-400A-89D9-245E681647D7}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {27B110CC-43C0-400A-89D9-245E681647D7}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {27B110CC-43C0-400A-89D9-245E681647D7}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {27B110CC-43C0-400A-89D9-245E681647D7}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {27B110CC-43C0-400A-89D9-245E681647D7}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {27B110CC-43C0-400A-89D9-245E681647D7}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {27B110CC-43C0-400A-89D9-245E681647D7}.Debug|ARM64.Build.0 = Debug|ARM64 + {27B110CC-43C0-400A-89D9-245E681647D7}.Debug|x64.ActiveCfg = Debug|x64 + {27B110CC-43C0-400A-89D9-245E681647D7}.Debug|x64.Build.0 = Debug|x64 + {27B110CC-43C0-400A-89D9-245E681647D7}.Debug|x86.ActiveCfg = Debug|Win32 + {27B110CC-43C0-400A-89D9-245E681647D7}.Debug|x86.Build.0 = Debug|Win32 + {27B110CC-43C0-400A-89D9-245E681647D7}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {27B110CC-43C0-400A-89D9-245E681647D7}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {27B110CC-43C0-400A-89D9-245E681647D7}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {27B110CC-43C0-400A-89D9-245E681647D7}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {27B110CC-43C0-400A-89D9-245E681647D7}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {27B110CC-43C0-400A-89D9-245E681647D7}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {27B110CC-43C0-400A-89D9-245E681647D7}.Release|ARM64.ActiveCfg = Release|ARM64 + {27B110CC-43C0-400A-89D9-245E681647D7}.Release|ARM64.Build.0 = Release|ARM64 + {27B110CC-43C0-400A-89D9-245E681647D7}.Release|x64.ActiveCfg = Release|x64 + {27B110CC-43C0-400A-89D9-245E681647D7}.Release|x64.Build.0 = Release|x64 + {27B110CC-43C0-400A-89D9-245E681647D7}.Release|x86.ActiveCfg = Release|Win32 + {27B110CC-43C0-400A-89D9-245E681647D7}.Release|x86.Build.0 = Release|Win32 + {1DE84812-E143-4C4B-A61D-9267AAD55401}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {1DE84812-E143-4C4B-A61D-9267AAD55401}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {1DE84812-E143-4C4B-A61D-9267AAD55401}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {1DE84812-E143-4C4B-A61D-9267AAD55401}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {1DE84812-E143-4C4B-A61D-9267AAD55401}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {1DE84812-E143-4C4B-A61D-9267AAD55401}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {1DE84812-E143-4C4B-A61D-9267AAD55401}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {1DE84812-E143-4C4B-A61D-9267AAD55401}.Debug|ARM64.Build.0 = Debug|ARM64 + {1DE84812-E143-4C4B-A61D-9267AAD55401}.Debug|x64.ActiveCfg = Debug|x64 + {1DE84812-E143-4C4B-A61D-9267AAD55401}.Debug|x64.Build.0 = Debug|x64 + {1DE84812-E143-4C4B-A61D-9267AAD55401}.Debug|x86.ActiveCfg = Debug|Win32 + {1DE84812-E143-4C4B-A61D-9267AAD55401}.Debug|x86.Build.0 = Debug|Win32 + {1DE84812-E143-4C4B-A61D-9267AAD55401}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {1DE84812-E143-4C4B-A61D-9267AAD55401}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {1DE84812-E143-4C4B-A61D-9267AAD55401}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {1DE84812-E143-4C4B-A61D-9267AAD55401}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {1DE84812-E143-4C4B-A61D-9267AAD55401}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {1DE84812-E143-4C4B-A61D-9267AAD55401}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {1DE84812-E143-4C4B-A61D-9267AAD55401}.Release|ARM64.ActiveCfg = Release|ARM64 + {1DE84812-E143-4C4B-A61D-9267AAD55401}.Release|ARM64.Build.0 = Release|ARM64 + {1DE84812-E143-4C4B-A61D-9267AAD55401}.Release|x64.ActiveCfg = Release|x64 + {1DE84812-E143-4C4B-A61D-9267AAD55401}.Release|x64.Build.0 = Release|x64 + {1DE84812-E143-4C4B-A61D-9267AAD55401}.Release|x86.ActiveCfg = Release|Win32 + {1DE84812-E143-4C4B-A61D-9267AAD55401}.Release|x86.Build.0 = Release|Win32 + {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Debug|ARM64.Build.0 = Debug|ARM64 + {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Debug|x64.ActiveCfg = Debug|x64 + {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Debug|x64.Build.0 = Debug|x64 + {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Debug|x86.ActiveCfg = Debug|Win32 + {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Debug|x86.Build.0 = Debug|Win32 + {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Release|ARM64.ActiveCfg = Release|ARM64 + {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Release|ARM64.Build.0 = Release|ARM64 + {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Release|x64.ActiveCfg = Release|x64 + {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Release|x64.Build.0 = Release|x64 + {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Release|x86.ActiveCfg = Release|Win32 + {4A87569C-4BD3-4113-B4B9-573D65B3D3F8}.Release|x86.Build.0 = Release|Win32 + {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Debug|ARM64.Build.0 = Debug|ARM64 + {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Debug|x64.ActiveCfg = Debug|x64 + {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Debug|x64.Build.0 = Debug|x64 + {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Debug|x86.ActiveCfg = Debug|Win32 + {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Debug|x86.Build.0 = Debug|Win32 + {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Release|ARM64.ActiveCfg = Release|ARM64 + {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Release|ARM64.Build.0 = Release|ARM64 + {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Release|x64.ActiveCfg = Release|x64 + {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Release|x64.Build.0 = Release|x64 + {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Release|x86.ActiveCfg = Release|Win32 + {769FF0C1-4424-4FA3-BC44-D7A7DA312A06}.Release|x86.Build.0 = Release|Win32 + {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Debug|ARM64.Build.0 = Debug|ARM64 + {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Debug|x64.ActiveCfg = Debug|x64 + {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Debug|x64.Build.0 = Debug|x64 + {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Debug|x86.ActiveCfg = Debug|Win32 + {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Debug|x86.Build.0 = Debug|Win32 + {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Release|ARM64.ActiveCfg = Release|ARM64 + {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Release|ARM64.Build.0 = Release|ARM64 + {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Release|x64.ActiveCfg = Release|x64 + {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Release|x64.Build.0 = Release|x64 + {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Release|x86.ActiveCfg = Release|Win32 + {6D9E00D8-2893-45E4-9363-3F7F61D416BD}.Release|x86.Build.0 = Release|Win32 + {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Debug|ARM64.Build.0 = Debug|ARM64 + {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Debug|x64.ActiveCfg = Debug|x64 + {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Debug|x64.Build.0 = Debug|x64 + {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Debug|x86.ActiveCfg = Debug|Win32 + {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Debug|x86.Build.0 = Debug|Win32 + {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Release|ARM64.ActiveCfg = Release|ARM64 + {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Release|ARM64.Build.0 = Release|ARM64 + {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Release|x64.ActiveCfg = Release|x64 + {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Release|x64.Build.0 = Release|x64 + {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Release|x86.ActiveCfg = Release|Win32 + {70B35F59-AFC2-4D8F-8833-5314D2047A81}.Release|x86.Build.0 = Release|Win32 + {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Debug|ARM64.Build.0 = Debug|ARM64 + {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Debug|x64.ActiveCfg = Debug|x64 + {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Debug|x64.Build.0 = Debug|x64 + {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Debug|x86.ActiveCfg = Debug|Win32 + {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Debug|x86.Build.0 = Debug|Win32 + {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Release|ARM64.ActiveCfg = Release|ARM64 + {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Release|ARM64.Build.0 = Release|ARM64 + {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Release|x64.ActiveCfg = Release|x64 + {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Release|x64.Build.0 = Release|x64 + {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Release|x86.ActiveCfg = Release|Win32 + {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7}.Release|x86.Build.0 = Release|Win32 + {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Debug|ARM64.Build.0 = Debug|ARM64 + {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Debug|x64.ActiveCfg = Debug|x64 + {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Debug|x64.Build.0 = Debug|x64 + {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Debug|x86.ActiveCfg = Debug|Win32 + {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Debug|x86.Build.0 = Debug|Win32 + {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Release|ARM64.ActiveCfg = Release|ARM64 + {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Release|ARM64.Build.0 = Release|ARM64 + {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Release|x64.ActiveCfg = Release|x64 + {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Release|x64.Build.0 = Release|x64 + {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Release|x86.ActiveCfg = Release|Win32 + {3755E9F4-CB48-4EC3-B561-3B85964EBDEF}.Release|x86.Build.0 = Release|Win32 + {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Debug|ARM64.Build.0 = Debug|ARM64 + {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Debug|x64.ActiveCfg = Debug|x64 + {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Debug|x64.Build.0 = Debug|x64 + {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Debug|x86.ActiveCfg = Debug|Win32 + {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Debug|x86.Build.0 = Debug|Win32 + {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Release|ARM64.ActiveCfg = Release|ARM64 + {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Release|ARM64.Build.0 = Release|ARM64 + {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Release|x64.ActiveCfg = Release|x64 + {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Release|x64.Build.0 = Release|x64 + {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Release|x86.ActiveCfg = Release|Win32 + {F81C5819-85B4-4D2E-B6DC-104A7634461B}.Release|x86.Build.0 = Release|Win32 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug|ARM64.Build.0 = Debug|ARM64 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug|x64.ActiveCfg = Debug|x64 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug|x64.Build.0 = Debug|x64 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug|x86.ActiveCfg = Debug|Win32 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Debug|x86.Build.0 = Debug|Win32 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release|ARM64.ActiveCfg = Release|ARM64 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release|ARM64.Build.0 = Release|ARM64 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release|x64.ActiveCfg = Release|x64 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release|x64.Build.0 = Release|x64 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release|x86.ActiveCfg = Release|Win32 + {CC62F7DB-D089-4677-8575-CAB7A7815C43}.Release|x86.Build.0 = Release|Win32 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug|ARM64.Build.0 = Debug|ARM64 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug|x64.ActiveCfg = Debug|x64 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug|x64.Build.0 = Debug|x64 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug|x86.ActiveCfg = Debug|Win32 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Debug|x86.Build.0 = Debug|Win32 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release|ARM64.ActiveCfg = Release|ARM64 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release|ARM64.Build.0 = Release|ARM64 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release|x64.ActiveCfg = Release|x64 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release|x64.Build.0 = Release|x64 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release|x86.ActiveCfg = Release|Win32 + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26}.Release|x86.Build.0 = Release|Win32 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug|ARM64.Build.0 = Debug|ARM64 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug|x64.ActiveCfg = Debug|x64 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug|x64.Build.0 = Debug|x64 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug|x86.ActiveCfg = Debug|Win32 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Debug|x86.Build.0 = Debug|Win32 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release|ARM64.ActiveCfg = Release|ARM64 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release|ARM64.Build.0 = Release|ARM64 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release|x64.ActiveCfg = Release|x64 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release|x64.Build.0 = Release|x64 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release|x86.ActiveCfg = Release|Win32 + {A4B0D971-3CD6-41C9-8AB2-055D25A33373}.Release|x86.Build.0 = Release|Win32 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug|ARM64.Build.0 = Debug|ARM64 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug|x64.ActiveCfg = Debug|x64 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug|x64.Build.0 = Debug|x64 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug|x86.ActiveCfg = Debug|Win32 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Debug|x86.Build.0 = Debug|Win32 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release|ARM64.ActiveCfg = Release|ARM64 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release|ARM64.Build.0 = Release|ARM64 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release|x64.ActiveCfg = Release|x64 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release|x64.Build.0 = Release|x64 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release|x86.ActiveCfg = Release|Win32 + {15CDD310-6980-42A6-8082-3A6B7730D13F}.Release|x86.Build.0 = Release|Win32 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug|ARM64.Build.0 = Debug|ARM64 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug|x64.ActiveCfg = Debug|x64 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug|x64.Build.0 = Debug|x64 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug|x86.ActiveCfg = Debug|Win32 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Debug|x86.Build.0 = Debug|Win32 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release|ARM64.ActiveCfg = Release|ARM64 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release|ARM64.Build.0 = Release|ARM64 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release|x64.ActiveCfg = Release|x64 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release|x64.Build.0 = Release|x64 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release|x86.ActiveCfg = Release|Win32 + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F}.Release|x86.Build.0 = Release|Win32 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug|ARM64.Build.0 = Debug|ARM64 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug|x64.ActiveCfg = Debug|x64 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug|x64.Build.0 = Debug|x64 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug|x86.ActiveCfg = Debug|Win32 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Debug|x86.Build.0 = Debug|Win32 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release|ARM64.ActiveCfg = Release|ARM64 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release|ARM64.Build.0 = Release|ARM64 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release|x64.ActiveCfg = Release|x64 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release|x64.Build.0 = Release|x64 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release|x86.ActiveCfg = Release|Win32 + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7}.Release|x86.Build.0 = Release|Win32 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug|ARM64.Build.0 = Debug|ARM64 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug|x64.ActiveCfg = Debug|x64 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug|x64.Build.0 = Debug|x64 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug|x86.ActiveCfg = Debug|Win32 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Debug|x86.Build.0 = Debug|Win32 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release|ARM64.ActiveCfg = Release|ARM64 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release|ARM64.Build.0 = Release|ARM64 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release|x64.ActiveCfg = Release|x64 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release|x64.Build.0 = Release|x64 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release|x86.ActiveCfg = Release|Win32 + {88DE5AD6-0074-4A5A-BE22-C840153E35D5}.Release|x86.Build.0 = Release|Win32 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug|ARM64.Build.0 = Debug|ARM64 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug|x64.ActiveCfg = Debug|x64 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug|x64.Build.0 = Debug|x64 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug|x86.ActiveCfg = Debug|Win32 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Debug|x86.Build.0 = Debug|Win32 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release|ARM64.ActiveCfg = Release|ARM64 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release|ARM64.Build.0 = Release|ARM64 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release|x64.ActiveCfg = Release|x64 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release|x64.Build.0 = Release|x64 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release|x86.ActiveCfg = Release|Win32 + {A546E75A-5242-46E6-9A9E-6C91554EAB84}.Release|x86.Build.0 = Release|Win32 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug|ARM64.Build.0 = Debug|ARM64 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug|x64.ActiveCfg = Debug|x64 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug|x64.Build.0 = Debug|x64 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug|x86.ActiveCfg = Debug|Win32 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Debug|x86.Build.0 = Debug|Win32 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release|ARM64.ActiveCfg = Release|ARM64 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release|ARM64.Build.0 = Release|ARM64 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release|x64.ActiveCfg = Release|x64 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release|x64.Build.0 = Release|x64 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release|x86.ActiveCfg = Release|Win32 + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}.Release|x86.Build.0 = Release|Win32 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug|ARM64.Build.0 = Debug|ARM64 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug|x64.ActiveCfg = Debug|x64 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug|x64.Build.0 = Debug|x64 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug|x86.ActiveCfg = Debug|Win32 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Debug|x86.Build.0 = Debug|Win32 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Release|ARM64.ActiveCfg = Release|ARM64 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Release|ARM64.Build.0 = Release|ARM64 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Release|x64.ActiveCfg = Release|x64 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Release|x64.Build.0 = Release|x64 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Release|x86.ActiveCfg = Release|Win32 + {DF25E545-00FF-4E64-844C-7DF98991F901}.Release|x86.Build.0 = Release|Win32 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug|ARM64.Build.0 = Debug|ARM64 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug|x64.ActiveCfg = Debug|x64 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug|x64.Build.0 = Debug|x64 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug|x86.ActiveCfg = Debug|Win32 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Debug|x86.Build.0 = Debug|Win32 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release|ARM64.ActiveCfg = Release|ARM64 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release|ARM64.Build.0 = Release|ARM64 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release|x64.ActiveCfg = Release|x64 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release|x64.Build.0 = Release|x64 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release|x86.ActiveCfg = Release|Win32 + {703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release|x86.Build.0 = Release|Win32 + {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Debug|ARM64.Build.0 = Debug|ARM64 + {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Debug|x64.ActiveCfg = Debug|x64 + {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Debug|x64.Build.0 = Debug|x64 + {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Debug|x86.ActiveCfg = Debug|Win32 + {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Debug|x86.Build.0 = Debug|Win32 + {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Release|ARM64.ActiveCfg = Release|ARM64 + {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Release|ARM64.Build.0 = Release|ARM64 + {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Release|x64.ActiveCfg = Release|x64 + {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Release|x64.Build.0 = Release|x64 + {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Release|x86.ActiveCfg = Release|Win32 + {FAFEE2F9-24B0-4AF1-B512-433E9590033F}.Release|x86.Build.0 = Release|Win32 + {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug|ARM64.Build.0 = Debug|ARM64 + {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug|x64.ActiveCfg = Debug|x64 + {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug|x64.Build.0 = Debug|x64 + {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug|x86.ActiveCfg = Debug|Win32 + {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug|x86.Build.0 = Debug|Win32 + {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release|ARM64.ActiveCfg = Release|ARM64 + {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release|ARM64.Build.0 = Release|ARM64 + {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release|x64.ActiveCfg = Release|x64 + {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release|x64.Build.0 = Release|x64 + {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release|x86.ActiveCfg = Release|Win32 + {8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release|x86.Build.0 = Release|Win32 + {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug|ARM64.Build.0 = Debug|ARM64 + {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug|x64.ActiveCfg = Debug|x64 + {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug|x64.Build.0 = Debug|x64 + {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug|x86.ActiveCfg = Debug|Win32 + {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Debug|x86.Build.0 = Debug|Win32 + {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release|ARM64.ActiveCfg = Release|ARM64 + {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release|ARM64.Build.0 = Release|ARM64 + {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release|x64.ActiveCfg = Release|x64 + {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release|x64.Build.0 = Release|x64 + {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release|x86.ActiveCfg = Release|Win32 + {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release|x86.Build.0 = Release|Win32 + {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Debug|ARM64.Build.0 = Debug|ARM64 + {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Debug|x64.ActiveCfg = Debug|x64 + {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Debug|x64.Build.0 = Debug|x64 + {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Debug|x86.ActiveCfg = Debug|Win32 + {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Debug|x86.Build.0 = Debug|Win32 + {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Release|ARM64.ActiveCfg = Release|ARM64 + {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Release|ARM64.Build.0 = Release|ARM64 + {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Release|x64.ActiveCfg = Release|x64 + {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Release|x64.Build.0 = Release|x64 + {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Release|x86.ActiveCfg = Release|Win32 + {3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Release|x86.Build.0 = Release|Win32 + {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Debug|ARM64.Build.0 = Debug|ARM64 + {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Debug|x64.ActiveCfg = Debug|x64 + {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Debug|x64.Build.0 = Debug|x64 + {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Debug|x86.ActiveCfg = Debug|Win32 + {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Debug|x86.Build.0 = Debug|Win32 + {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Release|ARM64.ActiveCfg = Release|ARM64 + {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Release|ARM64.Build.0 = Release|ARM64 + {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Release|x64.ActiveCfg = Release|x64 + {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Release|x64.Build.0 = Release|x64 + {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Release|x86.ActiveCfg = Release|Win32 + {CCA63A76-D9FC-4130-9F67-4D97F9770D53}.Release|x86.Build.0 = Release|Win32 + {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug|ARM64.Build.0 = Debug|ARM64 + {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug|x64.ActiveCfg = Debug|x64 + {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug|x64.Build.0 = Debug|x64 + {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug|x86.ActiveCfg = Debug|Win32 + {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug|x86.Build.0 = Debug|Win32 + {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release|ARM64.ActiveCfg = Release|ARM64 + {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release|ARM64.Build.0 = Release|ARM64 + {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release|x64.ActiveCfg = Release|x64 + {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release|x64.Build.0 = Release|x64 + {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release|x86.ActiveCfg = Release|Win32 + {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release|x86.Build.0 = Release|Win32 + {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Debug|ARM64.Build.0 = Debug|ARM64 + {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Debug|x64.ActiveCfg = Debug|x64 + {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Debug|x64.Build.0 = Debug|x64 + {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Debug|x86.ActiveCfg = Debug|Win32 + {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Debug|x86.Build.0 = Debug|Win32 + {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Release|ARM64.ActiveCfg = Release|ARM64 + {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Release|ARM64.Build.0 = Release|ARM64 + {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Release|x64.ActiveCfg = Release|x64 + {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Release|x64.Build.0 = Release|x64 + {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Release|x86.ActiveCfg = Release|Win32 + {3384C257-3CFE-4A8F-838C-19DAC5C955DA}.Release|x86.Build.0 = Release|Win32 + {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Debug|ARM64.Build.0 = Debug|ARM64 + {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Debug|x64.ActiveCfg = Debug|x64 + {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Debug|x64.Build.0 = Debug|x64 + {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Debug|x86.ActiveCfg = Debug|Win32 + {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Debug|x86.Build.0 = Debug|Win32 + {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Release|ARM64.ActiveCfg = Release|ARM64 + {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Release|ARM64.Build.0 = Release|ARM64 + {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Release|x64.ActiveCfg = Release|x64 + {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Release|x64.Build.0 = Release|x64 + {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Release|x86.ActiveCfg = Release|Win32 + {2B140378-125F-4DE9-AC37-2CC1B73D7254}.Release|x86.Build.0 = Release|Win32 + {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Debug|ARM64.Build.0 = Debug|ARM64 + {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Debug|x64.ActiveCfg = Debug|x64 + {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Debug|x64.Build.0 = Debug|x64 + {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Debug|x86.ActiveCfg = Debug|Win32 + {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Debug|x86.Build.0 = Debug|Win32 + {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Release|ARM64.ActiveCfg = Release|ARM64 + {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Release|ARM64.Build.0 = Release|ARM64 + {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Release|x64.ActiveCfg = Release|x64 + {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Release|x64.Build.0 = Release|x64 + {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Release|x86.ActiveCfg = Release|Win32 + {F4C55B99-E1C5-496A-8AC2-40188C38F4F6}.Release|x86.Build.0 = Release|Win32 + {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Debug|ARM64.Build.0 = Debug|ARM64 + {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Debug|x64.ActiveCfg = Debug|x64 + {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Debug|x64.Build.0 = Debug|x64 + {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Debug|x86.ActiveCfg = Debug|Win32 + {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Debug|x86.Build.0 = Debug|Win32 + {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Release|ARM64.ActiveCfg = Release|ARM64 + {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Release|ARM64.Build.0 = Release|ARM64 + {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Release|x64.ActiveCfg = Release|x64 + {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Release|x64.Build.0 = Release|x64 + {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Release|x86.ActiveCfg = Release|Win32 + {2AA91EED-2D32-4B09-84A3-53D41EED1005}.Release|x86.Build.0 = Release|Win32 + {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Debug|ARM64.Build.0 = Debug|ARM64 + {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Debug|x64.ActiveCfg = Debug|x64 + {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Debug|x64.Build.0 = Debug|x64 + {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Debug|x86.ActiveCfg = Debug|Win32 + {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Debug|x86.Build.0 = Debug|Win32 + {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Release|ARM64.ActiveCfg = Release|ARM64 + {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Release|ARM64.Build.0 = Release|ARM64 + {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Release|x64.ActiveCfg = Release|x64 + {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Release|x64.Build.0 = Release|x64 + {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Release|x86.ActiveCfg = Release|Win32 + {EC0910F6-8D66-4509-BF57-A5EE7AE9485F}.Release|x86.Build.0 = Release|Win32 + {921391C6-7626-4212-9928-BC82BC785461}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {921391C6-7626-4212-9928-BC82BC785461}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {921391C6-7626-4212-9928-BC82BC785461}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {921391C6-7626-4212-9928-BC82BC785461}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {921391C6-7626-4212-9928-BC82BC785461}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {921391C6-7626-4212-9928-BC82BC785461}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {921391C6-7626-4212-9928-BC82BC785461}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {921391C6-7626-4212-9928-BC82BC785461}.Debug|ARM64.Build.0 = Debug|ARM64 + {921391C6-7626-4212-9928-BC82BC785461}.Debug|x64.ActiveCfg = Debug|x64 + {921391C6-7626-4212-9928-BC82BC785461}.Debug|x64.Build.0 = Debug|x64 + {921391C6-7626-4212-9928-BC82BC785461}.Debug|x86.ActiveCfg = Debug|Win32 + {921391C6-7626-4212-9928-BC82BC785461}.Debug|x86.Build.0 = Debug|Win32 + {921391C6-7626-4212-9928-BC82BC785461}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {921391C6-7626-4212-9928-BC82BC785461}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {921391C6-7626-4212-9928-BC82BC785461}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {921391C6-7626-4212-9928-BC82BC785461}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {921391C6-7626-4212-9928-BC82BC785461}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {921391C6-7626-4212-9928-BC82BC785461}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {921391C6-7626-4212-9928-BC82BC785461}.Release|ARM64.ActiveCfg = Release|ARM64 + {921391C6-7626-4212-9928-BC82BC785461}.Release|ARM64.Build.0 = Release|ARM64 + {921391C6-7626-4212-9928-BC82BC785461}.Release|x64.ActiveCfg = Release|x64 + {921391C6-7626-4212-9928-BC82BC785461}.Release|x64.Build.0 = Release|x64 + {921391C6-7626-4212-9928-BC82BC785461}.Release|x86.ActiveCfg = Release|Win32 + {921391C6-7626-4212-9928-BC82BC785461}.Release|x86.Build.0 = Release|Win32 + {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Debug|ARM64.Build.0 = Debug|ARM64 + {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Debug|x64.ActiveCfg = Debug|x64 + {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Debug|x64.Build.0 = Debug|x64 + {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Debug|x86.ActiveCfg = Debug|Win32 + {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Debug|x86.Build.0 = Debug|Win32 + {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Release|ARM64.ActiveCfg = Release|ARM64 + {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Release|ARM64.Build.0 = Release|ARM64 + {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Release|x64.ActiveCfg = Release|x64 + {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Release|x64.Build.0 = Release|x64 + {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Release|x86.ActiveCfg = Release|Win32 + {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F}.Release|x86.Build.0 = Release|Win32 + {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Debug|ARM64.Build.0 = Debug|ARM64 + {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Debug|x64.ActiveCfg = Debug|x64 + {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Debug|x64.Build.0 = Debug|x64 + {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Debug|x86.ActiveCfg = Debug|Win32 + {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Debug|x86.Build.0 = Debug|Win32 + {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Release|ARM64.ActiveCfg = Release|ARM64 + {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Release|ARM64.Build.0 = Release|ARM64 + {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Release|x64.ActiveCfg = Release|x64 + {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Release|x64.Build.0 = Release|x64 + {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Release|x86.ActiveCfg = Release|Win32 + {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8}.Release|x86.Build.0 = Release|Win32 + {C54703BF-D68A-480D-BE27-49B62E45D582}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {C54703BF-D68A-480D-BE27-49B62E45D582}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {C54703BF-D68A-480D-BE27-49B62E45D582}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {C54703BF-D68A-480D-BE27-49B62E45D582}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {C54703BF-D68A-480D-BE27-49B62E45D582}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {C54703BF-D68A-480D-BE27-49B62E45D582}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {C54703BF-D68A-480D-BE27-49B62E45D582}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {C54703BF-D68A-480D-BE27-49B62E45D582}.Debug|ARM64.Build.0 = Debug|ARM64 + {C54703BF-D68A-480D-BE27-49B62E45D582}.Debug|x64.ActiveCfg = Debug|x64 + {C54703BF-D68A-480D-BE27-49B62E45D582}.Debug|x64.Build.0 = Debug|x64 + {C54703BF-D68A-480D-BE27-49B62E45D582}.Debug|x86.ActiveCfg = Debug|Win32 + {C54703BF-D68A-480D-BE27-49B62E45D582}.Debug|x86.Build.0 = Debug|Win32 + {C54703BF-D68A-480D-BE27-49B62E45D582}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {C54703BF-D68A-480D-BE27-49B62E45D582}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {C54703BF-D68A-480D-BE27-49B62E45D582}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {C54703BF-D68A-480D-BE27-49B62E45D582}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {C54703BF-D68A-480D-BE27-49B62E45D582}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {C54703BF-D68A-480D-BE27-49B62E45D582}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {C54703BF-D68A-480D-BE27-49B62E45D582}.Release|ARM64.ActiveCfg = Release|ARM64 + {C54703BF-D68A-480D-BE27-49B62E45D582}.Release|ARM64.Build.0 = Release|ARM64 + {C54703BF-D68A-480D-BE27-49B62E45D582}.Release|x64.ActiveCfg = Release|x64 + {C54703BF-D68A-480D-BE27-49B62E45D582}.Release|x64.Build.0 = Release|x64 + {C54703BF-D68A-480D-BE27-49B62E45D582}.Release|x86.ActiveCfg = Release|Win32 + {C54703BF-D68A-480D-BE27-49B62E45D582}.Release|x86.Build.0 = Release|Win32 + {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Debug|ARM64.Build.0 = Debug|ARM64 + {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Debug|x64.ActiveCfg = Debug|x64 + {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Debug|x64.Build.0 = Debug|x64 + {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Debug|x86.ActiveCfg = Debug|Win32 + {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Debug|x86.Build.0 = Debug|Win32 + {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Release|ARM64.ActiveCfg = Release|ARM64 + {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Release|ARM64.Build.0 = Release|ARM64 + {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Release|x64.ActiveCfg = Release|x64 + {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Release|x64.Build.0 = Release|x64 + {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Release|x86.ActiveCfg = Release|Win32 + {9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Release|x86.Build.0 = Release|Win32 + {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug|ARM64.Build.0 = Debug|ARM64 + {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug|x64.ActiveCfg = Debug|x64 + {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug|x64.Build.0 = Debug|x64 + {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug|x86.ActiveCfg = Debug|Win32 + {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug|x86.Build.0 = Debug|Win32 + {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release|ARM64.ActiveCfg = Release|ARM64 + {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release|ARM64.Build.0 = Release|ARM64 + {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release|x64.ActiveCfg = Release|x64 + {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release|x64.Build.0 = Release|x64 + {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release|x86.ActiveCfg = Release|Win32 + {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.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 + {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug|ARM64.Build.0 = Debug|ARM64 + {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug|x64.ActiveCfg = Debug|x64 + {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug|x64.Build.0 = Debug|x64 + {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug|x86.ActiveCfg = Debug|Win32 + {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug|x86.Build.0 = Debug|Win32 + {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release|ARM64.ActiveCfg = Release|ARM64 + {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release|ARM64.Build.0 = Release|ARM64 + {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release|x64.ActiveCfg = Release|x64 + {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release|x64.Build.0 = Release|x64 + {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release|x86.ActiveCfg = Release|Win32 + {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release|x86.Build.0 = Release|Win32 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug|ARM64.Build.0 = Debug|ARM64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug|x64.ActiveCfg = Debug|x64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug|x64.Build.0 = Debug|x64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug|x86.ActiveCfg = Debug|Win32 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug|x86.Build.0 = Debug|Win32 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release|ARM64.ActiveCfg = Release|ARM64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release|ARM64.Build.0 = Release|ARM64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release|x64.ActiveCfg = Release|x64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release|x64.Build.0 = Release|x64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release|x86.ActiveCfg = Release|Win32 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release|x86.Build.0 = Release|Win32 + {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Debug|ARM64.Build.0 = Debug|ARM64 + {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Debug|x64.ActiveCfg = Debug|x64 + {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Debug|x64.Build.0 = Debug|x64 + {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Debug|x86.ActiveCfg = Debug|Win32 + {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Debug|x86.Build.0 = Debug|Win32 + {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Release|ARM64.ActiveCfg = Release|ARM64 + {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Release|ARM64.Build.0 = Release|ARM64 + {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Release|x64.ActiveCfg = Release|x64 + {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Release|x64.Build.0 = Release|x64 + {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Release|x86.ActiveCfg = Release|Win32 + {A61DAD9C-271C-4E95-81AA-DB4CD58564D4}.Release|x86.Build.0 = Release|Win32 + {49C67F03-1A56-4F96-B278-39B66EC93678}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {49C67F03-1A56-4F96-B278-39B66EC93678}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {49C67F03-1A56-4F96-B278-39B66EC93678}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {49C67F03-1A56-4F96-B278-39B66EC93678}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {49C67F03-1A56-4F96-B278-39B66EC93678}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {49C67F03-1A56-4F96-B278-39B66EC93678}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {49C67F03-1A56-4F96-B278-39B66EC93678}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {49C67F03-1A56-4F96-B278-39B66EC93678}.Debug|ARM64.Build.0 = Debug|ARM64 + {49C67F03-1A56-4F96-B278-39B66EC93678}.Debug|x64.ActiveCfg = Debug|x64 + {49C67F03-1A56-4F96-B278-39B66EC93678}.Debug|x64.Build.0 = Debug|x64 + {49C67F03-1A56-4F96-B278-39B66EC93678}.Debug|x86.ActiveCfg = Debug|Win32 + {49C67F03-1A56-4F96-B278-39B66EC93678}.Debug|x86.Build.0 = Debug|Win32 + {49C67F03-1A56-4F96-B278-39B66EC93678}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {49C67F03-1A56-4F96-B278-39B66EC93678}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {49C67F03-1A56-4F96-B278-39B66EC93678}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {49C67F03-1A56-4F96-B278-39B66EC93678}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {49C67F03-1A56-4F96-B278-39B66EC93678}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {49C67F03-1A56-4F96-B278-39B66EC93678}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {49C67F03-1A56-4F96-B278-39B66EC93678}.Release|ARM64.ActiveCfg = Release|ARM64 + {49C67F03-1A56-4F96-B278-39B66EC93678}.Release|ARM64.Build.0 = Release|ARM64 + {49C67F03-1A56-4F96-B278-39B66EC93678}.Release|x64.ActiveCfg = Release|x64 + {49C67F03-1A56-4F96-B278-39B66EC93678}.Release|x64.Build.0 = Release|x64 + {49C67F03-1A56-4F96-B278-39B66EC93678}.Release|x86.ActiveCfg = Release|Win32 + {49C67F03-1A56-4F96-B278-39B66EC93678}.Release|x86.Build.0 = Release|Win32 + {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Debug|ARM64.Build.0 = Debug|ARM64 + {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Debug|x64.ActiveCfg = Debug|x64 + {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Debug|x64.Build.0 = Debug|x64 + {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Debug|x86.ActiveCfg = Debug|Win32 + {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Debug|x86.Build.0 = Debug|Win32 + {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Release|ARM64.ActiveCfg = Release|ARM64 + {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Release|ARM64.Build.0 = Release|ARM64 + {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Release|x64.ActiveCfg = Release|x64 + {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Release|x64.Build.0 = Release|x64 + {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Release|x86.ActiveCfg = Release|Win32 + {D496308F-3C3C-40B3-A3ED-EA327D244B3E}.Release|x86.Build.0 = Release|Win32 + {3B27F358-2679-4F38-B297-17B536F580BB}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {3B27F358-2679-4F38-B297-17B536F580BB}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {3B27F358-2679-4F38-B297-17B536F580BB}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {3B27F358-2679-4F38-B297-17B536F580BB}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {3B27F358-2679-4F38-B297-17B536F580BB}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {3B27F358-2679-4F38-B297-17B536F580BB}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {3B27F358-2679-4F38-B297-17B536F580BB}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {3B27F358-2679-4F38-B297-17B536F580BB}.Debug|ARM64.Build.0 = Debug|ARM64 + {3B27F358-2679-4F38-B297-17B536F580BB}.Debug|x64.ActiveCfg = Debug|x64 + {3B27F358-2679-4F38-B297-17B536F580BB}.Debug|x64.Build.0 = Debug|x64 + {3B27F358-2679-4F38-B297-17B536F580BB}.Debug|x86.ActiveCfg = Debug|Win32 + {3B27F358-2679-4F38-B297-17B536F580BB}.Debug|x86.Build.0 = Debug|Win32 + {3B27F358-2679-4F38-B297-17B536F580BB}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {3B27F358-2679-4F38-B297-17B536F580BB}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {3B27F358-2679-4F38-B297-17B536F580BB}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {3B27F358-2679-4F38-B297-17B536F580BB}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {3B27F358-2679-4F38-B297-17B536F580BB}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {3B27F358-2679-4F38-B297-17B536F580BB}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {3B27F358-2679-4F38-B297-17B536F580BB}.Release|ARM64.ActiveCfg = Release|ARM64 + {3B27F358-2679-4F38-B297-17B536F580BB}.Release|ARM64.Build.0 = Release|ARM64 + {3B27F358-2679-4F38-B297-17B536F580BB}.Release|x64.ActiveCfg = Release|x64 + {3B27F358-2679-4F38-B297-17B536F580BB}.Release|x64.Build.0 = Release|x64 + {3B27F358-2679-4F38-B297-17B536F580BB}.Release|x86.ActiveCfg = Release|Win32 + {3B27F358-2679-4F38-B297-17B536F580BB}.Release|x86.Build.0 = Release|Win32 + {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug|ARM64.Build.0 = Debug|ARM64 + {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug|x64.ActiveCfg = Debug|x64 + {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug|x64.Build.0 = Debug|x64 + {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug|x86.ActiveCfg = Debug|Win32 + {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug|x86.Build.0 = Debug|Win32 + {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release|ARM64.ActiveCfg = Release|ARM64 + {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release|ARM64.Build.0 = Release|ARM64 + {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release|x64.ActiveCfg = Release|x64 + {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release|x64.Build.0 = Release|x64 + {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release|x86.ActiveCfg = Release|Win32 + {718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release|x86.Build.0 = Release|Win32 + {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug|ARM64.Build.0 = Debug|ARM64 + {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug|x64.ActiveCfg = Debug|x64 + {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug|x64.Build.0 = Debug|x64 + {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug|x86.ActiveCfg = Debug|Win32 + {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Debug|x86.Build.0 = Debug|Win32 + {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release|ARM64.ActiveCfg = Release|ARM64 + {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release|ARM64.Build.0 = Release|ARM64 + {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release|x64.ActiveCfg = Release|x64 + {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release|x64.Build.0 = Release|x64 + {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release|x86.ActiveCfg = Release|Win32 + {19CA0070-B4B2-4394-90B7-D0C259AA35BA}.Release|x86.Build.0 = Release|Win32 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|ARM64.Build.0 = Debug|ARM64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|x64.ActiveCfg = Debug|x64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|x64.Build.0 = Debug|x64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|x86.ActiveCfg = Debug|Win32 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Debug|x86.Build.0 = Debug|Win32 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|ARM64.ActiveCfg = Release|ARM64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|ARM64.Build.0 = Release|ARM64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|x64.ActiveCfg = Release|x64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|x64.Build.0 = Release|x64 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|x86.ActiveCfg = Release|Win32 + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E}.Release|x86.Build.0 = Release|Win32 + {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug|ARM64.Build.0 = Debug|ARM64 + {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug|x64.ActiveCfg = Debug|x64 + {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug|x64.Build.0 = Debug|x64 + {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug|x86.ActiveCfg = Debug|Win32 + {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Debug|x86.Build.0 = Debug|Win32 + {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release|ARM64.ActiveCfg = Release|ARM64 + {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release|ARM64.Build.0 = Release|ARM64 + {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release|x64.ActiveCfg = Release|x64 + {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release|x64.Build.0 = Release|x64 + {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release|x86.ActiveCfg = Release|Win32 + {9DB1F875-6E65-4195-B23F-ED8095C0B99C}.Release|x86.Build.0 = Release|Win32 + {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug|ARM64.Build.0 = Debug|ARM64 + {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug|x64.ActiveCfg = Debug|x64 + {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug|x64.Build.0 = Debug|x64 + {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug|x86.ActiveCfg = Debug|Win32 + {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Debug|x86.Build.0 = Debug|Win32 + {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release|ARM64.ActiveCfg = Release|ARM64 + {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release|ARM64.Build.0 = Release|ARM64 + {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release|x64.ActiveCfg = Release|x64 + {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release|x64.Build.0 = Release|x64 + {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release|x86.ActiveCfg = Release|Win32 + {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F}.Release|x86.Build.0 = Release|Win32 + {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug|ARM64.Build.0 = Debug|ARM64 + {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug|x64.ActiveCfg = Debug|x64 + {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug|x64.Build.0 = Debug|x64 + {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug|x86.ActiveCfg = Debug|Win32 + {8E132D5A-2C00-48D0-8747-97E41356F26F}.Debug|x86.Build.0 = Debug|Win32 + {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release|ARM64.ActiveCfg = Release|ARM64 + {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release|ARM64.Build.0 = Release|ARM64 + {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release|x64.ActiveCfg = Release|x64 + {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release|x64.Build.0 = Release|x64 + {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release|x86.ActiveCfg = Release|Win32 + {8E132D5A-2C00-48D0-8747-97E41356F26F}.Release|x86.Build.0 = Release|Win32 + {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug|ARM64.Build.0 = Debug|ARM64 + {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug|x64.ActiveCfg = Debug|x64 + {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug|x64.Build.0 = Debug|x64 + {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug|x86.ActiveCfg = Debug|Win32 + {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Debug|x86.Build.0 = Debug|Win32 + {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release|ARM64.ActiveCfg = Release|ARM64 + {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release|ARM64.Build.0 = Release|ARM64 + {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release|x64.ActiveCfg = Release|x64 + {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release|x64.Build.0 = Release|x64 + {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release|x86.ActiveCfg = Release|Win32 + {A4662163-83E7-4309-8CAA-B0BF13655FE6}.Release|x86.Build.0 = Release|Win32 + {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug|ARM64.Build.0 = Debug|ARM64 + {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug|x64.ActiveCfg = Debug|x64 + {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug|x64.Build.0 = Debug|x64 + {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug|x86.ActiveCfg = Debug|Win32 + {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Debug|x86.Build.0 = Debug|Win32 + {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release|ARM64.ActiveCfg = Release|ARM64 + {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release|ARM64.Build.0 = Release|ARM64 + {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release|x64.ActiveCfg = Release|x64 + {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release|x64.Build.0 = Release|x64 + {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release|x86.ActiveCfg = Release|Win32 + {5F4B766F-DD52-4B53-B6C3-BC7611E17F20}.Release|x86.Build.0 = Release|Win32 + {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug|ARM64.Build.0 = Debug|ARM64 + {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug|x64.ActiveCfg = Debug|x64 + {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug|x64.Build.0 = Debug|x64 + {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug|x86.ActiveCfg = Debug|Win32 + {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Debug|x86.Build.0 = Debug|Win32 + {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release|ARM64.ActiveCfg = Release|ARM64 + {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release|ARM64.Build.0 = Release|ARM64 + {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release|x64.ActiveCfg = Release|x64 + {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release|x64.Build.0 = Release|x64 + {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release|x86.ActiveCfg = Release|Win32 + {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release|x86.Build.0 = Release|Win32 + {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug|ARM64.Build.0 = Debug|ARM64 + {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug|x64.ActiveCfg = Debug|x64 + {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug|x64.Build.0 = Debug|x64 + {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug|x86.ActiveCfg = Debug|Win32 + {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug|x86.Build.0 = Debug|Win32 + {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release|ARM64.ActiveCfg = Release|ARM64 + {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release|ARM64.Build.0 = Release|ARM64 + {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release|x64.ActiveCfg = Release|x64 + {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release|x64.Build.0 = Release|x64 + {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release|x86.ActiveCfg = Release|Win32 + {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release|x86.Build.0 = Release|Win32 + {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug|ARM64.Build.0 = Debug|ARM64 + {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug|x64.ActiveCfg = Debug|x64 + {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug|x64.Build.0 = Debug|x64 + {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug|x86.ActiveCfg = Debug|Win32 + {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug|x86.Build.0 = Debug|Win32 + {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release|ARM64.ActiveCfg = Release|ARM64 + {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release|ARM64.Build.0 = Release|ARM64 + {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release|x64.ActiveCfg = Release|x64 + {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release|x64.Build.0 = Release|x64 + {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release|x86.ActiveCfg = Release|Win32 + {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Release|x86.Build.0 = Release|Win32 + {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug|ARM64.Build.0 = Debug|ARM64 + {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug|x64.ActiveCfg = Debug|x64 + {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug|x64.Build.0 = Debug|x64 + {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug|x86.ActiveCfg = Debug|Win32 + {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Debug|x86.Build.0 = Debug|Win32 + {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release|ARM64.ActiveCfg = Release|ARM64 + {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release|ARM64.Build.0 = Release|ARM64 + {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release|x64.ActiveCfg = Release|x64 + {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release|x64.Build.0 = Release|x64 + {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release|x86.ActiveCfg = Release|Win32 + {DFB40A10-F8B7-412A-BCC3-5EE49294D816}.Release|x86.Build.0 = Release|Win32 + {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug|ARM64.Build.0 = Debug|ARM64 + {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug|x64.ActiveCfg = Debug|x64 + {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug|x64.Build.0 = Debug|x64 + {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug|x86.ActiveCfg = Debug|Win32 + {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Debug|x86.Build.0 = Debug|Win32 + {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release|ARM64.ActiveCfg = Release|ARM64 + {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release|ARM64.Build.0 = Release|ARM64 + {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release|x64.ActiveCfg = Release|x64 + {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release|x64.Build.0 = Release|x64 + {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release|x86.ActiveCfg = Release|Win32 + {BB58A5FB-1A35-4471-86D0-A5189EC541B3}.Release|x86.Build.0 = Release|Win32 + {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug|ARM64.Build.0 = Debug|ARM64 + {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug|x64.ActiveCfg = Debug|x64 + {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug|x64.Build.0 = Debug|x64 + {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug|x86.ActiveCfg = Debug|Win32 + {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Debug|x86.Build.0 = Debug|Win32 + {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release|ARM64.ActiveCfg = Release|ARM64 + {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release|ARM64.Build.0 = Release|ARM64 + {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release|x64.ActiveCfg = Release|x64 + {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release|x64.Build.0 = Release|x64 + {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release|x86.ActiveCfg = Release|Win32 + {61997220-5383-4AE5-ABD4-5F45AE1B0F2A}.Release|x86.Build.0 = Release|Win32 + {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug|ARM64.Build.0 = Debug|ARM64 + {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug|x64.ActiveCfg = Debug|x64 + {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug|x64.Build.0 = Debug|x64 + {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug|x86.ActiveCfg = Debug|Win32 + {7467E9AE-844F-444D-8A3F-17397544BA21}.Debug|x86.Build.0 = Debug|Win32 + {7467E9AE-844F-444D-8A3F-17397544BA21}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {7467E9AE-844F-444D-8A3F-17397544BA21}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {7467E9AE-844F-444D-8A3F-17397544BA21}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {7467E9AE-844F-444D-8A3F-17397544BA21}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {7467E9AE-844F-444D-8A3F-17397544BA21}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {7467E9AE-844F-444D-8A3F-17397544BA21}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {7467E9AE-844F-444D-8A3F-17397544BA21}.Release|ARM64.ActiveCfg = Release|ARM64 + {7467E9AE-844F-444D-8A3F-17397544BA21}.Release|ARM64.Build.0 = Release|ARM64 + {7467E9AE-844F-444D-8A3F-17397544BA21}.Release|x64.ActiveCfg = Release|x64 + {7467E9AE-844F-444D-8A3F-17397544BA21}.Release|x64.Build.0 = Release|x64 + {7467E9AE-844F-444D-8A3F-17397544BA21}.Release|x86.ActiveCfg = Release|Win32 + {7467E9AE-844F-444D-8A3F-17397544BA21}.Release|x86.Build.0 = Release|Win32 + {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug|ARM64.Build.0 = Debug|ARM64 + {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug|x64.ActiveCfg = Debug|x64 + {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug|x64.Build.0 = Debug|x64 + {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug|x86.ActiveCfg = Debug|Win32 + {497FDF54-9762-4048-A833-61CC3980A0FB}.Debug|x86.Build.0 = Debug|Win32 + {497FDF54-9762-4048-A833-61CC3980A0FB}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {497FDF54-9762-4048-A833-61CC3980A0FB}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {497FDF54-9762-4048-A833-61CC3980A0FB}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {497FDF54-9762-4048-A833-61CC3980A0FB}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {497FDF54-9762-4048-A833-61CC3980A0FB}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {497FDF54-9762-4048-A833-61CC3980A0FB}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {497FDF54-9762-4048-A833-61CC3980A0FB}.Release|ARM64.ActiveCfg = Release|ARM64 + {497FDF54-9762-4048-A833-61CC3980A0FB}.Release|ARM64.Build.0 = Release|ARM64 + {497FDF54-9762-4048-A833-61CC3980A0FB}.Release|x64.ActiveCfg = Release|x64 + {497FDF54-9762-4048-A833-61CC3980A0FB}.Release|x64.Build.0 = Release|x64 + {497FDF54-9762-4048-A833-61CC3980A0FB}.Release|x86.ActiveCfg = Release|Win32 + {497FDF54-9762-4048-A833-61CC3980A0FB}.Release|x86.Build.0 = Release|Win32 + {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug|ARM64.Build.0 = Debug|ARM64 + {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug|x64.ActiveCfg = Debug|x64 + {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug|x64.Build.0 = Debug|x64 + {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug|x86.ActiveCfg = Debug|Win32 + {29B00F47-BE91-4A1F-B87D-B1302F038316}.Debug|x86.Build.0 = Debug|Win32 + {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release|ARM64.ActiveCfg = Release|ARM64 + {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release|ARM64.Build.0 = Release|ARM64 + {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release|x64.ActiveCfg = Release|x64 + {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release|x64.Build.0 = Release|x64 + {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release|x86.ActiveCfg = Release|Win32 + {29B00F47-BE91-4A1F-B87D-B1302F038316}.Release|x86.Build.0 = Release|Win32 + {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug|ARM64.Build.0 = Debug|ARM64 + {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug|x64.ActiveCfg = Debug|x64 + {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug|x64.Build.0 = Debug|x64 + {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug|x86.ActiveCfg = Debug|Win32 + {124935CC-73BB-489E-92E8-4F922A85DB5D}.Debug|x86.Build.0 = Debug|Win32 + {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release|ARM64.ActiveCfg = Release|ARM64 + {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release|ARM64.Build.0 = Release|ARM64 + {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release|x64.ActiveCfg = Release|x64 + {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release|x64.Build.0 = Release|x64 + {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release|x86.ActiveCfg = Release|Win32 + {124935CC-73BB-489E-92E8-4F922A85DB5D}.Release|x86.Build.0 = Release|Win32 + {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug|ARM64.Build.0 = Debug|ARM64 + {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug|x64.ActiveCfg = Debug|x64 + {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug|x64.Build.0 = Debug|x64 + {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug|x86.ActiveCfg = Debug|Win32 + {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Debug|x86.Build.0 = Debug|Win32 + {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release|ARM64.ActiveCfg = Release|ARM64 + {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release|ARM64.Build.0 = Release|ARM64 + {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release|x64.ActiveCfg = Release|x64 + {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release|x64.Build.0 = Release|x64 + {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release|x86.ActiveCfg = Release|Win32 + {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F}.Release|x86.Build.0 = Release|Win32 + {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug|ARM64.Build.0 = Debug|ARM64 + {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug|x64.ActiveCfg = Debug|x64 + {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug|x64.Build.0 = Debug|x64 + {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug|x86.ActiveCfg = Debug|Win32 + {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Debug|x86.Build.0 = Debug|Win32 + {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release|ARM64.ActiveCfg = Release|ARM64 + {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release|ARM64.Build.0 = Release|ARM64 + {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release|x64.ActiveCfg = Release|x64 + {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release|x64.Build.0 = Release|x64 + {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release|x86.ActiveCfg = Release|Win32 + {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2}.Release|x86.Build.0 = Release|Win32 + {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug|ARM64.Build.0 = Debug|ARM64 + {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug|x64.ActiveCfg = Debug|x64 + {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug|x64.Build.0 = Debug|x64 + {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug|x86.ActiveCfg = Debug|Win32 + {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Debug|x86.Build.0 = Debug|Win32 + {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release|ARM64.ActiveCfg = Release|ARM64 + {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release|ARM64.Build.0 = Release|ARM64 + {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release|x64.ActiveCfg = Release|x64 + {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release|x64.Build.0 = Release|x64 + {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release|x86.ActiveCfg = Release|Win32 + {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91}.Release|x86.Build.0 = Release|Win32 + {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug|ARM64.Build.0 = Debug|ARM64 + {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug|x64.ActiveCfg = Debug|x64 + {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug|x64.Build.0 = Debug|x64 + {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug|x86.ActiveCfg = Debug|Win32 + {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Debug|x86.Build.0 = Debug|Win32 + {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release|ARM64.ActiveCfg = Release|ARM64 + {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release|ARM64.Build.0 = Release|ARM64 + {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release|x64.ActiveCfg = Release|x64 + {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release|x64.Build.0 = Release|x64 + {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release|x86.ActiveCfg = Release|Win32 + {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F}.Release|x86.Build.0 = Release|Win32 + {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug|ARM64.Build.0 = Debug|ARM64 + {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug|x64.ActiveCfg = Debug|x64 + {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug|x64.Build.0 = Debug|x64 + {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug|x86.ActiveCfg = Debug|Win32 + {9DE2FC01-A839-4F89-8319-9071D4C54821}.Debug|x86.Build.0 = Debug|Win32 + {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release|ARM64.ActiveCfg = Release|ARM64 + {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release|ARM64.Build.0 = Release|ARM64 + {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release|x64.ActiveCfg = Release|x64 + {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release|x64.Build.0 = Release|x64 + {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release|x86.ActiveCfg = Release|Win32 + {9DE2FC01-A839-4F89-8319-9071D4C54821}.Release|x86.Build.0 = Release|Win32 + {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug|ARM64.Build.0 = Debug|ARM64 + {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug|x64.ActiveCfg = Debug|x64 + {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug|x64.Build.0 = Debug|x64 + {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug|x86.ActiveCfg = Debug|Win32 + {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Debug|x86.Build.0 = Debug|Win32 + {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release|ARM64.ActiveCfg = Release|ARM64 + {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release|ARM64.Build.0 = Release|ARM64 + {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release|x64.ActiveCfg = Release|x64 + {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release|x64.Build.0 = Release|x64 + {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release|x86.ActiveCfg = Release|Win32 + {2F578155-D51F-4C03-AB7F-5C5122CA46CC}.Release|x86.Build.0 = Release|Win32 + {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug|ARM64.Build.0 = Debug|ARM64 + {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug|x64.ActiveCfg = Debug|x64 + {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug|x64.Build.0 = Debug|x64 + {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug|x86.ActiveCfg = Debug|Win32 + {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Debug|x86.Build.0 = Debug|Win32 + {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release|ARM64.ActiveCfg = Release|ARM64 + {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release|ARM64.Build.0 = Release|ARM64 + {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release|x64.ActiveCfg = Release|x64 + {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release|x64.Build.0 = Release|x64 + {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release|x86.ActiveCfg = Release|Win32 + {1C829D1A-892C-451C-AF0B-AC65C85F5CC6}.Release|x86.Build.0 = Release|Win32 + {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Debug|ARM64.Build.0 = Debug|ARM64 + {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Debug|x64.ActiveCfg = Debug|x64 + {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Debug|x64.Build.0 = Debug|x64 + {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Debug|x86.ActiveCfg = Debug|Win32 + {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Debug|x86.Build.0 = Debug|Win32 + {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Release|ARM64.ActiveCfg = Release|ARM64 + {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Release|ARM64.Build.0 = Release|ARM64 + {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Release|x64.ActiveCfg = Release|x64 + {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Release|x64.Build.0 = Release|x64 + {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Release|x86.ActiveCfg = Release|Win32 + {84DE22BB-C25F-425C-A7FE-0120CF107B83}.Release|x86.Build.0 = Release|Win32 + {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Debug|ARM64.Build.0 = Debug|ARM64 + {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Debug|x64.ActiveCfg = Debug|x64 + {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Debug|x64.Build.0 = Debug|x64 + {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Debug|x86.ActiveCfg = Debug|Win32 + {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Debug|x86.Build.0 = Debug|Win32 + {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Release|ARM64.ActiveCfg = Release|ARM64 + {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Release|ARM64.Build.0 = Release|ARM64 + {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Release|x64.ActiveCfg = Release|x64 + {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Release|x64.Build.0 = Release|x64 + {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Release|x86.ActiveCfg = Release|Win32 + {98152EDD-7E28-4FA3-89D8-B636ED5D5F65}.Release|x86.Build.0 = Release|Win32 + {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Debug|ARM64.Build.0 = Debug|ARM64 + {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Debug|x64.ActiveCfg = Debug|x64 + {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Debug|x64.Build.0 = Debug|x64 + {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Debug|x86.ActiveCfg = Debug|Win32 + {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Debug|x86.Build.0 = Debug|Win32 + {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Release|ARM64.ActiveCfg = Release|ARM64 + {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Release|ARM64.Build.0 = Release|ARM64 + {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Release|x64.ActiveCfg = Release|x64 + {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Release|x64.Build.0 = Release|x64 + {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Release|x86.ActiveCfg = Release|Win32 + {B7FDD40F-DDA4-468E-9C40-EEB175964A26}.Release|x86.Build.0 = Release|Win32 + {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Debug|ARM64.Build.0 = Debug|ARM64 + {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Debug|x64.ActiveCfg = Debug|x64 + {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Debug|x64.Build.0 = Debug|x64 + {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Debug|x86.ActiveCfg = Debug|Win32 + {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Debug|x86.Build.0 = Debug|Win32 + {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Release|ARM64.ActiveCfg = Release|ARM64 + {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Release|ARM64.Build.0 = Release|ARM64 + {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Release|x64.ActiveCfg = Release|x64 + {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Release|x64.Build.0 = Release|x64 + {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Release|x86.ActiveCfg = Release|Win32 + {028F0967-B253-45DA-B1C4-FACCE45D0D8D}.Release|x86.Build.0 = Release|Win32 + {666346D7-C84B-498D-AE17-53B20C62DB1A}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {666346D7-C84B-498D-AE17-53B20C62DB1A}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {666346D7-C84B-498D-AE17-53B20C62DB1A}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {666346D7-C84B-498D-AE17-53B20C62DB1A}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {666346D7-C84B-498D-AE17-53B20C62DB1A}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {666346D7-C84B-498D-AE17-53B20C62DB1A}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {666346D7-C84B-498D-AE17-53B20C62DB1A}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {666346D7-C84B-498D-AE17-53B20C62DB1A}.Debug|ARM64.Build.0 = Debug|ARM64 + {666346D7-C84B-498D-AE17-53B20C62DB1A}.Debug|x64.ActiveCfg = Debug|x64 + {666346D7-C84B-498D-AE17-53B20C62DB1A}.Debug|x64.Build.0 = Debug|x64 + {666346D7-C84B-498D-AE17-53B20C62DB1A}.Debug|x86.ActiveCfg = Debug|Win32 + {666346D7-C84B-498D-AE17-53B20C62DB1A}.Debug|x86.Build.0 = Debug|Win32 + {666346D7-C84B-498D-AE17-53B20C62DB1A}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {666346D7-C84B-498D-AE17-53B20C62DB1A}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {666346D7-C84B-498D-AE17-53B20C62DB1A}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {666346D7-C84B-498D-AE17-53B20C62DB1A}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {666346D7-C84B-498D-AE17-53B20C62DB1A}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {666346D7-C84B-498D-AE17-53B20C62DB1A}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {666346D7-C84B-498D-AE17-53B20C62DB1A}.Release|ARM64.ActiveCfg = Release|ARM64 + {666346D7-C84B-498D-AE17-53B20C62DB1A}.Release|ARM64.Build.0 = Release|ARM64 + {666346D7-C84B-498D-AE17-53B20C62DB1A}.Release|x64.ActiveCfg = Release|x64 + {666346D7-C84B-498D-AE17-53B20C62DB1A}.Release|x64.Build.0 = Release|x64 + {666346D7-C84B-498D-AE17-53B20C62DB1A}.Release|x86.ActiveCfg = Release|Win32 + {666346D7-C84B-498D-AE17-53B20C62DB1A}.Release|x86.Build.0 = Release|Win32 + {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Debug|ARM64.Build.0 = Debug|ARM64 + {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Debug|x64.ActiveCfg = Debug|x64 + {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Debug|x64.Build.0 = Debug|x64 + {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Debug|x86.ActiveCfg = Debug|Win32 + {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Debug|x86.Build.0 = Debug|Win32 + {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Release|ARM64.ActiveCfg = Release|ARM64 + {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Release|ARM64.Build.0 = Release|ARM64 + {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Release|x64.ActiveCfg = Release|x64 + {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Release|x64.Build.0 = Release|x64 + {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Release|x86.ActiveCfg = Release|Win32 + {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91}.Release|x86.Build.0 = Release|Win32 + {6C897101-BE52-4387-8AA2-062123A76BA1}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {6C897101-BE52-4387-8AA2-062123A76BA1}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {6C897101-BE52-4387-8AA2-062123A76BA1}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {6C897101-BE52-4387-8AA2-062123A76BA1}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {6C897101-BE52-4387-8AA2-062123A76BA1}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {6C897101-BE52-4387-8AA2-062123A76BA1}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {6C897101-BE52-4387-8AA2-062123A76BA1}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {6C897101-BE52-4387-8AA2-062123A76BA1}.Debug|ARM64.Build.0 = Debug|ARM64 + {6C897101-BE52-4387-8AA2-062123A76BA1}.Debug|x64.ActiveCfg = Debug|x64 + {6C897101-BE52-4387-8AA2-062123A76BA1}.Debug|x64.Build.0 = Debug|x64 + {6C897101-BE52-4387-8AA2-062123A76BA1}.Debug|x86.ActiveCfg = Debug|Win32 + {6C897101-BE52-4387-8AA2-062123A76BA1}.Debug|x86.Build.0 = Debug|Win32 + {6C897101-BE52-4387-8AA2-062123A76BA1}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {6C897101-BE52-4387-8AA2-062123A76BA1}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {6C897101-BE52-4387-8AA2-062123A76BA1}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {6C897101-BE52-4387-8AA2-062123A76BA1}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {6C897101-BE52-4387-8AA2-062123A76BA1}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {6C897101-BE52-4387-8AA2-062123A76BA1}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {6C897101-BE52-4387-8AA2-062123A76BA1}.Release|ARM64.ActiveCfg = Release|ARM64 + {6C897101-BE52-4387-8AA2-062123A76BA1}.Release|ARM64.Build.0 = Release|ARM64 + {6C897101-BE52-4387-8AA2-062123A76BA1}.Release|x64.ActiveCfg = Release|x64 + {6C897101-BE52-4387-8AA2-062123A76BA1}.Release|x64.Build.0 = Release|x64 + {6C897101-BE52-4387-8AA2-062123A76BA1}.Release|x86.ActiveCfg = Release|Win32 + {6C897101-BE52-4387-8AA2-062123A76BA1}.Release|x86.Build.0 = Release|Win32 + {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Debug|ARM64.Build.0 = Debug|ARM64 + {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Debug|x64.ActiveCfg = Debug|x64 + {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Debug|x64.Build.0 = Debug|x64 + {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Debug|x86.ActiveCfg = Debug|Win32 + {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Debug|x86.Build.0 = Debug|Win32 + {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Release|ARM64.ActiveCfg = Release|ARM64 + {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Release|ARM64.Build.0 = Release|ARM64 + {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Release|x64.ActiveCfg = Release|x64 + {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Release|x64.Build.0 = Release|x64 + {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Release|x86.ActiveCfg = Release|Win32 + {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}.Release|x86.Build.0 = Release|Win32 + {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Debug|ARM64.Build.0 = Debug|ARM64 + {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Debug|x64.ActiveCfg = Debug|x64 + {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Debug|x64.Build.0 = Debug|x64 + {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Debug|x86.ActiveCfg = Debug|Win32 + {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Debug|x86.Build.0 = Debug|Win32 + {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Release|ARM64.ActiveCfg = Release|ARM64 + {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Release|ARM64.Build.0 = Release|ARM64 + {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Release|x64.ActiveCfg = Release|x64 + {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Release|x64.Build.0 = Release|x64 + {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Release|x86.ActiveCfg = Release|Win32 + {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}.Release|x86.Build.0 = Release|Win32 + {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Debug|ARM64.Build.0 = Debug|ARM64 + {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Debug|x64.ActiveCfg = Debug|x64 + {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Debug|x64.Build.0 = Debug|x64 + {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Debug|x86.ActiveCfg = Debug|Win32 + {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Debug|x86.Build.0 = Debug|Win32 + {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Release|ARM64.ActiveCfg = Release|ARM64 + {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Release|ARM64.Build.0 = Release|ARM64 + {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Release|x64.ActiveCfg = Release|x64 + {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Release|x64.Build.0 = Release|x64 + {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Release|x86.ActiveCfg = Release|Win32 + {30011884-25EE-42C9-BB15-888CAFB1AA6E}.Release|x86.Build.0 = Release|Win32 + {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Debug|ARM64.Build.0 = Debug|ARM64 + {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Debug|x64.ActiveCfg = Debug|x64 + {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Debug|x64.Build.0 = Debug|x64 + {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Debug|x86.ActiveCfg = Debug|Win32 + {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Debug|x86.Build.0 = Debug|Win32 + {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Release|ARM64.ActiveCfg = Release|ARM64 + {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Release|ARM64.Build.0 = Release|ARM64 + {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Release|x64.ActiveCfg = Release|x64 + {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Release|x64.Build.0 = Release|x64 + {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Release|x86.ActiveCfg = Release|Win32 + {32FE2658-1D70-442E-8672-0AC5C6F0BD7B}.Release|x86.Build.0 = Release|Win32 + {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Debug|ARM64.Build.0 = Debug|ARM64 + {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Debug|x64.ActiveCfg = Debug|x64 + {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Debug|x64.Build.0 = Debug|x64 + {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Debug|x86.ActiveCfg = Debug|Win32 + {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Debug|x86.Build.0 = Debug|Win32 + {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Release|ARM64.ActiveCfg = Release|ARM64 + {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Release|ARM64.Build.0 = Release|ARM64 + {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Release|x64.ActiveCfg = Release|x64 + {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Release|x64.Build.0 = Release|x64 + {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Release|x86.ActiveCfg = Release|Win32 + {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F}.Release|x86.Build.0 = Release|Win32 + {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Debug|ARM64.Build.0 = Debug|ARM64 + {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Debug|x64.ActiveCfg = Debug|x64 + {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Debug|x64.Build.0 = Debug|x64 + {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Debug|x86.ActiveCfg = Debug|Win32 + {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Debug|x86.Build.0 = Debug|Win32 + {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Release|ARM64.ActiveCfg = Release|ARM64 + {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Release|ARM64.Build.0 = Release|ARM64 + {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F}.Release|x64.ActiveCfg = Release|x64 + {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 + {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 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|ARM64.Build.0 = Debug|ARM64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|x64.ActiveCfg = Debug|x64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|x64.Build.0 = Debug|x64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|x86.ActiveCfg = Debug|Win32 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Debug|x86.Build.0 = Debug|Win32 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|ARM64.ActiveCfg = Release|ARM64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|ARM64.Build.0 = Release|ARM64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|x64.ActiveCfg = Release|x64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|x64.Build.0 = Release|x64 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|x86.ActiveCfg = Release|Win32 + {DC163251-16C3-4B72-B965-ACDBA0F02BD1}.Release|x86.Build.0 = Release|Win32 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|ARM64.Build.0 = Debug|ARM64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|x64.ActiveCfg = Debug|x64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|x64.Build.0 = Debug|x64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|x86.ActiveCfg = Debug|Win32 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Debug|x86.Build.0 = Debug|Win32 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|ARM64.ActiveCfg = Release|ARM64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|ARM64.Build.0 = Release|ARM64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|x64.ActiveCfg = Release|x64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|x64.Build.0 = Release|x64 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|x86.ActiveCfg = Release|Win32 + {D35D2FDA-B53F-4F70-81CA-24D95812B89C}.Release|x86.Build.0 = Release|Win32 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|ARM64.Build.0 = Debug|ARM64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|x64.ActiveCfg = Debug|x64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|x64.Build.0 = Debug|x64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|x86.ActiveCfg = Debug|Win32 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Debug|x86.Build.0 = Debug|Win32 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|ARM64.ActiveCfg = Release|ARM64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|ARM64.Build.0 = Release|ARM64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|x64.ActiveCfg = Release|x64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|x64.Build.0 = Release|x64 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|x86.ActiveCfg = Release|Win32 + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1} + {278D8859-20B1-428F-8448-064F46E1F021} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1} + {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1} + {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1} + {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1} + {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1} + {CC132A4D-D081-4C26-BFB9-AB11984054F8} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1} + {E9D708A5-9C1F-4B84-A795-C5F191801762} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1} + {0981CA98-E4A5-4DF1-987F-A41D09131EFC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {103B292B-049B-4B15-85A1-9F902840DB2C} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {0C2D2F82-AE67-400C-B19C-8C9B957B132A} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {E6784F91-4E4E-4956-A079-73FAB1AC7BE6} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} + {BFB22AB2-041B-4A1B-80C0-1D4BE410C8A9} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} + {93A1F656-0D29-4C5E-B140-11F23FF5D6AB} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} + {F81C5819-85B6-4D2E-B6DC-104A7634461B} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} + {66CC5B13-881A-412F-8C51-746622A91C5A} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {CB75B7C9-4E00-43B8-B2A9-9ACB4FC40F9B} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {557138B0-7BE2-4392-B2E2-B45734031A62} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {9EED87BB-527F-4D05-9384-6D16CFD627A8} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {6D1CA2F1-7FCA-4249-9220-075C2DF4F965} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {946A1700-C7AA-46F0-AEF2-67C98B5722AC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {FD193822-3D5C-4161-A147-884C2ABDE483} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {20AD0AC9-9159-4744-99CC-6AC5779D6B87} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {0199E349-0701-40BC-8A7F-06A54FFA3E7C} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {BCB71111-8505-4B35-8CEF-EC6115DC9D4D} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {8F19E3DA-8929-4000-87B5-3CA6929636CC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {51A00565-5787-4911-9CC0-28403AA4909D} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {92B64AE7-D773-4F05-89F1-CE59BBF4F053} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {A2BA5E5C-FDB9-4939-B0B5-2B753A5E33D3} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {A643BB06-735D-47F3-BFE7-B6D3C36F7097} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {B332DCA8-3599-4A99-917A-82261BDC27AC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {59089B0C-AAB4-4532-B294-44DEAE7178B7} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {C298876B-6C12-4EA4-903B-33450BCD9884} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {83F586FA-C801-4979-ACCA-006BD628CC88} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {86CBE96B-F5FE-483C-BA4A-DC9B1D43AF22} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {FF2970AE-E2E9-405F-B321-D523A1BD44A0} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {79417CE2-FEEB-42F0-BC53-62D5267B19B1} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {AFDDE100-2D36-4749-817D-12E54C56312F} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {B7812167-50FB-4934-996F-DF6FE4CBBFDF} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {39DB56C7-05F8-492C-A8D4-F19E40FECB59} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {82F3D34B-8DB2-4C6A-98B1-132245DD9D99} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {14BA7F98-02CC-4648-9236-676BFF9458AF} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {0859A973-E4FE-4688-8D16-0253163FDE24} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {F3412853-2B6A-4334-8CF2-B796CDAE0850} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {BE097E8F-B6F3-45DC-8A27-E0EBC31AB912} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {D03F2C82-9553-4AFA-8F49-9234009122B6} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {FE232CA5-6C0D-4ADF-9A21-775D4DC048D3} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {A53CCF42-A972-478F-9336-0F618B3EC06A} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {0037A3CD-4F50-48B2-9AC3-5A0D1D16D2CA} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {870723DD-945A-4136-B65B-4AF3BF85369C} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {EA6488AD-445B-4835-87FB-EBC9E2EDAF97} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {E07B6DBE-3358-4BA0-AABF-CDD8F96AECF0} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {472BCBDC-62E0-441D-B2FD-0EE0FC6CEEB4} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {589C8E9B-0BB3-4D6D-A70C-0A28E469F20E} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {3AD868E6-8355-4F29-B5ED-7DE94AD786E7} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {2B78CF0A-5403-45E2-99BD-493F1679BCDB} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {0AB968E0-E993-45CE-8875-7453C96DF583} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {25923141-9859-4AFE-8168-0DF78322FC63} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {7E855020-7FA4-482D-B510-2E709354FE8B} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {9782E0C8-2BD3-4F67-B420-21CF19CA2435} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {9F4135E3-9814-452C-9B35-0EFBCD792B49} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {C45343E6-DAB6-4F3A-A00A-8BED71A098BE} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {B19DD336-538E-4091-A559-EAA717FEC899} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {0BF60202-43F7-48E9-8717-D31E56FA5BE0} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {4E863E5B-0B95-43BE-8D4F-B9EB6C394FEC} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {6D75CD88-1A03-4955-B8C7-ACFC3742154F} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {8DD0EB7E-668E-452D-91D7-906C64A9C8AC} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {F6FD9C75-AAA7-48C9-B19D-FD37C8FB9B7E} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} + {1FE8758D-7E8A-41F3-9B6D-FD50E9A2A03D} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} + {25BCB876-B60A-499B-9046-E9801CFD7780} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} + {56FB0A45-145F-4EAE-B2C8-E5833E682D8F} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} + {2BB0C1D4-9298-45AC-B244-67A99769A292} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} + {99A40FC5-9DB0-4B80-8D97-867EF00FA2CB} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} + {81064BCE-EEC1-43B0-9912-F05F2B54B11A} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} + {31B41997-3890-45E3-93FE-C57B363E9C0D} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} + {D550AB93-DF31-4B76-873F-F075018352F4} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} + {8CF3F7BA-4C99-43EB-B4F1-7CA346817D0A} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} + {F90FCDC5-EE14-4B89-96DB-4392E28F34AF} = {278D8859-20B1-428F-8448-064F46E1F021} + {93A864C9-93B7-4E5C-ACE7-E8FC5F9EFF79} = {278D8859-20B1-428F-8448-064F46E1F021} + {56E68E37-B3FC-4799-91AF-0CA10B6D55A5} = {278D8859-20B1-428F-8448-064F46E1F021} + {03E7018C-44A2-4C46-9CE7-F2A135A2692B} = {278D8859-20B1-428F-8448-064F46E1F021} + {F3F6FE4D-9D9E-451A-B0BA-81456104B672} = {278D8859-20B1-428F-8448-064F46E1F021} + {C27794B5-1293-4EA7-BC0E-0F18E6325539} = {278D8859-20B1-428F-8448-064F46E1F021} + {02F41059-12A2-4A96-8D77-07EFE4B108FD} = {278D8859-20B1-428F-8448-064F46E1F021} + {B774E0B9-9514-4E88-975F-4EB6C3B8D519} = {278D8859-20B1-428F-8448-064F46E1F021} + {D91367C2-2189-4859-A7FE-D2CAB84FA15C} = {278D8859-20B1-428F-8448-064F46E1F021} + {33459B4E-1839-4856-BF6B-22480D11FE31} = {278D8859-20B1-428F-8448-064F46E1F021} + {48871156-181A-475A-BD8D-200086A09675} = {278D8859-20B1-428F-8448-064F46E1F021} + {C4416DA1-9E62-46BA-9CD3-F8963C79E1A1} = {278D8859-20B1-428F-8448-064F46E1F021} + {1C49E35A-2838-49D9-9D5F-4B8134960EF6} = {278D8859-20B1-428F-8448-064F46E1F021} + {F91142E2-A999-47F0-9E74-38C1E2930EBE} = {278D8859-20B1-428F-8448-064F46E1F021} + {1EDD4BCF-345C-4065-8CBD-7285224293C3} = {278D8859-20B1-428F-8448-064F46E1F021} + {A6B2A11B-0669-4AF5-A025-8DD02DBBE5EA} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {B176BB4A-CA31-4E2A-B790-3EA0ED2EE870} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {D08AA2A0-2F94-4BF5-B42D-E92450F03FD1} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {4A7D0ECA-D7CC-4E66-B741-C92E9C1B42FF} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {CF3755C4-937D-4ABF-B7B3-95140808717F} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {D34939FE-8873-4C53-8D6C-74DED78EA3C4} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {D408A730-363A-4ABF-BCEF-5D63DCC66042} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {F532AFBC-9E62-4A89-BB99-1044E4B2D8ED} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {52FB7463-C128-42AF-A02F-78F48473EA9A} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {7381D91E-5C72-48F0-AAB4-95C9B10D7484} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {D36EC43E-B31F-4CF4-8285-93A7A9D90189} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {274C0319-7E1E-4188-936B-8DF3331230B3} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {41BBCC10-CFDE-48A1-B2E0-A0EC6A668629} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {600C3D4F-0670-4DB4-B30F-520A729053B5} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {11F33A39-74B7-4018-B5F9-CC285A673A8F} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {A6F5E35E-B4A7-41B3-853A-75558E6E0715} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {291B4975-8EFF-4C7C-8AF3-44A77B8491B8} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {FDE6080B-E203-4066-910D-AD0302566008} = {E9D708A5-9C1F-4B84-A795-C5F191801762} + {E1B6D565-9D7C-46B7-9202-ECF54974DE50} = {E9D708A5-9C1F-4B84-A795-C5F191801762} + {C8765523-58F8-4C8E-9914-693396F6F0FF} = {E9D708A5-9C1F-4B84-A795-C5F191801762} + {2F1B955B-275E-4D8E-8864-06FEC44D7912} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {F2DB2E59-76BF-4D81-859A-AFC289C046C0} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} + {3FE7E9B6-49AC-4246-A789-28DB4644567B} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {EBBBF4A0-2DA2-4DE6-B4FE-C6654A2417A0} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {191A5289-BA65-4638-A215-C521F0187313} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {8B1AF423-00F1-4924-AC54-F77D402D2AC9} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {658A1B85-554E-4A5D-973A-FFE592CDD5F2} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {07CA51AD-72AE-46A2-AAED-DC3E3F807976} = {E9D708A5-9C1F-4B84-A795-C5F191801762} + {27B110CC-43C0-400A-89D9-245E681647D7} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} + {1DE84812-E143-4C4B-A61D-9267AAD55401} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {4A87569C-4BD3-4113-B4B9-573D65B3D3F8} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} + {769FF0C1-4424-4FA3-BC44-D7A7DA312A06} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {6D9E00D8-2893-45E4-9363-3F7F61D416BD} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {70B35F59-AFC2-4D8F-8833-5314D2047A81} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {DFDE29A7-4F54-455D-B20B-D2BF79D3B3F7} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {3755E9F4-CB48-4EC3-B561-3B85964EBDEF} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {F81C5819-85B4-4D2E-B6DC-104A7634461B} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} + {CC62F7DB-D089-4677-8575-CAB7A7815C43} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {7AF97D44-707E-48DC-81CB-C9D8D7C9ED26} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {A4B0D971-3CD6-41C9-8AB2-055D25A33373} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} + {15CDD310-6980-42A6-8082-3A6B7730D13F} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {71DB4284-5B1C-4E86-9AF5-B91542D44A6F} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {4B39E5FC-0A96-4057-9AA5-8D5A52880DA7} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {88DE5AD6-0074-4A5A-BE22-C840153E35D5} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {A546E75A-5242-46E6-9A9E-6C91554EAB84} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {EFA150D4-F93B-4D7D-A69C-9E8B4663BECD} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {DF25E545-00FF-4E64-844C-7DF98991F901} = {278D8859-20B1-428F-8448-064F46E1F021} + {703BE7BA-5B99-4F70-806D-3A259F6A991E} = {278D8859-20B1-428F-8448-064F46E1F021} + {FAFEE2F9-24B0-4AF1-B512-433E9590033F} = {278D8859-20B1-428F-8448-064F46E1F021} + {8245DAD9-D402-4D5C-8F45-32229CD3B263} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {41BBCC10-6FDE-48A1-B2E0-A0EC6A668629} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {3A7FE53D-35F7-49DC-9C9A-A5204A53523F} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {CCA63A76-D9FC-4130-9F67-4D97F9770D53} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {3384C257-3CFE-4A8F-838C-19DAC5C955DA} = {278D8859-20B1-428F-8448-064F46E1F021} + {2B140378-125F-4DE9-AC37-2CC1B73D7254} = {278D8859-20B1-428F-8448-064F46E1F021} + {F4C55B99-E1C5-496A-8AC2-40188C38F4F6} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {2AA91EED-2D32-4B09-84A3-53D41EED1005} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {EC0910F6-8D66-4509-BF57-A5EE7AE9485F} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {921391C6-7626-4212-9928-BC82BC785461} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {6B8C5711-6AB4-4023-9FDD-E9D976E8D18F} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {4DF6D5E4-6796-4257-B466-BCD62DEBBCF8} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {C54703BF-D68A-480D-BE27-49B62E45D582} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {9CD8BCAD-F212-4BCC-BA98-899743CE3279} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} + {0981CA28-E4A5-4DF1-987F-A41D09131EFC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} + {A61DAD9C-271C-4E95-81AA-DB4CD58564D4} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {49C67F03-1A56-4F96-B278-39B66EC93678} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {D496308F-3C3C-40B3-A3ED-EA327D244B3E} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} + {3B27F358-2679-4F38-B297-17B536F580BB} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {718FCBD0-591D-448C-B7D5-9F1CA8544E7B} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {19CA0070-B4B2-4394-90B7-D0C259AA35BA} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {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} + {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC} = {E9D708A5-9C1F-4B84-A795-C5F191801762} + {0C442799-B09C-4CD1-9538-711B6E85E9BF} = {278D8859-20B1-428F-8448-064F46E1F021} + {DFB40A10-F8B7-412A-BCC3-5EE49294D816} = {278D8859-20B1-428F-8448-064F46E1F021} + {BB58A5FB-1A35-4471-86D0-A5189EC541B3} = {278D8859-20B1-428F-8448-064F46E1F021} + {61997220-5383-4AE5-ABD4-5F45AE1B0F2A} = {278D8859-20B1-428F-8448-064F46E1F021} + {7467E9AE-844F-444D-8A3F-17397544BA21} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {497FDF54-9762-4048-A833-61CC3980A0FB} = {278D8859-20B1-428F-8448-064F46E1F021} + {29B00F47-BE91-4A1F-B87D-B1302F038316} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} + {124935CC-73BB-489E-92E8-4F922A85DB5D} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F} = {278D8859-20B1-428F-8448-064F46E1F021} + {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2} = {278D8859-20B1-428F-8448-064F46E1F021} + {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91} = {278D8859-20B1-428F-8448-064F46E1F021} + {1ACC8236-EF4E-44B0-BD0C-AB1D95D5890F} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {9DE2FC01-A839-4F89-8319-9071D4C54821} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {2F578155-D51F-4C03-AB7F-5C5122CA46CC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {1C829D1A-892C-451C-AF0B-AC65C85F5CC6} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {84DE22BB-C25F-425C-A7FE-0120CF107B83} = {278D8859-20B1-428F-8448-064F46E1F021} + {98152EDD-7E28-4FA3-89D8-B636ED5D5F65} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {B7FDD40F-DDA4-468E-9C40-EEB175964A26} = {278D8859-20B1-428F-8448-064F46E1F021} + {028F0967-B253-45DA-B1C4-FACCE45D0D8D} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {666346D7-C84B-498D-AE17-53B20C62DB1A} = {278D8859-20B1-428F-8448-064F46E1F021} + {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {6C897101-BE52-4387-8AA2-062123A76BA1} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} + {30011884-25EE-42C9-BB15-888CAFB1AA6E} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {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} + {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} + {DC163251-16C3-4B72-B965-ACDBA0F02BD1} = {278D8859-20B1-428F-8448-064F46E1F021} + {D35D2FDA-B53F-4F70-81CA-24D95812B89C} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29} + EndGlobalSection +EndGlobal diff --git a/src/raylib.h b/src/raylib.h index f9c504680..06138ceca 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1621,6 +1621,8 @@ RLAPI void SetModelMeshMaterial(Model *model, int meshId, int materialId); RLAPI ModelAnimation *LoadModelAnimations(const char *fileName, int *animCount); // Load model animations from file RLAPI void UpdateModelAnimation(Model model, ModelAnimation anim, int frame); // Update model animation pose (CPU) RLAPI void UpdateModelAnimationBones(Model model, ModelAnimation anim, int frame); // Update model animation mesh bone matrices (GPU skinning) +RLAPI void UpdateModelAnimationBonesLerp(Model model, ModelAnimation animA, int frameA, ModelAnimation animB, int frameB, float value); // Update model animation mesh bone matrices with interpolation between two poses(GPU skinning) +RLAPI void UpdateModelVertsToCurrentBones(Model model); // Update model vertices according to mesh bone matrices (CPU) RLAPI void UnloadModelAnimation(ModelAnimation anim); // Unload animation data RLAPI void UnloadModelAnimations(ModelAnimation *animations, int animCount); // Unload animation array data RLAPI bool IsModelAnimationValid(Model model, ModelAnimation anim); // Check model animation skeleton match diff --git a/src/rmodels.c b/src/rmodels.c index 0ee103212..b90b6a53f 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -2346,12 +2346,70 @@ void UpdateModelAnimationBones(Model model, ModelAnimation anim, int frame) } } -// at least 2x speed up vs the old method -// Update model animated vertex data (positions and normals) for a given frame -// NOTE: Updated data is uploaded to GPU -void UpdateModelAnimation(Model model, ModelAnimation anim, int frame) +// Update model animated bones transform matrices by interpolating between two different given frames of different ModelAnimation(could be same too) +// NOTE: Updated data is not uploaded to GPU but kept at model.meshes[i].boneMatrices[boneId], +// to be uploaded to shader at drawing, in case GPU skinning is enabled +void UpdateModelAnimationBonesLerp(Model model, ModelAnimation animA, int frameA, ModelAnimation animB, int frameB, float value) { - UpdateModelAnimationBones(model,anim,frame); + if ((animA.frameCount > 0) && (animA.bones != NULL) && (animA.framePoses != NULL) && + (animB.frameCount > 0) && (animB.bones != NULL) && (animB.framePoses != NULL) && + (value >= 0.0f) && (value <= 1.0f)) + { + frameA = frameA % animA.frameCount; + frameB = frameB % animB.frameCount; + + for (int i = 0; i < model.meshCount; i++) + { + if (model.meshes[i].boneMatrices) + { + assert(model.meshes[i].boneCount == animA.boneCount); + assert(model.meshes[i].boneCount == animB.boneCount); + + for (int boneId = 0; boneId < model.meshes[i].boneCount; boneId++) + { + Vector3 inTranslation = model.bindPose[boneId].translation; + Quaternion inRotation = model.bindPose[boneId].rotation; + Vector3 inScale = model.bindPose[boneId].scale; + + Vector3 outATranslation = animA.framePoses[frameA][boneId].translation; + Quaternion outARotation = animA.framePoses[frameA][boneId].rotation; + Vector3 outAScale = animA.framePoses[frameA][boneId].scale; + + Vector3 outBTranslation = animB.framePoses[frameB][boneId].translation; + Quaternion outBRotation = animB.framePoses[frameB][boneId].rotation; + Vector3 outBScale = animB.framePoses[frameB][boneId].scale; + + Vector3 outTranslation = Vector3Lerp(outATranslation, outBTranslation, value); + Quaternion outRotation = QuaternionSlerp(outARotation, outBRotation, value); + Vector3 outScale = Vector3Lerp(outAScale, outBScale, value); + + Vector3 invTranslation = Vector3RotateByQuaternion(Vector3Negate(inTranslation), QuaternionInvert(inRotation)); + Quaternion invRotation = QuaternionInvert(inRotation); + Vector3 invScale = Vector3Divide((Vector3){ 1.0f, 1.0f, 1.0f }, inScale); + + Vector3 boneTranslation = Vector3Add( + Vector3RotateByQuaternion(Vector3Multiply(outScale, invTranslation), + outRotation), outTranslation); + Quaternion boneRotation = QuaternionMultiply(outRotation, invRotation); + Vector3 boneScale = Vector3Multiply(outScale, invScale); + + Matrix boneMatrix = MatrixMultiply(MatrixMultiply( + QuaternionToMatrix(boneRotation), + MatrixTranslate(boneTranslation.x, boneTranslation.y, boneTranslation.z)), + MatrixScale(boneScale.x, boneScale.y, boneScale.z)); + + model.meshes[i].boneMatrices[boneId] = boneMatrix; + } + } + } + } +} + +// Update model vertex data (positions and normals) from mesh bone data +// NOTE: Updated data is uploaded to GPU +void UpdateModelVertsToCurrentBones(Model model) +{ + //UpdateModelAnimationBones(model, anim, frame); // TODO: Review for (int m = 0; m < model.meshCount; m++) { @@ -2416,6 +2474,15 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, int frame) } } +// at least 2x speed up vs the old method +// Update model animated vertex data (positions and normals) for a given frame +// NOTE: Updated data is uploaded to GPU +void UpdateModelAnimation(Model model, ModelAnimation anim, int frame) +{ + UpdateModelAnimationBones(model,anim,frame); + UpdateModelVertsToCurrentBones(model); +} + // Unload animation array data void UnloadModelAnimations(ModelAnimation *animations, int animCount) { diff --git a/tools/rlparser/output/raylib_api.json b/tools/rlparser/output/raylib_api.json index 96875fe87..f102abb1d 100644 --- a/tools/rlparser/output/raylib_api.json +++ b/tools/rlparser/output/raylib_api.json @@ -11436,6 +11436,48 @@ } ] }, + { + "name": "UpdateModelAnimationBonesLerp", + "description": "Update model animation mesh bone matrices with interpolation between two poses(GPU skinning)", + "returnType": "void", + "params": [ + { + "type": "Model", + "name": "model" + }, + { + "type": "ModelAnimation", + "name": "animA" + }, + { + "type": "int", + "name": "frameA" + }, + { + "type": "ModelAnimation", + "name": "animB" + }, + { + "type": "int", + "name": "frameB" + }, + { + "type": "float", + "name": "value" + } + ] + }, + { + "name": "UpdateModelVertsToCurrentBones", + "description": "Update model vertices according to mesh bone matrices (CPU)", + "returnType": "void", + "params": [ + { + "type": "Model", + "name": "model" + } + ] + }, { "name": "UnloadModelAnimation", "description": "Unload animation data", diff --git a/tools/rlparser/output/raylib_api.lua b/tools/rlparser/output/raylib_api.lua index a1f79cbe6..3707896bb 100644 --- a/tools/rlparser/output/raylib_api.lua +++ b/tools/rlparser/output/raylib_api.lua @@ -7812,6 +7812,27 @@ return { {type = "int", name = "frame"} } }, + { + name = "UpdateModelAnimationBonesLerp", + description = "Update model animation mesh bone matrices with interpolation between two poses(GPU skinning)", + returnType = "void", + params = { + {type = "Model", name = "model"}, + {type = "ModelAnimation", name = "animA"}, + {type = "int", name = "frameA"}, + {type = "ModelAnimation", name = "animB"}, + {type = "int", name = "frameB"}, + {type = "float", name = "value"} + } + }, + { + name = "UpdateModelVertsToCurrentBones", + description = "Update model vertices according to mesh bone matrices (CPU)", + returnType = "void", + params = { + {type = "Model", name = "model"} + } + }, { name = "UnloadModelAnimation", description = "Unload animation data", diff --git a/tools/rlparser/output/raylib_api.txt b/tools/rlparser/output/raylib_api.txt index e7ff4c98b..9c25843f5 100644 --- a/tools/rlparser/output/raylib_api.txt +++ b/tools/rlparser/output/raylib_api.txt @@ -992,7 +992,7 @@ Callback 006: AudioCallback() (2 input parameters) Param[1]: bufferData (type: void *) Param[2]: frames (type: unsigned int) -Functions found: 599 +Functions found: 601 Function 001: InitWindow() (3 input parameters) Name: InitWindow @@ -4354,24 +4354,39 @@ Function 522: UpdateModelAnimationBones() (3 input parameters) Param[1]: model (type: Model) Param[2]: anim (type: ModelAnimation) Param[3]: frame (type: int) -Function 523: UnloadModelAnimation() (1 input parameters) +Function 523: UpdateModelAnimationBonesLerp() (6 input parameters) + Name: UpdateModelAnimationBonesLerp + Return type: void + Description: Update model animation mesh bone matrices with interpolation between two poses(GPU skinning) + Param[1]: model (type: Model) + Param[2]: animA (type: ModelAnimation) + Param[3]: frameA (type: int) + Param[4]: animB (type: ModelAnimation) + Param[5]: frameB (type: int) + Param[6]: value (type: float) +Function 524: UpdateModelVertsToCurrentBones() (1 input parameters) + Name: UpdateModelVertsToCurrentBones + Return type: void + Description: Update model vertices according to mesh bone matrices (CPU) + Param[1]: model (type: Model) +Function 525: UnloadModelAnimation() (1 input parameters) Name: UnloadModelAnimation Return type: void Description: Unload animation data Param[1]: anim (type: ModelAnimation) -Function 524: UnloadModelAnimations() (2 input parameters) +Function 526: UnloadModelAnimations() (2 input parameters) Name: UnloadModelAnimations Return type: void Description: Unload animation array data Param[1]: animations (type: ModelAnimation *) Param[2]: animCount (type: int) -Function 525: IsModelAnimationValid() (2 input parameters) +Function 527: IsModelAnimationValid() (2 input parameters) Name: IsModelAnimationValid Return type: bool Description: Check model animation skeleton match Param[1]: model (type: Model) Param[2]: anim (type: ModelAnimation) -Function 526: CheckCollisionSpheres() (4 input parameters) +Function 528: CheckCollisionSpheres() (4 input parameters) Name: CheckCollisionSpheres Return type: bool Description: Check collision between two spheres @@ -4379,40 +4394,40 @@ Function 526: CheckCollisionSpheres() (4 input parameters) Param[2]: radius1 (type: float) Param[3]: center2 (type: Vector3) Param[4]: radius2 (type: float) -Function 527: CheckCollisionBoxes() (2 input parameters) +Function 529: CheckCollisionBoxes() (2 input parameters) Name: CheckCollisionBoxes Return type: bool Description: Check collision between two bounding boxes Param[1]: box1 (type: BoundingBox) Param[2]: box2 (type: BoundingBox) -Function 528: CheckCollisionBoxSphere() (3 input parameters) +Function 530: CheckCollisionBoxSphere() (3 input parameters) Name: CheckCollisionBoxSphere Return type: bool Description: Check collision between box and sphere Param[1]: box (type: BoundingBox) Param[2]: center (type: Vector3) Param[3]: radius (type: float) -Function 529: GetRayCollisionSphere() (3 input parameters) +Function 531: GetRayCollisionSphere() (3 input parameters) Name: GetRayCollisionSphere Return type: RayCollision Description: Get collision info between ray and sphere Param[1]: ray (type: Ray) Param[2]: center (type: Vector3) Param[3]: radius (type: float) -Function 530: GetRayCollisionBox() (2 input parameters) +Function 532: GetRayCollisionBox() (2 input parameters) Name: GetRayCollisionBox Return type: RayCollision Description: Get collision info between ray and box Param[1]: ray (type: Ray) Param[2]: box (type: BoundingBox) -Function 531: GetRayCollisionMesh() (3 input parameters) +Function 533: GetRayCollisionMesh() (3 input parameters) Name: GetRayCollisionMesh Return type: RayCollision Description: Get collision info between ray and mesh Param[1]: ray (type: Ray) Param[2]: mesh (type: Mesh) Param[3]: transform (type: Matrix) -Function 532: GetRayCollisionTriangle() (4 input parameters) +Function 534: GetRayCollisionTriangle() (4 input parameters) Name: GetRayCollisionTriangle Return type: RayCollision Description: Get collision info between ray and triangle @@ -4420,7 +4435,7 @@ Function 532: GetRayCollisionTriangle() (4 input parameters) Param[2]: p1 (type: Vector3) Param[3]: p2 (type: Vector3) Param[4]: p3 (type: Vector3) -Function 533: GetRayCollisionQuad() (5 input parameters) +Function 535: GetRayCollisionQuad() (5 input parameters) Name: GetRayCollisionQuad Return type: RayCollision Description: Get collision info between ray and quad @@ -4429,158 +4444,158 @@ Function 533: GetRayCollisionQuad() (5 input parameters) Param[3]: p2 (type: Vector3) Param[4]: p3 (type: Vector3) Param[5]: p4 (type: Vector3) -Function 534: InitAudioDevice() (0 input parameters) +Function 536: InitAudioDevice() (0 input parameters) Name: InitAudioDevice Return type: void Description: Initialize audio device and context No input parameters -Function 535: CloseAudioDevice() (0 input parameters) +Function 537: CloseAudioDevice() (0 input parameters) Name: CloseAudioDevice Return type: void Description: Close the audio device and context No input parameters -Function 536: IsAudioDeviceReady() (0 input parameters) +Function 538: IsAudioDeviceReady() (0 input parameters) Name: IsAudioDeviceReady Return type: bool Description: Check if audio device has been initialized successfully No input parameters -Function 537: SetMasterVolume() (1 input parameters) +Function 539: SetMasterVolume() (1 input parameters) Name: SetMasterVolume Return type: void Description: Set master volume (listener) Param[1]: volume (type: float) -Function 538: GetMasterVolume() (0 input parameters) +Function 540: GetMasterVolume() (0 input parameters) Name: GetMasterVolume Return type: float Description: Get master volume (listener) No input parameters -Function 539: LoadWave() (1 input parameters) +Function 541: LoadWave() (1 input parameters) Name: LoadWave Return type: Wave Description: Load wave data from file Param[1]: fileName (type: const char *) -Function 540: LoadWaveFromMemory() (3 input parameters) +Function 542: LoadWaveFromMemory() (3 input parameters) Name: LoadWaveFromMemory Return type: Wave Description: Load wave from memory buffer, fileType refers to extension: i.e. '.wav' Param[1]: fileType (type: const char *) Param[2]: fileData (type: const unsigned char *) Param[3]: dataSize (type: int) -Function 541: IsWaveValid() (1 input parameters) +Function 543: IsWaveValid() (1 input parameters) Name: IsWaveValid Return type: bool Description: Checks if wave data is valid (data loaded and parameters) Param[1]: wave (type: Wave) -Function 542: LoadSound() (1 input parameters) +Function 544: LoadSound() (1 input parameters) Name: LoadSound Return type: Sound Description: Load sound from file Param[1]: fileName (type: const char *) -Function 543: LoadSoundFromWave() (1 input parameters) +Function 545: LoadSoundFromWave() (1 input parameters) Name: LoadSoundFromWave Return type: Sound Description: Load sound from wave data Param[1]: wave (type: Wave) -Function 544: LoadSoundAlias() (1 input parameters) +Function 546: LoadSoundAlias() (1 input parameters) Name: LoadSoundAlias Return type: Sound Description: Create a new sound that shares the same sample data as the source sound, does not own the sound data Param[1]: source (type: Sound) -Function 545: IsSoundValid() (1 input parameters) +Function 547: IsSoundValid() (1 input parameters) Name: IsSoundValid Return type: bool Description: Checks if a sound is valid (data loaded and buffers initialized) Param[1]: sound (type: Sound) -Function 546: UpdateSound() (3 input parameters) +Function 548: UpdateSound() (3 input parameters) Name: UpdateSound Return type: void Description: Update sound buffer with new data (default data format: 32 bit float, stereo) Param[1]: sound (type: Sound) Param[2]: data (type: const void *) Param[3]: sampleCount (type: int) -Function 547: UnloadWave() (1 input parameters) +Function 549: UnloadWave() (1 input parameters) Name: UnloadWave Return type: void Description: Unload wave data Param[1]: wave (type: Wave) -Function 548: UnloadSound() (1 input parameters) +Function 550: UnloadSound() (1 input parameters) Name: UnloadSound Return type: void Description: Unload sound Param[1]: sound (type: Sound) -Function 549: UnloadSoundAlias() (1 input parameters) +Function 551: UnloadSoundAlias() (1 input parameters) Name: UnloadSoundAlias Return type: void Description: Unload a sound alias (does not deallocate sample data) Param[1]: alias (type: Sound) -Function 550: ExportWave() (2 input parameters) +Function 552: ExportWave() (2 input parameters) Name: ExportWave Return type: bool Description: Export wave data to file, returns true on success Param[1]: wave (type: Wave) Param[2]: fileName (type: const char *) -Function 551: ExportWaveAsCode() (2 input parameters) +Function 553: ExportWaveAsCode() (2 input parameters) Name: ExportWaveAsCode Return type: bool Description: Export wave sample data to code (.h), returns true on success Param[1]: wave (type: Wave) Param[2]: fileName (type: const char *) -Function 552: PlaySound() (1 input parameters) +Function 554: PlaySound() (1 input parameters) Name: PlaySound Return type: void Description: Play a sound Param[1]: sound (type: Sound) -Function 553: StopSound() (1 input parameters) +Function 555: StopSound() (1 input parameters) Name: StopSound Return type: void Description: Stop playing a sound Param[1]: sound (type: Sound) -Function 554: PauseSound() (1 input parameters) +Function 556: PauseSound() (1 input parameters) Name: PauseSound Return type: void Description: Pause a sound Param[1]: sound (type: Sound) -Function 555: ResumeSound() (1 input parameters) +Function 557: ResumeSound() (1 input parameters) Name: ResumeSound Return type: void Description: Resume a paused sound Param[1]: sound (type: Sound) -Function 556: IsSoundPlaying() (1 input parameters) +Function 558: IsSoundPlaying() (1 input parameters) Name: IsSoundPlaying Return type: bool Description: Check if a sound is currently playing Param[1]: sound (type: Sound) -Function 557: SetSoundVolume() (2 input parameters) +Function 559: SetSoundVolume() (2 input parameters) Name: SetSoundVolume Return type: void Description: Set volume for a sound (1.0 is max level) Param[1]: sound (type: Sound) Param[2]: volume (type: float) -Function 558: SetSoundPitch() (2 input parameters) +Function 560: SetSoundPitch() (2 input parameters) Name: SetSoundPitch Return type: void Description: Set pitch for a sound (1.0 is base level) Param[1]: sound (type: Sound) Param[2]: pitch (type: float) -Function 559: SetSoundPan() (2 input parameters) +Function 561: SetSoundPan() (2 input parameters) Name: SetSoundPan Return type: void Description: Set pan for a sound (-1.0 left, 0.0 center, 1.0 right) Param[1]: sound (type: Sound) Param[2]: pan (type: float) -Function 560: WaveCopy() (1 input parameters) +Function 562: WaveCopy() (1 input parameters) Name: WaveCopy Return type: Wave Description: Copy a wave to a new wave Param[1]: wave (type: Wave) -Function 561: WaveCrop() (3 input parameters) +Function 563: WaveCrop() (3 input parameters) Name: WaveCrop Return type: void Description: Crop a wave to defined frames range Param[1]: wave (type: Wave *) Param[2]: initFrame (type: int) Param[3]: finalFrame (type: int) -Function 562: WaveFormat() (4 input parameters) +Function 564: WaveFormat() (4 input parameters) Name: WaveFormat Return type: void Description: Convert wave data to desired format @@ -4588,203 +4603,203 @@ Function 562: WaveFormat() (4 input parameters) Param[2]: sampleRate (type: int) Param[3]: sampleSize (type: int) Param[4]: channels (type: int) -Function 563: LoadWaveSamples() (1 input parameters) +Function 565: LoadWaveSamples() (1 input parameters) Name: LoadWaveSamples Return type: float * Description: Load samples data from wave as a 32bit float data array Param[1]: wave (type: Wave) -Function 564: UnloadWaveSamples() (1 input parameters) +Function 566: UnloadWaveSamples() (1 input parameters) Name: UnloadWaveSamples Return type: void Description: Unload samples data loaded with LoadWaveSamples() Param[1]: samples (type: float *) -Function 565: LoadMusicStream() (1 input parameters) +Function 567: LoadMusicStream() (1 input parameters) Name: LoadMusicStream Return type: Music Description: Load music stream from file Param[1]: fileName (type: const char *) -Function 566: LoadMusicStreamFromMemory() (3 input parameters) +Function 568: LoadMusicStreamFromMemory() (3 input parameters) Name: LoadMusicStreamFromMemory Return type: Music Description: Load music stream from data Param[1]: fileType (type: const char *) Param[2]: data (type: const unsigned char *) Param[3]: dataSize (type: int) -Function 567: IsMusicValid() (1 input parameters) +Function 569: IsMusicValid() (1 input parameters) Name: IsMusicValid Return type: bool Description: Checks if a music stream is valid (context and buffers initialized) Param[1]: music (type: Music) -Function 568: UnloadMusicStream() (1 input parameters) +Function 570: UnloadMusicStream() (1 input parameters) Name: UnloadMusicStream Return type: void Description: Unload music stream Param[1]: music (type: Music) -Function 569: PlayMusicStream() (1 input parameters) +Function 571: PlayMusicStream() (1 input parameters) Name: PlayMusicStream Return type: void Description: Start music playing Param[1]: music (type: Music) -Function 570: IsMusicStreamPlaying() (1 input parameters) +Function 572: IsMusicStreamPlaying() (1 input parameters) Name: IsMusicStreamPlaying Return type: bool Description: Check if music is playing Param[1]: music (type: Music) -Function 571: UpdateMusicStream() (1 input parameters) +Function 573: UpdateMusicStream() (1 input parameters) Name: UpdateMusicStream Return type: void Description: Updates buffers for music streaming Param[1]: music (type: Music) -Function 572: StopMusicStream() (1 input parameters) +Function 574: StopMusicStream() (1 input parameters) Name: StopMusicStream Return type: void Description: Stop music playing Param[1]: music (type: Music) -Function 573: PauseMusicStream() (1 input parameters) +Function 575: PauseMusicStream() (1 input parameters) Name: PauseMusicStream Return type: void Description: Pause music playing Param[1]: music (type: Music) -Function 574: ResumeMusicStream() (1 input parameters) +Function 576: ResumeMusicStream() (1 input parameters) Name: ResumeMusicStream Return type: void Description: Resume playing paused music Param[1]: music (type: Music) -Function 575: SeekMusicStream() (2 input parameters) +Function 577: SeekMusicStream() (2 input parameters) Name: SeekMusicStream Return type: void Description: Seek music to a position (in seconds) Param[1]: music (type: Music) Param[2]: position (type: float) -Function 576: SetMusicVolume() (2 input parameters) +Function 578: SetMusicVolume() (2 input parameters) Name: SetMusicVolume Return type: void Description: Set volume for music (1.0 is max level) Param[1]: music (type: Music) Param[2]: volume (type: float) -Function 577: SetMusicPitch() (2 input parameters) +Function 579: SetMusicPitch() (2 input parameters) Name: SetMusicPitch Return type: void Description: Set pitch for a music (1.0 is base level) Param[1]: music (type: Music) Param[2]: pitch (type: float) -Function 578: SetMusicPan() (2 input parameters) +Function 580: SetMusicPan() (2 input parameters) Name: SetMusicPan Return type: void Description: Set pan for a music (-1.0 left, 0.0 center, 1.0 right) Param[1]: music (type: Music) Param[2]: pan (type: float) -Function 579: GetMusicTimeLength() (1 input parameters) +Function 581: GetMusicTimeLength() (1 input parameters) Name: GetMusicTimeLength Return type: float Description: Get music time length (in seconds) Param[1]: music (type: Music) -Function 580: GetMusicTimePlayed() (1 input parameters) +Function 582: GetMusicTimePlayed() (1 input parameters) Name: GetMusicTimePlayed Return type: float Description: Get current music time played (in seconds) Param[1]: music (type: Music) -Function 581: LoadAudioStream() (3 input parameters) +Function 583: LoadAudioStream() (3 input parameters) Name: LoadAudioStream Return type: AudioStream Description: Load audio stream (to stream raw audio pcm data) Param[1]: sampleRate (type: unsigned int) Param[2]: sampleSize (type: unsigned int) Param[3]: channels (type: unsigned int) -Function 582: IsAudioStreamValid() (1 input parameters) +Function 584: IsAudioStreamValid() (1 input parameters) Name: IsAudioStreamValid Return type: bool Description: Checks if an audio stream is valid (buffers initialized) Param[1]: stream (type: AudioStream) -Function 583: UnloadAudioStream() (1 input parameters) +Function 585: UnloadAudioStream() (1 input parameters) Name: UnloadAudioStream Return type: void Description: Unload audio stream and free memory Param[1]: stream (type: AudioStream) -Function 584: UpdateAudioStream() (3 input parameters) +Function 586: UpdateAudioStream() (3 input parameters) Name: UpdateAudioStream Return type: void Description: Update audio stream buffers with data Param[1]: stream (type: AudioStream) Param[2]: data (type: const void *) Param[3]: frameCount (type: int) -Function 585: IsAudioStreamProcessed() (1 input parameters) +Function 587: IsAudioStreamProcessed() (1 input parameters) Name: IsAudioStreamProcessed Return type: bool Description: Check if any audio stream buffers requires refill Param[1]: stream (type: AudioStream) -Function 586: PlayAudioStream() (1 input parameters) +Function 588: PlayAudioStream() (1 input parameters) Name: PlayAudioStream Return type: void Description: Play audio stream Param[1]: stream (type: AudioStream) -Function 587: PauseAudioStream() (1 input parameters) +Function 589: PauseAudioStream() (1 input parameters) Name: PauseAudioStream Return type: void Description: Pause audio stream Param[1]: stream (type: AudioStream) -Function 588: ResumeAudioStream() (1 input parameters) +Function 590: ResumeAudioStream() (1 input parameters) Name: ResumeAudioStream Return type: void Description: Resume audio stream Param[1]: stream (type: AudioStream) -Function 589: IsAudioStreamPlaying() (1 input parameters) +Function 591: IsAudioStreamPlaying() (1 input parameters) Name: IsAudioStreamPlaying Return type: bool Description: Check if audio stream is playing Param[1]: stream (type: AudioStream) -Function 590: StopAudioStream() (1 input parameters) +Function 592: StopAudioStream() (1 input parameters) Name: StopAudioStream Return type: void Description: Stop audio stream Param[1]: stream (type: AudioStream) -Function 591: SetAudioStreamVolume() (2 input parameters) +Function 593: SetAudioStreamVolume() (2 input parameters) Name: SetAudioStreamVolume Return type: void Description: Set volume for audio stream (1.0 is max level) Param[1]: stream (type: AudioStream) Param[2]: volume (type: float) -Function 592: SetAudioStreamPitch() (2 input parameters) +Function 594: SetAudioStreamPitch() (2 input parameters) Name: SetAudioStreamPitch Return type: void Description: Set pitch for audio stream (1.0 is base level) Param[1]: stream (type: AudioStream) Param[2]: pitch (type: float) -Function 593: SetAudioStreamPan() (2 input parameters) +Function 595: SetAudioStreamPan() (2 input parameters) Name: SetAudioStreamPan Return type: void Description: Set pan for audio stream (0.5 is centered) Param[1]: stream (type: AudioStream) Param[2]: pan (type: float) -Function 594: SetAudioStreamBufferSizeDefault() (1 input parameters) +Function 596: SetAudioStreamBufferSizeDefault() (1 input parameters) Name: SetAudioStreamBufferSizeDefault Return type: void Description: Default size for new audio streams Param[1]: size (type: int) -Function 595: SetAudioStreamCallback() (2 input parameters) +Function 597: SetAudioStreamCallback() (2 input parameters) Name: SetAudioStreamCallback Return type: void Description: Audio thread callback to request new data Param[1]: stream (type: AudioStream) Param[2]: callback (type: AudioCallback) -Function 596: AttachAudioStreamProcessor() (2 input parameters) +Function 598: AttachAudioStreamProcessor() (2 input parameters) Name: AttachAudioStreamProcessor Return type: void Description: Attach audio stream processor to stream, receives frames x 2 samples as 'float' (stereo) Param[1]: stream (type: AudioStream) Param[2]: processor (type: AudioCallback) -Function 597: DetachAudioStreamProcessor() (2 input parameters) +Function 599: DetachAudioStreamProcessor() (2 input parameters) Name: DetachAudioStreamProcessor Return type: void Description: Detach audio stream processor from stream Param[1]: stream (type: AudioStream) Param[2]: processor (type: AudioCallback) -Function 598: AttachAudioMixedProcessor() (1 input parameters) +Function 600: AttachAudioMixedProcessor() (1 input parameters) Name: AttachAudioMixedProcessor Return type: void Description: Attach audio stream processor to the entire audio pipeline, receives frames x 2 samples as 'float' (stereo) Param[1]: processor (type: AudioCallback) -Function 599: DetachAudioMixedProcessor() (1 input parameters) +Function 601: DetachAudioMixedProcessor() (1 input parameters) Name: DetachAudioMixedProcessor Return type: void Description: Detach audio stream processor from the entire audio pipeline diff --git a/tools/rlparser/output/raylib_api.xml b/tools/rlparser/output/raylib_api.xml index 8734f405d..d3314a5d1 100644 --- a/tools/rlparser/output/raylib_api.xml +++ b/tools/rlparser/output/raylib_api.xml @@ -678,7 +678,7 @@ - + @@ -2918,6 +2918,17 @@ + + + + + + + + + + + From 71607db6672ae843e2f9c541f4fd0f260d80ea0a Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 19 Feb 2026 16:46:30 +0100 Subject: [PATCH 206/232] Moved easings example to shapes --- examples/others/reasings.h | 263 ------------------ .../shapes_easings_testbed.c} | 39 ++- .../shapes_easings_testbed.png} | Bin projects/VS2022/raylib.sln | 4 +- 4 files changed, 27 insertions(+), 279 deletions(-) delete mode 100644 examples/others/reasings.h rename examples/{others/easings_testbed.c => shapes/shapes_easings_testbed.c} (87%) rename examples/{others/easings_testbed.png => shapes/shapes_easings_testbed.png} (100%) diff --git a/examples/others/reasings.h b/examples/others/reasings.h deleted file mode 100644 index c3ee1169f..000000000 --- a/examples/others/reasings.h +++ /dev/null @@ -1,263 +0,0 @@ -/******************************************************************************************* -* -* reasings - raylib easings library, based on Robert Penner library -* -* Useful easing functions for values animation -* -* This header uses: -* #define REASINGS_STATIC_INLINE // Inlines all functions code, so it runs faster. -* // This requires lots of memory on system. -* How to use: -* The four inputs t,b,c,d are defined as follows: -* t = current time (in any unit measure, but same unit as duration) -* b = starting value to interpolate -* c = the total change in value of b that needs to occur -* d = total time it should take to complete (duration) -* -* Example: -* -* int currentTime = 0; -* int duration = 100; -* float startPositionX = 0.0f; -* float finalPositionX = 30.0f; -* float currentPositionX = startPositionX; -* -* while (currentPositionX < finalPositionX) -* { -* currentPositionX = EaseSineIn(currentTime, startPositionX, finalPositionX - startPositionX, duration); -* currentTime++; -* } -* -* A port of Robert Penner's easing equations to C (http://robertpenner.com/easing/) -* -* Robert Penner License -* --------------------------------------------------------------------------------- -* Open source under the BSD License. -* -* Copyright (c) 2001 Robert Penner. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, -* are permitted provided that the following conditions are met: -* -* - Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* - Redistributions in binary form must reproduce the above copyright notice, -* this list of conditions and the following disclaimer in the documentation -* and/or other materials provided with the distribution. -* - Neither the name of the author nor the names of contributors may be used -* to endorse or promote products derived from this software without specific -* prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -* OF THE POSSIBILITY OF SUCH DAMAGE. -* --------------------------------------------------------------------------------- -* -* Copyright (c) 2015-2024 Ramon Santamaria (@raysan5) -* -* This software is provided "as-is", without any express or implied warranty. In no event -* will the authors be held liable for any damages arising from the use of this software. -* -* Permission is granted to anyone to use this software for any purpose, including commercial -* applications, and to alter it and redistribute it freely, subject to the following restrictions: -* -* 1. The origin of this software must not be misrepresented; you must not claim that you -* wrote the original software. If you use this software in a product, an acknowledgment -* in the product documentation would be appreciated but is not required. -* -* 2. Altered source versions must be plainly marked as such, and must not be misrepresented -* as being the original software. -* -* 3. This notice may not be removed or altered from any source distribution. -* -**********************************************************************************************/ - -#ifndef REASINGS_H -#define REASINGS_H - -#define REASINGS_STATIC_INLINE // NOTE: By default, compile functions as static inline - -#if defined(REASINGS_STATIC_INLINE) - #define EASEDEF static inline -#else - #define EASEDEF extern -#endif - -#include // Required for: sinf(), cosf(), sqrtf(), powf() - -#ifndef PI - #define PI 3.14159265358979323846f //Required as PI is not always defined in math.h -#endif - -#if defined(__cplusplus) -extern "C" { // Prevents name mangling of functions -#endif - -// Linear Easing functions -EASEDEF float EaseLinearNone(float t, float b, float c, float d) { return (c*t/d + b); } // Ease: Linear -EASEDEF float EaseLinearIn(float t, float b, float c, float d) { return (c*t/d + b); } // Ease: Linear In -EASEDEF float EaseLinearOut(float t, float b, float c, float d) { return (c*t/d + b); } // Ease: Linear Out -EASEDEF float EaseLinearInOut(float t, float b, float c, float d) { return (c*t/d + b); } // Ease: Linear In Out - -// Sine Easing functions -EASEDEF float EaseSineIn(float t, float b, float c, float d) { return (-c*cosf(t/d*(PI/2.0f)) + c + b); } // Ease: Sine In -EASEDEF float EaseSineOut(float t, float b, float c, float d) { return (c*sinf(t/d*(PI/2.0f)) + b); } // Ease: Sine Out -EASEDEF float EaseSineInOut(float t, float b, float c, float d) { return (-c/2.0f*(cosf(PI*t/d) - 1.0f) + b); } // Ease: Sine In Out - -// Circular Easing functions -EASEDEF float EaseCircIn(float t, float b, float c, float d) { t /= d; return (-c*(sqrtf(1.0f - t*t) - 1.0f) + b); } // Ease: Circular In -EASEDEF float EaseCircOut(float t, float b, float c, float d) { t = t/d - 1.0f; return (c*sqrtf(1.0f - t*t) + b); } // Ease: Circular Out -EASEDEF float EaseCircInOut(float t, float b, float c, float d) // Ease: Circular In Out -{ - if ((t/=d/2.0f) < 1.0f) return (-c/2.0f*(sqrtf(1.0f - t*t) - 1.0f) + b); - t -= 2.0f; return (c/2.0f*(sqrtf(1.0f - t*t) + 1.0f) + b); -} - -// Cubic Easing functions -EASEDEF float EaseCubicIn(float t, float b, float c, float d) { t /= d; return (c*t*t*t + b); } // Ease: Cubic In -EASEDEF float EaseCubicOut(float t, float b, float c, float d) { t = t/d - 1.0f; return (c*(t*t*t + 1.0f) + b); } // Ease: Cubic Out -EASEDEF float EaseCubicInOut(float t, float b, float c, float d) // Ease: Cubic In Out -{ - if ((t/=d/2.0f) < 1.0f) return (c/2.0f*t*t*t + b); - t -= 2.0f; return (c/2.0f*(t*t*t + 2.0f) + b); -} - -// Quadratic Easing functions -EASEDEF float EaseQuadIn(float t, float b, float c, float d) { t /= d; return (c*t*t + b); } // Ease: Quadratic In -EASEDEF float EaseQuadOut(float t, float b, float c, float d) { t /= d; return (-c*t*(t - 2.0f) + b); } // Ease: Quadratic Out -EASEDEF float EaseQuadInOut(float t, float b, float c, float d) // Ease: Quadratic In Out -{ - if ((t/=d/2) < 1) return (((c/2)*(t*t)) + b); - return (-c/2.0f*(((t - 1.0f)*(t - 3.0f)) - 1.0f) + b); -} - -// Exponential Easing functions -EASEDEF float EaseExpoIn(float t, float b, float c, float d) { return (t == 0.0f) ? b : (c*powf(2.0f, 10.0f*(t/d - 1.0f)) + b); } // Ease: Exponential In -EASEDEF float EaseExpoOut(float t, float b, float c, float d) { return (t == d) ? (b + c) : (c*(-powf(2.0f, -10.0f*t/d) + 1.0f) + b); } // Ease: Exponential Out -EASEDEF float EaseExpoInOut(float t, float b, float c, float d) // Ease: Exponential In Out -{ - if (t == 0.0f) return b; - if (t == d) return (b + c); - if ((t/=d/2.0f) < 1.0f) return (c/2.0f*powf(2.0f, 10.0f*(t - 1.0f)) + b); - - return (c/2.0f*(-powf(2.0f, -10.0f*(t - 1.0f)) + 2.0f) + b); -} - -// Back Easing functions -EASEDEF float EaseBackIn(float t, float b, float c, float d) // Ease: Back In -{ - float s = 1.70158f; - float postFix = t/=d; - return (c*(postFix)*t*((s + 1.0f)*t - s) + b); -} - -EASEDEF float EaseBackOut(float t, float b, float c, float d) // Ease: Back Out -{ - float s = 1.70158f; - t = t/d - 1.0f; - return (c*(t*t*((s + 1.0f)*t + s) + 1.0f) + b); -} - -EASEDEF float EaseBackInOut(float t, float b, float c, float d) // Ease: Back In Out -{ - float s = 1.70158f; - if ((t/=d/2.0f) < 1.0f) - { - s *= 1.525f; - return (c/2.0f*(t*t*((s + 1.0f)*t - s)) + b); - } - - float postFix = t-=2.0f; - s *= 1.525f; - return (c/2.0f*((postFix)*t*((s + 1.0f)*t + s) + 2.0f) + b); -} - -// Bounce Easing functions -EASEDEF float EaseBounceOut(float t, float b, float c, float d) // Ease: Bounce Out -{ - if ((t/=d) < (1.0f/2.75f)) - { - return (c*(7.5625f*t*t) + b); - } - else if (t < (2.0f/2.75f)) - { - float postFix = t-=(1.5f/2.75f); - return (c*(7.5625f*(postFix)*t + 0.75f) + b); - } - else if (t < (2.5/2.75)) - { - float postFix = t-=(2.25f/2.75f); - return (c*(7.5625f*(postFix)*t + 0.9375f) + b); - } - else - { - float postFix = t-=(2.625f/2.75f); - return (c*(7.5625f*(postFix)*t + 0.984375f) + b); - } -} - -EASEDEF float EaseBounceIn(float t, float b, float c, float d) { return (c - EaseBounceOut(d - t, 0.0f, c, d) + b); } // Ease: Bounce In -EASEDEF float EaseBounceInOut(float t, float b, float c, float d) // Ease: Bounce In Out -{ - if (t < d/2.0f) return (EaseBounceIn(t*2.0f, 0.0f, c, d)*0.5f + b); - else return (EaseBounceOut(t*2.0f - d, 0.0f, c, d)*0.5f + c*0.5f + b); -} - -// Elastic Easing functions -EASEDEF float EaseElasticIn(float t, float b, float c, float d) // Ease: Elastic In -{ - if (t == 0.0f) return b; - if ((t/=d) == 1.0f) return (b + c); - - float p = d*0.3f; - float a = c; - float s = p/4.0f; - float postFix = a*powf(2.0f, 10.0f*(t-=1.0f)); - - return (-(postFix*sinf((t*d-s)*(2.0f*PI)/p )) + b); -} - -EASEDEF float EaseElasticOut(float t, float b, float c, float d) // Ease: Elastic Out -{ - if (t == 0.0f) return b; - if ((t/=d) == 1.0f) return (b + c); - - float p = d*0.3f; - float a = c; - float s = p/4.0f; - - return (a*powf(2.0f,-10.0f*t)*sinf((t*d-s)*(2.0f*PI)/p) + c + b); -} - -EASEDEF float EaseElasticInOut(float t, float b, float c, float d) // Ease: Elastic In Out -{ - if (t == 0.0f) return b; - if ((t/=d/2.0f) == 2.0f) return (b + c); - - float p = d*(0.3f*1.5f); - float a = c; - float s = p/4.0f; - - if (t < 1.0f) - { - float postFix = a*powf(2.0f, 10.0f*(t-=1.0f)); - return -0.5f*(postFix*sinf((t*d-s)*(2.0f*PI)/p)) + b; - } - - float postFix = a*powf(2.0f, -10.0f*(t-=1.0f)); - - return (postFix*sinf((t*d-s)*(2.0f*PI)/p)*0.5f + c + b); -} - -#if defined(__cplusplus) -} -#endif - -#endif // REASINGS_H diff --git a/examples/others/easings_testbed.c b/examples/shapes/shapes_easings_testbed.c similarity index 87% rename from examples/others/easings_testbed.c rename to examples/shapes/shapes_easings_testbed.c index fa4a599ee..a3ff23a7c 100644 --- a/examples/others/easings_testbed.c +++ b/examples/shapes/shapes_easings_testbed.c @@ -1,11 +1,11 @@ /******************************************************************************************* * -* raylib [others] example - easings testbed -* -* Example originally created with raylib 2.5, last time updated with raylib 2.5 +* raylib [shapes] example - easings testbed * * Example complexity rating: [★★★☆] 3/4 * +* Example originally created with raylib 2.5, last time updated with raylib 2.5 +* * Example contributed by Juan Miguel López (@flashback-fx) and reviewed by Ramon Santamaria (@raysan5) * * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, @@ -26,6 +26,9 @@ #define D_MIN 1.0f #define D_MAX 10000.0f +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- // Easing types enum EasingTypes { EASE_LINEAR_NONE = 0, @@ -60,13 +63,13 @@ enum EasingTypes { EASING_NONE = NUM_EASING_TYPES }; -static float NoEase(float t, float b, float c, float d); // NoEase function declaration, function used when "no easing" is selected for any axis - -// Easing functions reference data -static const struct { +typedef struct EasingFuncs { const char *name; float (*func)(float, float, float, float); -} Easings[] = { +} EasingFuncs; + +// Easing functions reference data +static const EasingFuncs easings[] = { [EASE_LINEAR_NONE] = { .name = "EaseLinearNone", .func = EaseLinearNone }, [EASE_LINEAR_IN] = { .name = "EaseLinearIn", .func = EaseLinearIn }, [EASE_LINEAR_OUT] = { .name = "EaseLinearOut", .func = EaseLinearOut }, @@ -98,6 +101,12 @@ static const struct { [EASING_NONE] = { .name = "None", .func = NoEase }, }; +//------------------------------------------------------------------------------------ +// Module Functions Declaration +//------------------------------------------------------------------------------------ +// Function used when "no easing" is selected for any axis +static float NoEase(float t, float b, float c, float d); + //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ @@ -108,7 +117,7 @@ int main(void) const int screenWidth = 800; const int screenHeight = 450; - InitWindow(screenWidth, screenHeight, "raylib [others] example - easings testbed"); + InitWindow(screenWidth, screenHeight, "raylib [shapes] example - easings testbed"); Vector2 ballPosition = { 100.0f, 100.0f }; @@ -157,11 +166,11 @@ int main(void) } // Change d (duration) value - if (IsKeyPressed(KEY_W) && d < D_MAX - D_STEP) d += D_STEP; - else if (IsKeyPressed(KEY_Q) && d > D_MIN + D_STEP) d -= D_STEP; + if (IsKeyPressed(KEY_W) && (d < D_MAX - D_STEP)) d += D_STEP; + else if (IsKeyPressed(KEY_Q) && (d > D_MIN + D_STEP)) d -= D_STEP; - if (IsKeyDown(KEY_S) && d < D_MAX - D_STEP_FINE) d += D_STEP_FINE; - else if (IsKeyDown(KEY_A) && d > D_MIN + D_STEP_FINE) d -= D_STEP_FINE; + if (IsKeyDown(KEY_S) && (d < D_MAX - D_STEP_FINE)) d += D_STEP_FINE; + else if (IsKeyDown(KEY_A) && (d > D_MIN + D_STEP_FINE)) d -= D_STEP_FINE; // Play, pause and restart controls if (IsKeyPressed(KEY_SPACE) || IsKeyPressed(KEY_T) || @@ -220,7 +229,9 @@ int main(void) return 0; } - +//------------------------------------------------------------------------------------ +// Module Functions Declaration +//------------------------------------------------------------------------------------ // NoEase function, used when "no easing" is selected for any axis // It just ignores all parameters besides b static float NoEase(float t, float b, float c, float d) diff --git a/examples/others/easings_testbed.png b/examples/shapes/shapes_easings_testbed.png similarity index 100% rename from examples/others/easings_testbed.png rename to examples/shapes/shapes_easings_testbed.png diff --git a/projects/VS2022/raylib.sln b/projects/VS2022/raylib.sln index 8483dc563..740d1bcbe 100644 --- a/projects/VS2022/raylib.sln +++ b/projects/VS2022/raylib.sln @@ -5619,8 +5619,8 @@ 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} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} - {9DB1F875-6E65-4195-B23F-ED8095C0B99C} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E} = {278D8859-20B1-428F-8448-064F46E1F021} + {9DB1F875-6E65-4195-B23F-ED8095C0B99C} = {278D8859-20B1-428F-8448-064F46E1F021} {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} From 98c773491179984e3de53a929fd31b467589a738 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 19 Feb 2026 16:46:48 +0100 Subject: [PATCH 207/232] REVIEWED: `models_basic_voxel` example --- examples/models/models_basic_voxel.c | 13 +++++++++---- examples/models/models_basic_voxel.png | Bin 349583 -> 29035 bytes 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/examples/models/models_basic_voxel.c b/examples/models/models_basic_voxel.c index a70da1822..61313ecef 100644 --- a/examples/models/models_basic_voxel.c +++ b/examples/models/models_basic_voxel.c @@ -16,6 +16,7 @@ ********************************************************************************************/ #include "raylib.h" + #include "raymath.h" #define WORLD_SIZE 8 // Size of our voxel world (8x8x8 cubes) @@ -32,7 +33,7 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [models] example - basic voxel"); - DisableCursor(); // Lock mouse to window center + DisableCursor(); // Lock mouse to window center // Define the camera to look into our 3d world (first person) Camera3D camera = { 0 }; @@ -59,7 +60,7 @@ int main(void) } } } - + SetTargetFPS(60); //-------------------------------------------------------------------------------------- @@ -74,7 +75,7 @@ int main(void) if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) { // Cast a ray from the screen center (where crosshair would be) - Vector2 screenCenter = { screenWidth/2.0f, screenHeight/2.0f }; + Vector2 screenCenter = { GetScreenWidth()/2.0f, GetScreenHeight()/2.0f }; Ray ray = GetMouseRay(screenCenter, camera); // Check ray collision with all voxels @@ -132,8 +133,11 @@ int main(void) } } } - + EndMode3D(); + + // Draw reference point for raycasting to delete blocks + DrawCircle(GetRenderWidth()/2, GetScreenHeight()/2, 4, RED); DrawText("Left-click a voxel to remove it!", 10, 10, 20, DARKGRAY); DrawText("WASD to move, mouse to look around", 10, 35, 10, GRAY); @@ -145,6 +149,7 @@ int main(void) // De-Initialization //-------------------------------------------------------------------------------------- UnloadModel(cubeModel); + CloseWindow(); //-------------------------------------------------------------------------------------- diff --git a/examples/models/models_basic_voxel.png b/examples/models/models_basic_voxel.png index 8bbcaf8dae98aa01624392f07822e36f2f44a53d..0666ec8c8dd1b5c043ecfe6afffcb6fe5d4494ae 100644 GIT binary patch literal 29035 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%0A^Vr^v4`8hs~>J7}}@qJobzeWh`LrrU%B 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 literal 349583 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

D)bQt8=^%55 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¯=oYv~c#@#(mswRYT? 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

5=3z&^$j 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 s$8SCT%`DKW|Nr6t& Date: Thu, 19 Feb 2026 17:01:27 +0100 Subject: [PATCH 208/232] REVIEWED: examples: moved some examples out of others --- examples/Makefile | 7 ------- .../core_window_web.c} | 12 ++++++------ examples/core/core_window_web.png | Bin 0 -> 15094 bytes examples/examples_list.txt | 6 ------ examples/others/web_basic_window.png | Bin 10297 -> 0 bytes .../resources/shaders/glsl430/gol.glsl | 0 .../resources/shaders/glsl430/gol_render.glsl | 0 .../shaders/glsl430/gol_transfert.glsl | 0 .../shaders_rlgl_compute.c} | 7 ++++--- .../shaders_rlgl_compute.png} | Bin 10 files changed, 10 insertions(+), 22 deletions(-) rename examples/{others/web_basic_window.c => core/core_window_web.c} (93%) create mode 100644 examples/core/core_window_web.png delete mode 100644 examples/others/web_basic_window.png rename examples/{others => shaders}/resources/shaders/glsl430/gol.glsl (100%) rename examples/{others => shaders}/resources/shaders/glsl430/gol_render.glsl (100%) rename examples/{others => shaders}/resources/shaders/glsl430/gol_transfert.glsl (100%) rename examples/{others/rlgl_compute_shader.c => shaders/shaders_rlgl_compute.c} (97%) rename examples/{others/rlgl_compute_shader.png => shaders/shaders_rlgl_compute.png} (100%) diff --git a/examples/Makefile b/examples/Makefile index 4f86ad5c0..2db2d8453 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -729,13 +729,6 @@ AUDIO = \ audio/audio_spectrum_visualizer \ audio/audio_stream_effects -OTHERS = \ - others/easings_testbed \ - others/embedded_files_loading \ - others/raylib_opengl_interop \ - others/rlgl_compute_shader \ - others/rlgl_standalone \ - others/web_basic_window #EXAMPLES_LIST_END # Define processes to execute diff --git a/examples/others/web_basic_window.c b/examples/core/core_window_web.c similarity index 93% rename from examples/others/web_basic_window.c rename to examples/core/core_window_web.c index 217c47fbc..3b1b50748 100644 --- a/examples/others/web_basic_window.c +++ b/examples/core/core_window_web.c @@ -1,14 +1,14 @@ /******************************************************************************************* * -* raylib [others] example - basic window -* -* This example has been adapted to compile for PLATFORM_WEB and PLATFORM_DESKTOP -* As you will notice, code structure is slightly different to the other examples +* raylib [core] example - window web * * Example complexity rating: [★☆☆☆] 1/4 * * Example originally created with raylib 1.3, last time updated with raylib 5.5 * +* This example has been adapted to compile for PLATFORM_WEB and PLATFORM_DESKTOP +* As you will notice, code structure is slightly different to the other examples +* * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software * @@ -40,7 +40,7 @@ int main(void) { // Initialization //-------------------------------------------------------------------------------------- - InitWindow(screenWidth, screenHeight, "raylib [others] example - web basic window"); + InitWindow(screenWidth, screenHeight, "raylib [core] example - window web"); #if defined(PLATFORM_WEB) emscripten_set_main_loop(UpdateDrawFrame, 0, 1); @@ -79,7 +79,7 @@ void UpdateDrawFrame(void) ClearBackground(RAYWHITE); - DrawText("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY); + DrawText("Welcome to raylib web structure!", 220, 200, 20, SKYBLUE); EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/examples/core/core_window_web.png b/examples/core/core_window_web.png new file mode 100644 index 0000000000000000000000000000000000000000..32886d665c07f38031ab8ce00696ae2a718d8d95 GIT binary patch literal 15094 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYU_8XZ1{4ubUVDOp!D_Fki(^PdT=Jh^Utia^ z1sX^(Emp)qlyEREyBHwH+jvnx0xQ8-)p{U5u-U`G)Ii)2=qSoXt^+2 zE{v87qvgVAxqxl_bF_3EEgeTo$I;S}*wQh>dBFz}ab}Kww~LUGInKt5d?zxpaL&&x zh~@y#zTD2>xM0ZQA$xLh$&>sgeKLK0Gn|A>*A+O3%V#|_z3@(U)yr&?_@1zG@I+9v zDvO)7!s5(A6Bak;1S~{Dp5g%`scT@x%<@bdzMlP?cHeDrvI$Fu9Mj^LIVKYkGci0V z96je6dY0|SH+%Df=R`)5G;gD#2-A^yEY2A%vqOs6W>+OG=DB%9rSe{vuRF9#>y-=7K9@1~oxAo*u!RrB znHC!>EM8fK#T#I+0sUfN#cVX|2GFYa#HGapT{3So92UtnH_^{yGyh#_GrtT1s@cqA7GZko39wbEn z5f!2mOn(o5**D>zU==^t+HY|@TbI}deDptY@8ZO&TT4`u9`COIQn%z{6)=3-V!`IB zy&}e3Mh?ap6he8?Sk`ToEiQx_Y^KiTvHU zEq81KUQWF7p=Bw1(q-|LFWYauY`pQs?|qG9PR(Pj{chUp!FDc`h6GnRp5Qw0xy(X=p{7Dn3(=zX2ha$&Sw7%dk@%Z1T$ z0ox$ZXz4gwI*yi(qow0$={Q=OV literal 0 HcmV?d00001 diff --git a/examples/examples_list.txt b/examples/examples_list.txt index eda62ee13..196fd15a7 100644 --- a/examples/examples_list.txt +++ b/examples/examples_list.txt @@ -211,9 +211,3 @@ audio;audio_stream_effects;★★★★;4.2;5.0;2022;2025;"Ramon Santamaria";@ra audio;audio_sound_multi;★★☆☆;5.0;5.0;2023;2025;"Jeffery Myers";@JeffM2501 audio;audio_sound_positioning;★★☆☆;5.5;5.5;2025;2025;"Le Juez Victor";@Bigfoot71 audio;audio_spectrum_visualizer;★★★☆;6.0;5.6-dev;2025;2025;"IANN";@meisei4 -others;rlgl_standalone;★★★★;1.6;4.0;2014;2025;"Ramon Santamaria";@raysan5 -others;rlgl_compute_shader;★★★★;4.0;4.0;2021;2025;"Teddy Astie";@tsnake41 -others;easings_testbed;★★★☆;2.5;3.0;2019;2025;"Juan Miguel López";@flashback-fx -others;raylib_opengl_interop;★★★★;3.8;4.0;2021;2025;"Stephan Soller";@arkanis -others;embedded_files_loading;★★☆☆;3.0;3.5;2020;2025;"Kristian Holmgren";@defutura -others;web_basic_window;★☆☆☆;5.6-dev;5.6-dev;2014;2025;"Ramon Santamaria";@raysan5 diff --git a/examples/others/web_basic_window.png b/examples/others/web_basic_window.png deleted file mode 100644 index 346184417a436343a769ba38a9ad9cfda0195181..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10297 zcmeHNdr(tX8ovPwtb*t`tzf8RsjKd8D-SDCgd{K^I$MIZ(%@J~s0vjWd4vcALV~zH zhS9L&w2Oko9cN)Tx8$nWqC65rEUZd04virSi8M&a4JJUiggozF5Nvk_{@Xuq=FUmZ zx#xV}m*4r$_qzAu0eX`Es*S4v0Px?xFX12nc#;5s(CzDujchpD+=qP;*aws10f{`= zfOWjG^0JDGGYgLc2Qp8bD%ws@JVZLZWBbnS5fMq2crpNN{oDS8xI-lwZ-$;- zCibqQeXd9OpHWA%eJ<;O5AKLh6qcwbVhLwrK7KTENc4x&zr?!{hgpVB)uFY5-~G=; zi>Rb}_VD`!1n)rBQnSia_Wp(f|JtB;BY~_}RMfu8YwfR-0$DdANi^sBPf;)7uZt_6 z3V_N_9)6kngK_Xxco*R5H{Uomt|fUS2;TMm!fS%ol5QOz%nh9#PS{1vez-XCTLK}J z=H>f#)xy%N1cJwrbIszDs@o4Tmjs;MNuqgO0N(WjS)?5#8tcg|b;3mZ#r!DwxkZWo zi_pC&1;&_`MH6&=m)UZ0uz3AQZoU7a zM2EaFw(Cd>lD%z?d3*Wh2K^`&r}uiFU&3KfCBSBRoL%a(1dF(2t-o#F(yiV_T$Jcv zei++O+HX+p!$t-pb5m2>FZ-`q!r>OQ0xtbqzSbt6Z7GOal;{8k>#{(L#iu_c1~1{j zVy=KoU2>1K&No|^yC~887B35QYU-Qls9j4qbV*mhC93WMkGxL)lX`LMX~$Op8Wg|a z+EkMKqJ zpKnFg3|_c|VpjGtc|%)8`)x0@I~B$0t@UsIEJ;-~OEuaZWeA7qa#BS+UMFMFQXhI! zxnSQ%WoYm?BjS#|n)6u4L>}C;cQ8WuNI_G*0yOK=E#)c>GgiT%@?%@=T#uf=4>8a+ zrEYmGmWF7fX^rH%VqO;=0_`@?#79aYiW}C6Z9F?iGta+RWx3{VoK1%uKeNSVP^xL~ zxOd9>+PyyOllk=1_SZ_Y`@y8x!Q^Q`q0D|SrG%{+*(uFwFt?f3>_GWYoZv2V=p-LO zPIFA0ALQEDym@Eccc#)%-K7ZG+(dDM{D(2a=9}o*Utph^bPEb!vcbkV8-=02B1ChBx6snl50FuP*bUaZv?NrY`_or)yLGH!O=6sLq6RYbwsBp^@OVb7!oW$U zisZ%7!gdj=*00qYSeTI{_{u@N1?ul`>0m{S zyWYHg>-B$PJMZ>B_MmGf?zTN~R4GK^)j!Q7Rv=hg4q9#FbrUeBf#;lw-WpcSBh-(f zmQo3(7Ca5oQLK2QW;bLgU`vXn!(O(>b~VGQG&;*ApgCZ`MYkMr*;?3FC9QVnfTg)% z;L{Z9hF}qkCiuAA<~-|(Y=k)2V;JHt@ zJ&wK64pEI?BSRsv`u`|kV{LG={CFD##b>q2XDr$JLaQZ3(aNPW^l*Vn8c;h>Hnthl zN*UqsoNVMeWm{vwHG5S-n`XvhsDPveS|nxwfo+hqVHiVImP8)8a^9f7^3tFmut4%m zWa>(l0pTNhqbj0*3g*$FGDJV%Y*fXj=OH$R$P5p~m|~gr{jP@ltLJM&UVW%v2V7NX z?~)n)c?d#v%o#Y4#@dci4zv=qTPr>UGeZ2E4AMqbgv+M9k;Zev2-G%t zuT1J&rz;!VhLLJrQzN4WHli+Dbr-B-P)p2QH$>US5TRhN?BsT#)C5t+&23skwfrU~ zSoK&7Tb8p)X{?o!KC^z&p2jIe++T*Y+M`Vkx*4trVI$VDbUn4-0vlz~Ny0M4h7)Xl zt_jm*-`>8aU}Z zHz<6`kr(%mD2XQU_fr$b+OgZ*%h2g^WVI7ER;YB4{E2RpqdVtRS${IdAuos|vhOWI zs{5KWB2}l#r{|CQDT9nGa@$i1MkyWChEE~4 zn~sLQzQh-j-2?KG87-0Ui*@X-_OSKgT|hnlq=~stRR~qsW`o5YqL=}e#_T{aecw{Wxhm;pAY +#include // Required for: NULL // IMPORTANT: This must match gol*.glsl GOL_WIDTH constant // This must be a multiple of 16 (check golLogic compute dispatch) diff --git a/examples/others/rlgl_compute_shader.png b/examples/shaders/shaders_rlgl_compute.png similarity index 100% rename from examples/others/rlgl_compute_shader.png rename to examples/shaders/shaders_rlgl_compute.png From 781c37972a56e977b01e0a540ba7a96688eecdb4 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 19 Feb 2026 17:11:02 +0100 Subject: [PATCH 209/232] Updated examples, removed others category processing --- examples/Makefile | 1 + examples/Makefile.Web | 4 + examples/README.md | 13 +- examples/examples_list.txt | 7 + examples/shapes/shapes_easings_testbed.c | 23 +- .../examples/shapes_easings_testbed.vcxproj | 569 ++++++++++++++++++ projects/VS2022/raylib.sln | 165 +---- tools/rexm/reports/examples_issues.md | 7 - tools/rexm/reports/examples_validation.md | 9 +- tools/rexm/rexm.c | 30 +- 10 files changed, 638 insertions(+), 190 deletions(-) create mode 100644 projects/VS2022/examples/shapes_easings_testbed.vcxproj diff --git a/examples/Makefile b/examples/Makefile index 2db2d8453..a6b2d6941 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -578,6 +578,7 @@ SHAPES = \ shapes/shapes_easings_ball \ shapes/shapes_easings_box \ shapes/shapes_easings_rectangles \ + shapes/shapes_easings_testbed \ shapes/shapes_following_eyes \ shapes/shapes_hilbert_curve \ shapes/shapes_kaleidoscope \ diff --git a/examples/Makefile.Web b/examples/Makefile.Web index 3841dff29..0e9515382 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -563,6 +563,7 @@ SHAPES = \ shapes/shapes_easings_ball \ shapes/shapes_easings_box \ shapes/shapes_easings_rectangles \ + shapes/shapes_easings_testbed \ shapes/shapes_following_eyes \ shapes/shapes_hilbert_curve \ shapes/shapes_kaleidoscope \ @@ -917,6 +918,9 @@ shapes/shapes_easings_box: shapes/shapes_easings_box.c shapes/shapes_easings_rectangles: shapes/shapes_easings_rectangles.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) +shapes/shapes_easings_testbed: shapes/shapes_easings_testbed.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + shapes/shapes_following_eyes: shapes/shapes_following_eyes.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) diff --git a/examples/README.md b/examples/README.md index 6b2c1950b..d96ca5c10 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: 208] +## EXAMPLES COLLECTION [TOTAL: 203] ### category: core [48] @@ -74,7 +74,7 @@ Examples using raylib [core](../src/rcore.c) module platform functionality: wind | [core_compute_hash](core/core_compute_hash.c) | core_compute_hash | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) | | [core_keyboard_testbed](core/core_keyboard_testbed.c) | core_keyboard_testbed | ⭐⭐☆☆ | 5.6 | 5.6 | [Ramon Santamaria](https://github.com/raysan5) | -### category: shapes [39] +### category: shapes [40] Examples using raylib shapes drawing functionality, provided by raylib [shapes](../src/rshapes.c) module. @@ -119,6 +119,7 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes]( | [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) | | [shapes_hilbert_curve](shapes/shapes_hilbert_curve.c) | shapes_hilbert_curve | ⭐⭐⭐☆ | 5.6 | 5.6 | [Hamza RAHAL](https://github.com/hmz-rhl) | +| [shapes_easings_testbed](shapes/shapes_easings_testbed.c) | shapes_easings_testbed | ⭐⭐⭐☆ | 2.5 | 2.5 | [Juan Miguel López](https://github.com/flashback-fx) | ### category: textures [30] @@ -270,18 +271,12 @@ Examples using raylib audio functionality, including sound/music loading and pla | [audio_sound_positioning](audio/audio_sound_positioning.c) | audio_sound_positioning | ⭐⭐☆☆ | 5.5 | 5.5 | [Le Juez Victor](https://github.com/Bigfoot71) | | [audio_spectrum_visualizer](audio/audio_spectrum_visualizer.c) | audio_spectrum_visualizer | ⭐⭐⭐☆ | 6.0 | 5.6-dev | [IANN](https://github.com/meisei4) | -### category: others [6] +### category: others [0] Examples showing raylib misc functionality that does not fit in other categories, like standalone modules usage or examples integrating external libraries. | example | image | difficulty
level | version
created | last version
updated | original
developer | |-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------| -| [rlgl_standalone](others/rlgl_standalone.c) | rlgl_standalone | ⭐⭐⭐⭐️ | 1.6 | 4.0 | [Ramon Santamaria](https://github.com/raysan5) | -| [rlgl_compute_shader](others/rlgl_compute_shader.c) | rlgl_compute_shader | ⭐⭐⭐⭐️ | 4.0 | 4.0 | [Teddy Astie](https://github.com/tsnake41) | -| [easings_testbed](others/easings_testbed.c) | easings_testbed | ⭐⭐⭐☆ | 2.5 | 3.0 | [Juan Miguel López](https://github.com/flashback-fx) | -| [raylib_opengl_interop](others/raylib_opengl_interop.c) | raylib_opengl_interop | ⭐⭐⭐⭐️ | 3.8 | 4.0 | [Stephan Soller](https://github.com/arkanis) | -| [embedded_files_loading](others/embedded_files_loading.c) | embedded_files_loading | ⭐⭐☆☆ | 3.0 | 3.5 | [Kristian Holmgren](https://github.com/defutura) | -| [web_basic_window](others/web_basic_window.c) | web_basic_window | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) | Some example missing? As always, contributions are welcome, feel free to send new examples! Here is an [examples template](examples_template.c) with instructions to start with! diff --git a/examples/examples_list.txt b/examples/examples_list.txt index 196fd15a7..0ad7a763a 100644 --- a/examples/examples_list.txt +++ b/examples/examples_list.txt @@ -96,6 +96,7 @@ shapes;shapes_rlgl_triangle;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Robin";@Robi shapes;shapes_ball_physics;★★☆☆;5.6-dev;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto shapes;shapes_penrose_tile;★★★★;5.5;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto shapes;shapes_hilbert_curve;★★★☆;5.6;5.6;2025;2025;"Hamza RAHAL";@hmz-rhl +shapes;shapes_easings_testbed;★★★☆;2.5;2.5;2019;2025;"Juan Miguel López";@flashback-fx 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 @@ -211,3 +212,9 @@ audio;audio_stream_effects;★★★★;4.2;5.0;2022;2025;"Ramon Santamaria";@ra audio;audio_sound_multi;★★☆☆;5.0;5.0;2023;2025;"Jeffery Myers";@JeffM2501 audio;audio_sound_positioning;★★☆☆;5.5;5.5;2025;2025;"Le Juez Victor";@Bigfoot71 audio;audio_spectrum_visualizer;★★★☆;6.0;5.6-dev;2025;2025;"IANN";@meisei4 +ei4 +ei4 +meisei4 +ei4 +ei4 +ei4 diff --git a/examples/shapes/shapes_easings_testbed.c b/examples/shapes/shapes_easings_testbed.c index a3ff23a7c..3f4f2528a 100644 --- a/examples/shapes/shapes_easings_testbed.c +++ b/examples/shapes/shapes_easings_testbed.c @@ -68,6 +68,15 @@ typedef struct EasingFuncs { float (*func)(float, float, float, float); } EasingFuncs; +//------------------------------------------------------------------------------------ +// Module Functions Declaration +//------------------------------------------------------------------------------------ +// Function used when "no easing" is selected for any axis +static float NoEase(float t, float b, float c, float d); + +//------------------------------------------------------------------------------------ +// Global Variables Definition +//------------------------------------------------------------------------------------ // Easing functions reference data static const EasingFuncs easings[] = { [EASE_LINEAR_NONE] = { .name = "EaseLinearNone", .func = EaseLinearNone }, @@ -101,11 +110,7 @@ static const EasingFuncs easings[] = { [EASING_NONE] = { .name = "None", .func = NoEase }, }; -//------------------------------------------------------------------------------------ -// Module Functions Declaration -//------------------------------------------------------------------------------------ -// Function used when "no easing" is selected for any axis -static float NoEase(float t, float b, float c, float d); + //------------------------------------------------------------------------------------ // Program main entry point @@ -191,8 +196,8 @@ int main(void) // Movement computation if (!paused && ((boundedT && t < d) || !boundedT)) { - ballPosition.x = Easings[easingX].func(t, 100.0f, 700.0f - 170.0f, d); - ballPosition.y = Easings[easingY].func(t, 100.0f, 400.0f - 170.0f, d); + ballPosition.x = easings[easingX].func(t, 100.0f, 700.0f - 170.0f, d); + ballPosition.y = easings[easingY].func(t, 100.0f, 400.0f - 170.0f, d); t += 1.0f; } //---------------------------------------------------------------------------------- @@ -204,8 +209,8 @@ int main(void) ClearBackground(RAYWHITE); // Draw information text - DrawText(TextFormat("Easing x: %s", Easings[easingX].name), 20, FONT_SIZE, FONT_SIZE, LIGHTGRAY); - DrawText(TextFormat("Easing y: %s", Easings[easingY].name), 20, FONT_SIZE*2, FONT_SIZE, LIGHTGRAY); + DrawText(TextFormat("Easing x: %s", easings[easingX].name), 20, FONT_SIZE, FONT_SIZE, LIGHTGRAY); + DrawText(TextFormat("Easing y: %s", easings[easingY].name), 20, FONT_SIZE*2, FONT_SIZE, LIGHTGRAY); DrawText(TextFormat("t (%c) = %.2f d = %.2f", (boundedT == true)? 'b' : 'u', t, d), 20, FONT_SIZE*3, FONT_SIZE, LIGHTGRAY); // Draw instructions text diff --git a/projects/VS2022/examples/shapes_easings_testbed.vcxproj b/projects/VS2022/examples/shapes_easings_testbed.vcxproj new file mode 100644 index 000000000..b2d63b10c --- /dev/null +++ b/projects/VS2022/examples/shapes_easings_testbed.vcxproj @@ -0,0 +1,569 @@ + + + + + Debug.DLL + ARM64 + + + Debug.DLL + Win32 + + + Debug.DLL + x64 + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + Release.DLL + ARM64 + + + Release.DLL + Win32 + + + Release.DLL + x64 + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + {4250CE87-9AA0-43BB-AB47-0636548922B5} + Win32Proj + shapes_easings_testbed + 10.0 + shapes_easings_testbed + + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + $(SolutionDir)..\..\examples\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/raylib.sln b/projects/VS2022/raylib.sln index 740d1bcbe..7b4c4b30a 100644 --- a/projects/VS2022/raylib.sln +++ b/projects/VS2022/raylib.sln @@ -21,8 +21,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shaders", "shaders", "{5317 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "audio", "audio", "{CC132A4D-D081-4C26-BFB9-AB11984054F8}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "others", "others", "{E9D708A5-9C1F-4B84-A795-C5F191801762}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_basic_window", "examples\core_basic_window.vcxproj", "{0981CA98-E4A5-4DF1-987F-A41D09131EFC}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_sprite_animation", "examples\textures_sprite_animation.vcxproj", "{C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC}" @@ -231,12 +229,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_texture_rendering", EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_texture_waves", "examples\shaders_texture_waves.vcxproj", "{291B4975-8EFF-4C7C-8AF3-44A77B8491B8}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "embedded_files_loading", "examples\embedded_files_loading.vcxproj", "{FDE6080B-E203-4066-910D-AD0302566008}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "easings_testbed", "examples\easings_testbed.vcxproj", "{E1B6D565-9D7C-46B7-9202-ECF54974DE50}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rlgl_standalone", "examples\rlgl_standalone.vcxproj", "{C8765523-58F8-4C8E-9914-693396F6F0FF}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_loading_vox", "examples\models_loading_vox.vcxproj", "{2F1B955B-275E-4D8E-8864-06FEC44D7912}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_loading_gltf", "examples\models_loading_gltf.vcxproj", "{F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}" @@ -255,8 +247,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_basic_screen_manager", EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_custom_frame_control", "examples\core_custom_frame_control.vcxproj", "{658A1B85-554E-4A5D-973A-FFE592CDD5F2}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rlgl_compute_shader", "examples\rlgl_compute_shader.vcxproj", "{07CA51AD-72AE-46A2-AAED-DC3E3F807976}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_3d_drawing", "examples\text_3d_drawing.vcxproj", "{27B110CC-43C0-400A-89D9-245E681647D7}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_polygon_drawing", "examples\textures_polygon_drawing.vcxproj", "{1DE84812-E143-4C4B-A61D-9267AAD55401}" @@ -363,8 +353,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_ascii_rendering", " EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_monitor_detector", "examples\core_monitor_detector.vcxproj", "{FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "web_basic_window", "examples\web_basic_window.vcxproj", "{A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_kaleidoscope", "examples\shapes_kaleidoscope.vcxproj", "{0C442799-B09C-4CD1-9538-711B6E85E9BF}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_recursive_tree", "examples\shapes_recursive_tree.vcxproj", "{DFB40A10-F8B7-412A-BCC3-5EE49294D816}" @@ -437,6 +425,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_keyboard_testbed", "ex EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_framebuffer_rendering", "examples\textures_framebuffer_rendering.vcxproj", "{F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_easings_testbed", "examples\shapes_easings_testbed.vcxproj", "{4250CE87-9AA0-43BB-AB47-0636548922B5}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug.DLL|ARM64 = Debug.DLL|ARM64 @@ -2973,76 +2963,6 @@ Global {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Release|x64.Build.0 = Release|x64 {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Release|x86.ActiveCfg = Release|Win32 {291B4975-8EFF-4C7C-8AF3-44A77B8491B8}.Release|x86.Build.0 = Release|Win32 - {FDE6080B-E203-4066-910D-AD0302566008}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {FDE6080B-E203-4066-910D-AD0302566008}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {FDE6080B-E203-4066-910D-AD0302566008}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {FDE6080B-E203-4066-910D-AD0302566008}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {FDE6080B-E203-4066-910D-AD0302566008}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {FDE6080B-E203-4066-910D-AD0302566008}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {FDE6080B-E203-4066-910D-AD0302566008}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {FDE6080B-E203-4066-910D-AD0302566008}.Debug|ARM64.Build.0 = Debug|ARM64 - {FDE6080B-E203-4066-910D-AD0302566008}.Debug|x64.ActiveCfg = Debug|x64 - {FDE6080B-E203-4066-910D-AD0302566008}.Debug|x64.Build.0 = Debug|x64 - {FDE6080B-E203-4066-910D-AD0302566008}.Debug|x86.ActiveCfg = Debug|Win32 - {FDE6080B-E203-4066-910D-AD0302566008}.Debug|x86.Build.0 = Debug|Win32 - {FDE6080B-E203-4066-910D-AD0302566008}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {FDE6080B-E203-4066-910D-AD0302566008}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {FDE6080B-E203-4066-910D-AD0302566008}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {FDE6080B-E203-4066-910D-AD0302566008}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {FDE6080B-E203-4066-910D-AD0302566008}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {FDE6080B-E203-4066-910D-AD0302566008}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {FDE6080B-E203-4066-910D-AD0302566008}.Release|ARM64.ActiveCfg = Release|ARM64 - {FDE6080B-E203-4066-910D-AD0302566008}.Release|ARM64.Build.0 = Release|ARM64 - {FDE6080B-E203-4066-910D-AD0302566008}.Release|x64.ActiveCfg = Release|x64 - {FDE6080B-E203-4066-910D-AD0302566008}.Release|x64.Build.0 = Release|x64 - {FDE6080B-E203-4066-910D-AD0302566008}.Release|x86.ActiveCfg = Release|Win32 - {FDE6080B-E203-4066-910D-AD0302566008}.Release|x86.Build.0 = Release|Win32 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug|ARM64.Build.0 = Debug|ARM64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug|x64.ActiveCfg = Debug|x64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug|x64.Build.0 = Debug|x64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug|x86.ActiveCfg = Debug|Win32 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Debug|x86.Build.0 = Debug|Win32 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release|ARM64.ActiveCfg = Release|ARM64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release|ARM64.Build.0 = Release|ARM64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release|x64.ActiveCfg = Release|x64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release|x64.Build.0 = Release|x64 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release|x86.ActiveCfg = Release|Win32 - {E1B6D565-9D7C-46B7-9202-ECF54974DE50}.Release|x86.Build.0 = Release|Win32 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug|ARM64.Build.0 = Debug|ARM64 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug|x64.ActiveCfg = Debug|x64 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug|x64.Build.0 = Debug|x64 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug|x86.ActiveCfg = Debug|Win32 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Debug|x86.Build.0 = Debug|Win32 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release|ARM64.ActiveCfg = Release|ARM64 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release|ARM64.Build.0 = Release|ARM64 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release|x64.ActiveCfg = Release|x64 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release|x64.Build.0 = Release|x64 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release|x86.ActiveCfg = Release|Win32 - {C8765523-58F8-4C8E-9914-693396F6F0FF}.Release|x86.Build.0 = Release|Win32 {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 {2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 @@ -3259,30 +3179,6 @@ Global {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Release|x64.Build.0 = Release|x64 {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Release|x86.ActiveCfg = Release|Win32 {658A1B85-554E-4A5D-973A-FFE592CDD5F2}.Release|x86.Build.0 = Release|Win32 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug|ARM64.Build.0 = Debug|ARM64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug|x64.ActiveCfg = Debug|x64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug|x64.Build.0 = Debug|x64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug|x86.ActiveCfg = Debug|Win32 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Debug|x86.Build.0 = Debug|Win32 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release|ARM64.ActiveCfg = Release|ARM64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release|ARM64.Build.0 = Release|ARM64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release|x64.ActiveCfg = Release|x64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release|x64.Build.0 = Release|x64 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release|x86.ActiveCfg = Release|Win32 - {07CA51AD-72AE-46A2-AAED-DC3E3F807976}.Release|x86.Build.0 = Release|Win32 {27B110CC-43C0-400A-89D9-245E681647D7}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 {27B110CC-43C0-400A-89D9-245E681647D7}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 {27B110CC-43C0-400A-89D9-245E681647D7}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 @@ -4555,30 +4451,6 @@ Global {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release|x64.Build.0 = Release|x64 {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release|x86.ActiveCfg = Release|Win32 {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3}.Release|x86.Build.0 = Release|Win32 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug|ARM64.Build.0 = Debug|ARM64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug|x64.ActiveCfg = Debug|x64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug|x64.Build.0 = Debug|x64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug|x86.ActiveCfg = Debug|Win32 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Debug|x86.Build.0 = Debug|Win32 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release|ARM64.ActiveCfg = Release|ARM64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release|ARM64.Build.0 = Release|ARM64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release|x64.ActiveCfg = Release|x64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release|x64.Build.0 = Release|x64 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release|x86.ActiveCfg = Release|Win32 - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC}.Release|x86.Build.0 = Release|Win32 {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 {0C442799-B09C-4CD1-9538-711B6E85E9BF}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 @@ -5443,6 +5315,30 @@ Global {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|x64.Build.0 = Release|x64 {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|x86.ActiveCfg = Release|Win32 {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C}.Release|x86.Build.0 = Release|Win32 + {4250CE87-9AA0-43BB-AB47-0636548922B5}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {4250CE87-9AA0-43BB-AB47-0636548922B5}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {4250CE87-9AA0-43BB-AB47-0636548922B5}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {4250CE87-9AA0-43BB-AB47-0636548922B5}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {4250CE87-9AA0-43BB-AB47-0636548922B5}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {4250CE87-9AA0-43BB-AB47-0636548922B5}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {4250CE87-9AA0-43BB-AB47-0636548922B5}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {4250CE87-9AA0-43BB-AB47-0636548922B5}.Debug|ARM64.Build.0 = Debug|ARM64 + {4250CE87-9AA0-43BB-AB47-0636548922B5}.Debug|x64.ActiveCfg = Debug|x64 + {4250CE87-9AA0-43BB-AB47-0636548922B5}.Debug|x64.Build.0 = Debug|x64 + {4250CE87-9AA0-43BB-AB47-0636548922B5}.Debug|x86.ActiveCfg = Debug|Win32 + {4250CE87-9AA0-43BB-AB47-0636548922B5}.Debug|x86.Build.0 = Debug|Win32 + {4250CE87-9AA0-43BB-AB47-0636548922B5}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {4250CE87-9AA0-43BB-AB47-0636548922B5}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {4250CE87-9AA0-43BB-AB47-0636548922B5}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {4250CE87-9AA0-43BB-AB47-0636548922B5}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {4250CE87-9AA0-43BB-AB47-0636548922B5}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {4250CE87-9AA0-43BB-AB47-0636548922B5}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {4250CE87-9AA0-43BB-AB47-0636548922B5}.Release|ARM64.ActiveCfg = Release|ARM64 + {4250CE87-9AA0-43BB-AB47-0636548922B5}.Release|ARM64.Build.0 = Release|ARM64 + {4250CE87-9AA0-43BB-AB47-0636548922B5}.Release|x64.ActiveCfg = Release|x64 + {4250CE87-9AA0-43BB-AB47-0636548922B5}.Release|x64.Build.0 = Release|x64 + {4250CE87-9AA0-43BB-AB47-0636548922B5}.Release|x86.ActiveCfg = Release|Win32 + {4250CE87-9AA0-43BB-AB47-0636548922B5}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -5455,7 +5351,6 @@ Global {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1} {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1} {CC132A4D-D081-4C26-BFB9-AB11984054F8} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1} - {E9D708A5-9C1F-4B84-A795-C5F191801762} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1} {0981CA98-E4A5-4DF1-987F-A41D09131EFC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {C25D2CC6-80CA-4C8A-BE3B-2E0F4EA5D0CC} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} {103B292B-049B-4B15-85A1-9F902840DB2C} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} @@ -5560,9 +5455,6 @@ Global {11F33A39-74B7-4018-B5F9-CC285A673A8F} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} {A6F5E35E-B4A7-41B3-853A-75558E6E0715} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} {291B4975-8EFF-4C7C-8AF3-44A77B8491B8} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {FDE6080B-E203-4066-910D-AD0302566008} = {E9D708A5-9C1F-4B84-A795-C5F191801762} - {E1B6D565-9D7C-46B7-9202-ECF54974DE50} = {E9D708A5-9C1F-4B84-A795-C5F191801762} - {C8765523-58F8-4C8E-9914-693396F6F0FF} = {E9D708A5-9C1F-4B84-A795-C5F191801762} {2F1B955B-275E-4D8E-8864-06FEC44D7912} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} {F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} {F2DB2E59-76BF-4D81-859A-AFC289C046C0} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} @@ -5572,7 +5464,6 @@ Global {3CFF7AB8-32CB-4D6D-9FED-53DBEF277359} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {8B1AF423-00F1-4924-AC54-F77D402D2AC9} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {658A1B85-554E-4A5D-973A-FFE592CDD5F2} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {07CA51AD-72AE-46A2-AAED-DC3E3F807976} = {E9D708A5-9C1F-4B84-A795-C5F191801762} {27B110CC-43C0-400A-89D9-245E681647D7} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} {1DE84812-E143-4C4B-A61D-9267AAD55401} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} {4A87569C-4BD3-4113-B4B9-573D65B3D3F8} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} @@ -5610,7 +5501,7 @@ Global {C54703BF-D68A-480D-BE27-49B62E45D582} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} {9CD8BCAD-F212-4BCC-BA98-899743CE3279} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} {0981CA28-E4A5-4DF1-987F-A41D09131EFC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {278D8859-20B1-428F-8448-064F46E1F021} {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} @@ -5626,7 +5517,6 @@ Global {A4662163-83E7-4309-8CAA-B0BF13655FE6} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} {5F4B766F-DD52-4B53-B6C3-BC7611E17F20} = {278D8859-20B1-428F-8448-064F46E1F021} {FF5F9EE9-29C5-40EE-BBCF-AE51B001FEC3} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {A9C422E7-0F03-4DBC-AC93-5C3EF4942DEC} = {E9D708A5-9C1F-4B84-A795-C5F191801762} {0C442799-B09C-4CD1-9538-711B6E85E9BF} = {278D8859-20B1-428F-8448-064F46E1F021} {DFB40A10-F8B7-412A-BCC3-5EE49294D816} = {278D8859-20B1-428F-8448-064F46E1F021} {BB58A5FB-1A35-4471-86D0-A5189EC541B3} = {278D8859-20B1-428F-8448-064F46E1F021} @@ -5663,6 +5553,7 @@ Global {DC163251-16C3-4B72-B965-ACDBA0F02BD1} = {278D8859-20B1-428F-8448-064F46E1F021} {D35D2FDA-B53F-4F70-81CA-24D95812B89C} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {4250CE87-9AA0-43BB-AB47-0636548922B5} = {278D8859-20B1-428F-8448-064F46E1F021} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29} diff --git a/tools/rexm/reports/examples_issues.md b/tools/rexm/reports/examples_issues.md index 081170806..a648295cc 100644 --- a/tools/rexm/reports/examples_issues.md +++ b/tools/rexm/reports/examples_issues.md @@ -20,10 +20,3 @@ 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 | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | diff --git a/tools/rexm/reports/examples_validation.md b/tools/rexm/reports/examples_validation.md index d8f4a9521..90283ace7 100644 --- a/tools/rexm/reports/examples_validation.md +++ b/tools/rexm/reports/examples_validation.md @@ -62,7 +62,7 @@ Example elements validated: | core_viewport_scaling | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_input_actions | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_directory_files | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| core_highdpi_testbed | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| core_highdpi_testbed | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_screen_recording | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_clipboard_text | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_text_file_loading | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | @@ -107,6 +107,7 @@ Example elements validated: | shapes_ball_physics | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_penrose_tile | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_hilbert_curve | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_easings_testbed | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_logo_raylib | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_srcrec_dstrec | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_image_drawing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | @@ -222,9 +223,3 @@ 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 | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 70001a5f3..30ef6411f 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -63,7 +63,7 @@ #endif #define REXM_MAX_EXAMPLES 512 -#define REXM_MAX_EXAMPLE_CATEGORIES 8 +#define REXM_MAX_EXAMPLE_CATEGORIES 7 #define REXM_MAX_BUFFER_SIZE (2*1024*1024) // 2MB @@ -83,7 +83,7 @@ //---------------------------------------------------------------------------------- // raylib example info struct typedef struct { - char category[16]; // Example category: core, shapes, textures, text, models, shaders, audio, [others] + char category[16]; // Example category: core, shapes, textures, text, models, shaders, audio char name[128]; // Example name: _name_part int stars; // Example stars count: ★☆☆☆ char verCreated[12]; // Example raylib creation version @@ -151,7 +151,7 @@ typedef enum { OP_TESTLOG = 9, // Process available examples logs to generate report } rlExampleOperation; -static const char *exCategories[REXM_MAX_EXAMPLE_CATEGORIES] = { "core", "shapes", "textures", "text", "models", "shaders", "audio", "others" }; +static const char *exCategories[REXM_MAX_EXAMPLE_CATEGORIES] = { "core", "shapes", "textures", "text", "models", "shaders", "audio" }; // Paths required for examples management // NOTE: Paths can be provided with environment variables @@ -170,7 +170,7 @@ static const char *exVSProjectSolutionFile = NULL; // Env REXM_EXAMPLES_VS2022_S static int UpdateRequiredFiles(void); // Load examples collection information -// NOTE 1: Load by category: "ALL", "core", "shapes", "textures", "text", "models", "shaders", others" +// NOTE 1: Load by category: "ALL", "core", "shapes", "textures", "text", "models", "shaders", audio" // NOTE 2: Sort examples list on request flag static rlExampleInfo *LoadExampleData(const char *filter, bool sort, int *exCount); static void UnloadExampleData(rlExampleInfo *exInfo); @@ -590,7 +590,6 @@ int main(int argc, char *argv[]) else if (TextIsEqual(exCategory, "models")) nextCategoryIndex = 5; else if (TextIsEqual(exCategory, "shaders")) nextCategoryIndex = 6; else if (TextIsEqual(exCategory, "audio")) nextCategoryIndex = 7; - else if (TextIsEqual(exCategory, "others")) nextCategoryIndex = -1; // Add to EOF // Get required example info from example file header (if provided) @@ -1039,7 +1038,7 @@ int main(int argc, char *argv[]) if (nextCatIndex > (REXM_MAX_EXAMPLE_CATEGORIES - 1)) nextCatIndex = -1; // EOF // Find position to add new example on list, just before the following category - // Category order: core, shapes, textures, text, models, shaders, audio, [others] + // Category order: core, shapes, textures, text, models, shaders, audio int exListNextCatIndex = -1; if (nextCatIndex != -1) exListNextCatIndex = TextFindIndex(exList, exCategories[nextCatIndex]); else exListNextCatIndex = exListLen; // EOF @@ -1972,7 +1971,6 @@ static int UpdateRequiredFiles(void) //------------------------------------------------------------------------------------------------ // Edit: raylib/examples/Makefile.Web --> Update from collection - // NOTE: We avoid the "others" category on web building //------------------------------------------------------------------------------------------------ LOG("INFO: Updating raylib/examples/Makefile.Web\n"); char *mkwText = LoadFileText(TextFormat("%s/Makefile.Web", exBasePath)); @@ -1985,8 +1983,7 @@ static int UpdateRequiredFiles(void) memcpy(mkwTextUpdated, mkwText, mkwListStartIndex); mkwIndex = sprintf(mkwTextUpdated + mkwListStartIndex, "#EXAMPLES_LIST_START\n"); - // NOTE: We avoid the "others" category on web building - for (int i = 0; i < REXM_MAX_EXAMPLE_CATEGORIES - 1; i++) + for (int i = 0; i < REXM_MAX_EXAMPLE_CATEGORIES; i++) { mkwIndex += sprintf(mkwTextUpdated + mkwListStartIndex + mkwIndex, TextFormat("%s = \\\n", TextToUpper(exCategories[i]))); @@ -2011,8 +2008,7 @@ static int UpdateRequiredFiles(void) mkwIndex += sprintf(mkwTextUpdated + mkwListStartIndex + mkwIndex, "shaders: $(SHADERS)\n"); mkwIndex += sprintf(mkwTextUpdated + mkwListStartIndex + mkwIndex, "audio: $(AUDIO)\n\n"); - // NOTE: We avoid the "others" category on web building - for (int i = 0; i < REXM_MAX_EXAMPLE_CATEGORIES - 1; i++) + for (int i = 0; i < REXM_MAX_EXAMPLE_CATEGORIES; i++) { mkwIndex += sprintf(mkwTextUpdated + mkwListStartIndex + mkwIndex, TextFormat("# Compile %s examples\n", TextToUpper(exCategories[i]))); @@ -2159,12 +2155,6 @@ static int UpdateRequiredFiles(void) mdIndex += sprintf(mdTextUpdated + mdListStartIndex + mdIndex, "Examples using raylib audio functionality, including sound/music loading and playing. This functionality is provided by raylib [raudio](../src/raudio.c) module. Note this module can be used standalone independently of raylib.\n\n"); } - else if (i == 7) // "others" - { - mdIndex += sprintf(mdTextUpdated + mdListStartIndex + mdIndex, TextFormat("\n### category: others [%i]\n\n", exCollectionCount)); - mdIndex += sprintf(mdTextUpdated + mdListStartIndex + mdIndex, - "Examples showing raylib misc functionality that does not fit in other categories, like standalone modules usage or examples integrating external libraries.\n\n"); - } // Table header required mdIndex += sprintf(mdTextUpdated + mdListStartIndex + mdIndex, "| example | image | difficulty
level | version
created | last version
updated | original
developer |\n"); @@ -2227,8 +2217,7 @@ static int UpdateRequiredFiles(void) char starsText[16] = { 0 }; - // NOTE: We avoid "others" category - for (int i = 0; i < REXM_MAX_EXAMPLE_CATEGORIES - 1; i++) + for (int i = 0; i < REXM_MAX_EXAMPLE_CATEGORIES; i++) { int exCollectionCount = 0; rlExampleInfo *exCollection = LoadExampleData(exCategories[i], false, &exCollectionCount); @@ -2295,8 +2284,7 @@ static rlExampleInfo *LoadExampleData(const char *filter, bool sort, int *exCoun (lines[i][0] == 's') || // shapes, shaders (lines[i][0] == 't') || // textures, text (lines[i][0] == 'm') || // models - (lines[i][0] == 'a') || // audio - (lines[i][0] == 'o'))) // TODO: Get others category? + (lines[i][0] == 'a'))) // audio { rlExampleInfo info = { 0 }; int result = ParseExampleInfoLine(lines[i], &info); From 0a7c7569aaf4491e80073a4ef95961d75302f5e6 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 19 Feb 2026 17:11:32 +0100 Subject: [PATCH 210/232] Update examples_list.txt --- examples/examples_list.txt | 6 ------ 1 file changed, 6 deletions(-) diff --git a/examples/examples_list.txt b/examples/examples_list.txt index 0ad7a763a..6dd4aee40 100644 --- a/examples/examples_list.txt +++ b/examples/examples_list.txt @@ -212,9 +212,3 @@ audio;audio_stream_effects;★★★★;4.2;5.0;2022;2025;"Ramon Santamaria";@ra audio;audio_sound_multi;★★☆☆;5.0;5.0;2023;2025;"Jeffery Myers";@JeffM2501 audio;audio_sound_positioning;★★☆☆;5.5;5.5;2025;2025;"Le Juez Victor";@Bigfoot71 audio;audio_spectrum_visualizer;★★★☆;6.0;5.6-dev;2025;2025;"IANN";@meisei4 -ei4 -ei4 -meisei4 -ei4 -ei4 -ei4 From b9f16a28d358ae041b0474cb9c297b7affd33526 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 19 Feb 2026 17:13:20 +0100 Subject: [PATCH 211/232] REXM: Update examples collection --- examples/Makefile | 2 +- examples/Makefile.Web | 4 + examples/README.md | 12 +- examples/examples_list.txt | 1 + examples/shaders/shaders_rlgl_compute.c | 4 +- .../examples/shaders_rlgl_compute.vcxproj | 569 ++++++++++++++++++ projects/VS2022/raylib.sln | 27 + tools/rexm/reports/examples_validation.md | 1 + 8 files changed, 608 insertions(+), 12 deletions(-) create mode 100644 projects/VS2022/examples/shaders_rlgl_compute.vcxproj diff --git a/examples/Makefile b/examples/Makefile index a6b2d6941..5f3f44773 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -708,6 +708,7 @@ SHADERS = \ shaders/shaders_palette_switch \ shaders/shaders_postprocessing \ shaders/shaders_raymarching_rendering \ + shaders/shaders_rlgl_compute \ shaders/shaders_rounded_rectangle \ shaders/shaders_shadowmap_rendering \ shaders/shaders_shapes_textures \ @@ -729,7 +730,6 @@ AUDIO = \ audio/audio_sound_positioning \ audio/audio_spectrum_visualizer \ audio/audio_stream_effects - #EXAMPLES_LIST_END # Define processes to execute diff --git a/examples/Makefile.Web b/examples/Makefile.Web index 0e9515382..3f0c28506 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -693,6 +693,7 @@ SHADERS = \ shaders/shaders_palette_switch \ shaders/shaders_postprocessing \ shaders/shaders_raymarching_rendering \ + shaders/shaders_rlgl_compute \ shaders/shaders_rounded_rectangle \ shaders/shaders_shadowmap_rendering \ shaders/shaders_shapes_textures \ @@ -1465,6 +1466,9 @@ shaders/shaders_raymarching_rendering: shaders/shaders_raymarching_rendering.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file shaders/resources/shaders/glsl100/raymarching.fs@resources/shaders/glsl100/raymarching.fs +shaders/shaders_rlgl_compute: shaders/shaders_rlgl_compute.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + shaders/shaders_rounded_rectangle: shaders/shaders_rounded_rectangle.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file shaders/resources/shaders/glsl100/base.vs@resources/shaders/glsl100/base.vs \ diff --git a/examples/README.md b/examples/README.md index d96ca5c10..69f6d71d1 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: 203] +## EXAMPLES COLLECTION [TOTAL: 204] ### category: core [48] @@ -215,7 +215,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 [33] +### category: shaders [34] 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. @@ -254,6 +254,7 @@ Examples using raylib shaders functionality, including shaders loading, paramete | [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) | +| [shaders_rlgl_compute](shaders/shaders_rlgl_compute.c) | shaders_rlgl_compute | ⭐⭐⭐⭐️ | 4.0 | 4.0 | [Teddy Astie](https://github.com/tsnake41) | ### category: audio [9] @@ -271,12 +272,5 @@ Examples using raylib audio functionality, including sound/music loading and pla | [audio_sound_positioning](audio/audio_sound_positioning.c) | audio_sound_positioning | ⭐⭐☆☆ | 5.5 | 5.5 | [Le Juez Victor](https://github.com/Bigfoot71) | | [audio_spectrum_visualizer](audio/audio_spectrum_visualizer.c) | audio_spectrum_visualizer | ⭐⭐⭐☆ | 6.0 | 5.6-dev | [IANN](https://github.com/meisei4) | -### category: others [0] - -Examples showing raylib misc functionality that does not fit in other categories, like standalone modules usage or examples integrating external libraries. - -| example | image | difficulty
level | version
created | last version
updated | original
developer | -|-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------| - Some example missing? As always, contributions are welcome, feel free to send new examples! Here is an [examples template](examples_template.c) with instructions to start with! diff --git a/examples/examples_list.txt b/examples/examples_list.txt index 6dd4aee40..a8f8cb00c 100644 --- a/examples/examples_list.txt +++ b/examples/examples_list.txt @@ -203,6 +203,7 @@ shaders;shaders_lightmap_rendering;★★★☆;4.5;4.5;2019;2025;"Jussi Viitala 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 +shaders;shaders_rlgl_compute;★★★★;4.0;4.0;2021;2025;"Teddy Astie";@tsnake41 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/shaders_rlgl_compute.c b/examples/shaders/shaders_rlgl_compute.c index fd8a4cec7..af3bb6fe4 100644 --- a/examples/shaders/shaders_rlgl_compute.c +++ b/examples/shaders/shaders_rlgl_compute.c @@ -1,6 +1,6 @@ /******************************************************************************************* * -* raylib [others] example - compute shader +* raylib [shaders] example - rlgl compute * * WARNING: This example requires raylib compiled with OpenGL 4.3 version for * compute shaders support, shaders used in this example are #version 430 @@ -58,7 +58,7 @@ int main(void) const int screenWidth = GOL_WIDTH; const int screenHeight = GOL_WIDTH; - InitWindow(screenWidth, screenHeight, "raylib [others] example - compute shader"); + InitWindow(screenWidth, screenHeight, "raylib [shaders] example - rlgl compute"); const Vector2 resolution = { (float)screenWidth, (float)screenHeight }; unsigned int brushSize = 8; diff --git a/projects/VS2022/examples/shaders_rlgl_compute.vcxproj b/projects/VS2022/examples/shaders_rlgl_compute.vcxproj new file mode 100644 index 000000000..583898f19 --- /dev/null +++ b/projects/VS2022/examples/shaders_rlgl_compute.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 + + + + {6B1A933E-71B8-4C1F-9E79-02D98830E671} + Win32Proj + shaders_rlgl_compute + 10.0 + shaders_rlgl_compute + + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + + + + + + + {e89d61ac-55de-4482-afd4-df7242ebc859} + + + + + + \ No newline at end of file diff --git a/projects/VS2022/raylib.sln b/projects/VS2022/raylib.sln index 7b4c4b30a..6575b6307 100644 --- a/projects/VS2022/raylib.sln +++ b/projects/VS2022/raylib.sln @@ -427,6 +427,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_framebuffer_render EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_easings_testbed", "examples\shapes_easings_testbed.vcxproj", "{4250CE87-9AA0-43BB-AB47-0636548922B5}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_rlgl_compute", "examples\shaders_rlgl_compute.vcxproj", "{6B1A933E-71B8-4C1F-9E79-02D98830E671}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug.DLL|ARM64 = Debug.DLL|ARM64 @@ -5339,6 +5341,30 @@ Global {4250CE87-9AA0-43BB-AB47-0636548922B5}.Release|x64.Build.0 = Release|x64 {4250CE87-9AA0-43BB-AB47-0636548922B5}.Release|x86.ActiveCfg = Release|Win32 {4250CE87-9AA0-43BB-AB47-0636548922B5}.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 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -5554,6 +5580,7 @@ Global {D35D2FDA-B53F-4F70-81CA-24D95812B89C} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} {4250CE87-9AA0-43BB-AB47-0636548922B5} = {278D8859-20B1-428F-8448-064F46E1F021} + {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29} diff --git a/tools/rexm/reports/examples_validation.md b/tools/rexm/reports/examples_validation.md index 90283ace7..633fcae2f 100644 --- a/tools/rexm/reports/examples_validation.md +++ b/tools/rexm/reports/examples_validation.md @@ -214,6 +214,7 @@ Example elements validated: | shaders_rounded_rectangle | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_depth_rendering | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_game_of_life | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shaders_rlgl_compute | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | audio_module_playing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | audio_music_stream | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | audio_raw_stream | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | From dea67fa18a3c4b345b79981c7f82a69d8ae5f63a Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 19 Feb 2026 17:15:26 +0100 Subject: [PATCH 212/232] REXM: Update examples collection --- examples/Makefile | 1 + examples/Makefile.Web | 7 + examples/README.md | 5 +- examples/examples_list.txt | 1 + examples/shapes/shapes_easings_testbed.c | 2 - .../models_animation_bone_blending.vcxproj | 569 ++++++++++++++++++ projects/VS2022/raylib.sln | 27 + tools/rexm/reports/examples_issues.md | 1 + tools/rexm/reports/examples_validation.md | 1 + 9 files changed, 610 insertions(+), 4 deletions(-) create mode 100644 projects/VS2022/examples/models_animation_bone_blending.vcxproj diff --git a/examples/Makefile b/examples/Makefile index 5f3f44773..103cdc0fa 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -656,6 +656,7 @@ TEXT = \ text/text_writing_anim MODELS = \ + models/models_animation_bone_blending \ models/models_animation_gpu_skinning \ models/models_animation_playing \ models/models_basic_voxel \ diff --git a/examples/Makefile.Web b/examples/Makefile.Web index 3f0c28506..663751ad1 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -641,6 +641,7 @@ TEXT = \ text/text_writing_anim MODELS = \ + models/models_animation_bone_blending \ models/models_animation_gpu_skinning \ models/models_animation_playing \ models/models_basic_voxel \ @@ -1193,6 +1194,12 @@ text/text_writing_anim: text/text_writing_anim.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) # Compile MODELS examples +models/models_animation_bone_blending: models/models_animation_bone_blending.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ + --preload-file models/resources/models/gltf/greenman.glb@resources/models/gltf/greenman.glb \ + --preload-file models/resources/shaders/glsl100/skinning.vs@resources/shaders/glsl100/skinning.vs \ + --preload-file models/resources/shaders/glsl100/skinning.fs@resources/shaders/glsl100/skinning.fs + models/models_animation_gpu_skinning: models/models_animation_gpu_skinning.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file models/resources/models/gltf/greenman.glb@resources/models/gltf/greenman.glb \ diff --git a/examples/README.md b/examples/README.md index 69f6d71d1..2b7474cff 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: 204] +## EXAMPLES COLLECTION [TOTAL: 205] ### category: core [48] @@ -181,7 +181,7 @@ Examples using raylib text functionality, including sprite fonts loading/generat | [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] +### category: models [28] Examples using raylib models functionality, including models loading/generation and drawing, provided by raylib [models](../src/rmodels.c) module. @@ -214,6 +214,7 @@ Examples using raylib models functionality, including models loading/generation | [models_rotating_cube](models/models_rotating_cube.c) | models_rotating_cube | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Jopestpe](https://github.com/jopestpe) | | [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) | +| [models_animation_bone_blending](models/models_animation_bone_blending.c) | models_animation_bone_blending | ⭐⭐⭐⭐️ | 5.5 | 5.5 | [dmitrii-brand](https://github.com/dmitrii-brand) | ### category: shaders [34] diff --git a/examples/examples_list.txt b/examples/examples_list.txt index a8f8cb00c..be0def2d8 100644 --- a/examples/examples_list.txt +++ b/examples/examples_list.txt @@ -170,6 +170,7 @@ models;models_basic_voxel;★★☆☆;5.5;5.5;2025;2025;"Tim Little";@timlittle models;models_rotating_cube;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Jopestpe";@jopestpe models;models_decals;★★★★;5.6-dev;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates models;models_directional_billboard;★★☆☆;5.6-dev;5.6;2025;2025;"Robin";@RobinsAviary +models;models_animation_bone_blending;★★★★;5.5;5.5;2026;2026;"dmitrii-brand";@dmitrii-brand shaders;shaders_ascii_rendering;★★☆☆;5.5;5.6;2025;2025;"Maicon Santana";@maiconpintoabreu shaders;shaders_basic_lighting;★★★★;3.0;4.2;2019;2025;"Chris Camacho";@chriscamacho shaders;shaders_model_shader;★★☆☆;1.3;3.7;2014;2025;"Ramon Santamaria";@raysan5 diff --git a/examples/shapes/shapes_easings_testbed.c b/examples/shapes/shapes_easings_testbed.c index 3f4f2528a..ce9b7d485 100644 --- a/examples/shapes/shapes_easings_testbed.c +++ b/examples/shapes/shapes_easings_testbed.c @@ -110,8 +110,6 @@ static const EasingFuncs easings[] = { [EASING_NONE] = { .name = "None", .func = NoEase }, }; - - //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ diff --git a/projects/VS2022/examples/models_animation_bone_blending.vcxproj b/projects/VS2022/examples/models_animation_bone_blending.vcxproj new file mode 100644 index 000000000..f03989949 --- /dev/null +++ b/projects/VS2022/examples/models_animation_bone_blending.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 + + + + {6B1A933E-71B8-4C1F-9E79-02D98830E671} + Win32Proj + models_animation_bone_blending + 10.0 + models_animation_bone_blending + + + + 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\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\models + 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 6575b6307..fdbf427ce 100644 --- a/projects/VS2022/raylib.sln +++ b/projects/VS2022/raylib.sln @@ -429,6 +429,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_easings_testbed", "e EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_rlgl_compute", "examples\shaders_rlgl_compute.vcxproj", "{6B1A933E-71B8-4C1F-9E79-02D98830E671}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_animation_bone_blending", "examples\models_animation_bone_blending.vcxproj", "{6B1A933E-71B8-4C1F-9E79-02D98830E671}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug.DLL|ARM64 = Debug.DLL|ARM64 @@ -5365,6 +5367,30 @@ Global {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 + {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 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -5581,6 +5607,7 @@ Global {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} {4250CE87-9AA0-43BB-AB47-0636548922B5} = {278D8859-20B1-428F-8448-064F46E1F021} {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29} diff --git a/tools/rexm/reports/examples_issues.md b/tools/rexm/reports/examples_issues.md index a648295cc..3fcc136e5 100644 --- a/tools/rexm/reports/examples_issues.md +++ b/tools/rexm/reports/examples_issues.md @@ -20,3 +20,4 @@ Example elements validated: ``` | **EXAMPLE NAME** | [C] | [CAT]| [INFO]|[PNG]|[WPNG]| [RES]| [MK] |[MKWEB]| [VCX]| [SOL]|[RDME]|[JS] | [WOUT]|[WMETA]| |:---------------------------------|:---:|:----:|:-----:|:---:|:----:|:----:|:----:|:-----:|:----:|:----:|:----:|:---:|:-----:|:-----:| +| models_animation_bone_blending | ✔ | ✔ | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | diff --git a/tools/rexm/reports/examples_validation.md b/tools/rexm/reports/examples_validation.md index 633fcae2f..b2c05ebba 100644 --- a/tools/rexm/reports/examples_validation.md +++ b/tools/rexm/reports/examples_validation.md @@ -181,6 +181,7 @@ Example elements validated: | models_rotating_cube | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | models_decals | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | models_directional_billboard | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| models_animation_bone_blending | ✔ | ✔ | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_ascii_rendering | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_basic_lighting | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_model_shader | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | From 1f4e1bc477feccf3ed3a355a578f7c14e2fd171b Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 19 Feb 2026 17:18:50 +0100 Subject: [PATCH 213/232] REXM: Update examples collection --- examples/Makefile | 1 + examples/Makefile.Web | 7 ++++++ examples/README.md | 5 ++-- examples/examples_list.txt | 1 + examples/models/models_animation_blending.c | 6 ++--- projects/VS2022/raylib.sln | 27 +++++++++++++++++++++ tools/rexm/reports/examples_validation.md | 1 + 7 files changed, 43 insertions(+), 5 deletions(-) diff --git a/examples/Makefile b/examples/Makefile index 103cdc0fa..a1ddb12a0 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -656,6 +656,7 @@ TEXT = \ text/text_writing_anim MODELS = \ + models/models_animation_blending \ models/models_animation_bone_blending \ models/models_animation_gpu_skinning \ models/models_animation_playing \ diff --git a/examples/Makefile.Web b/examples/Makefile.Web index 663751ad1..c308fa8f7 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -641,6 +641,7 @@ TEXT = \ text/text_writing_anim MODELS = \ + models/models_animation_blending \ models/models_animation_bone_blending \ models/models_animation_gpu_skinning \ models/models_animation_playing \ @@ -1194,6 +1195,12 @@ text/text_writing_anim: text/text_writing_anim.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) # Compile MODELS examples +models/models_animation_blending: models/models_animation_blending.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ + --preload-file models/resources/models/gltf/robot.glb@resources/models/gltf/robot.glb \ + --preload-file models/resources/shaders/glsl100/skinning.vs@resources/shaders/glsl100/skinning.vs \ + --preload-file models/resources/shaders/glsl100/skinning.fs@resources/shaders/glsl100/skinning.fs + models/models_animation_bone_blending: models/models_animation_bone_blending.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file models/resources/models/gltf/greenman.glb@resources/models/gltf/greenman.glb \ diff --git a/examples/README.md b/examples/README.md index 2b7474cff..26ba4d3d6 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: 205] +## EXAMPLES COLLECTION [TOTAL: 206] ### category: core [48] @@ -181,7 +181,7 @@ Examples using raylib text functionality, including sprite fonts loading/generat | [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 [28] +### category: models [29] Examples using raylib models functionality, including models loading/generation and drawing, provided by raylib [models](../src/rmodels.c) module. @@ -215,6 +215,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) | | [models_animation_bone_blending](models/models_animation_bone_blending.c) | models_animation_bone_blending | ⭐⭐⭐⭐️ | 5.5 | 5.5 | [dmitrii-brand](https://github.com/dmitrii-brand) | +| [models_animation_blending](models/models_animation_blending.c) | models_animation_blending | ☆☆☆☆ | 5.5 | 5.6-dev | [Kirandeep](https://github.com/Kirandeep-Singh-Khehra) | ### category: shaders [34] diff --git a/examples/examples_list.txt b/examples/examples_list.txt index be0def2d8..ededf8e5a 100644 --- a/examples/examples_list.txt +++ b/examples/examples_list.txt @@ -171,6 +171,7 @@ models;models_rotating_cube;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Jopestpe";@j models;models_decals;★★★★;5.6-dev;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates models;models_directional_billboard;★★☆☆;5.6-dev;5.6;2025;2025;"Robin";@RobinsAviary models;models_animation_bone_blending;★★★★;5.5;5.5;2026;2026;"dmitrii-brand";@dmitrii-brand +models;models_animation_blending;☆☆☆☆;5.5;5.6-dev;2024;2024;"Kirandeep";@Kirandeep-Singh-Khehra shaders;shaders_ascii_rendering;★★☆☆;5.5;5.6;2025;2025;"Maicon Santana";@maiconpintoabreu shaders;shaders_basic_lighting;★★★★;3.0;4.2;2019;2025;"Chris Camacho";@chriscamacho shaders;shaders_model_shader;★★☆☆;1.3;3.7;2014;2025;"Ramon Santamaria";@raysan5 diff --git a/examples/models/models_animation_blending.c b/examples/models/models_animation_blending.c index 225c1bfbb..b33dbe85d 100644 --- a/examples/models/models_animation_blending.c +++ b/examples/models/models_animation_blending.c @@ -1,8 +1,8 @@ /******************************************************************************************* * -* raylib [core] example - Model animation blending +* raylib [models] example - animation blending * -* Example originally created with raylib 5.5 +* Example originally created with raylib 5.5, last time updated with raylib 5.6-dev * * Example contributed by Kirandeep (@Kirandeep-Singh-Khehra) * @@ -37,7 +37,7 @@ int main(void) const int screenWidth = 800; const int screenHeight = 450; - InitWindow(screenWidth, screenHeight, "raylib [models] example - Model Animation Blending"); + InitWindow(screenWidth, screenHeight, "raylib [models] example - animation blending"); // Define the camera to look into our 3d world Camera camera = { 0 }; diff --git a/projects/VS2022/raylib.sln b/projects/VS2022/raylib.sln index fdbf427ce..6cd7e8efc 100644 --- a/projects/VS2022/raylib.sln +++ b/projects/VS2022/raylib.sln @@ -431,6 +431,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_rlgl_compute", "exa EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_animation_bone_blending", "examples\models_animation_bone_blending.vcxproj", "{6B1A933E-71B8-4C1F-9E79-02D98830E671}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_animation_blending", "examples\models_animation_blending.vcxproj", "{6B1A933E-71B8-4C1F-9E79-02D98830E671}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug.DLL|ARM64 = Debug.DLL|ARM64 @@ -5391,6 +5393,30 @@ Global {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 + {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 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -5608,6 +5634,7 @@ Global {4250CE87-9AA0-43BB-AB47-0636548922B5} = {278D8859-20B1-428F-8448-064F46E1F021} {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29} diff --git a/tools/rexm/reports/examples_validation.md b/tools/rexm/reports/examples_validation.md index b2c05ebba..391c007cb 100644 --- a/tools/rexm/reports/examples_validation.md +++ b/tools/rexm/reports/examples_validation.md @@ -182,6 +182,7 @@ Example elements validated: | models_decals | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | models_directional_billboard | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | models_animation_bone_blending | ✔ | ✔ | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| models_animation_blending | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_ascii_rendering | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_basic_lighting | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_model_shader | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | From 1a5e22808c35350ec98fec3664d73569916af4af Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 19 Feb 2026 17:19:44 +0100 Subject: [PATCH 214/232] REXM: Update examples collection --- examples/Makefile | 1 + examples/Makefile.Web | 4 + examples/README.md | 5 +- examples/examples_list.txt | 1 + .../VS2022/examples/core_window_web.vcxproj | 569 ++++++++++++++++++ projects/VS2022/raylib.sln | 27 + tools/rexm/reports/examples_validation.md | 1 + 7 files changed, 606 insertions(+), 2 deletions(-) create mode 100644 projects/VS2022/examples/core_window_web.vcxproj diff --git a/examples/Makefile b/examples/Makefile index a1ddb12a0..40906ebfc 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -561,6 +561,7 @@ CORE = \ core/core_window_flags \ core/core_window_letterbox \ core/core_window_should_close \ + core/core_window_web \ core/core_world_screen SHAPES = \ diff --git a/examples/Makefile.Web b/examples/Makefile.Web index c308fa8f7..b91f59267 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -546,6 +546,7 @@ CORE = \ core/core_window_flags \ core/core_window_letterbox \ core/core_window_should_close \ + core/core_window_web \ core/core_world_screen SHAPES = \ @@ -875,6 +876,9 @@ core/core_window_letterbox: core/core_window_letterbox.c core/core_window_should_close: core/core_window_should_close.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) +core/core_window_web: core/core_window_web.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + core/core_world_screen: core/core_world_screen.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) diff --git a/examples/README.md b/examples/README.md index 26ba4d3d6..2b8b9dd98 100644 --- a/examples/README.md +++ b/examples/README.md @@ -17,9 +17,9 @@ You may find it easier to use than other toolchains, especially when it comes to - `zig build [module]` to compile all examples for a module (e.g. `zig build core`) - `zig build [example]` to compile _and run_ a particular example (e.g. `zig build core_basic_window`) -## EXAMPLES COLLECTION [TOTAL: 206] +## EXAMPLES COLLECTION [TOTAL: 207] -### category: core [48] +### category: core [49] Examples using raylib [core](../src/rcore.c) module platform functionality: window creation, inputs, drawing modes and system functionality. @@ -73,6 +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) | | [core_keyboard_testbed](core/core_keyboard_testbed.c) | core_keyboard_testbed | ⭐⭐☆☆ | 5.6 | 5.6 | [Ramon Santamaria](https://github.com/raysan5) | +| [core_window_web](core/core_window_web.c) | core_window_web | ⭐☆☆☆ | 1.3 | 5.5 | [Ramon Santamaria](https://github.com/raysan5) | ### category: shapes [40] diff --git a/examples/examples_list.txt b/examples/examples_list.txt index ededf8e5a..85b997ec4 100644 --- a/examples/examples_list.txt +++ b/examples/examples_list.txt @@ -57,6 +57,7 @@ core;core_clipboard_text;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ananth S";@Anan core;core_text_file_loading;★☆☆☆;5.5;5.6;0;0;"Aanjishnu Bhattacharyya";@NimComPoo-04 core;core_compute_hash;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5 core;core_keyboard_testbed;★★☆☆;5.6;5.6;2026;2026;"Ramon Santamaria";@raysan5 +core;core_window_web;★☆☆☆;1.3;5.5;2015;2025;"Ramon Santamaria";@raysan5 shapes;shapes_basic_shapes;★☆☆☆;1.0;4.2;2014;2025;"Ramon Santamaria";@raysan5 shapes;shapes_bouncing_ball;★☆☆☆;2.5;2.5;2013;2025;"Ramon Santamaria";@raysan5 shapes;shapes_bullet_hell;★☆☆☆;5.6;5.6;2025;2025;"Zero";@zerohorsepower diff --git a/projects/VS2022/examples/core_window_web.vcxproj b/projects/VS2022/examples/core_window_web.vcxproj new file mode 100644 index 000000000..4d7a0e741 --- /dev/null +++ b/projects/VS2022/examples/core_window_web.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 + + + + {6B1A933E-71B8-4C1F-9E79-02D98830E671} + Win32Proj + core_window_web + 10.0 + core_window_web + + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\core + WindowsLocalDebugger + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + + + + + + + {e89d61ac-55de-4482-afd4-df7242ebc859} + + + + + + \ No newline at end of file diff --git a/projects/VS2022/raylib.sln b/projects/VS2022/raylib.sln index 6cd7e8efc..7f8fbbbf0 100644 --- a/projects/VS2022/raylib.sln +++ b/projects/VS2022/raylib.sln @@ -433,6 +433,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_animation_bone_blend EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_animation_blending", "examples\models_animation_blending.vcxproj", "{6B1A933E-71B8-4C1F-9E79-02D98830E671}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_window_web", "examples\core_window_web.vcxproj", "{6B1A933E-71B8-4C1F-9E79-02D98830E671}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug.DLL|ARM64 = Debug.DLL|ARM64 @@ -5417,6 +5419,30 @@ Global {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 + {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 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -5635,6 +5661,7 @@ Global {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29} diff --git a/tools/rexm/reports/examples_validation.md b/tools/rexm/reports/examples_validation.md index 391c007cb..9c0c02956 100644 --- a/tools/rexm/reports/examples_validation.md +++ b/tools/rexm/reports/examples_validation.md @@ -68,6 +68,7 @@ Example elements validated: | core_text_file_loading | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_compute_hash | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_keyboard_testbed | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| core_window_web | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_basic_shapes | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_bouncing_ball | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_bullet_hell | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | From 4a89da3300c10965a92884aaff98c89f807ed0fc Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 19 Feb 2026 17:22:45 +0100 Subject: [PATCH 215/232] Update VS2022 examples solution --- .../VS2022/examples/core_window_web.vcxproj | 2 +- .../models_animation_blending.vcxproj | 4 +- .../models_animation_bone_blending.vcxproj | 2 +- .../examples/shaders_rlgl_compute.vcxproj | 2 +- projects/VS2022/raylib.sln | 210 +++++++++--------- 5 files changed, 110 insertions(+), 110 deletions(-) diff --git a/projects/VS2022/examples/core_window_web.vcxproj b/projects/VS2022/examples/core_window_web.vcxproj index 4d7a0e741..d26befac0 100644 --- a/projects/VS2022/examples/core_window_web.vcxproj +++ b/projects/VS2022/examples/core_window_web.vcxproj @@ -51,7 +51,7 @@ - {6B1A933E-71B8-4C1F-9E79-02D98830E671} + {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3} Win32Proj core_window_web 10.0 diff --git a/projects/VS2022/examples/models_animation_blending.vcxproj b/projects/VS2022/examples/models_animation_blending.vcxproj index bf8a8b27a..3eca7a6f2 100644 --- a/projects/VS2022/examples/models_animation_blending.vcxproj +++ b/projects/VS2022/examples/models_animation_blending.vcxproj @@ -35,7 +35,7 @@ - {AFDDE100-2D36-4749-817D-12E54C56312F} + {BB9C957D-34F1-46AE-B64A-9E0499C1746D} Win32Proj models_animation_blending 10.0 @@ -384,4 +384,4 @@ - + \ No newline at end of file diff --git a/projects/VS2022/examples/models_animation_bone_blending.vcxproj b/projects/VS2022/examples/models_animation_bone_blending.vcxproj index f03989949..475ad47f0 100644 --- a/projects/VS2022/examples/models_animation_bone_blending.vcxproj +++ b/projects/VS2022/examples/models_animation_bone_blending.vcxproj @@ -51,7 +51,7 @@ - {6B1A933E-71B8-4C1F-9E79-02D98830E671} + {AC751FE1-C986-4B6A-92A8-28ED89DEE671} Win32Proj models_animation_bone_blending 10.0 diff --git a/projects/VS2022/examples/shaders_rlgl_compute.vcxproj b/projects/VS2022/examples/shaders_rlgl_compute.vcxproj index 583898f19..d10553409 100644 --- a/projects/VS2022/examples/shaders_rlgl_compute.vcxproj +++ b/projects/VS2022/examples/shaders_rlgl_compute.vcxproj @@ -51,7 +51,7 @@ - {6B1A933E-71B8-4C1F-9E79-02D98830E671} + {AEA9D0D4-B810-4624-BC75-10A291584ED6} Win32Proj shaders_rlgl_compute 10.0 diff --git a/projects/VS2022/raylib.sln b/projects/VS2022/raylib.sln index 7f8fbbbf0..873db235b 100644 --- a/projects/VS2022/raylib.sln +++ b/projects/VS2022/raylib.sln @@ -427,13 +427,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_framebuffer_render EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_easings_testbed", "examples\shapes_easings_testbed.vcxproj", "{4250CE87-9AA0-43BB-AB47-0636548922B5}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_rlgl_compute", "examples\shaders_rlgl_compute.vcxproj", "{6B1A933E-71B8-4C1F-9E79-02D98830E671}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_rlgl_compute", "examples\shaders_rlgl_compute.vcxproj", "{AEA9D0D4-B810-4624-BC75-10A291584ED6}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_animation_bone_blending", "examples\models_animation_bone_blending.vcxproj", "{6B1A933E-71B8-4C1F-9E79-02D98830E671}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_animation_bone_blending", "examples\models_animation_bone_blending.vcxproj", "{AC751FE1-C986-4B6A-92A8-28ED89DEE671}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_animation_blending", "examples\models_animation_blending.vcxproj", "{6B1A933E-71B8-4C1F-9E79-02D98830E671}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_animation_blending", "examples\models_animation_blending.vcxproj", "{BB9C957D-34F1-46AE-B64A-9E0499C1746D}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_window_web", "examples\core_window_web.vcxproj", "{6B1A933E-71B8-4C1F-9E79-02D98830E671}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_window_web", "examples\core_window_web.vcxproj", "{4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -5347,102 +5347,102 @@ Global {4250CE87-9AA0-43BB-AB47-0636548922B5}.Release|x64.Build.0 = Release|x64 {4250CE87-9AA0-43BB-AB47-0636548922B5}.Release|x86.ActiveCfg = Release|Win32 {4250CE87-9AA0-43BB-AB47-0636548922B5}.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 - {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 - {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 - {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 + {AEA9D0D4-B810-4624-BC75-10A291584ED6}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {AEA9D0D4-B810-4624-BC75-10A291584ED6}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {AEA9D0D4-B810-4624-BC75-10A291584ED6}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {AEA9D0D4-B810-4624-BC75-10A291584ED6}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {AEA9D0D4-B810-4624-BC75-10A291584ED6}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {AEA9D0D4-B810-4624-BC75-10A291584ED6}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {AEA9D0D4-B810-4624-BC75-10A291584ED6}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {AEA9D0D4-B810-4624-BC75-10A291584ED6}.Debug|ARM64.Build.0 = Debug|ARM64 + {AEA9D0D4-B810-4624-BC75-10A291584ED6}.Debug|x64.ActiveCfg = Debug|x64 + {AEA9D0D4-B810-4624-BC75-10A291584ED6}.Debug|x64.Build.0 = Debug|x64 + {AEA9D0D4-B810-4624-BC75-10A291584ED6}.Debug|x86.ActiveCfg = Debug|Win32 + {AEA9D0D4-B810-4624-BC75-10A291584ED6}.Debug|x86.Build.0 = Debug|Win32 + {AEA9D0D4-B810-4624-BC75-10A291584ED6}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {AEA9D0D4-B810-4624-BC75-10A291584ED6}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {AEA9D0D4-B810-4624-BC75-10A291584ED6}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {AEA9D0D4-B810-4624-BC75-10A291584ED6}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {AEA9D0D4-B810-4624-BC75-10A291584ED6}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {AEA9D0D4-B810-4624-BC75-10A291584ED6}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {AEA9D0D4-B810-4624-BC75-10A291584ED6}.Release|ARM64.ActiveCfg = Release|ARM64 + {AEA9D0D4-B810-4624-BC75-10A291584ED6}.Release|ARM64.Build.0 = Release|ARM64 + {AEA9D0D4-B810-4624-BC75-10A291584ED6}.Release|x64.ActiveCfg = Release|x64 + {AEA9D0D4-B810-4624-BC75-10A291584ED6}.Release|x64.Build.0 = Release|x64 + {AEA9D0D4-B810-4624-BC75-10A291584ED6}.Release|x86.ActiveCfg = Release|Win32 + {AEA9D0D4-B810-4624-BC75-10A291584ED6}.Release|x86.Build.0 = Release|Win32 + {AC751FE1-C986-4B6A-92A8-28ED89DEE671}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {AC751FE1-C986-4B6A-92A8-28ED89DEE671}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {AC751FE1-C986-4B6A-92A8-28ED89DEE671}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {AC751FE1-C986-4B6A-92A8-28ED89DEE671}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {AC751FE1-C986-4B6A-92A8-28ED89DEE671}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {AC751FE1-C986-4B6A-92A8-28ED89DEE671}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {AC751FE1-C986-4B6A-92A8-28ED89DEE671}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {AC751FE1-C986-4B6A-92A8-28ED89DEE671}.Debug|ARM64.Build.0 = Debug|ARM64 + {AC751FE1-C986-4B6A-92A8-28ED89DEE671}.Debug|x64.ActiveCfg = Debug|x64 + {AC751FE1-C986-4B6A-92A8-28ED89DEE671}.Debug|x64.Build.0 = Debug|x64 + {AC751FE1-C986-4B6A-92A8-28ED89DEE671}.Debug|x86.ActiveCfg = Debug|Win32 + {AC751FE1-C986-4B6A-92A8-28ED89DEE671}.Debug|x86.Build.0 = Debug|Win32 + {AC751FE1-C986-4B6A-92A8-28ED89DEE671}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {AC751FE1-C986-4B6A-92A8-28ED89DEE671}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {AC751FE1-C986-4B6A-92A8-28ED89DEE671}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {AC751FE1-C986-4B6A-92A8-28ED89DEE671}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {AC751FE1-C986-4B6A-92A8-28ED89DEE671}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {AC751FE1-C986-4B6A-92A8-28ED89DEE671}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {AC751FE1-C986-4B6A-92A8-28ED89DEE671}.Release|ARM64.ActiveCfg = Release|ARM64 + {AC751FE1-C986-4B6A-92A8-28ED89DEE671}.Release|ARM64.Build.0 = Release|ARM64 + {AC751FE1-C986-4B6A-92A8-28ED89DEE671}.Release|x64.ActiveCfg = Release|x64 + {AC751FE1-C986-4B6A-92A8-28ED89DEE671}.Release|x64.Build.0 = Release|x64 + {AC751FE1-C986-4B6A-92A8-28ED89DEE671}.Release|x86.ActiveCfg = Release|Win32 + {AC751FE1-C986-4B6A-92A8-28ED89DEE671}.Release|x86.Build.0 = Release|Win32 + {BB9C957D-34F1-46AE-B64A-9E0499C1746D}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|x64 + {BB9C957D-34F1-46AE-B64A-9E0499C1746D}.Debug.DLL|ARM64.Build.0 = Debug.DLL|x64 + {BB9C957D-34F1-46AE-B64A-9E0499C1746D}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {BB9C957D-34F1-46AE-B64A-9E0499C1746D}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {BB9C957D-34F1-46AE-B64A-9E0499C1746D}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {BB9C957D-34F1-46AE-B64A-9E0499C1746D}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {BB9C957D-34F1-46AE-B64A-9E0499C1746D}.Debug|ARM64.ActiveCfg = Debug|x64 + {BB9C957D-34F1-46AE-B64A-9E0499C1746D}.Debug|ARM64.Build.0 = Debug|x64 + {BB9C957D-34F1-46AE-B64A-9E0499C1746D}.Debug|x64.ActiveCfg = Debug|x64 + {BB9C957D-34F1-46AE-B64A-9E0499C1746D}.Debug|x64.Build.0 = Debug|x64 + {BB9C957D-34F1-46AE-B64A-9E0499C1746D}.Debug|x86.ActiveCfg = Debug|Win32 + {BB9C957D-34F1-46AE-B64A-9E0499C1746D}.Debug|x86.Build.0 = Debug|Win32 + {BB9C957D-34F1-46AE-B64A-9E0499C1746D}.Release.DLL|ARM64.ActiveCfg = Release.DLL|x64 + {BB9C957D-34F1-46AE-B64A-9E0499C1746D}.Release.DLL|ARM64.Build.0 = Release.DLL|x64 + {BB9C957D-34F1-46AE-B64A-9E0499C1746D}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {BB9C957D-34F1-46AE-B64A-9E0499C1746D}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {BB9C957D-34F1-46AE-B64A-9E0499C1746D}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {BB9C957D-34F1-46AE-B64A-9E0499C1746D}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {BB9C957D-34F1-46AE-B64A-9E0499C1746D}.Release|ARM64.ActiveCfg = Release|x64 + {BB9C957D-34F1-46AE-B64A-9E0499C1746D}.Release|ARM64.Build.0 = Release|x64 + {BB9C957D-34F1-46AE-B64A-9E0499C1746D}.Release|x64.ActiveCfg = Release|x64 + {BB9C957D-34F1-46AE-B64A-9E0499C1746D}.Release|x64.Build.0 = Release|x64 + {BB9C957D-34F1-46AE-B64A-9E0499C1746D}.Release|x86.ActiveCfg = Release|Win32 + {BB9C957D-34F1-46AE-B64A-9E0499C1746D}.Release|x86.Build.0 = Release|Win32 + {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}.Debug|ARM64.Build.0 = Debug|ARM64 + {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}.Debug|x64.ActiveCfg = Debug|x64 + {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}.Debug|x64.Build.0 = Debug|x64 + {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}.Debug|x86.ActiveCfg = Debug|Win32 + {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}.Debug|x86.Build.0 = Debug|Win32 + {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}.Release|ARM64.ActiveCfg = Release|ARM64 + {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}.Release|ARM64.Build.0 = Release|ARM64 + {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}.Release|x64.ActiveCfg = Release|x64 + {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}.Release|x64.Build.0 = Release|x64 + {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}.Release|x86.ActiveCfg = Release|Win32 + {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -5605,7 +5605,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} = {278D8859-20B1-428F-8448-064F46E1F021} + {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} {6777EC3C-077C-42FC-B4AD-B799CE55CCE4} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} {A61DAD9C-271C-4E95-81AA-DB4CD58564D4} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} @@ -5658,10 +5658,10 @@ Global {D35D2FDA-B53F-4F70-81CA-24D95812B89C} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {F8DC77C0-556C-4672-B5B3-D2FA4ADC505C} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} {4250CE87-9AA0-43BB-AB47-0636548922B5} = {278D8859-20B1-428F-8448-064F46E1F021} - {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} - {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} - {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {AEA9D0D4-B810-4624-BC75-10A291584ED6} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {AC751FE1-C986-4B6A-92A8-28ED89DEE671} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {BB9C957D-34F1-46AE-B64A-9E0499C1746D} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} + {4E7157E0-6CDB-47AE-A19A-FEC3876FA8A3} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29} From 90dd9aef727ab1903a80e6c9783e0da2376bad0c Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 19 Feb 2026 17:40:22 +0100 Subject: [PATCH 216/232] REVIEWED: `GenImageFontAtlas()`, no need for the conservative approach flag --- src/rtext.c | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/src/rtext.c b/src/rtext.c index 0fd2d8e6b..e0aa4fddd 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -818,25 +818,11 @@ Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyp totalWidth += glyphs[i].image.width + 2*padding; } -//#define SUPPORT_FONT_ATLAS_SIZE_CONSERVATIVE -#if defined(SUPPORT_FONT_ATLAS_SIZE_CONSERVATIVE) - int rowCount = 0; - int imageSize = 64; // Define minimum starting value to avoid unnecessary calculation steps for very small images - - // NOTE: maxGlyphWidth is maximum possible space left at the end of row - while (totalWidth > (imageSize - maxGlyphWidth)*rowCount) - { - imageSize *= 2; // Double the size of image (to keep POT) - rowCount = imageSize/(fontSize + 2*padding); // Calculate new row count for the new image size - } - - atlas.width = imageSize; // Atlas bitmap width - atlas.height = imageSize; // Atlas bitmap height -#else int paddedFontSize = fontSize + 2*padding; - // No need for a so-conservative atlas generation - // NOTE: Multiplying total expected are by 1.2f scale factor + // Estimate image atlas size from available data + // NOTE: Multiplying total expected area by 1.2f scale factor but in case + // some glyphs do not fit, the atlas height is scaled x2 to fit them float totalArea = totalWidth*paddedFontSize*1.2f; float imageMinSize = sqrtf(totalArea); int imageSize = (int)powf(2, ceilf(logf(imageMinSize)/logf(2))); @@ -851,7 +837,6 @@ Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyp atlas.width = imageSize; // Atlas bitmap width atlas.height = imageSize; // Atlas bitmap height } -#endif int atlasDataSize = atlas.width*atlas.height; // Save total size for bounds checking atlas.data = (unsigned char *)RL_CALLOC(atlasDataSize, 1); // Create a bitmap to store characters (8 bpp) From 4a3c49cdcbf09857a675179e63f27e5a6ffe9b22 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 19 Feb 2026 17:55:13 +0100 Subject: [PATCH 217/232] REVIEWED: `rlLoadTextureDepth()`, address inconsistencies with WebGL 2.0 for sized depth formats #5500 --- src/rlgl.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/rlgl.h b/src/rlgl.h index d05bc42cb..3168b6a63 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -3432,6 +3432,13 @@ unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer) else glInternalFormat = GL_DEPTH_COMPONENT16; } #endif +#if defined(GRAPHICS_API_OPENGL_ES3) + // NOTE: This sized internal format should also work for WebGL 2.0 + // WARNING: Specification only allows GL_DEPTH_COMPONENT32F for GL_FLOAT type + // REF: https://registry.khronos.org/OpenGL-Refpages/es3.0/html/glTexImage2D.xhtml + if (RLGL.ExtSupported.maxDepthBits == 24) glInternalFormat = GL_DEPTH_COMPONENT24; + else glInternalFormat = GL_DEPTH_COMPONENT16; +#endif if (!useRenderBuffer && RLGL.ExtSupported.texDepth) { From ce617cd8146b85adce4c0527e150cc151457be99 Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 20 Feb 2026 11:46:46 +0100 Subject: [PATCH 218/232] Update rlgl.h --- src/rlgl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rlgl.h b/src/rlgl.h index 3168b6a63..0cde3e6eb 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -3422,7 +3422,7 @@ unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer) // Possible formats: GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT32 and GL_DEPTH_COMPONENT32F unsigned int glInternalFormat = GL_DEPTH_COMPONENT; -#if (defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_ES3)) +#if defined(GRAPHICS_API_OPENGL_ES2) // WARNING: WebGL platform requires unsized internal format definition (GL_DEPTH_COMPONENT) // while other platforms using OpenGL ES 2.0 require/support sized internal formats depending on the GPU capabilities if (!RLGL.ExtSupported.texDepthWebGL || useRenderBuffer) From 0aacd330d4f8dc3a86805362ac10b426e4c3ca8e Mon Sep 17 00:00:00 2001 From: David Reid Date: Fri, 20 Feb 2026 22:46:41 +1000 Subject: [PATCH 219/232] [raudio] Remove usage of `ma_data_converter_get_required_input_frame_count()` (#5568) * Audio: Remove use of ma_data_converter_get_required_input_frame_count(). This function is being removed from miniaudio. To make this work with the current architecture of raylib it requires the use of a cache. This commit implements a generic solution that works across all AudioBuffer types (static, streams and callback based), but the static case could be optimized to avoid the cache by incorporating the functionality of ReadAudioBufferFramesInInternalFormat() into ReadAudioBufferFramesInMixingFormat(). It would be unpractical to avoid the cache with streams and callback-based AudioBuffers however so this commit sticks with a generic solution. * Audio: Correct usage of miniaudio's dynamic rate adjustment. This affects pitch shifting. The output rate is being modified with ma_data_converter_set_rate(), but then that value is being used in the computation of the output rate the next time SetAudioBufferPitch() which results in a cascade. The correct way to do this is to use an anchored output rate as the basis for the calculation after pitch shifting. In this case, it's the device's sample rate that acts as the anchor. * Audio: Optimize memory usage for data conversion. This reduces the per-AudioBuffer conversion cache from 256 PCM frames down to 8. --- src/raudio.c | 96 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 76 insertions(+), 20 deletions(-) diff --git a/src/raudio.c b/src/raudio.c index 75547d285..8322f1baf 100644 --- a/src/raudio.c +++ b/src/raudio.c @@ -295,6 +295,10 @@ typedef struct tagBITMAPINFOHEADER { #define MAX_AUDIO_BUFFER_POOL_CHANNELS 16 // Audio pool channels #endif +#ifndef AUDIO_BUFFER_RESIDUAL_CAPACITY + #define AUDIO_BUFFER_RESIDUAL_CAPACITY 8 // In PCM frames. For resampling and pitch shifting. +#endif + //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- @@ -337,6 +341,8 @@ typedef enum { // Audio buffer struct struct rAudioBuffer { ma_data_converter converter; // Audio data converter + unsigned char* converterResidual; // Cached residual input frames for use by the converter + unsigned int converterResidualCount; // The number of valid frames sitting in converterResidual AudioCallback callback; // Audio buffer callback for buffer filling on audio threads rAudioProcessor *processor; // Audio processor @@ -586,6 +592,15 @@ AudioBuffer *LoadAudioBuffer(ma_format format, ma_uint32 channels, ma_uint32 sam return NULL; } + // A cache for use by the converter is necessary when resampling because + // when generating output frames a different number of input frames will + // be consumed. Any residual input frames need to be kept track of to + // ensure there are no discontinuities. Since raylib supports pitch + // shifting, which is done through resampling, a cache will always be + // required. This will be kept relatively small to avoid too much wastage. + audioBuffer->converterResidualCount = 0; + audioBuffer->converterResidual = (unsigned char*)RL_CALLOC(AUDIO_BUFFER_RESIDUAL_CAPACITY*ma_get_bytes_per_frame(format, channels), 1); + // Init audio buffer values audioBuffer->volume = 1.0f; audioBuffer->pitch = 1.0f; @@ -621,6 +636,7 @@ void UnloadAudioBuffer(AudioBuffer *buffer) { UntrackAudioBuffer(buffer); ma_data_converter_uninit(&buffer->converter, NULL); + RL_FREE(buffer->converterResidual); RL_FREE(buffer->data); RL_FREE(buffer); } @@ -705,7 +721,7 @@ void SetAudioBufferPitch(AudioBuffer *buffer, float pitch) // Note that this changes the duration of the sound: // - higher pitches will make the sound faster // - lower pitches make it slower - ma_uint32 outputSampleRate = (ma_uint32)((float)buffer->converter.sampleRateOut/pitch); + ma_uint32 outputSampleRate = (ma_uint32)((float)AUDIO.System.device.sampleRate/pitch); ma_data_converter_set_rate(&buffer->converter, buffer->converter.sampleRateIn, outputSampleRate); buffer->pitch = pitch; @@ -2456,38 +2472,78 @@ static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, f // NOTE: Continuously converting data from the AudioBuffer's internal format to the mixing format, // which should be defined by the output format of the data converter. // This is done until frameCount frames have been output. - // The important detail to remember is that more data than required should neeveer be read, - // for the specified number of output frames. - // This can be achieved with ma_data_converter_get_required_input_frame_count() + ma_uint32 bpf = ma_get_bytes_per_frame(audioBuffer->converter.formatIn, audioBuffer->converter.channelsIn); ma_uint8 inputBuffer[4096] = { 0 }; - ma_uint32 inputBufferFrameCap = sizeof(inputBuffer)/ma_get_bytes_per_frame(audioBuffer->converter.formatIn, audioBuffer->converter.channelsIn); - + ma_uint32 inputBufferFrameCap = sizeof(inputBuffer)/bpf; + ma_uint32 totalOutputFramesProcessed = 0; while (totalOutputFramesProcessed < frameCount) { + float *runningFramesOut = framesOut + (totalOutputFramesProcessed*audioBuffer->converter.channelsOut); ma_uint64 outputFramesToProcessThisIteration = frameCount - totalOutputFramesProcessed; ma_uint64 inputFramesToProcessThisIteration = 0; - - (void)ma_data_converter_get_required_input_frame_count(&audioBuffer->converter, outputFramesToProcessThisIteration, &inputFramesToProcessThisIteration); - if (inputFramesToProcessThisIteration > inputBufferFrameCap) + + // Process any residual input frames from the previous read first. + if (audioBuffer->converterResidualCount > 0) { - inputFramesToProcessThisIteration = inputBufferFrameCap; + ma_uint64 inputFramesProcessedThisIteration = audioBuffer->converterResidualCount; + ma_uint64 outputFramesProcessedThisIteration = outputFramesToProcessThisIteration; + ma_data_converter_process_pcm_frames(&audioBuffer->converter, audioBuffer->converterResidual, &inputFramesProcessedThisIteration, runningFramesOut, &outputFramesProcessedThisIteration); + + // Make sure the data in the cache is consumed. This can be optimized to use a cursor instead of a memmove(). + memmove(audioBuffer->converterResidual, audioBuffer->converterResidual + inputFramesProcessedThisIteration*bpf, (size_t)(AUDIO_BUFFER_RESIDUAL_CAPACITY - inputFramesProcessedThisIteration) * bpf); + audioBuffer->converterResidualCount -= (ma_uint32)inputFramesProcessedThisIteration; // Safe cast + + totalOutputFramesProcessed += (ma_uint32)outputFramesProcessedThisIteration; // Safe cast } + else + { + // Getting here means there are no residual frames from the previous read. Fresh data can now be + // pulled from the AudioBuffer and processed. + // + // A best guess needs to be used made to determine how many input frames to pull from the + // buffer. There are three possible outcomes: 1) exact; 2) underestimated; 3) overestimated. + // + // When the guess is exactly correct or underestimated there is nothing special to handle - it'll be + // handled naturally by the loop. + // + // When the guess is overestimated, that's when it gets more complicated. In this case, any overflow + // needs to be stored in a buffer for later processing by the next read. + ma_uint32 estimatedInputFrameCount = (ma_uint32)(((float)audioBuffer->converter.resampler.sampleRateIn / audioBuffer->converter.resampler.sampleRateOut) * outputFramesToProcessThisIteration); + if (estimatedInputFrameCount == 0) + { + estimatedInputFrameCount = 1; // Make sure at least one input frame is read. + } - float *runningFramesOut = framesOut + (totalOutputFramesProcessed*audioBuffer->converter.channelsOut); + if (estimatedInputFrameCount > inputBufferFrameCap) + { + estimatedInputFrameCount = inputBufferFrameCap; + } - // At this point we can convert the data to our mixing format - ma_uint64 inputFramesProcessedThisIteration = ReadAudioBufferFramesInInternalFormat(audioBuffer, inputBuffer, (ma_uint32)inputFramesToProcessThisIteration); - ma_uint64 outputFramesProcessedThisIteration = outputFramesToProcessThisIteration; - ma_data_converter_process_pcm_frames(&audioBuffer->converter, inputBuffer, &inputFramesProcessedThisIteration, runningFramesOut, &outputFramesProcessedThisIteration); + estimatedInputFrameCount = ReadAudioBufferFramesInInternalFormat(audioBuffer, inputBuffer, estimatedInputFrameCount); - totalOutputFramesProcessed += (ma_uint32)outputFramesProcessedThisIteration; // Safe cast + ma_uint64 inputFramesProcessedThisIteration = estimatedInputFrameCount; + ma_uint64 outputFramesProcessedThisIteration = outputFramesToProcessThisIteration; + ma_data_converter_process_pcm_frames(&audioBuffer->converter, inputBuffer, &inputFramesProcessedThisIteration, runningFramesOut, &outputFramesProcessedThisIteration); - if (inputFramesProcessedThisIteration < inputFramesToProcessThisIteration) break; // Ran out of input data + if (estimatedInputFrameCount > inputFramesProcessedThisIteration) + { + // Getting here means the estimated input frame count was overestimated. The residual needs + // be stored for later use. + ma_uint64 residualFrameCount = estimatedInputFrameCount - inputFramesProcessedThisIteration; - // This should never be hit, but added here for safety - // Ensures we get out of the loop when no input nor output frames are processed - if ((inputFramesProcessedThisIteration == 0) && (outputFramesProcessedThisIteration == 0)) break; + // A safety check to make sure the capacity of the residual cache is not exceeded. + if (residualFrameCount > AUDIO_BUFFER_RESIDUAL_CAPACITY) + { + residualFrameCount = AUDIO_BUFFER_RESIDUAL_CAPACITY; + } + + memcpy(audioBuffer->converterResidual, inputBuffer + inputFramesProcessedThisIteration*bpf, (size_t)(residualFrameCount * bpf)); + audioBuffer->converterResidualCount = residualFrameCount; + } + + totalOutputFramesProcessed += (ma_uint32)outputFramesProcessedThisIteration; + } } return totalOutputFramesProcessed; From f33823cefea894d633279823059234b82d9ba8ca Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 20 Feb 2026 15:55:38 +0100 Subject: [PATCH 220/232] Update textures_screen_buffer.c --- examples/textures/textures_screen_buffer.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/examples/textures/textures_screen_buffer.c b/examples/textures/textures_screen_buffer.c index 503b8d249..9f40f180b 100644 --- a/examples/textures/textures_screen_buffer.c +++ b/examples/textures/textures_screen_buffer.c @@ -66,11 +66,9 @@ int main(void) // Grow flameRoot for (int x = 2; x < flameWidth; x++) { - unsigned char flame = flameRootBuffer[x]; - if (flame == 255) continue; + int flame = (int)flameRootBuffer[x]; flame += GetRandomValue(0, 2); - if (flame > 255) flame = 255; - flameRootBuffer[x] = flame; + flameRootBuffer[x] = (flameInc > 255)? 255: (unsigned char)flame; } // Transfer flameRoot to indexBuffer From d996bf2bbd48ff21ccfbd68b87b06ca11eed29e0 Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 20 Feb 2026 16:06:59 +0100 Subject: [PATCH 221/232] Update textures_screen_buffer.c --- examples/textures/textures_screen_buffer.c | 35 ++++++++++++---------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/examples/textures/textures_screen_buffer.c b/examples/textures/textures_screen_buffer.c index 9f40f180b..9c0f25031 100644 --- a/examples/textures/textures_screen_buffer.c +++ b/examples/textures/textures_screen_buffer.c @@ -52,6 +52,7 @@ int main(void) float hue = t*t; float saturation = t; float value = t; + palette[i] = ColorFromHSV(250.0f + 150.0f*hue, saturation, value); } @@ -68,7 +69,7 @@ int main(void) { int flame = (int)flameRootBuffer[x]; flame += GetRandomValue(0, 2); - flameRootBuffer[x] = (flameInc > 255)? 255: (unsigned char)flame; + flameRootBuffer[x] = (flame > 255)? 255: (unsigned char)flame; } // Transfer flameRoot to indexBuffer @@ -81,8 +82,7 @@ int main(void) // Clear top row, because it can't move any higher for (int x = 0; x < imageWidth; x++) { - if (indexBuffer[x] == 0) continue; - indexBuffer[x] = 0; + if (indexBuffer[x] != 0) indexBuffer[x] = 0; } // Skip top row, it is already cleared @@ -92,18 +92,22 @@ int main(void) { unsigned int i = x + y*imageWidth; unsigned char colorIndex = indexBuffer[i]; - if (colorIndex == 0) continue; - - // Move pixel a row above - indexBuffer[i] = 0; - int moveX = GetRandomValue(0, 2) - 1; - int newX = x + moveX; - if (newX < 0 || newX >= imageWidth) continue; - - unsigned int iabove = i - imageWidth + moveX; - int decay = GetRandomValue(0, 3); - colorIndex -= (decay < colorIndex)? decay : colorIndex; - indexBuffer[iabove] = colorIndex; + + if (colorIndex != 0) + { + // Move pixel a row above + indexBuffer[i] = 0; + int moveX = GetRandomValue(0, 2) - 1; + int newX = x + moveX; + + if ((newX > 0) && (newX < imageWidth)) + { + unsigned int iabove = i - imageWidth + moveX; + int decay = GetRandomValue(0, 3); + colorIndex -= (decay < colorIndex)? decay : colorIndex; + indexBuffer[iabove] = colorIndex; + } + } } } @@ -115,6 +119,7 @@ int main(void) unsigned int i = x + y*imageWidth; unsigned char colorIndex = indexBuffer[i]; Color col = palette[colorIndex]; + ImageDrawPixel(&screenImage, x, y, col); } } From 2454b3ed4b6b49af46f89b3796ca94facd548ff0 Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 20 Feb 2026 16:27:08 +0100 Subject: [PATCH 222/232] REVIEWED: `TextReplace()` and `TextLength()`, avoid using `strcpy()` --- src/rtext.c | 58 ++++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/src/rtext.c b/src/rtext.c index e0aa4fddd..840b452d3 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -1497,15 +1497,14 @@ void UnloadTextLines(char **lines, int lineCount) } // Get text length in bytes, check for \0 character +// NOTE: Alternative: use strlen(text) unsigned int TextLength(const char *text) { unsigned int length = 0; if (text != NULL) - { - // NOTE: Alternative: use strlen(text) - - while (*text++) length++; + { + while (text[length] != '\0') length++; } return length; @@ -1718,7 +1717,7 @@ char *TextReplace(const char *text, const char *search, const char *replacement) { char *result = NULL; - if ((text != NULL) && (search != NULL)) + if ((text != NULL) && (search != NULL) && (search[0] != '\0')) { if (replacement == NULL) replacement = ""; @@ -1732,8 +1731,6 @@ char *TextReplace(const char *text, const char *search, const char *replacement) textLen = TextLength(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 @@ -1742,34 +1739,37 @@ char *TextReplace(const char *text, const char *search, const char *replacement) // Allocate returning string and point temp to it int tempLen = textLen + (replaceLen - searchLen)*count + 1; - temp = result = (char *)RL_MALLOC(tempLen); + temp = result = (char *)RL_CALLOC(tempLen, sizeof(char)); - 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 (result != NULL) // Memory was allocated { - insertPoint = (char *)strstr(text, search); - lastReplacePos = (int)(insertPoint - text); - - memcpy(temp, text, lastReplacePos); - temp += lastReplacePos; - - if (replaceLen > 0) + // 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 > 0) { - memcpy(temp, replacement, replaceLen); - temp += replaceLen; + insertPoint = (char *)strstr(text, search); + lastReplacePos = (int)(insertPoint - text); + + memcpy(temp, text, lastReplacePos); + temp += lastReplacePos; + + if (replaceLen > 0) + { + memcpy(temp, replacement, replaceLen); + temp += replaceLen; + } + + text += (lastReplacePos + searchLen); // Move to next "end of replace" + + count--; } - text += lastReplacePos + searchLen; // Move to next "end of replace" + // Copy remaind text part after replacement to result (pointed by moving temp) + // NOTE: Text pointer internal copy has been updated along the process + strncpy(temp, text, TextLength(text)); } - - // Copy remaind text part after replacement to result (pointed by moving temp) - strcpy(temp, text); // OK - //strncpy(temp, text, tempLen - 1); // WRONG } return result; From d03a59ca3e8d59d607b9734dc420cc1c4411ec55 Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 20 Feb 2026 16:36:13 +0100 Subject: [PATCH 223/232] Update core_directory_files.c --- examples/core/core_directory_files.c | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/examples/core/core_directory_files.c b/examples/core/core_directory_files.c index f879b933e..b0a204d37 100644 --- a/examples/core/core_directory_files.c +++ b/examples/core/core_directory_files.c @@ -81,27 +81,6 @@ int main(void) GuiListViewEx((Rectangle){ 0, 50, GetScreenWidth(), GetScreenHeight() - 50 }, files.paths, files.count, &listScrollIndex, &listItemActive, &listItemFocused); - /* - for (int i = 0; i < (int)files.count; i++) - { - Color color = Fade(LIGHTGRAY, 0.3f); - - if (!IsPathFile(files.paths[i]) && DirectoryExists(files.paths[i])) - { - if (GuiButton((Rectangle){0.0f, 85.0f + 40.0f*(float)i, screenWidth, 40}, "")) - { - TextCopy(directory, files.paths[i]); - UnloadDirectoryFiles(files); - files = LoadDirectoryFiles(directory); - continue; - } - } - - DrawRectangle(0, 85 + 40*i, screenWidth, 40, color); - DrawText(GetFileName(files.paths[i]), 120, 100 + 40*i, 10, GRAY); - } - */ - EndDrawing(); //---------------------------------------------------------------------------------- } From 19e6352d37ead88a1a22d3a6462f31aad0ce95f8 Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 20 Feb 2026 18:16:49 +0100 Subject: [PATCH 224/232] Update shapes_easings_testbed.c --- examples/shapes/shapes_easings_testbed.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/shapes/shapes_easings_testbed.c b/examples/shapes/shapes_easings_testbed.c index ce9b7d485..1c9fcf741 100644 --- a/examples/shapes/shapes_easings_testbed.c +++ b/examples/shapes/shapes_easings_testbed.c @@ -17,7 +17,7 @@ #include "raylib.h" -#include "reasings.h" // Required for easing functions +#include "reasings.h" // Required for: easing functions #define FONT_SIZE 20 From d148d9515ba913a16a79c214b762b833e4c2f352 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Fri, 20 Feb 2026 17:44:34 +0000 Subject: [PATCH 225/232] Fix text input on SDL3 (#5574) --- src/platforms/rcore_desktop_sdl.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index ca49e6a8e..371d907f7 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -2016,6 +2016,22 @@ int InitPlatform(void) // Init window #if defined(USING_VERSION_SDL3) platform.window = SDL_CreateWindow(CORE.Window.title, CORE.Window.screen.width, CORE.Window.screen.height, flags); + + // NOTE: SDL3 no longer enables TextInput by default, so this is needed to preserve the behaviour and keep GetCharPressed working. + // This code is derived from SDL before the change was made: https://github.com/libsdl-org/SDL/commit/72fc6f86e5d605a3787222bc7dc18c5379047f4a. + const char *enableOSK = SDL_GetHint(SDL_HINT_ENABLE_SCREEN_KEYBOARD); + if (enableOSK == NULL) + { + SDL_SetHint(SDL_HINT_ENABLE_SCREEN_KEYBOARD, "0"); + } + if (!SDL_StartTextInput(platform.window)) + { + TRACELOG(LOG_WARNING, "SDL: Failed to start text input: %s", SDL_GetError()); + } + if (enableOSK == NULL) + { + SDL_SetHint(SDL_HINT_ENABLE_SCREEN_KEYBOARD, NULL); + } #else platform.window = SDL_CreateWindow(CORE.Window.title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, CORE.Window.screen.width, CORE.Window.screen.height, flags); #endif From 0343cb6a3762fba8d3f5870321a8490fb9f39b1b Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 20 Feb 2026 18:47:53 +0100 Subject: [PATCH 226/232] Update rcore_desktop_sdl.c --- src/platforms/rcore_desktop_sdl.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index 371d907f7..789457d2f 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -2017,21 +2017,14 @@ int InitPlatform(void) #if defined(USING_VERSION_SDL3) platform.window = SDL_CreateWindow(CORE.Window.title, CORE.Window.screen.width, CORE.Window.screen.height, flags); - // NOTE: SDL3 no longer enables TextInput by default, so this is needed to preserve the behaviour and keep GetCharPressed working. - // This code is derived from SDL before the change was made: https://github.com/libsdl-org/SDL/commit/72fc6f86e5d605a3787222bc7dc18c5379047f4a. + + // NOTE: SDL3 no longer enables text input by default, + // it is needed to be enabled manually to keep GetCharPressed() working + // REF: https://github.com/libsdl-org/SDL/commit/72fc6f86e5d605a3787222bc7dc18c5379047f4a const char *enableOSK = SDL_GetHint(SDL_HINT_ENABLE_SCREEN_KEYBOARD); - if (enableOSK == NULL) - { - SDL_SetHint(SDL_HINT_ENABLE_SCREEN_KEYBOARD, "0"); - } - if (!SDL_StartTextInput(platform.window)) - { - TRACELOG(LOG_WARNING, "SDL: Failed to start text input: %s", SDL_GetError()); - } - if (enableOSK == NULL) - { - SDL_SetHint(SDL_HINT_ENABLE_SCREEN_KEYBOARD, NULL); - } + if (enableOSK == NULL) SDL_SetHint(SDL_HINT_ENABLE_SCREEN_KEYBOARD, "0"); + if (!SDL_StartTextInput(platform.window)) TRACELOG(LOG_WARNING, "SDL: Failed to start text input: %s", SDL_GetError()); + if (enableOSK == NULL) SDL_SetHint(SDL_HINT_ENABLE_SCREEN_KEYBOARD, NULL); #else platform.window = SDL_CreateWindow(CORE.Window.title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, CORE.Window.screen.width, CORE.Window.screen.height, flags); #endif From 29b9c050c78b14afaddf0087d8f70f3f6d7c80f1 Mon Sep 17 00:00:00 2001 From: Thomas Anderson <5776225+CrackedPixel@users.noreply.github.com> Date: Fri, 20 Feb 2026 13:18:28 -0600 Subject: [PATCH 227/232] fix example (#5575) --- examples/core/core_directory_files.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/core/core_directory_files.c b/examples/core/core_directory_files.c index b0a204d37..922d47d5b 100644 --- a/examples/core/core_directory_files.c +++ b/examples/core/core_directory_files.c @@ -79,7 +79,7 @@ int main(void) GuiSetStyle(LISTVIEW, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); GuiSetStyle(LISTVIEW, TEXT_PADDING, 40); GuiListViewEx((Rectangle){ 0, 50, GetScreenWidth(), GetScreenHeight() - 50 }, - files.paths, files.count, &listScrollIndex, &listItemActive, &listItemFocused); + (const char**)files.paths, files.count, &listScrollIndex, &listItemActive, &listItemFocused); EndDrawing(); //---------------------------------------------------------------------------------- From 09f22f3c86d7be5e1d4743768a087703d1822d71 Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 20 Feb 2026 23:02:43 +0100 Subject: [PATCH 228/232] REVIEWED: Avoid `const char **` usage (aligned with raylib) --- examples/core/core_directory_files.c | 2 +- examples/core/raygui.h | 38 ++++++++++++++-------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/examples/core/core_directory_files.c b/examples/core/core_directory_files.c index 922d47d5b..b0a204d37 100644 --- a/examples/core/core_directory_files.c +++ b/examples/core/core_directory_files.c @@ -79,7 +79,7 @@ int main(void) GuiSetStyle(LISTVIEW, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); GuiSetStyle(LISTVIEW, TEXT_PADDING, 40); GuiListViewEx((Rectangle){ 0, 50, GetScreenWidth(), GetScreenHeight() - 50 }, - (const char**)files.paths, files.count, &listScrollIndex, &listItemActive, &listItemFocused); + files.paths, files.count, &listScrollIndex, &listItemActive, &listItemFocused); EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/examples/core/raygui.h b/examples/core/raygui.h index 67c16be45..83102e749 100644 --- a/examples/core/raygui.h +++ b/examples/core/raygui.h @@ -772,7 +772,7 @@ RAYGUIAPI int GuiWindowBox(Rectangle bounds, const char *title); RAYGUIAPI int GuiGroupBox(Rectangle bounds, const char *text); // Group Box control with text name RAYGUIAPI int GuiLine(Rectangle bounds, const char *text); // Line separator control, could contain text RAYGUIAPI int GuiPanel(Rectangle bounds, const char *text); // Panel control, useful to group controls -RAYGUIAPI int GuiTabBar(Rectangle bounds, const char **text, int count, int *active); // Tab Bar control, returns TAB to be closed or -1 +RAYGUIAPI int GuiTabBar(Rectangle bounds, char **text, int count, int *active); // Tab Bar control, returns TAB to be closed or -1 RAYGUIAPI int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector2 *scroll, Rectangle *view); // Scroll Panel control // Basic controls set @@ -800,7 +800,7 @@ RAYGUIAPI int GuiGrid(Rectangle bounds, const char *text, float spacing, int sub // Advance controls set RAYGUIAPI int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *active); // List View control -RAYGUIAPI int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus); // List View with extended parameters +RAYGUIAPI int GuiListViewEx(Rectangle bounds, char **text, int count, int *scrollIndex, int *active, int *focus); // List View with extended parameters RAYGUIAPI int GuiMessageBox(Rectangle bounds, const char *title, const char *message, const char *buttons); // Message Box control, displays a message RAYGUIAPI int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, const char *buttons, char *text, int textMaxSize, bool *secretViewActive); // Text Input Box control, ask for text, supports secret RAYGUIAPI int GuiColorPicker(Rectangle bounds, const char *text, Color *color); // Color Picker control (multiple color controls) @@ -1526,7 +1526,7 @@ static Color GetColor(int hexValue); // Returns a Color struct fr static int ColorToInt(Color color); // Returns hexadecimal value for a Color static bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle static const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed' -static const char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings +static char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings static int TextToInteger(const char *text); // Get integer value from text static float TextToFloat(const char *text); // Get float value from text @@ -1549,7 +1549,7 @@ static const char *GetTextIcon(const char *text, int *iconId); // Get text icon static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, Color tint); // Gui draw text using default font static void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor, Color color); // Gui draw rectangle using default raygui style -static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow); // Split controls text into multiple strings +static char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow); // Split controls text into multiple strings static Vector3 ConvertHSVtoRGB(Vector3 hsv); // Convert color data from HSV to RGB static Vector3 ConvertRGBtoHSV(Vector3 rgb); // Convert color data from RGB to HSV @@ -1783,7 +1783,7 @@ int GuiPanel(Rectangle bounds, const char *text) // Tab Bar control // NOTE: Using GuiToggle() for the TABS -int GuiTabBar(Rectangle bounds, const char **text, int count, int *active) +int GuiTabBar(Rectangle bounds, char **text, int count, int *active) { #define RAYGUI_TABBAR_ITEM_WIDTH 148 @@ -2168,7 +2168,7 @@ int GuiToggleGroup(Rectangle bounds, const char *text, int *active) // Get substrings items from text (items pointers) int rows[RAYGUI_TOGGLEGROUP_MAX_ITEMS] = { 0 }; int itemCount = 0; - const char **items = GuiTextSplit(text, ';', &itemCount, rows); + char **items = GuiTextSplit(text, ';', &itemCount, rows); int prevRow = rows[0]; @@ -2212,7 +2212,7 @@ int GuiToggleSlider(Rectangle bounds, const char *text, int *active) // Get substrings items from text (items pointers) int itemCount = 0; - const char **items = NULL; + char **items = NULL; if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL); @@ -2356,7 +2356,7 @@ int GuiComboBox(Rectangle bounds, const char *text, int *active) // Get substrings items from text (items pointers, lengths and count) int itemCount = 0; - const char **items = GuiTextSplit(text, ';', &itemCount, NULL); + char **items = GuiTextSplit(text, ';', &itemCount, NULL); if (*active < 0) *active = 0; else if (*active > (itemCount - 1)) *active = itemCount - 1; @@ -2422,7 +2422,7 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod // Get substrings items from text (items pointers, lengths and count) int itemCount = 0; - const char **items = GuiTextSplit(text, ';', &itemCount, NULL); + char **items = GuiTextSplit(text, ';', &itemCount, NULL); Rectangle boundsOpen = bounds; boundsOpen.height = (itemCount + 1)*(bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING)); @@ -3602,7 +3602,7 @@ int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *activ { int result = 0; int itemCount = 0; - const char **items = NULL; + char **items = NULL; if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL); @@ -3612,7 +3612,7 @@ int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *activ } // List View control with extended parameters -int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus) +int GuiListViewEx(Rectangle bounds, char **text, int count, int *scrollIndex, int *active, int *focus) { int result = 0; GuiState state = guiState; @@ -4140,7 +4140,7 @@ int GuiMessageBox(Rectangle bounds, const char *title, const char *message, cons int result = -1; // Returns clicked button from buttons list, 0 refers to closed window button int buttonCount = 0; - const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL); + char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL); Rectangle buttonBounds = { 0 }; buttonBounds.x = bounds.x + RAYGUI_MESSAGEBOX_BUTTON_PADDING; buttonBounds.y = bounds.y + bounds.height - RAYGUI_MESSAGEBOX_BUTTON_HEIGHT - RAYGUI_MESSAGEBOX_BUTTON_PADDING; @@ -4199,7 +4199,7 @@ int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, co int result = -1; int buttonCount = 0; - const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL); + char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL); Rectangle buttonBounds = { 0 }; buttonBounds.x = bounds.x + RAYGUI_TEXTINPUTBOX_BUTTON_PADDING; buttonBounds.y = bounds.y + bounds.height - RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT - RAYGUI_TEXTINPUTBOX_BUTTON_PADDING; @@ -5119,11 +5119,11 @@ static const char *GetTextIcon(const char *text, int *iconId) // Get text divided into lines (by line-breaks '\n') // WARNING: It returns pointers to new lines but it does not add NULL ('\0') terminator! -static const char **GetTextLines(const char *text, int *count) +static char **GetTextLines(const char *text, int *count) { #define RAYGUI_MAX_TEXT_LINES 128 - static const char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 }; + static char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 }; for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings int textLength = (int)strlen(text); @@ -5194,7 +5194,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C // WARNING: GuiTextSplit() function can't be used now because it can have already been used // before the GuiDrawText() call and its buffer is static, it would be overriden :( int lineCount = 0; - const char **lines = GetTextLines(text, &lineCount); + char **lines = GetTextLines(text, &lineCount); // Text style variables //int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT); @@ -5444,7 +5444,7 @@ static void GuiTooltip(Rectangle controlRec) // Split controls text into multiple strings // Also check for multiple columns (required by GuiToggleGroup()) -static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow) +static char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow) { // NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter) // inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated, @@ -5463,7 +5463,7 @@ static const char **GuiTextSplit(const char *text, char delimiter, int *count, i #define RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE 1024 #endif - static const char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data) + static char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data) static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; // Buffer data (text input copy with '\0' added) memset(buffer, 0, RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE); @@ -5863,7 +5863,7 @@ static void DrawRectangleGradientV(int posX, int posY, int width, int height, Co } // Split string into multiple strings -const char **TextSplit(const char *text, char delimiter, int *count) +char **TextSplit(const char *text, char delimiter, int *count) { // NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter) // inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated, From c519e9f566225ee8a0fd4a1cd7c58497c31ab11b Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 20 Feb 2026 23:56:11 +0100 Subject: [PATCH 229/232] REVIEWED: Simplified `char **` approach --- examples/core/raygui.h | 11 +++++---- examples/models/raygui.h | 47 +++++++++++++++++++-------------------- examples/shaders/raygui.h | 47 +++++++++++++++++++-------------------- examples/shapes/raygui.h | 47 +++++++++++++++++++-------------------- 4 files changed, 74 insertions(+), 78 deletions(-) diff --git a/examples/core/raygui.h b/examples/core/raygui.h index 83102e749..42c5ae7bc 100644 --- a/examples/core/raygui.h +++ b/examples/core/raygui.h @@ -5131,12 +5131,11 @@ static char **GetTextLines(const char *text, int *count) lines[0] = text; *count = 1; - for (int i = 0, k = 0; (i < textLength) && (*count < RAYGUI_MAX_TEXT_LINES); i++) + for (int i = 0; (i < textLength) && (*count < RAYGUI_MAX_TEXT_LINES); i++) { - if (text[i] == '\n') + if ((text[i] == '\n') && ((i + 1) < textLength)) { - k++; - lines[k] = &text[i + 1]; // WARNING: next value is valid? + lines[*count] = &text[i + 1]; *count += 1; } } @@ -5463,8 +5462,8 @@ static char **GuiTextSplit(const char *text, char delimiter, int *count, int *te #define RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE 1024 #endif - static char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data) - static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; // Buffer data (text input copy with '\0' added) + static char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data) + static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; // Buffer data (text input copy with '\0' added) memset(buffer, 0, RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE); result[0] = buffer; diff --git a/examples/models/raygui.h b/examples/models/raygui.h index 67c16be45..42c5ae7bc 100644 --- a/examples/models/raygui.h +++ b/examples/models/raygui.h @@ -772,7 +772,7 @@ RAYGUIAPI int GuiWindowBox(Rectangle bounds, const char *title); RAYGUIAPI int GuiGroupBox(Rectangle bounds, const char *text); // Group Box control with text name RAYGUIAPI int GuiLine(Rectangle bounds, const char *text); // Line separator control, could contain text RAYGUIAPI int GuiPanel(Rectangle bounds, const char *text); // Panel control, useful to group controls -RAYGUIAPI int GuiTabBar(Rectangle bounds, const char **text, int count, int *active); // Tab Bar control, returns TAB to be closed or -1 +RAYGUIAPI int GuiTabBar(Rectangle bounds, char **text, int count, int *active); // Tab Bar control, returns TAB to be closed or -1 RAYGUIAPI int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector2 *scroll, Rectangle *view); // Scroll Panel control // Basic controls set @@ -800,7 +800,7 @@ RAYGUIAPI int GuiGrid(Rectangle bounds, const char *text, float spacing, int sub // Advance controls set RAYGUIAPI int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *active); // List View control -RAYGUIAPI int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus); // List View with extended parameters +RAYGUIAPI int GuiListViewEx(Rectangle bounds, char **text, int count, int *scrollIndex, int *active, int *focus); // List View with extended parameters RAYGUIAPI int GuiMessageBox(Rectangle bounds, const char *title, const char *message, const char *buttons); // Message Box control, displays a message RAYGUIAPI int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, const char *buttons, char *text, int textMaxSize, bool *secretViewActive); // Text Input Box control, ask for text, supports secret RAYGUIAPI int GuiColorPicker(Rectangle bounds, const char *text, Color *color); // Color Picker control (multiple color controls) @@ -1526,7 +1526,7 @@ static Color GetColor(int hexValue); // Returns a Color struct fr static int ColorToInt(Color color); // Returns hexadecimal value for a Color static bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle static const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed' -static const char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings +static char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings static int TextToInteger(const char *text); // Get integer value from text static float TextToFloat(const char *text); // Get float value from text @@ -1549,7 +1549,7 @@ static const char *GetTextIcon(const char *text, int *iconId); // Get text icon static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, Color tint); // Gui draw text using default font static void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor, Color color); // Gui draw rectangle using default raygui style -static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow); // Split controls text into multiple strings +static char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow); // Split controls text into multiple strings static Vector3 ConvertHSVtoRGB(Vector3 hsv); // Convert color data from HSV to RGB static Vector3 ConvertRGBtoHSV(Vector3 rgb); // Convert color data from RGB to HSV @@ -1783,7 +1783,7 @@ int GuiPanel(Rectangle bounds, const char *text) // Tab Bar control // NOTE: Using GuiToggle() for the TABS -int GuiTabBar(Rectangle bounds, const char **text, int count, int *active) +int GuiTabBar(Rectangle bounds, char **text, int count, int *active) { #define RAYGUI_TABBAR_ITEM_WIDTH 148 @@ -2168,7 +2168,7 @@ int GuiToggleGroup(Rectangle bounds, const char *text, int *active) // Get substrings items from text (items pointers) int rows[RAYGUI_TOGGLEGROUP_MAX_ITEMS] = { 0 }; int itemCount = 0; - const char **items = GuiTextSplit(text, ';', &itemCount, rows); + char **items = GuiTextSplit(text, ';', &itemCount, rows); int prevRow = rows[0]; @@ -2212,7 +2212,7 @@ int GuiToggleSlider(Rectangle bounds, const char *text, int *active) // Get substrings items from text (items pointers) int itemCount = 0; - const char **items = NULL; + char **items = NULL; if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL); @@ -2356,7 +2356,7 @@ int GuiComboBox(Rectangle bounds, const char *text, int *active) // Get substrings items from text (items pointers, lengths and count) int itemCount = 0; - const char **items = GuiTextSplit(text, ';', &itemCount, NULL); + char **items = GuiTextSplit(text, ';', &itemCount, NULL); if (*active < 0) *active = 0; else if (*active > (itemCount - 1)) *active = itemCount - 1; @@ -2422,7 +2422,7 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod // Get substrings items from text (items pointers, lengths and count) int itemCount = 0; - const char **items = GuiTextSplit(text, ';', &itemCount, NULL); + char **items = GuiTextSplit(text, ';', &itemCount, NULL); Rectangle boundsOpen = bounds; boundsOpen.height = (itemCount + 1)*(bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING)); @@ -3602,7 +3602,7 @@ int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *activ { int result = 0; int itemCount = 0; - const char **items = NULL; + char **items = NULL; if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL); @@ -3612,7 +3612,7 @@ int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *activ } // List View control with extended parameters -int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus) +int GuiListViewEx(Rectangle bounds, char **text, int count, int *scrollIndex, int *active, int *focus) { int result = 0; GuiState state = guiState; @@ -4140,7 +4140,7 @@ int GuiMessageBox(Rectangle bounds, const char *title, const char *message, cons int result = -1; // Returns clicked button from buttons list, 0 refers to closed window button int buttonCount = 0; - const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL); + char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL); Rectangle buttonBounds = { 0 }; buttonBounds.x = bounds.x + RAYGUI_MESSAGEBOX_BUTTON_PADDING; buttonBounds.y = bounds.y + bounds.height - RAYGUI_MESSAGEBOX_BUTTON_HEIGHT - RAYGUI_MESSAGEBOX_BUTTON_PADDING; @@ -4199,7 +4199,7 @@ int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, co int result = -1; int buttonCount = 0; - const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL); + char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL); Rectangle buttonBounds = { 0 }; buttonBounds.x = bounds.x + RAYGUI_TEXTINPUTBOX_BUTTON_PADDING; buttonBounds.y = bounds.y + bounds.height - RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT - RAYGUI_TEXTINPUTBOX_BUTTON_PADDING; @@ -5119,11 +5119,11 @@ static const char *GetTextIcon(const char *text, int *iconId) // Get text divided into lines (by line-breaks '\n') // WARNING: It returns pointers to new lines but it does not add NULL ('\0') terminator! -static const char **GetTextLines(const char *text, int *count) +static char **GetTextLines(const char *text, int *count) { #define RAYGUI_MAX_TEXT_LINES 128 - static const char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 }; + static char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 }; for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings int textLength = (int)strlen(text); @@ -5131,12 +5131,11 @@ static const char **GetTextLines(const char *text, int *count) lines[0] = text; *count = 1; - for (int i = 0, k = 0; (i < textLength) && (*count < RAYGUI_MAX_TEXT_LINES); i++) + for (int i = 0; (i < textLength) && (*count < RAYGUI_MAX_TEXT_LINES); i++) { - if (text[i] == '\n') + if ((text[i] == '\n') && ((i + 1) < textLength)) { - k++; - lines[k] = &text[i + 1]; // WARNING: next value is valid? + lines[*count] = &text[i + 1]; *count += 1; } } @@ -5194,7 +5193,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C // WARNING: GuiTextSplit() function can't be used now because it can have already been used // before the GuiDrawText() call and its buffer is static, it would be overriden :( int lineCount = 0; - const char **lines = GetTextLines(text, &lineCount); + char **lines = GetTextLines(text, &lineCount); // Text style variables //int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT); @@ -5444,7 +5443,7 @@ static void GuiTooltip(Rectangle controlRec) // Split controls text into multiple strings // Also check for multiple columns (required by GuiToggleGroup()) -static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow) +static char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow) { // NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter) // inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated, @@ -5463,8 +5462,8 @@ static const char **GuiTextSplit(const char *text, char delimiter, int *count, i #define RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE 1024 #endif - static const char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data) - static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; // Buffer data (text input copy with '\0' added) + static char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data) + static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; // Buffer data (text input copy with '\0' added) memset(buffer, 0, RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE); result[0] = buffer; @@ -5863,7 +5862,7 @@ static void DrawRectangleGradientV(int posX, int posY, int width, int height, Co } // Split string into multiple strings -const char **TextSplit(const char *text, char delimiter, int *count) +char **TextSplit(const char *text, char delimiter, int *count) { // NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter) // inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated, diff --git a/examples/shaders/raygui.h b/examples/shaders/raygui.h index 67c16be45..42c5ae7bc 100644 --- a/examples/shaders/raygui.h +++ b/examples/shaders/raygui.h @@ -772,7 +772,7 @@ RAYGUIAPI int GuiWindowBox(Rectangle bounds, const char *title); RAYGUIAPI int GuiGroupBox(Rectangle bounds, const char *text); // Group Box control with text name RAYGUIAPI int GuiLine(Rectangle bounds, const char *text); // Line separator control, could contain text RAYGUIAPI int GuiPanel(Rectangle bounds, const char *text); // Panel control, useful to group controls -RAYGUIAPI int GuiTabBar(Rectangle bounds, const char **text, int count, int *active); // Tab Bar control, returns TAB to be closed or -1 +RAYGUIAPI int GuiTabBar(Rectangle bounds, char **text, int count, int *active); // Tab Bar control, returns TAB to be closed or -1 RAYGUIAPI int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector2 *scroll, Rectangle *view); // Scroll Panel control // Basic controls set @@ -800,7 +800,7 @@ RAYGUIAPI int GuiGrid(Rectangle bounds, const char *text, float spacing, int sub // Advance controls set RAYGUIAPI int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *active); // List View control -RAYGUIAPI int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus); // List View with extended parameters +RAYGUIAPI int GuiListViewEx(Rectangle bounds, char **text, int count, int *scrollIndex, int *active, int *focus); // List View with extended parameters RAYGUIAPI int GuiMessageBox(Rectangle bounds, const char *title, const char *message, const char *buttons); // Message Box control, displays a message RAYGUIAPI int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, const char *buttons, char *text, int textMaxSize, bool *secretViewActive); // Text Input Box control, ask for text, supports secret RAYGUIAPI int GuiColorPicker(Rectangle bounds, const char *text, Color *color); // Color Picker control (multiple color controls) @@ -1526,7 +1526,7 @@ static Color GetColor(int hexValue); // Returns a Color struct fr static int ColorToInt(Color color); // Returns hexadecimal value for a Color static bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle static const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed' -static const char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings +static char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings static int TextToInteger(const char *text); // Get integer value from text static float TextToFloat(const char *text); // Get float value from text @@ -1549,7 +1549,7 @@ static const char *GetTextIcon(const char *text, int *iconId); // Get text icon static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, Color tint); // Gui draw text using default font static void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor, Color color); // Gui draw rectangle using default raygui style -static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow); // Split controls text into multiple strings +static char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow); // Split controls text into multiple strings static Vector3 ConvertHSVtoRGB(Vector3 hsv); // Convert color data from HSV to RGB static Vector3 ConvertRGBtoHSV(Vector3 rgb); // Convert color data from RGB to HSV @@ -1783,7 +1783,7 @@ int GuiPanel(Rectangle bounds, const char *text) // Tab Bar control // NOTE: Using GuiToggle() for the TABS -int GuiTabBar(Rectangle bounds, const char **text, int count, int *active) +int GuiTabBar(Rectangle bounds, char **text, int count, int *active) { #define RAYGUI_TABBAR_ITEM_WIDTH 148 @@ -2168,7 +2168,7 @@ int GuiToggleGroup(Rectangle bounds, const char *text, int *active) // Get substrings items from text (items pointers) int rows[RAYGUI_TOGGLEGROUP_MAX_ITEMS] = { 0 }; int itemCount = 0; - const char **items = GuiTextSplit(text, ';', &itemCount, rows); + char **items = GuiTextSplit(text, ';', &itemCount, rows); int prevRow = rows[0]; @@ -2212,7 +2212,7 @@ int GuiToggleSlider(Rectangle bounds, const char *text, int *active) // Get substrings items from text (items pointers) int itemCount = 0; - const char **items = NULL; + char **items = NULL; if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL); @@ -2356,7 +2356,7 @@ int GuiComboBox(Rectangle bounds, const char *text, int *active) // Get substrings items from text (items pointers, lengths and count) int itemCount = 0; - const char **items = GuiTextSplit(text, ';', &itemCount, NULL); + char **items = GuiTextSplit(text, ';', &itemCount, NULL); if (*active < 0) *active = 0; else if (*active > (itemCount - 1)) *active = itemCount - 1; @@ -2422,7 +2422,7 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod // Get substrings items from text (items pointers, lengths and count) int itemCount = 0; - const char **items = GuiTextSplit(text, ';', &itemCount, NULL); + char **items = GuiTextSplit(text, ';', &itemCount, NULL); Rectangle boundsOpen = bounds; boundsOpen.height = (itemCount + 1)*(bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING)); @@ -3602,7 +3602,7 @@ int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *activ { int result = 0; int itemCount = 0; - const char **items = NULL; + char **items = NULL; if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL); @@ -3612,7 +3612,7 @@ int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *activ } // List View control with extended parameters -int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus) +int GuiListViewEx(Rectangle bounds, char **text, int count, int *scrollIndex, int *active, int *focus) { int result = 0; GuiState state = guiState; @@ -4140,7 +4140,7 @@ int GuiMessageBox(Rectangle bounds, const char *title, const char *message, cons int result = -1; // Returns clicked button from buttons list, 0 refers to closed window button int buttonCount = 0; - const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL); + char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL); Rectangle buttonBounds = { 0 }; buttonBounds.x = bounds.x + RAYGUI_MESSAGEBOX_BUTTON_PADDING; buttonBounds.y = bounds.y + bounds.height - RAYGUI_MESSAGEBOX_BUTTON_HEIGHT - RAYGUI_MESSAGEBOX_BUTTON_PADDING; @@ -4199,7 +4199,7 @@ int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, co int result = -1; int buttonCount = 0; - const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL); + char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL); Rectangle buttonBounds = { 0 }; buttonBounds.x = bounds.x + RAYGUI_TEXTINPUTBOX_BUTTON_PADDING; buttonBounds.y = bounds.y + bounds.height - RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT - RAYGUI_TEXTINPUTBOX_BUTTON_PADDING; @@ -5119,11 +5119,11 @@ static const char *GetTextIcon(const char *text, int *iconId) // Get text divided into lines (by line-breaks '\n') // WARNING: It returns pointers to new lines but it does not add NULL ('\0') terminator! -static const char **GetTextLines(const char *text, int *count) +static char **GetTextLines(const char *text, int *count) { #define RAYGUI_MAX_TEXT_LINES 128 - static const char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 }; + static char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 }; for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings int textLength = (int)strlen(text); @@ -5131,12 +5131,11 @@ static const char **GetTextLines(const char *text, int *count) lines[0] = text; *count = 1; - for (int i = 0, k = 0; (i < textLength) && (*count < RAYGUI_MAX_TEXT_LINES); i++) + for (int i = 0; (i < textLength) && (*count < RAYGUI_MAX_TEXT_LINES); i++) { - if (text[i] == '\n') + if ((text[i] == '\n') && ((i + 1) < textLength)) { - k++; - lines[k] = &text[i + 1]; // WARNING: next value is valid? + lines[*count] = &text[i + 1]; *count += 1; } } @@ -5194,7 +5193,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C // WARNING: GuiTextSplit() function can't be used now because it can have already been used // before the GuiDrawText() call and its buffer is static, it would be overriden :( int lineCount = 0; - const char **lines = GetTextLines(text, &lineCount); + char **lines = GetTextLines(text, &lineCount); // Text style variables //int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT); @@ -5444,7 +5443,7 @@ static void GuiTooltip(Rectangle controlRec) // Split controls text into multiple strings // Also check for multiple columns (required by GuiToggleGroup()) -static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow) +static char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow) { // NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter) // inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated, @@ -5463,8 +5462,8 @@ static const char **GuiTextSplit(const char *text, char delimiter, int *count, i #define RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE 1024 #endif - static const char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data) - static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; // Buffer data (text input copy with '\0' added) + static char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data) + static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; // Buffer data (text input copy with '\0' added) memset(buffer, 0, RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE); result[0] = buffer; @@ -5863,7 +5862,7 @@ static void DrawRectangleGradientV(int posX, int posY, int width, int height, Co } // Split string into multiple strings -const char **TextSplit(const char *text, char delimiter, int *count) +char **TextSplit(const char *text, char delimiter, int *count) { // NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter) // inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated, diff --git a/examples/shapes/raygui.h b/examples/shapes/raygui.h index 67c16be45..42c5ae7bc 100644 --- a/examples/shapes/raygui.h +++ b/examples/shapes/raygui.h @@ -772,7 +772,7 @@ RAYGUIAPI int GuiWindowBox(Rectangle bounds, const char *title); RAYGUIAPI int GuiGroupBox(Rectangle bounds, const char *text); // Group Box control with text name RAYGUIAPI int GuiLine(Rectangle bounds, const char *text); // Line separator control, could contain text RAYGUIAPI int GuiPanel(Rectangle bounds, const char *text); // Panel control, useful to group controls -RAYGUIAPI int GuiTabBar(Rectangle bounds, const char **text, int count, int *active); // Tab Bar control, returns TAB to be closed or -1 +RAYGUIAPI int GuiTabBar(Rectangle bounds, char **text, int count, int *active); // Tab Bar control, returns TAB to be closed or -1 RAYGUIAPI int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector2 *scroll, Rectangle *view); // Scroll Panel control // Basic controls set @@ -800,7 +800,7 @@ RAYGUIAPI int GuiGrid(Rectangle bounds, const char *text, float spacing, int sub // Advance controls set RAYGUIAPI int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *active); // List View control -RAYGUIAPI int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus); // List View with extended parameters +RAYGUIAPI int GuiListViewEx(Rectangle bounds, char **text, int count, int *scrollIndex, int *active, int *focus); // List View with extended parameters RAYGUIAPI int GuiMessageBox(Rectangle bounds, const char *title, const char *message, const char *buttons); // Message Box control, displays a message RAYGUIAPI int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, const char *buttons, char *text, int textMaxSize, bool *secretViewActive); // Text Input Box control, ask for text, supports secret RAYGUIAPI int GuiColorPicker(Rectangle bounds, const char *text, Color *color); // Color Picker control (multiple color controls) @@ -1526,7 +1526,7 @@ static Color GetColor(int hexValue); // Returns a Color struct fr static int ColorToInt(Color color); // Returns hexadecimal value for a Color static bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle static const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed' -static const char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings +static char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings static int TextToInteger(const char *text); // Get integer value from text static float TextToFloat(const char *text); // Get float value from text @@ -1549,7 +1549,7 @@ static const char *GetTextIcon(const char *text, int *iconId); // Get text icon static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, Color tint); // Gui draw text using default font static void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor, Color color); // Gui draw rectangle using default raygui style -static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow); // Split controls text into multiple strings +static char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow); // Split controls text into multiple strings static Vector3 ConvertHSVtoRGB(Vector3 hsv); // Convert color data from HSV to RGB static Vector3 ConvertRGBtoHSV(Vector3 rgb); // Convert color data from RGB to HSV @@ -1783,7 +1783,7 @@ int GuiPanel(Rectangle bounds, const char *text) // Tab Bar control // NOTE: Using GuiToggle() for the TABS -int GuiTabBar(Rectangle bounds, const char **text, int count, int *active) +int GuiTabBar(Rectangle bounds, char **text, int count, int *active) { #define RAYGUI_TABBAR_ITEM_WIDTH 148 @@ -2168,7 +2168,7 @@ int GuiToggleGroup(Rectangle bounds, const char *text, int *active) // Get substrings items from text (items pointers) int rows[RAYGUI_TOGGLEGROUP_MAX_ITEMS] = { 0 }; int itemCount = 0; - const char **items = GuiTextSplit(text, ';', &itemCount, rows); + char **items = GuiTextSplit(text, ';', &itemCount, rows); int prevRow = rows[0]; @@ -2212,7 +2212,7 @@ int GuiToggleSlider(Rectangle bounds, const char *text, int *active) // Get substrings items from text (items pointers) int itemCount = 0; - const char **items = NULL; + char **items = NULL; if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL); @@ -2356,7 +2356,7 @@ int GuiComboBox(Rectangle bounds, const char *text, int *active) // Get substrings items from text (items pointers, lengths and count) int itemCount = 0; - const char **items = GuiTextSplit(text, ';', &itemCount, NULL); + char **items = GuiTextSplit(text, ';', &itemCount, NULL); if (*active < 0) *active = 0; else if (*active > (itemCount - 1)) *active = itemCount - 1; @@ -2422,7 +2422,7 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod // Get substrings items from text (items pointers, lengths and count) int itemCount = 0; - const char **items = GuiTextSplit(text, ';', &itemCount, NULL); + char **items = GuiTextSplit(text, ';', &itemCount, NULL); Rectangle boundsOpen = bounds; boundsOpen.height = (itemCount + 1)*(bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING)); @@ -3602,7 +3602,7 @@ int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *activ { int result = 0; int itemCount = 0; - const char **items = NULL; + char **items = NULL; if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL); @@ -3612,7 +3612,7 @@ int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *activ } // List View control with extended parameters -int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus) +int GuiListViewEx(Rectangle bounds, char **text, int count, int *scrollIndex, int *active, int *focus) { int result = 0; GuiState state = guiState; @@ -4140,7 +4140,7 @@ int GuiMessageBox(Rectangle bounds, const char *title, const char *message, cons int result = -1; // Returns clicked button from buttons list, 0 refers to closed window button int buttonCount = 0; - const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL); + char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL); Rectangle buttonBounds = { 0 }; buttonBounds.x = bounds.x + RAYGUI_MESSAGEBOX_BUTTON_PADDING; buttonBounds.y = bounds.y + bounds.height - RAYGUI_MESSAGEBOX_BUTTON_HEIGHT - RAYGUI_MESSAGEBOX_BUTTON_PADDING; @@ -4199,7 +4199,7 @@ int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, co int result = -1; int buttonCount = 0; - const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL); + char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL); Rectangle buttonBounds = { 0 }; buttonBounds.x = bounds.x + RAYGUI_TEXTINPUTBOX_BUTTON_PADDING; buttonBounds.y = bounds.y + bounds.height - RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT - RAYGUI_TEXTINPUTBOX_BUTTON_PADDING; @@ -5119,11 +5119,11 @@ static const char *GetTextIcon(const char *text, int *iconId) // Get text divided into lines (by line-breaks '\n') // WARNING: It returns pointers to new lines but it does not add NULL ('\0') terminator! -static const char **GetTextLines(const char *text, int *count) +static char **GetTextLines(const char *text, int *count) { #define RAYGUI_MAX_TEXT_LINES 128 - static const char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 }; + static char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 }; for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings int textLength = (int)strlen(text); @@ -5131,12 +5131,11 @@ static const char **GetTextLines(const char *text, int *count) lines[0] = text; *count = 1; - for (int i = 0, k = 0; (i < textLength) && (*count < RAYGUI_MAX_TEXT_LINES); i++) + for (int i = 0; (i < textLength) && (*count < RAYGUI_MAX_TEXT_LINES); i++) { - if (text[i] == '\n') + if ((text[i] == '\n') && ((i + 1) < textLength)) { - k++; - lines[k] = &text[i + 1]; // WARNING: next value is valid? + lines[*count] = &text[i + 1]; *count += 1; } } @@ -5194,7 +5193,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C // WARNING: GuiTextSplit() function can't be used now because it can have already been used // before the GuiDrawText() call and its buffer is static, it would be overriden :( int lineCount = 0; - const char **lines = GetTextLines(text, &lineCount); + char **lines = GetTextLines(text, &lineCount); // Text style variables //int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT); @@ -5444,7 +5443,7 @@ static void GuiTooltip(Rectangle controlRec) // Split controls text into multiple strings // Also check for multiple columns (required by GuiToggleGroup()) -static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow) +static char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow) { // NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter) // inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated, @@ -5463,8 +5462,8 @@ static const char **GuiTextSplit(const char *text, char delimiter, int *count, i #define RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE 1024 #endif - static const char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data) - static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; // Buffer data (text input copy with '\0' added) + static char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data) + static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; // Buffer data (text input copy with '\0' added) memset(buffer, 0, RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE); result[0] = buffer; @@ -5863,7 +5862,7 @@ static void DrawRectangleGradientV(int posX, int posY, int width, int height, Co } // Split string into multiple strings -const char **TextSplit(const char *text, char delimiter, int *count) +char **TextSplit(const char *text, char delimiter, int *count) { // NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter) // inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated, From 005ff74eb08a0bb6b9ccb825b7c84a8fe146b096 Mon Sep 17 00:00:00 2001 From: David Reid Date: Sat, 21 Feb 2026 17:02:40 +1000 Subject: [PATCH 230/232] Audio: Improvements to device configuration (#5577) * Audio: Stop setting capture config options. Since the device is being configured as a playback device, all capture config options are unused and therefore need to not be set. * Audio: Stop pre-silencing the miniaudio output buffer. raylib already manually silences the output buffer prior to mixing so there is no reason to have miniaudio also do it. It can therefore be disabled via the device config to make data processing slightly more efficient. * Audio: Stop forcing fixed sized processing callbacks. There is no requirement for raylib to have guaranteed fixed sized audio processing. By disabling it, audio processing can be made more efficient by not having to run the data through an internal intermediary buffer. * Audio: Make the period size (latency) configurable. The default period size is 10ms, but this is inappropriate for certain platforms so it is useful to be able to allow those platforms to configure the period size as required. * Audio: Fix documentation for pan. The pan if -1..1, not 0..1. --- src/config.h | 1 + src/raudio.c | 11 +++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/config.h b/src/config.h index 5e7c6f1d2..3beaeeceb 100644 --- a/src/config.h +++ b/src/config.h @@ -303,6 +303,7 @@ #define AUDIO_DEVICE_FORMAT ma_format_f32 // Device output format (miniaudio: float-32bit) #define AUDIO_DEVICE_CHANNELS 2 // Device output channels: stereo #define AUDIO_DEVICE_SAMPLE_RATE 0 // Device sample rate (device default) +#define AUDIO_DEVICE_PERIOD_SIZE_IN_FRAMES 0 // Device period size (controls latency, 0 defaults to 10ms) #define MAX_AUDIO_BUFFER_POOL_CHANNELS 16 // Maximum number of audio pool channels diff --git a/src/raudio.c b/src/raudio.c index 8322f1baf..848b48c4d 100644 --- a/src/raudio.c +++ b/src/raudio.c @@ -290,6 +290,9 @@ typedef struct tagBITMAPINFOHEADER { #ifndef AUDIO_DEVICE_SAMPLE_RATE #define AUDIO_DEVICE_SAMPLE_RATE 0 // Device output sample rate #endif +#ifndef AUDIO_DEVICE_PERIOD_SIZE_IN_FRAMES + #define AUDIO_DEVICE_PERIOD_SIZE_IN_FRAMES 0 // Device latency. 0 defaults to 10ms +#endif #ifndef MAX_AUDIO_BUFFER_POOL_CHANNELS #define MAX_AUDIO_BUFFER_POOL_CHANNELS 16 // Audio pool channels @@ -349,7 +352,7 @@ struct rAudioBuffer { float volume; // Audio buffer volume float pitch; // Audio buffer pitch - float pan; // Audio buffer pan (0.0f to 1.0f) + float pan; // Audio buffer pan (-1.0f to 1.0f) bool playing; // Audio buffer state: AUDIO_PLAYING bool paused; // Audio buffer state: AUDIO_PAUSED @@ -477,12 +480,12 @@ void InitAudioDevice(void) config.playback.pDeviceID = NULL; // NULL for the default playback AUDIO.System.device config.playback.format = AUDIO_DEVICE_FORMAT; config.playback.channels = AUDIO_DEVICE_CHANNELS; - config.capture.pDeviceID = NULL; // NULL for the default capture AUDIO.System.device - config.capture.format = ma_format_s16; - config.capture.channels = 1; config.sampleRate = AUDIO_DEVICE_SAMPLE_RATE; + config.periodSizeInFrames = AUDIO_DEVICE_PERIOD_SIZE_IN_FRAMES; config.dataCallback = OnSendAudioDataToDevice; config.pUserData = NULL; + config.noPreSilencedOutputBuffer = true; // raylib pre-silences the output buffer manually + config.noFixedSizedCallback = true; // raylib does not require fixed sized callback guarantees. This bypasses an internal intermediary buffer result = ma_device_init(&AUDIO.System.context, &config, &AUDIO.System.device); if (result != MA_SUCCESS) From 0c91f230fd9a7056bb51870dbb8c5ec305c02e10 Mon Sep 17 00:00:00 2001 From: David Reid Date: Sat, 21 Feb 2026 17:04:32 +1000 Subject: [PATCH 231/232] Audio: Fix a glitch at the end of a sound. (#5578) This is happening because the processing function keeps reading audio data from the AudioBuffer even after it has been marked as stopped. There is also an error in ReadAudioBufferFramesInInternalFormat() where if it is called on a stopped sound, it'll still return audio frames. This has also been addressed with this commit. --- src/raudio.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/raudio.c b/src/raudio.c index 848b48c4d..4866f32f9 100644 --- a/src/raudio.c +++ b/src/raudio.c @@ -2377,6 +2377,12 @@ static void OnLog(void *pUserData, ma_uint32 level, const char *pMessage) // Reads audio data from an AudioBuffer object in internal format static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer, void *framesOut, ma_uint32 frameCount) { + // Don't read anything if the sound is not playing + if (!audioBuffer->playing) + { + return 0; + } + // Using audio buffer callback if (audioBuffer->callback) { @@ -2522,18 +2528,20 @@ static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, f { estimatedInputFrameCount = inputBufferFrameCap; } + + ma_uint32 inputFramesInInternalFormatCount = ReadAudioBufferFramesInInternalFormat(audioBuffer, inputBuffer, estimatedInputFrameCount); - estimatedInputFrameCount = ReadAudioBufferFramesInInternalFormat(audioBuffer, inputBuffer, estimatedInputFrameCount); - - ma_uint64 inputFramesProcessedThisIteration = estimatedInputFrameCount; + ma_uint64 inputFramesProcessedThisIteration = inputFramesInInternalFormatCount; ma_uint64 outputFramesProcessedThisIteration = outputFramesToProcessThisIteration; ma_data_converter_process_pcm_frames(&audioBuffer->converter, inputBuffer, &inputFramesProcessedThisIteration, runningFramesOut, &outputFramesProcessedThisIteration); - if (estimatedInputFrameCount > inputFramesProcessedThisIteration) + totalOutputFramesProcessed += (ma_uint32)outputFramesProcessedThisIteration; + + if (inputFramesInInternalFormatCount > inputFramesProcessedThisIteration) { // Getting here means the estimated input frame count was overestimated. The residual needs // be stored for later use. - ma_uint64 residualFrameCount = estimatedInputFrameCount - inputFramesProcessedThisIteration; + ma_uint64 residualFrameCount = inputFramesInInternalFormatCount - inputFramesProcessedThisIteration; // A safety check to make sure the capacity of the residual cache is not exceeded. if (residualFrameCount > AUDIO_BUFFER_RESIDUAL_CAPACITY) @@ -2545,7 +2553,9 @@ static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, f audioBuffer->converterResidualCount = residualFrameCount; } - totalOutputFramesProcessed += (ma_uint32)outputFramesProcessedThisIteration; + if (inputFramesInInternalFormatCount < estimatedInputFrameCount) { + break; // Reached the end of the sound + } } } From 11e3e6e0b994d0543cb83e253438e08402dba014 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 21 Feb 2026 09:09:43 +0100 Subject: [PATCH 232/232] REVIEWED: Formating, tested sound examples --- src/raudio.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/src/raudio.c b/src/raudio.c index 4866f32f9..2740462b4 100644 --- a/src/raudio.c +++ b/src/raudio.c @@ -2378,10 +2378,7 @@ static void OnLog(void *pUserData, ma_uint32 level, const char *pMessage) static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer, void *framesOut, ma_uint32 frameCount) { // Don't read anything if the sound is not playing - if (!audioBuffer->playing) - { - return 0; - } + if (!audioBuffer->playing) return 0; // Using audio buffer callback if (audioBuffer->callback) @@ -2519,16 +2516,9 @@ static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, f // When the guess is overestimated, that's when it gets more complicated. In this case, any overflow // needs to be stored in a buffer for later processing by the next read. ma_uint32 estimatedInputFrameCount = (ma_uint32)(((float)audioBuffer->converter.resampler.sampleRateIn / audioBuffer->converter.resampler.sampleRateOut) * outputFramesToProcessThisIteration); - if (estimatedInputFrameCount == 0) - { - estimatedInputFrameCount = 1; // Make sure at least one input frame is read. - } + if (estimatedInputFrameCount == 0) estimatedInputFrameCount = 1; // Make sure at least one input frame is read. + if (estimatedInputFrameCount > inputBufferFrameCap) estimatedInputFrameCount = inputBufferFrameCap; - if (estimatedInputFrameCount > inputBufferFrameCap) - { - estimatedInputFrameCount = inputBufferFrameCap; - } - ma_uint32 inputFramesInInternalFormatCount = ReadAudioBufferFramesInInternalFormat(audioBuffer, inputBuffer, estimatedInputFrameCount); ma_uint64 inputFramesProcessedThisIteration = inputFramesInInternalFormatCount; @@ -2553,9 +2543,7 @@ static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, f audioBuffer->converterResidualCount = residualFrameCount; } - if (inputFramesInInternalFormatCount < estimatedInputFrameCount) { - break; // Reached the end of the sound - } + if (inputFramesInInternalFormatCount < estimatedInputFrameCount) break; // Reached the end of the sound } }